Browse Source

Added C++ component wrappers for physics joints

BearishSun 10 years ago
parent
commit
8f58454d3e
50 changed files with 2047 additions and 30 deletions
  1. 21 0
      BansheeCore/BansheeCore.vcxproj
  2. 63 0
      BansheeCore/BansheeCore.vcxproj.filters
  3. 1 1
      BansheeCore/Include/BsCBoxColliderRTTI.h
  4. 1 1
      BansheeCore/Include/BsCCollider.h
  5. 117 0
      BansheeCore/Include/BsCD6Joint.h
  6. 128 0
      BansheeCore/Include/BsCD6JointRTTI.h
  7. 89 0
      BansheeCore/Include/BsCDistanceJoint.h
  8. 56 0
      BansheeCore/Include/BsCDistanceJointRTTI.h
  9. 50 0
      BansheeCore/Include/BsCFixedJoint.h
  10. 42 0
      BansheeCore/Include/BsCFixedJointRTTI.h
  11. 78 0
      BansheeCore/Include/BsCHingeJoint.h
  12. 66 0
      BansheeCore/Include/BsCHingeJointRTTI.h
  13. 124 0
      BansheeCore/Include/BsCJoint.h
  14. 64 0
      BansheeCore/Include/BsCJointRTTI.h
  15. 71 0
      BansheeCore/Include/BsCSliderJoint.h
  16. 58 0
      BansheeCore/Include/BsCSliderJointRTTI.h
  17. 65 0
      BansheeCore/Include/BsCSphericalJoint.h
  18. 58 0
      BansheeCore/Include/BsCSphericalJointRTTI.h
  19. 3 1
      BansheeCore/Include/BsComponent.h
  20. 8 1
      BansheeCore/Include/BsCorePrerequisites.h
  21. 9 3
      BansheeCore/Include/BsD6Joint.h
  22. 1 1
      BansheeCore/Include/BsDistanceJoint.h
  23. 1 1
      BansheeCore/Include/BsFJoint.h
  24. 8 2
      BansheeCore/Include/BsHingeJoint.h
  25. 30 1
      BansheeCore/Include/BsJoint.h
  26. 7 0
      BansheeCore/Include/BsSceneObject.h
  27. 1 1
      BansheeCore/Include/BsSliderJoint.h
  28. 1 1
      BansheeCore/Include/BsSphericalJoint.h
  29. 177 0
      BansheeCore/Source/BsCD6Joint.cpp
  30. 121 0
      BansheeCore/Source/BsCDistanceJoint.cpp
  31. 30 0
      BansheeCore/Source/BsCFixedJoint.cpp
  32. 97 0
      BansheeCore/Source/BsCHingeJoint.cpp
  33. 216 0
      BansheeCore/Source/BsCJoint.cpp
  34. 81 0
      BansheeCore/Source/BsCSliderJoint.cpp
  35. 65 0
      BansheeCore/Source/BsCSphericalJoint.cpp
  36. 2 2
      BansheeCore/Source/BsJoint.cpp
  37. 9 0
      BansheeCore/Source/BsSceneObject.cpp
  38. 1 1
      BansheePhysX/Include/BsFPhysXJoint.h
  39. 1 1
      BansheePhysX/Include/BsPhysXDistanceJoint.h
  40. 2 2
      BansheePhysX/Include/BsPhysXHingeJoint.h
  41. 1 1
      BansheePhysX/Include/BsPhysXSliderJoint.h
  42. 1 1
      BansheePhysX/Include/BsPhysXSphericalJoint.h
  43. 1 1
      BansheePhysX/Source/BsFPhysXJoint.cpp
  44. 1 1
      BansheePhysX/Source/BsPhysXDistanceJoint.cpp
  45. 2 2
      BansheePhysX/Source/BsPhysXHingeJoint.cpp
  46. 1 1
      BansheePhysX/Source/BsPhysXSliderJoint.cpp
  47. 1 1
      BansheePhysX/Source/BsPhysXSphericalJoint.cpp
  48. 12 0
      BansheeUtility/Include/BsRTTIType.h
  49. 2 0
      BansheeUtility/Source/BsQuaternion.cpp
  50. 2 2
      SBansheeEngine/Source/BsManagedComponent.cpp

+ 21 - 0
BansheeCore/BansheeCore.vcxproj

@@ -304,6 +304,14 @@
     <ClInclude Include="Include\BsCCapsuleColliderRTTI.h" />
     <ClInclude Include="Include\BsCCollider.h" />
     <ClInclude Include="Include\BsCColliderRTTI.h" />
+    <ClInclude Include="Include\BsCD6Joint.h" />
+    <ClInclude Include="Include\BsCD6JointRTTI.h" />
+    <ClInclude Include="Include\BsCDistanceJoint.h" />
+    <ClInclude Include="Include\BsCDistanceJointRTTI.h" />
+    <ClInclude Include="Include\BsCFixedJointRTTI.h" />
+    <ClInclude Include="Include\BsCHingeJoint.h" />
+    <ClInclude Include="Include\BsCHingeJointRTTI.h" />
+    <ClInclude Include="Include\BsCJointRTTI.h" />
     <ClInclude Include="Include\BsCMeshCollider.h" />
     <ClInclude Include="Include\BsCMeshColliderRTTI.h" />
     <ClInclude Include="Include\BsCollider.h" />
@@ -313,8 +321,12 @@
     <ClInclude Include="Include\BsCPlaneColliderRTTI.h" />
     <ClInclude Include="Include\BsCRigidbody.h" />
     <ClInclude Include="Include\BsCRigidbodyRTTI.h" />
+    <ClInclude Include="Include\BsCSliderJoint.h" />
+    <ClInclude Include="Include\BsCSliderJointRTTI.h" />
     <ClInclude Include="Include\BsCSphereCollider.h" />
     <ClInclude Include="Include\BsCSphereColliderRTTI.h" />
+    <ClInclude Include="Include\BsCSphericalJoint.h" />
+    <ClInclude Include="Include\BsCSphericalJointRTTI.h" />
     <ClInclude Include="Include\BsD6Joint.h" />
     <ClInclude Include="Include\BsDistanceJoint.h" />
     <ClInclude Include="Include\BsFCollider.h" />
@@ -489,6 +501,8 @@
     <ClInclude Include="Include\BsTechnique.h" />
     <ClInclude Include="Include\BsViewportRTTI.h" />
     <ClInclude Include="Include\BsPhysicsManager.h" />
+    <ClInclude Include="Include\BsCJoint.h" />
+    <ClInclude Include="Include\BsCFixedJoint.h" />
     <ClInclude Include="Include\Win32\BsWin32Defs.h" />
     <ClInclude Include="Include\Win32\BsWin32Platform.h" />
     <ClInclude Include="Include\Win32\BsWin32DropTarget.h" />
@@ -502,13 +516,20 @@
     <ClCompile Include="Source\BsCBoxCollider.cpp" />
     <ClCompile Include="Source\BsCCapsuleCollider.cpp" />
     <ClCompile Include="Source\BsCCollider.cpp" />
+    <ClCompile Include="Source\BsCD6Joint.cpp" />
+    <ClCompile Include="Source\BsCDistanceJoint.cpp" />
+    <ClCompile Include="Source\BsCFixedJoint.cpp" />
+    <ClCompile Include="Source\BsCHingeJoint.cpp" />
+    <ClCompile Include="Source\BsCJoint.cpp" />
     <ClCompile Include="Source\BsCMeshCollider.cpp" />
     <ClCompile Include="Source\BsCollider.cpp" />
     <ClCompile Include="Source\BsCoreObjectCore.cpp" />
     <ClCompile Include="Source\BsCoreThread.cpp" />
     <ClCompile Include="Source\BsCPlaneCollider.cpp" />
     <ClCompile Include="Source\BsCRigidbody.cpp" />
+    <ClCompile Include="Source\BsCSliderJoint.cpp" />
     <ClCompile Include="Source\BsCSphereCollider.cpp" />
+    <ClCompile Include="Source\BsCSphericalJoint.cpp" />
     <ClCompile Include="Source\BsD6Joint.cpp" />
     <ClCompile Include="Source\BsDistanceJoint.cpp" />
     <ClCompile Include="Source\BsFCollider.cpp" />

+ 63 - 0
BansheeCore/BansheeCore.vcxproj.filters

@@ -704,6 +704,48 @@
     <ClInclude Include="Include\BsD6Joint.h">
       <Filter>Header Files\Physics</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsCJoint.h">
+      <Filter>Header Files\Components</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCJointRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCFixedJoint.h">
+      <Filter>Header Files\Components</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCFixedJointRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCHingeJoint.h">
+      <Filter>Header Files\Components</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCHingeJointRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCDistanceJoint.h">
+      <Filter>Header Files\Components</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCDistanceJointRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCSliderJoint.h">
+      <Filter>Header Files\Components</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCSliderJointRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCSphericalJoint.h">
+      <Filter>Header Files\Components</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCSphericalJointRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCD6Joint.h">
+      <Filter>Header Files\Components</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCD6JointRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsCoreApplication.cpp">
@@ -1117,5 +1159,26 @@
     <ClCompile Include="Source\BsD6Joint.cpp">
       <Filter>Source Files\Physics</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsCJoint.cpp">
+      <Filter>Source Files\Components</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCFixedJoint.cpp">
+      <Filter>Source Files\Components</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCHingeJoint.cpp">
+      <Filter>Source Files\Components</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCDistanceJoint.cpp">
+      <Filter>Source Files\Components</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCSliderJoint.cpp">
+      <Filter>Source Files\Components</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCSphericalJoint.cpp">
+      <Filter>Source Files\Components</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCD6Joint.cpp">
+      <Filter>Source Files\Components</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 1
BansheeCore/Include/BsCBoxColliderRTTI.h

@@ -36,7 +36,7 @@ namespace BansheeEngine
 			return TID_CBoxCollider;
 		}
 
-		std::shared_ptr<IReflectable> newRTTIObject() override
+		SPtr<IReflectable> newRTTIObject() override
 		{
 			return GameObjectRTTI::createGameObject<CBoxCollider>();
 		}

+ 1 - 1
BansheeCore/Include/BsCCollider.h

@@ -3,7 +3,7 @@
 #pragma once
 
 #include "BsCorePrerequisites.h"
-#include "BsBoxCollider.h"
+#include "BsCollider.h"
 #include "BsComponent.h"
 
 namespace BansheeEngine 

+ 117 - 0
BansheeCore/Include/BsCD6Joint.h

@@ -0,0 +1,117 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsD6Joint.h"
+#include "BsCJoint.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup Components-Core
+	 *  @{
+	 */
+
+	/**
+	 * @copydoc	D6Joint
+	 *
+	 * Wraps D6Joint as a Component.
+	 */
+    class BS_CORE_EXPORT CD6Joint : public CJoint
+    {
+    public:
+		CD6Joint(const HSceneObject& parent);
+
+		/** @copydoc D6Joint::getMotion */
+		inline D6Joint::Motion getMotion(D6Joint::Axis axis) const;
+
+		/** @copydoc D6Joint::setMotion */
+		inline void setMotion(D6Joint::Axis axis, D6Joint::Motion motion);
+
+		/** @copydoc D6Joint::getTwist */
+		inline Radian getTwist() const;
+
+		/** @copydoc D6Joint::getSwingY */
+		inline Radian getSwingY() const;
+
+		/** @copydoc D6Joint::getSwingZ */
+		inline Radian getSwingZ() const;
+
+		/** @copydoc D6Joint::getLimitLinear */
+		inline LimitLinear getLimitLinear() const;
+
+		/** @copydoc D6Joint::setLimitLinear */
+		inline void setLimitLinear(const LimitLinear& limit);
+
+		/** @copydoc D6Joint::getLimitTwist */
+		inline LimitAngularRange getLimitTwist() const;
+
+		/** @copydoc D6Joint::setLimitTwist */
+		inline void setLimitTwist(const LimitAngularRange& limit);
+
+		/** @copydoc D6Joint::getLimitSwing */
+		inline LimitConeRange getLimitSwing() const;
+
+		/** @copydoc D6Joint::setLimitSwing */
+		inline void setLimitSwing(const LimitConeRange& limit);
+
+		/** @copydoc D6Joint::getDrive */
+		inline D6Joint::Drive getDrive(D6Joint::DriveType type) const;
+
+		/** @copydoc D6Joint::setDrive */
+		inline void setDrive(D6Joint::DriveType type, const D6Joint::Drive& drive);
+
+		/** @copydoc D6Joint::getDrivePosition */
+		inline Vector3 getDrivePosition() const;
+
+		/** @copydoc D6Joint::getDriveRotation */
+		inline Quaternion getDriveRotation() const;
+
+		/** @copydoc D6Joint::setDriveTransform */
+		inline void setDriveTransform(const Vector3& position, const Quaternion& rotation);
+
+		/** @copydoc D6Joint::getDriveLinearVelocity */
+		inline Vector3 getDriveLinearVelocity() const;
+
+		/** @copydoc D6Joint::getDriveAngularVelocity */
+		inline Vector3 getDriveAngularVelocity() const;
+
+		/** @copydoc D6Joint::setDriveVelocity */
+		inline void setDriveVelocity(const Vector3& linear, const Vector3& angular);
+
+	    /**	Returns the D6 joint that this component wraps. */
+		SPtr<D6Joint> _getInternal() const { return std::static_pointer_cast<D6Joint>(mInternal); }
+
+		/************************************************************************/
+		/* 						COMPONENT OVERRIDES                      		*/
+		/************************************************************************/
+	protected:
+		friend class SceneObject;
+
+		/** @copydoc CJoint::createInternal */
+		SPtr<Joint> createInternal() override;
+
+		D6Joint::Motion mMotion[(UINT32)D6Joint::Motion::Count];
+		D6Joint::Drive mDrive[(UINT32)D6Joint::DriveType::Count];
+		LimitLinear mLimitLinear;
+		LimitAngularRange mLimitTwist;
+		LimitConeRange mLimitSwing;
+		Vector3 mDrivePosition;
+		Quaternion mDriveRotation;
+		Vector3 mDriveLinearVelocity;
+		Vector3 mDriveAngularVelocity;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class CD6JointRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+	protected:
+		CD6Joint() {} // Serialization only
+     };
+
+	 /** @} */
+}

+ 128 - 0
BansheeCore/Include/BsCD6JointRTTI.h

@@ -0,0 +1,128 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsCD6Joint.h"
+#include "BsGameObjectRTTI.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	float stiffness = 0.0f;
+	float damping = 0.0f;
+	float forceLimit = FLT_MAX;
+	bool acceleration = false;
+
+	class BS_CORE_EXPORT CD6JointRTTI : public RTTIType<CD6Joint, CJoint, CD6JointRTTI>
+	{
+		D6Joint::Motion& getMotion(CD6Joint* obj, UINT32 idx) { return obj->mMotion[idx]; }
+		void setMotion(CD6Joint* obj, UINT32 idx, D6Joint::Motion& value) { obj->mMotion[idx] = value; }
+		UINT32 getMotionCount(CD6Joint* obj) { return (UINT32)D6Joint::Motion::Count; }
+		void setMotionCount(CD6Joint* obj, UINT32 size) { /* Do nothing */ }
+
+		float& getDriveStiffness(CD6Joint* obj, UINT32 idx) { return obj->mDrive[idx].stiffness; }
+		void setDriveStiffness(CD6Joint* obj, UINT32 idx, float& value) { obj->mDrive[idx].stiffness = value; }
+
+		float& getDriveDamping(CD6Joint* obj, UINT32 idx) { return obj->mDrive[idx].damping; }
+		void setDriveDamping(CD6Joint* obj, UINT32 idx, float& value) { obj->mDrive[idx].damping = value; }
+
+		float& getDriveForceLimit(CD6Joint* obj, UINT32 idx) { return obj->mDrive[idx].forceLimit; }
+		void setDriveForceLimit(CD6Joint* obj, UINT32 idx, float& value) { obj->mDrive[idx].forceLimit = value; }
+
+		bool& getDriveAcceleration(CD6Joint* obj, UINT32 idx) { return obj->mDrive[idx].acceleration; }
+		void setDriveAcceleration(CD6Joint* obj, UINT32 idx, bool& value) { obj->mDrive[idx].acceleration = value; }
+
+		UINT32 getDriveCount(CD6Joint* obj) { return (UINT32)D6Joint::DriveType::Count; }
+		void setDriveCount(CD6Joint* obj, UINT32 size) { /* Do nothing */ }
+
+		BS_PLAIN_MEMBER_NAMED(mLimitLinearExtent, mLimitLinear.extent)
+		BS_PLAIN_MEMBER_NAMED(mLimitLinearContactDist, mLimitTwist.contactDist)
+		BS_PLAIN_MEMBER_NAMED(mLimitLinearRestitution, mLimitTwist.restitution)
+		BS_PLAIN_MEMBER_NAMED(mLimitLinearSpringDamping, mLimitTwist.spring.damping)
+		BS_PLAIN_MEMBER_NAMED(mLimitLinearSpringStiffness, mLimitTwist.spring.stiffness)
+
+		BS_PLAIN_MEMBER_NAMED(mLimitTwistLower, mLimitTwist.lower)
+		BS_PLAIN_MEMBER_NAMED(mLimitTwistUpper, mLimitTwist.upper)
+		BS_PLAIN_MEMBER_NAMED(mLimitTwistContactDist, mLimitTwist.contactDist)
+		BS_PLAIN_MEMBER_NAMED(mLimitTwistRestitution, mLimitTwist.restitution)
+		BS_PLAIN_MEMBER_NAMED(mLimitTwistSpringDamping, mLimitTwist.spring.damping)
+		BS_PLAIN_MEMBER_NAMED(mLimitTwistSpringStiffness, mLimitTwist.spring.stiffness)
+
+		BS_PLAIN_MEMBER_NAMED(mLimitSwingYLimitAngle, mLimitSwing.yLimitAngle)
+		BS_PLAIN_MEMBER_NAMED(mLimitSwingZLimitAngle, mLimitSwing.zLimitAngle)
+		BS_PLAIN_MEMBER_NAMED(mLimitSwingContactDist, mLimitSwing.contactDist)
+		BS_PLAIN_MEMBER_NAMED(mLimitSwingRestitution, mLimitSwing.restitution)
+		BS_PLAIN_MEMBER_NAMED(mLimitSwingSpringDamping, mLimitSwing.spring.damping)
+		BS_PLAIN_MEMBER_NAMED(mLimitSwingSpringStiffness, mLimitSwing.spring.stiffness)
+
+		BS_PLAIN_MEMBER(mDrivePosition)
+		BS_PLAIN_MEMBER(mDriveRotation)
+		BS_PLAIN_MEMBER(mDriveLinearVelocity)
+		BS_PLAIN_MEMBER(mDriveAngularVelocity)
+
+	public:
+		CD6JointRTTI()
+		{
+			addPlainArrayField("mMotion", 0, &CD6JointRTTI::getMotion, &CD6JointRTTI::getMotionCount, 
+				&CD6JointRTTI::setMotion, &CD6JointRTTI::setMotionCount);
+			addPlainArrayField("mDriveStiffnes", 1, &CD6JointRTTI::getDriveStiffness, &CD6JointRTTI::getDriveCount, 
+				&CD6JointRTTI::setDriveStiffness, &CD6JointRTTI::setDriveCount);
+			addPlainArrayField("mDriveDamping", 2, &CD6JointRTTI::getDriveDamping, &CD6JointRTTI::getDriveCount, 
+				&CD6JointRTTI::setDriveDamping, &CD6JointRTTI::setDriveCount);
+			addPlainArrayField("mDriveForceLimit", 3, &CD6JointRTTI::getDriveForceLimit, &CD6JointRTTI::getDriveCount, 
+				&CD6JointRTTI::setDriveForceLimit, &CD6JointRTTI::setDriveCount);
+			addPlainArrayField("mDriveAcceleartion", 4, &CD6JointRTTI::getDriveAcceleration, &CD6JointRTTI::getDriveCount, 
+				&CD6JointRTTI::setDriveAcceleration, &CD6JointRTTI::setDriveCount);
+
+			BS_ADD_PLAIN_FIELD(mLimitLinearExtent, 5);
+			BS_ADD_PLAIN_FIELD(mLimitLinearContactDist, 6);
+			BS_ADD_PLAIN_FIELD(mLimitLinearRestitution, 7);
+			BS_ADD_PLAIN_FIELD(mLimitLinearSpringDamping, 8);
+			BS_ADD_PLAIN_FIELD(mLimitLinearSpringStiffness, 9);
+
+			BS_ADD_PLAIN_FIELD(mLimitTwistLower, 10);
+			BS_ADD_PLAIN_FIELD(mLimitTwistUpper, 11);
+			BS_ADD_PLAIN_FIELD(mLimitTwistContactDist, 12);
+			BS_ADD_PLAIN_FIELD(mLimitTwistRestitution, 13);
+			BS_ADD_PLAIN_FIELD(mLimitTwistSpringDamping, 14);
+			BS_ADD_PLAIN_FIELD(mLimitTwistSpringStiffness, 15);
+
+			BS_ADD_PLAIN_FIELD(mLimitSwingYLimitAngle, 16);
+			BS_ADD_PLAIN_FIELD(mLimitSwingZLimitAngle, 17);
+			BS_ADD_PLAIN_FIELD(mLimitSwingContactDist, 18);
+			BS_ADD_PLAIN_FIELD(mLimitSwingRestitution, 19);
+			BS_ADD_PLAIN_FIELD(mLimitSwingSpringDamping, 20);
+			BS_ADD_PLAIN_FIELD(mLimitSwingSpringStiffness, 21);
+
+			BS_ADD_PLAIN_FIELD(mDrivePosition, 22);
+			BS_ADD_PLAIN_FIELD(mDriveRotation, 23);
+			BS_ADD_PLAIN_FIELD(mDriveLinearVelocity, 24);
+			BS_ADD_PLAIN_FIELD(mDriveAngularVelocity, 25);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "CD6Joint";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_CD6Joint;
+		}
+
+		SPtr<IReflectable> newRTTIObject() override
+		{
+			return GameObjectRTTI::createGameObject<CD6Joint>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 89 - 0
BansheeCore/Include/BsCDistanceJoint.h

@@ -0,0 +1,89 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsDistanceJoint.h"
+#include "BsCJoint.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup Components-Core
+	 *  @{
+	 */
+
+	/**
+	 * @copydoc	DistanceJoint
+	 *
+	 * Wraps DistanceJoint as a Component.
+	 */
+    class BS_CORE_EXPORT CDistanceJoint : public CJoint
+    {
+    public:
+		CDistanceJoint(const HSceneObject& parent);
+
+		/** @copydoc DistanceJoint::getDistance */
+		inline float getDistance() const;
+
+		/** @copydoc DistanceJoint::getMinDistance */
+		inline float getMinDistance() const;
+
+		/** @copydoc DistanceJoint::setMinDistance */
+		inline void setMinDistance(float value);
+
+		/** @copydoc DistanceJoint::getMaxDistance */
+		inline float getMaxDistance() const;
+
+		/** @copydoc DistanceJoint::setMaxDistance */
+		inline void setMaxDistance(float value);
+
+		/** @copydoc DistanceJoint::getTolerance */
+		inline float getTolerance() const;
+
+		/** @copydoc DistanceJoint::setTolerance */
+		inline void setTolerance(float value);
+
+		/** @copydoc DistanceJoint::getSpring */
+		inline Spring getSpring() const;
+
+		/** @copydoc DistanceJoint::setSpring */
+		inline void setSpring(const Spring& value);
+
+		/** @copydoc DistanceJoint::setFlag */
+		inline void setFlag(DistanceJoint::Flag flag, bool enabled);
+
+		/** @copydoc DistanceJoint::hasFlag */
+		inline bool hasFlag(DistanceJoint::Flag flag) const;
+
+	    /**	Returns the distance joint that this component wraps. */
+		SPtr<DistanceJoint> _getInternal() const { return std::static_pointer_cast<DistanceJoint>(mInternal); }
+
+		/************************************************************************/
+		/* 						COMPONENT OVERRIDES                      		*/
+		/************************************************************************/
+	protected:
+		friend class SceneObject;
+
+		/** @copydoc CJoint::createInternal */
+		SPtr<Joint> createInternal() override;
+
+		float mMinDistance = 0.0f;
+		float mMaxDistance = 0.0f;
+		float mTolerance = 0.25f;
+		Spring mSpring;
+		DistanceJoint::Flag mFlag = (DistanceJoint::Flag)0;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class CDistanceJointRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+	protected:
+		CDistanceJoint() {} // Serialization only
+     };
+
+	 /** @} */
+}

+ 56 - 0
BansheeCore/Include/BsCDistanceJointRTTI.h

@@ -0,0 +1,56 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsCDistanceJoint.h"
+#include "BsGameObjectRTTI.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT CDistanceJointRTTI : public RTTIType<CDistanceJoint, CJoint, CDistanceJointRTTI>
+	{
+		BS_PLAIN_MEMBER(mFlag)
+		BS_PLAIN_MEMBER(mMinDistance)
+		BS_PLAIN_MEMBER(mMaxDistance)
+		BS_PLAIN_MEMBER(mTolerance)
+		BS_PLAIN_MEMBER_NAMED(mSpringDamping, mSpring.damping)
+		BS_PLAIN_MEMBER_NAMED(mSpringStiffness, mSpring.stiffness)
+
+	public:
+		CDistanceJointRTTI()
+		{
+			BS_ADD_PLAIN_FIELD(mFlag, 0);
+			BS_ADD_PLAIN_FIELD(mMinDistance, 1);
+			BS_ADD_PLAIN_FIELD(mMaxDistance, 2);
+			BS_ADD_PLAIN_FIELD(mTolerance, 3);
+			BS_ADD_PLAIN_FIELD(mSpringDamping, 4);
+			BS_ADD_PLAIN_FIELD(mSpringStiffness, 5);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "CDistanceJoint";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_CDistanceJoint;
+		}
+
+		SPtr<IReflectable> newRTTIObject() override
+		{
+			return GameObjectRTTI::createGameObject<CDistanceJoint>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 50 - 0
BansheeCore/Include/BsCFixedJoint.h

@@ -0,0 +1,50 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsFixedJoint.h"
+#include "BsCJoint.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup Components-Core
+	 *  @{
+	 */
+
+	/**
+	 * @copydoc	FixedJoint
+	 *
+	 * Wraps FixedJoint as a Component.
+	 */
+    class BS_CORE_EXPORT CFixedJoint : public CJoint
+    {
+    public:
+		CFixedJoint(const HSceneObject& parent);
+
+	    /**	Returns the fixed joint that this component wraps. */
+		SPtr<FixedJoint> _getInternal() const { return std::static_pointer_cast<FixedJoint>(mInternal); }
+
+		/************************************************************************/
+		/* 						COMPONENT OVERRIDES                      		*/
+		/************************************************************************/
+	protected:
+		friend class SceneObject;
+
+		/** @copydoc CJoint::createInternal */
+		SPtr<Joint> createInternal() override;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class CFixedJointRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+	protected:
+		CFixedJoint() {} // Serialization only
+     };
+
+	 /** @} */
+}

+ 42 - 0
BansheeCore/Include/BsCFixedJointRTTI.h

@@ -0,0 +1,42 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsCFixedJoint.h"
+#include "BsGameObjectRTTI.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT CFixedJointRTTI : public RTTIType<CFixedJoint, CJoint, CFixedJointRTTI>
+	{
+	public:
+		CFixedJointRTTI()
+		{ }
+
+		const String& getRTTIName() override
+		{
+			static String name = "CFixedJoint";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_CFixedJoint;
+		}
+
+		SPtr<IReflectable> newRTTIObject() override
+		{
+			return GameObjectRTTI::createGameObject<CFixedJoint>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 78 - 0
BansheeCore/Include/BsCHingeJoint.h

@@ -0,0 +1,78 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsHingeJoint.h"
+#include "BsCJoint.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup Components-Core
+	 *  @{
+	 */
+
+	/**
+	 * @copydoc	HingeJoint
+	 *
+	 * Wraps HingeJoint as a Component.
+	 */
+    class BS_CORE_EXPORT CHingeJoint : public CJoint
+    {
+    public:
+		CHingeJoint(const HSceneObject& parent);
+
+		/** @copydoc HingeJoint::getAngle */
+		inline Radian getAngle() const;
+
+		/** @copydoc HingeJoint::getSpeed */
+		inline float getSpeed() const;
+
+		/** @copydoc HingeJoint::getLimit */
+		inline LimitAngularRange getLimit() const;
+
+		/** @copydoc HingeJoint::setLimit */
+		inline void setLimit(const LimitAngularRange& limit);
+
+		/** @copydoc HingeJoint::getDrive */
+		inline HingeJoint::Drive getDrive() const;
+
+		/** @copydoc HingeJoint::setDrive */
+		inline void setDrive(const HingeJoint::Drive& drive);
+
+		/** @copydoc HingeJoint::setFlag */
+		inline void setFlag(HingeJoint::Flag flag, bool enabled);
+
+		/** @copydoc HingeJoint::hasFlag */
+		inline bool hasFlag(HingeJoint::Flag flag) const;
+
+	    /**	Returns the hinge joint that this component wraps. */
+		SPtr<HingeJoint> _getInternal() const { return std::static_pointer_cast<HingeJoint>(mInternal); }
+
+		/************************************************************************/
+		/* 						COMPONENT OVERRIDES                      		*/
+		/************************************************************************/
+	protected:
+		friend class SceneObject;
+
+		/** @copydoc CJoint::createInternal */
+		SPtr<Joint> createInternal() override;
+
+		HingeJoint::Flag mFlag = (HingeJoint::Flag)0;
+		HingeJoint::Drive mDrive;
+		LimitAngularRange mLimit;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class CHingeJointRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+	protected:
+		CHingeJoint() {} // Serialization only
+     };
+
+	 /** @} */
+}

+ 66 - 0
BansheeCore/Include/BsCHingeJointRTTI.h

@@ -0,0 +1,66 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsCHingeJoint.h"
+#include "BsGameObjectRTTI.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT CHingeJointRTTI : public RTTIType<CHingeJoint, CJoint, CHingeJointRTTI>
+	{
+		BS_PLAIN_MEMBER(mFlag)
+		BS_PLAIN_MEMBER_NAMED(mDriveSpeed, mDrive.speed)
+		BS_PLAIN_MEMBER_NAMED(mDriveForceLimit, mDrive.forceLimit)
+		BS_PLAIN_MEMBER_NAMED(mDriveGearRatio, mDrive.gearRatio)
+		BS_PLAIN_MEMBER_NAMED(mDriveFreeSpin, mDrive.freeSpin)
+		BS_PLAIN_MEMBER_NAMED(mLimitLower, mLimit.lower)
+		BS_PLAIN_MEMBER_NAMED(mLimitUpper, mLimit.upper)
+		BS_PLAIN_MEMBER_NAMED(mLimitContactDist, mLimit.contactDist)
+		BS_PLAIN_MEMBER_NAMED(mLimitRestitution, mLimit.restitution)
+		BS_PLAIN_MEMBER_NAMED(mSpringDamping, mLimit.spring.damping)
+		BS_PLAIN_MEMBER_NAMED(mSpringStiffness, mLimit.spring.stiffness)
+
+	public:
+		CHingeJointRTTI()
+		{
+			BS_ADD_PLAIN_FIELD(mFlag, 0);
+			BS_ADD_PLAIN_FIELD(mDriveSpeed, 1);
+			BS_ADD_PLAIN_FIELD(mDriveForceLimit, 2);
+			BS_ADD_PLAIN_FIELD(mDriveGearRatio, 3);
+			BS_ADD_PLAIN_FIELD(mDriveFreeSpin, 4);
+			BS_ADD_PLAIN_FIELD(mLimitLower, 5);
+			BS_ADD_PLAIN_FIELD(mLimitUpper, 6);
+			BS_ADD_PLAIN_FIELD(mLimitContactDist, 7);
+			BS_ADD_PLAIN_FIELD(mLimitRestitution, 8);
+			BS_ADD_PLAIN_FIELD(mSpringDamping, 9);
+			BS_ADD_PLAIN_FIELD(mSpringStiffness, 10);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "CHingeJoint";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_CHingeJoint;
+		}
+
+		SPtr<IReflectable> newRTTIObject() override
+		{
+			return GameObjectRTTI::createGameObject<CHingeJoint>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 124 - 0
BansheeCore/Include/BsCJoint.h

@@ -0,0 +1,124 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsJoint.h"
+#include "BsComponent.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup Components-Core
+	 *  @{
+	 */
+
+	/**
+	 * @copydoc	Joint
+	 *
+	 * Wraps Joint as a Component.
+	 */
+    class BS_CORE_EXPORT CJoint : public Component
+    {
+    public:
+		CJoint(const HSceneObject& parent);
+		
+		/** @copydoc Joint::getBody */
+		inline HRigidbody getBody(JointBody body) const;
+
+		/** @copydoc Joint::setBody */
+		inline void setBody(JointBody body, const HRigidbody& value);
+
+		/** @copydoc Joint::getPosition */
+		inline Vector3 getPosition(JointBody body) const;
+
+		/** @copydoc Joint::getRotation */
+		inline Quaternion getRotation(JointBody body) const;
+
+		/** @copydoc Joint::setTransform */
+		inline void setTransform(JointBody body, const Vector3& position, const Quaternion& rotation);
+
+		/** @copydoc Joint::getBreakForce */
+		inline float getBreakForce() const;
+
+		/** @copydoc Joint::setBreakForce */
+		inline void setBreakForce(float force);
+
+		/** @copydoc Joint::getBreakTorque */
+		inline float getBreakTorque() const;
+
+		/** @copydoc Joint::setBreakToque */
+		inline void setBreakToque(float torque);
+
+		/** @copydoc Joint::getEnableCollision */
+		inline bool getEnableCollision() const;
+
+		/** @copydoc Joint::setEnableCollision */
+		inline void setEnableCollision(bool value);
+
+		/** @copydoc Joint::onJointBreak */
+		Event<void()> onJointBreak;
+
+		/** @cond INTERNAL */
+
+		/** Returns the Joint implementation wrapped by this component. */
+		SPtr<Joint> _getInternal() const { return mInternal; }
+
+		/** @endcond */
+
+		/************************************************************************/
+		/* 						COMPONENT OVERRIDES                      		*/
+		/************************************************************************/
+	protected:
+		friend class SceneObject;
+
+		/** @copydoc Component::onInitialized() */
+		void onInitialized() override;
+
+		/** @copydoc Component::onDestroyed() */
+		void onDestroyed() override;
+
+		/** @copydoc Component::onDisabled() */
+		void onDisabled() override;
+
+		/** @copydoc Component::onEnabled() */
+		void onEnabled() override;
+
+		/** @copydoc Component::onTransformChanged() */
+		void onTransformChanged(TransformChangedFlags flags) override;
+
+    protected:
+		/** Creates the internal representation of the Joint for use by the component. */
+		virtual SPtr<Joint> createInternal() = 0;
+
+		/** Creates the internal representation of the Joint and restores the values saved by the Component. */
+		virtual void restoreInternal();
+
+		/** Updates the local transform for the specified body attached to the joint. */
+		void updateTransform(JointBody body);
+
+		/** Triggered when the joint constraint gets broken. */
+		void triggerOnJointBroken();
+
+		SPtr<Joint> mInternal;
+
+		HRigidbody mBodies[2];
+		Vector3 mPositions[2];
+		Quaternion mRotations[2];
+		float mBreakForce = FLT_MAX;
+		float mBreakTorque = FLT_MAX;
+		bool mEnableCollision = false;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class CJointRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+	protected:
+		CJoint() {} // Serialization only
+     };
+
+	 /** @} */
+}

+ 64 - 0
BansheeCore/Include/BsCJointRTTI.h

@@ -0,0 +1,64 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsCJoint.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT CJointRTTI : public RTTIType<CJoint, Component, CJointRTTI>
+	{
+		BS_REFL_MEMBER_NAMED(mBodyA, mBodies[0]);
+		BS_REFL_MEMBER_NAMED(mBodyB, mBodies[1]);
+
+		BS_PLAIN_MEMBER_NAMED(mPositionA, mPositions[0]);
+		BS_PLAIN_MEMBER_NAMED(mPositionB, mPositions[1]);
+
+		BS_PLAIN_MEMBER_NAMED(mRotationA, mRotations[0]);
+		BS_PLAIN_MEMBER_NAMED(mRotationB, mRotations[1]);
+
+		BS_PLAIN_MEMBER(mBreakForce)
+		BS_PLAIN_MEMBER(mBreakTorque)
+		BS_PLAIN_MEMBER(mEnableCollision)
+
+	public:
+		CJointRTTI()
+		{
+			BS_ADD_REFL_FIELD(mBodyA, 0);
+			BS_ADD_REFL_FIELD(mBodyB, 1);
+			BS_ADD_PLAIN_FIELD(mPositionA, 2);
+			BS_ADD_PLAIN_FIELD(mPositionB, 3);
+			BS_ADD_PLAIN_FIELD(mRotationA, 4);
+			BS_ADD_PLAIN_FIELD(mRotationB, 5);
+			BS_ADD_PLAIN_FIELD(mBreakForce, 6);
+			BS_ADD_PLAIN_FIELD(mBreakTorque, 7);
+			BS_ADD_PLAIN_FIELD(mEnableCollision, 8);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "CJoint";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_CJoint;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 71 - 0
BansheeCore/Include/BsCSliderJoint.h

@@ -0,0 +1,71 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsSliderJoint.h"
+#include "BsCJoint.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup Components-Core
+	 *  @{
+	 */
+
+	/**
+	 * @copydoc	SliderJoint
+	 *
+	 * Wraps SliderJoint as a Component.
+	 */
+    class BS_CORE_EXPORT CSliderJoint : public CJoint
+    {
+    public:
+		CSliderJoint(const HSceneObject& parent);
+
+		/** @copydoc SliderJoint::getPosition */
+		inline float getPosition() const;
+
+		/** @copydoc SliderJoint::getSpeed */
+		inline float getSpeed() const;
+
+		/** @copydoc SliderJoint::getLimit */
+		inline LimitLinearRange getLimit() const;
+
+		/** @copydoc SliderJoint::setLimit */
+		inline void setLimit(const LimitLinearRange& limit);
+
+		/** @copydoc SliderJoint::setFlag */
+		inline void setFlag(SliderJoint::Flag flag, bool enabled);
+
+		/** @copydoc SliderJoint::hasFlag */
+		inline bool hasFlag(SliderJoint::Flag flag) const;
+
+	    /**	Returns the slider joint that this component wraps. */
+		SPtr<SliderJoint> _getInternal() const { return std::static_pointer_cast<SliderJoint>(mInternal); }
+
+		/************************************************************************/
+		/* 						COMPONENT OVERRIDES                      		*/
+		/************************************************************************/
+	protected:
+		friend class SceneObject;
+
+		/** @copydoc CJoint::createInternal */
+		SPtr<Joint> createInternal() override;
+
+		SliderJoint::Flag mFlag = (SliderJoint::Flag)0;
+		LimitLinearRange mLimit;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class CSliderJointRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+	protected:
+		CSliderJoint() {} // Serialization only
+     };
+
+	 /** @} */
+}

+ 58 - 0
BansheeCore/Include/BsCSliderJointRTTI.h

@@ -0,0 +1,58 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsCSliderJoint.h"
+#include "BsGameObjectRTTI.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT CSliderJointRTTI : public RTTIType<CSliderJoint, CJoint, CSliderJointRTTI>
+	{
+		BS_PLAIN_MEMBER(mFlag)
+		BS_PLAIN_MEMBER_NAMED(mLimitLower, mLimit.lower)
+		BS_PLAIN_MEMBER_NAMED(mLimitUpper, mLimit.upper)
+		BS_PLAIN_MEMBER_NAMED(mLimitContactDist, mLimit.contactDist)
+		BS_PLAIN_MEMBER_NAMED(mLimitRestitution, mLimit.restitution)
+		BS_PLAIN_MEMBER_NAMED(mSpringDamping, mLimit.spring.damping)
+		BS_PLAIN_MEMBER_NAMED(mSpringStiffness, mLimit.spring.stiffness)
+
+	public:
+		CSliderJointRTTI()
+		{
+			BS_ADD_PLAIN_FIELD(mFlag, 0);
+			BS_ADD_PLAIN_FIELD(mLimitLower, 1);
+			BS_ADD_PLAIN_FIELD(mLimitUpper, 2);
+			BS_ADD_PLAIN_FIELD(mLimitContactDist, 3);
+			BS_ADD_PLAIN_FIELD(mLimitRestitution, 4);
+			BS_ADD_PLAIN_FIELD(mSpringDamping, 5);
+			BS_ADD_PLAIN_FIELD(mSpringStiffness, 6);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "CSliderJoint";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_CSliderJoint;
+		}
+
+		SPtr<IReflectable> newRTTIObject() override
+		{
+			return GameObjectRTTI::createGameObject<CSliderJoint>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 65 - 0
BansheeCore/Include/BsCSphericalJoint.h

@@ -0,0 +1,65 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsSphericalJoint.h"
+#include "BsCJoint.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup Components-Core
+	 *  @{
+	 */
+
+	/**
+	 * @copydoc	SphericalJoint
+	 *
+	 * Wraps SphericalJoint as a Component.
+	 */
+    class BS_CORE_EXPORT CSphericalJoint : public CJoint
+    {
+    public:
+		CSphericalJoint(const HSceneObject& parent);
+
+		/** @copydoc SphericalJoint::getLimit */
+		inline LimitConeRange getLimit() const;
+
+		/** @copydoc SphericalJoint::setLimit */
+		inline void setLimit(const LimitConeRange& limit);
+
+		/** @copydoc SphericalJoint::setFlag */
+		inline void setFlag(SphericalJoint::Flag flag, bool enabled);
+
+		/** @copydoc SphericalJoint::hasFlag */
+		inline bool hasFlag(SphericalJoint::Flag flag) const;
+
+	    /**	Returns the spherical joint that this component wraps. */
+		SPtr<SphericalJoint> _getInternal() const { return std::static_pointer_cast<SphericalJoint>(mInternal); }
+
+		/************************************************************************/
+		/* 						COMPONENT OVERRIDES                      		*/
+		/************************************************************************/
+	protected:
+		friend class SceneObject;
+
+		/** @copydoc CJoint::createInternal */
+		SPtr<Joint> createInternal() override;
+
+		SphericalJoint::Flag mFlag = (SphericalJoint::Flag)0;
+		LimitConeRange mLimit;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class CSphericalJointRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+	protected:
+		CSphericalJoint() {} // Serialization only
+     };
+
+	 /** @} */
+}

+ 58 - 0
BansheeCore/Include/BsCSphericalJointRTTI.h

@@ -0,0 +1,58 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsCSphericalJoint.h"
+#include "BsGameObjectRTTI.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT CSphericalJointRTTI : public RTTIType<CSphericalJoint, CJoint, CSphericalJointRTTI>
+	{
+		BS_PLAIN_MEMBER(mFlag)
+		BS_PLAIN_MEMBER_NAMED(mYLimitAngle, mLimit.yLimitAngle)
+		BS_PLAIN_MEMBER_NAMED(mZLimitAngle, mLimit.zLimitAngle)
+		BS_PLAIN_MEMBER_NAMED(mLimitContactDist, mLimit.contactDist)
+		BS_PLAIN_MEMBER_NAMED(mLimitRestitution, mLimit.restitution)
+		BS_PLAIN_MEMBER_NAMED(mSpringDamping, mLimit.spring.damping)
+		BS_PLAIN_MEMBER_NAMED(mSpringStiffness, mLimit.spring.stiffness)
+
+	public:
+		CSphericalJointRTTI()
+		{
+			BS_ADD_PLAIN_FIELD(mFlag, 0);
+			BS_ADD_PLAIN_FIELD(mYLimitAngle, 1);
+			BS_ADD_PLAIN_FIELD(mZLimitAngle, 2);
+			BS_ADD_PLAIN_FIELD(mLimitContactDist, 3);
+			BS_ADD_PLAIN_FIELD(mLimitRestitution, 4);
+			BS_ADD_PLAIN_FIELD(mSpringDamping, 5);
+			BS_ADD_PLAIN_FIELD(mSpringStiffness, 6);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "CSphericalJoint";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_CSphericalJoint;
+		}
+
+		SPtr<IReflectable> newRTTIObject() override
+		{
+			return GameObjectRTTI::createGameObject<CSphericalJoint>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 3 - 1
BansheeCore/Include/BsComponent.h

@@ -100,10 +100,12 @@ namespace BansheeEngine
 		Component(const Component& other) { }
 
 	protected:
-		HSceneObject mParent;
 		HComponent mThisHandle;
 		TransformChangedFlags mNotifyFlags;
 
+	private:
+		HSceneObject mParent;
+
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/************************************************************************/

+ 8 - 1
BansheeCore/Include/BsCorePrerequisites.h

@@ -440,7 +440,14 @@ namespace BansheeEngine
 		TID_CPlaneCollider = 1097,
 		TID_CRigidbody = 1098,
 		TID_PhysicsMesh = 1099,
-		TID_CMeshCollider = 1100
+		TID_CMeshCollider = 1100,
+		TID_CJoint = 1101,
+		TID_CFixedJoint = 1102,
+		TID_CDistanceJoint = 1103,
+		TID_CHingeJoint = 1104,
+		TID_CSphericalJoint = 1105,
+		TID_CSliderJoint = 1106,
+		TID_CD6Joint = 1107
 	};
 }
 

+ 9 - 3
BansheeCore/Include/BsD6Joint.h

@@ -12,17 +12,17 @@ namespace BansheeEngine
 	public:
 		enum class Axis
 		{
-			X, Y, Z, Twist, SwingY, SwingZ
+			X, Y, Z, Twist, SwingY, SwingZ, Count
 		};
 
 		enum class Motion
 		{
-			Locked, Limited, Free
+			Locked, Limited, Free, Count
 		};
 
 		enum class DriveType
 		{
-			X, Y, Z, Swing, Twist, SLERP
+			X, Y, Z, Swing, Twist, SLERP, Count
 		};
 
 		struct Drive
@@ -31,6 +31,12 @@ namespace BansheeEngine
 			float damping = 0.0f;
 			float forceLimit = FLT_MAX;
 			bool acceleration = false;
+
+			bool operator==(const Drive& other) const
+			{
+				return stiffness == other.stiffness && damping == other.damping && forceLimit == other.forceLimit &&
+					acceleration == other.acceleration;
+			}
 		};
 
 	public:

+ 1 - 1
BansheeCore/Include/BsDistanceJoint.h

@@ -35,7 +35,7 @@ namespace BansheeEngine
 		virtual void setSpring(const Spring& value) = 0;
 
 		virtual void setFlag(Flag flag, bool enabled) = 0;
-		virtual bool hasFlag(Flag flag) = 0;
+		virtual bool hasFlag(Flag flag) const = 0;
 
 		static SPtr<DistanceJoint> create();
 	};

+ 1 - 1
BansheeCore/Include/BsFJoint.h

@@ -29,7 +29,7 @@ namespace BansheeEngine
 		virtual void setBreakForce(float force) = 0;
 
 		virtual float getBreakTorque() const = 0;
-		virtual void setBreakToque(float torque) = 0;
+		virtual void setBreakTorque(float torque) = 0;
 
 		virtual bool getEnableCollision() const = 0;
 		virtual void setEnableCollision(bool value) = 0;

+ 8 - 2
BansheeCore/Include/BsHingeJoint.h

@@ -22,6 +22,12 @@ namespace BansheeEngine
 			float forceLimit = FLT_MAX;
 			float gearRatio = 1.0f;
 			bool freeSpin = false;
+
+			bool operator==(const Drive& other) const
+			{
+				return speed == other.speed && forceLimit == other.forceLimit && gearRatio == other.gearRatio && 
+					freeSpin && other.freeSpin;
+			}
 		};
 
 	public:
@@ -34,10 +40,10 @@ namespace BansheeEngine
 		virtual void setLimit(const LimitAngularRange& limit) = 0;
 
 		virtual Drive getDrive() const = 0;
-		virtual void setDrive(const Drive& drive) const = 0;
+		virtual void setDrive(const Drive& drive) = 0;
 
 		virtual void setFlag(Flag flag, bool enabled) = 0;
-		virtual bool hasFlag(Flag flag) = 0;
+		virtual bool hasFlag(Flag flag) const = 0;
 
 		static SPtr<HingeJoint> create();
 	};

+ 30 - 1
BansheeCore/Include/BsJoint.h

@@ -23,7 +23,7 @@ namespace BansheeEngine
 		inline void setBreakForce(float force);
 
 		inline float getBreakTorque() const;
-		inline void setBreakToque(float torque);
+		inline void setBreakTorque(float torque);
 
 		inline bool getEnableCollision() const;
 		inline void setEnableCollision(bool value);
@@ -40,6 +40,11 @@ namespace BansheeEngine
 			:stiffness(stiffness), damping(damping)
 		{ }
 
+		bool operator==(const Spring& other) const
+		{
+			return stiffness == other.stiffness && damping == other.damping;
+		}
+
 		float stiffness = 0.0f;
 		float damping = 0.0f;
 	};
@@ -57,6 +62,12 @@ namespace BansheeEngine
 			:lower(lower), upper(upper), spring(spring)
 		{ }
 
+		bool operator==(const LimitLinearRange& other) const
+		{
+			return lower == other.lower && upper == other.upper && contactDist == other.contactDist && 
+				restitution == other.restitution && spring == other.spring;
+		}
+
 		float lower = 0.0f;
 		float upper = 0.0f;
 		float contactDist = -1.0f;
@@ -77,6 +88,12 @@ namespace BansheeEngine
 			:extent(extent), spring(spring)
 		{ }
 
+		bool operator==(const LimitLinear& other) const
+		{
+			return extent == other.extent && contactDist == other.contactDist && restitution == other.restitution &&
+				spring == other.spring;
+		}
+
 		float extent = 0.0f;
 		float contactDist = -1.0f;
 		float restitution = 0.0f;
@@ -96,6 +113,12 @@ namespace BansheeEngine
 			:lower(lower), upper(upper), spring(spring)
 		{ }
 
+		bool operator==(const LimitAngularRange& other) const
+		{
+			return lower == other.lower && upper == other.upper && contactDist == other.contactDist && 
+				restitution == other.restitution && spring == other.spring;
+		}
+
 		Radian lower = Radian(0.0f);
 		Radian upper = Radian(0.0f);
 		float contactDist = -1.0f;
@@ -116,6 +139,12 @@ namespace BansheeEngine
 			:yLimitAngle(yLimitAngle), zLimitAngle(zLimitAngle), spring(spring)
 		{ }
 
+		bool operator==(const LimitConeRange& other) const
+		{
+			return yLimitAngle == other.yLimitAngle && zLimitAngle == other.zLimitAngle && 
+				contactDist == other.contactDist && restitution == other.restitution && spring == other.spring;
+		}
+
 		Radian yLimitAngle = Radian(Math::PI * 0.5f);
 		Radian zLimitAngle = Radian(Math::PI * 0.5f);
 		float contactDist = -1.0f;

+ 7 - 0
BansheeCore/Include/BsSceneObject.h

@@ -249,6 +249,13 @@ namespace BansheeEngine
 		 */
 		const Matrix4& getWorldTfrm() const;
 
+		/**
+		 * Gets the objects inverse world transform matrix.
+		 *
+		 * @note	Performance warning: This might involve updating the transforms if the transform is dirty.
+		 */
+		Matrix4 getInvWorldTfrm() const;
+
 		/** Gets the objects local transform matrix. */
 		const Matrix4& getLocalTfrm() const;
 

+ 1 - 1
BansheeCore/Include/BsSliderJoint.h

@@ -25,7 +25,7 @@ namespace BansheeEngine
 		virtual void setLimit(const LimitLinearRange& limit) = 0;
 
 		virtual void setFlag(Flag flag, bool enabled) = 0;
-		virtual bool hasFlag(Flag flag) = 0;
+		virtual bool hasFlag(Flag flag) const = 0;
 
 		static SPtr<SliderJoint> create();
 	};

+ 1 - 1
BansheeCore/Include/BsSphericalJoint.h

@@ -22,7 +22,7 @@ namespace BansheeEngine
 		virtual void setLimit(const LimitConeRange& limit) = 0;
 
 		virtual void setFlag(Flag flag, bool enabled) = 0;
-		virtual bool hasFlag(Flag flag) = 0;
+		virtual bool hasFlag(Flag flag) const = 0;
 
 		static SPtr<SphericalJoint> create();
 	};

+ 177 - 0
BansheeCore/Source/BsCD6Joint.cpp

@@ -0,0 +1,177 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsCD6Joint.h"
+#include "BsSceneObject.h"
+#include "BsCD6JointRTTI.h"
+
+namespace BansheeEngine
+{
+	CD6Joint::CD6Joint(const HSceneObject& parent)
+		: CJoint(parent)
+	{
+		setName("D6Joint");
+	}
+
+	D6Joint::Motion CD6Joint::getMotion(D6Joint::Axis axis) const
+	{
+		return mMotion[(int)axis];
+	}
+
+	void CD6Joint::setMotion(D6Joint::Axis axis, D6Joint::Motion motion)
+	{
+		if (mMotion[(int)axis] == motion)
+			return;
+
+		mMotion[(int)axis] = motion;
+
+		if (mInternal != nullptr)
+			_getInternal()->setMotion(axis, motion);
+	}
+
+	Radian CD6Joint::getTwist() const
+	{
+		if (mInternal == nullptr)
+			return Radian(0.0f);
+
+		return _getInternal()->getTwist();
+	}
+
+	Radian CD6Joint::getSwingY() const
+	{
+		if (mInternal == nullptr)
+			return Radian(0.0f);
+
+		return _getInternal()->getSwingY();
+	}
+
+	Radian CD6Joint::getSwingZ() const
+	{
+		if (mInternal == nullptr)
+			return Radian(0.0f);
+
+		return _getInternal()->getSwingZ();
+	}
+
+	LimitLinear CD6Joint::getLimitLinear() const
+	{
+		return mLimitLinear;
+	}
+
+	void CD6Joint::setLimitLinear(const LimitLinear& limit)
+	{
+		if (mLimitLinear == limit)
+			return;
+
+		mLimitLinear = limit;
+
+		if (mInternal != nullptr)
+			_getInternal()->setLimitLinear(limit);
+	}
+
+	LimitAngularRange CD6Joint::getLimitTwist() const
+	{
+		return mLimitTwist;
+	}
+
+	void CD6Joint::setLimitTwist(const LimitAngularRange& limit)
+	{
+		if (mLimitTwist == limit)
+			return;
+
+		mLimitTwist = limit;
+
+		if (mInternal != nullptr)
+			_getInternal()->setLimitTwist(limit);
+	}
+
+	LimitConeRange CD6Joint::getLimitSwing() const
+	{
+		return mLimitSwing;
+	}
+
+	void CD6Joint::setLimitSwing(const LimitConeRange& limit)
+	{
+		if (mLimitSwing == limit)
+			return;
+
+		mLimitSwing = limit;
+
+		if (mInternal != nullptr)
+			_getInternal()->setLimitSwing(limit);
+	}
+
+	D6Joint::Drive CD6Joint::getDrive(D6Joint::DriveType type) const
+	{
+		return mDrive[(int)type];
+	}
+
+	void CD6Joint::setDrive(D6Joint::DriveType type, const D6Joint::Drive& drive)
+	{
+		if (mDrive[(int)type] == drive)
+			return;
+
+		mDrive[(int)type] = drive;
+
+		if (mInternal != nullptr)
+			_getInternal()->setDrive(type, drive);
+	}
+
+	Vector3 CD6Joint::getDrivePosition() const
+	{
+		return mDrivePosition;
+	}
+
+	Quaternion CD6Joint::getDriveRotation() const
+	{
+		return mDriveRotation;
+	}
+
+	void CD6Joint::setDriveTransform(const Vector3& position, const Quaternion& rotation)
+	{
+		if (mDrivePosition == position && mDriveRotation == rotation)
+			return;
+
+		mDrivePosition = position;
+		mDriveRotation = rotation;
+
+		if (mInternal != nullptr)
+			_getInternal()->setDriveTransform(position, rotation);
+	}
+
+	Vector3 CD6Joint::getDriveLinearVelocity() const
+	{
+		return mDriveLinearVelocity;
+	}
+
+	Vector3 CD6Joint::getDriveAngularVelocity() const
+	{
+		return mDriveAngularVelocity;
+	}
+
+	void CD6Joint::setDriveVelocity(const Vector3& linear, const Vector3& angular)
+	{
+		if (mDriveLinearVelocity == linear && mDriveAngularVelocity == angular)
+			return;
+
+		mDriveLinearVelocity = linear;
+		mDriveAngularVelocity = angular;
+
+		if (mInternal != nullptr)
+			_getInternal()->setDriveVelocity(linear, angular);
+	}
+
+	SPtr<Joint> CD6Joint::createInternal()
+	{
+		return D6Joint::create();
+	}
+
+	RTTITypeBase* CD6Joint::getRTTIStatic()
+	{
+		return CD6JointRTTI::instance();
+	}
+
+	RTTITypeBase* CD6Joint::getRTTI() const
+	{
+		return CD6Joint::getRTTIStatic();
+	}
+}

+ 121 - 0
BansheeCore/Source/BsCDistanceJoint.cpp

@@ -0,0 +1,121 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsCDistanceJoint.h"
+#include "BsSceneObject.h"
+#include "BsCDistanceJointRTTI.h"
+
+namespace BansheeEngine
+{
+	CDistanceJoint::CDistanceJoint(const HSceneObject& parent)
+		: CJoint(parent)
+	{
+		setName("DistanceJoint");
+	}
+
+	float CDistanceJoint::getDistance() const
+	{
+		if (mInternal == nullptr)
+			return 0.0f;
+
+		return _getInternal()->getDistance();
+	}
+
+	float CDistanceJoint::getMinDistance() const
+	{
+		return mMinDistance;
+	}
+
+	void CDistanceJoint::setMinDistance(float value)
+	{
+		if (mMinDistance == value)
+			return;
+
+		mMinDistance = value;
+
+		if (mInternal != nullptr)
+			_getInternal()->setMinDistance(value);
+	}
+
+	float CDistanceJoint::getMaxDistance() const
+	{
+		return mMaxDistance;
+	}
+
+	void CDistanceJoint::setMaxDistance(float value)
+	{
+		if (mMaxDistance == value)
+			return;
+
+		mMaxDistance = value;
+
+		if (mInternal != nullptr)
+			_getInternal()->setMaxDistance(value);
+	}
+
+	float CDistanceJoint::getTolerance() const
+	{
+		return mTolerance;
+	}
+
+	void CDistanceJoint::setTolerance(float value)
+	{
+		if (mTolerance == value)
+			return;
+
+		mTolerance = value;
+
+		if (mInternal != nullptr)
+			_getInternal()->setTolerance(value);
+	}
+
+	Spring CDistanceJoint::getSpring() const
+	{
+		return mSpring;
+	}
+
+	void CDistanceJoint::setSpring(const Spring& value)
+	{
+		if (mSpring == value)
+			return;
+
+		mSpring = value;
+
+		if(mInternal != nullptr)
+			_getInternal()->setSpring(value);
+	}
+
+	void CDistanceJoint::setFlag(DistanceJoint::Flag flag, bool enabled)
+	{
+		bool isEnabled = ((UINT32)mFlag & (UINT32)flag) != 0;
+		if (isEnabled == enabled)
+			return;
+
+		if (enabled)
+			mFlag = (DistanceJoint::Flag)((UINT32)mFlag | (UINT32)flag);
+		else
+			mFlag = (DistanceJoint::Flag)((UINT32)mFlag & ~(UINT32)flag);
+
+		if (mInternal != nullptr)
+			_getInternal()->setFlag(flag, enabled);
+	}
+
+	bool CDistanceJoint::hasFlag(DistanceJoint::Flag flag) const
+	{
+		return ((UINT32)mFlag & (UINT32)flag) != 0;
+	}
+
+	SPtr<Joint> CDistanceJoint::createInternal()
+	{
+		return DistanceJoint::create();
+	}
+
+	RTTITypeBase* CDistanceJoint::getRTTIStatic()
+	{
+		return CDistanceJointRTTI::instance();
+	}
+
+	RTTITypeBase* CDistanceJoint::getRTTI() const
+	{
+		return CDistanceJoint::getRTTIStatic();
+	}
+}

+ 30 - 0
BansheeCore/Source/BsCFixedJoint.cpp

@@ -0,0 +1,30 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsCFixedJoint.h"
+#include "BsSceneObject.h"
+#include "BsCRigidbody.h"
+#include "BsCFixedJointRTTI.h"
+
+namespace BansheeEngine
+{
+	CFixedJoint::CFixedJoint(const HSceneObject& parent)
+		: CJoint(parent)
+	{
+		setName("FixedJoint");
+	}
+
+	SPtr<Joint> CFixedJoint::createInternal()
+	{
+		return FixedJoint::create();
+	}
+
+	RTTITypeBase* CFixedJoint::getRTTIStatic()
+	{
+		return CFixedJointRTTI::instance();
+	}
+
+	RTTITypeBase* CFixedJoint::getRTTI() const
+	{
+		return CFixedJoint::getRTTIStatic();
+	}
+}

+ 97 - 0
BansheeCore/Source/BsCHingeJoint.cpp

@@ -0,0 +1,97 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsCHingeJoint.h"
+#include "BsSceneObject.h"
+#include "BsCHingeJointRTTI.h"
+
+namespace BansheeEngine
+{
+	CHingeJoint::CHingeJoint(const HSceneObject& parent)
+		: CJoint(parent)
+	{
+		setName("HingeJoint");
+	}
+
+	Radian CHingeJoint::getAngle() const
+	{
+		if (mInternal == nullptr)
+			return Radian(0.0f);
+
+		return _getInternal()->getAngle();
+	}
+
+	float CHingeJoint::getSpeed() const
+	{
+		if (mInternal == nullptr)
+			return 0.0f;
+
+		return _getInternal()->getSpeed();
+	}
+
+	LimitAngularRange CHingeJoint::getLimit() const
+	{
+		return mLimit;
+	}
+
+	void CHingeJoint::setLimit(const LimitAngularRange& limit)
+	{
+		if (limit == mLimit)
+			return;
+
+		mLimit = limit;
+
+		if (mInternal != nullptr)
+			_getInternal()->setLimit(limit);
+	}
+
+	HingeJoint::Drive CHingeJoint::getDrive() const
+	{
+		return mDrive;
+	}
+
+	void CHingeJoint::setDrive(const HingeJoint::Drive& drive)
+	{
+		if (drive == mDrive)
+			return;
+
+		mDrive = drive;
+
+		if (mInternal != nullptr)
+			_getInternal()->setDrive(drive);
+	}
+
+	void CHingeJoint::setFlag(HingeJoint::Flag flag, bool enabled)
+	{
+		bool isEnabled = ((UINT32)mFlag & (UINT32)flag) != 0;
+		if (isEnabled == enabled)
+			return;
+
+		if (enabled)
+			mFlag = (HingeJoint::Flag)((UINT32)mFlag | (UINT32)flag);
+		else
+			mFlag = (HingeJoint::Flag)((UINT32)mFlag & ~(UINT32)flag);
+
+		if (mInternal != nullptr)
+			_getInternal()->setFlag(flag, enabled);
+	}
+
+	bool CHingeJoint::hasFlag(HingeJoint::Flag flag) const
+	{
+		return ((UINT32)mFlag & (UINT32)flag) != 0;
+	}
+
+	SPtr<Joint> CHingeJoint::createInternal()
+	{
+		return HingeJoint::create();
+	}
+
+	RTTITypeBase* CHingeJoint::getRTTIStatic()
+	{
+		return CHingeJointRTTI::instance();
+	}
+
+	RTTITypeBase* CHingeJoint::getRTTI() const
+	{
+		return CHingeJoint::getRTTIStatic();
+	}
+}

+ 216 - 0
BansheeCore/Source/BsCJoint.cpp

@@ -0,0 +1,216 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsCJoint.h"
+#include "BsCRigidbody.h"
+#include "BsSceneObject.h"
+#include "BsCJointRTTI.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	CJoint::CJoint(const HSceneObject& parent)
+		: Component(parent)
+	{
+		setName("Joint");
+
+		mNotifyFlags = (TransformChangedFlags)(TCF_Parent | TCF_Transform);
+	}
+
+	HRigidbody CJoint::getBody(JointBody body) const
+	{
+		return mBodies[(int)body];
+	}
+
+	void CJoint::setBody(JointBody body, const HRigidbody& value)
+	{
+		if (mBodies[(int)body] == value)
+			return;
+
+		mBodies[(int)body] = value;
+
+		if(mInternal != nullptr)
+		{
+			Rigidbody* rigidbody = nullptr;
+			if (value != nullptr)
+				rigidbody = value->_getInternal().get();
+
+			mInternal->setBody(body, rigidbody);
+			updateTransform(body);
+		}
+	}
+
+	Vector3 CJoint::getPosition(JointBody body) const
+	{
+		return mPositions[(int)body];
+	}
+
+	Quaternion CJoint::getRotation(JointBody body) const
+	{
+		return mRotations[(int)body];
+	}
+
+	void CJoint::setTransform(JointBody body, const Vector3& position, const Quaternion& rotation)
+	{
+		if (mPositions[(int)body] == position && mRotations[(int)body] == rotation)
+			return;
+
+		mPositions[(int)body] = position;
+		mRotations[(int)body] = rotation;
+
+		if(mInternal != nullptr)
+			updateTransform(body);
+	}
+
+	float CJoint::getBreakForce() const
+	{
+		return mBreakForce;
+	}
+
+	void CJoint::setBreakForce(float force)
+	{
+		if (mBreakForce == force)
+			return;
+
+		mBreakForce = force;
+
+		if (mInternal != nullptr)
+			mInternal->setBreakForce(force);
+	}
+
+	float CJoint::getBreakTorque() const
+	{
+		return mBreakTorque;
+	}
+
+	void CJoint::setBreakToque(float torque)
+	{
+		if (mBreakTorque == torque)
+			return;
+
+		mBreakTorque = torque;
+
+		if (mInternal != nullptr)
+			mInternal->setBreakTorque(torque);
+	}
+
+	bool CJoint::getEnableCollision() const
+	{
+		return mEnableCollision;
+	}
+
+	void CJoint::setEnableCollision(bool value)
+	{
+		if (mEnableCollision == value)
+			return;
+
+		mEnableCollision = value;
+
+		if (mInternal != nullptr)
+			mInternal->setEnableCollision(value);
+	}
+
+	void CJoint::onInitialized()
+	{
+
+	}
+
+	void CJoint::onDestroyed()
+	{
+		// This should release the last reference and destroy the internal joint
+		mInternal = nullptr;
+	}
+
+	void CJoint::onDisabled()
+	{
+		// This should release the last reference and destroy the internal joint
+		mInternal = nullptr;
+	}
+
+	void CJoint::onEnabled()
+	{
+		restoreInternal();
+	}
+
+	void CJoint::onTransformChanged(TransformChangedFlags flags)
+	{
+		if (!SO()->getActive())
+			return;
+
+		// TODO - This might get called during physics update, perhaps avoid that?
+		updateTransform(JointBody::A);
+		updateTransform(JointBody::B);
+	}
+
+	void CJoint::restoreInternal()
+	{
+		if (mInternal == nullptr)
+		{
+			mInternal = createInternal();
+
+			mInternal->onJointBreak.connect(std::bind(&CJoint::triggerOnJointBroken, this));
+		}
+
+		// Note: Merge into one call to avoid many virtual function calls
+		Rigidbody* bodies[2];
+
+		if (mBodies[0] != nullptr)
+			bodies[0] = mBodies[0]->_getInternal().get();
+		else
+			bodies[0] = nullptr;
+
+		if (mBodies[1] != nullptr)
+			bodies[1] = mBodies[1]->_getInternal().get();
+		else
+			bodies[1] = nullptr;
+
+		mInternal->setBody(JointBody::A, bodies[0]);
+		mInternal->setBody(JointBody::B, bodies[1]);
+		mInternal->setBreakForce(mBreakForce);
+		mInternal->setBreakTorque(mBreakTorque);
+		mInternal->setEnableCollision(mEnableCollision);
+
+		updateTransform(JointBody::A);
+		updateTransform(JointBody::B);
+	}
+
+	void CJoint::updateTransform(JointBody body)
+	{
+		Vector3 localPos;
+		Quaternion localRot;
+
+		localPos = mPositions[(int)body];
+		localRot = mRotations[(int)body];
+
+		// Transform to world space of the related body
+		HRigidbody rigidbody = mBodies[(int)body];
+		if(rigidbody != nullptr)
+		{
+			localRot = rigidbody->SO()->getWorldRotation() * localRot;
+			localPos = localRot.rotate(localPos) + rigidbody->SO()->getWorldPosition();
+		}
+
+		// Transform to space local to the joint
+		Quaternion invRotation = SO()->getWorldRotation().inverse();
+
+		localPos = invRotation.rotate(localPos - SO()->getWorldPosition());
+		localRot = invRotation * localRot;
+
+		mInternal->setTransform(body, localPos, localRot);
+	}
+
+	void CJoint::triggerOnJointBroken()
+	{
+		onJointBreak();
+	}
+
+	RTTITypeBase* CJoint::getRTTIStatic()
+	{
+		return CJointRTTI::instance();
+	}
+
+	RTTITypeBase* CJoint::getRTTI() const
+	{
+		return CJoint::getRTTIStatic();
+	}
+}

+ 81 - 0
BansheeCore/Source/BsCSliderJoint.cpp

@@ -0,0 +1,81 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsCSliderJoint.h"
+#include "BsSceneObject.h"
+#include "BsCSliderJointRTTI.h"
+
+namespace BansheeEngine
+{
+	CSliderJoint::CSliderJoint(const HSceneObject& parent)
+		: CJoint(parent)
+	{
+		setName("SliderJoint");
+	}
+
+	float CSliderJoint::getPosition() const
+	{
+		if (mInternal == nullptr)
+			return 0.0f;
+
+		return _getInternal()->getPosition();
+	}
+
+	float CSliderJoint::getSpeed() const
+	{
+		if (mInternal == nullptr)
+			return 0.0f;
+
+		return _getInternal()->getSpeed();
+	}
+
+	LimitLinearRange CSliderJoint::getLimit() const
+	{
+		return mLimit;
+	}
+
+	void CSliderJoint::setLimit(const LimitLinearRange& limit)
+	{
+		if (mLimit == limit)
+			return;
+
+		mLimit = limit;
+
+		if (mInternal != nullptr)
+			_getInternal()->setLimit(limit);
+	}
+
+	void CSliderJoint::setFlag(SliderJoint::Flag flag, bool enabled)
+	{
+		bool isEnabled = ((UINT32)mFlag & (UINT32)flag) != 0;
+		if (isEnabled == enabled)
+			return;
+
+		if (enabled)
+			mFlag = (SliderJoint::Flag)((UINT32)mFlag | (UINT32)flag);
+		else
+			mFlag = (SliderJoint::Flag)((UINT32)mFlag & ~(UINT32)flag);
+
+		if (mInternal != nullptr)
+			_getInternal()->setFlag(flag, enabled);
+	}
+
+	bool CSliderJoint::hasFlag(SliderJoint::Flag flag) const
+	{
+		return ((UINT32)mFlag & (UINT32)flag) != 0;
+	}
+
+	SPtr<Joint> CSliderJoint::createInternal()
+	{
+		return SliderJoint::create();
+	}
+
+	RTTITypeBase* CSliderJoint::getRTTIStatic()
+	{
+		return CSliderJointRTTI::instance();
+	}
+
+	RTTITypeBase* CSliderJoint::getRTTI() const
+	{
+		return CSliderJoint::getRTTIStatic();
+	}
+}

+ 65 - 0
BansheeCore/Source/BsCSphericalJoint.cpp

@@ -0,0 +1,65 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsCSphericalJoint.h"
+#include "BsSceneObject.h"
+#include "BsCSphericalJointRTTI.h"
+
+namespace BansheeEngine
+{
+	CSphericalJoint::CSphericalJoint(const HSceneObject& parent)
+		: CJoint(parent)
+	{
+		setName("SphericalJoint");
+	}
+
+	LimitConeRange CSphericalJoint::getLimit() const
+	{
+		return mLimit;
+	}
+
+	void CSphericalJoint::setLimit(const LimitConeRange& limit)
+	{
+		if (limit == mLimit)
+			return;
+
+		mLimit = limit;
+
+		if (mInternal != nullptr)
+			_getInternal()->setLimit(limit);
+	}
+	
+	void CSphericalJoint::setFlag(SphericalJoint::Flag flag, bool enabled)
+	{
+		bool isEnabled = ((UINT32)mFlag & (UINT32)flag) != 0;
+		if (isEnabled == enabled)
+			return;
+
+		if (enabled)
+			mFlag = (SphericalJoint::Flag)((UINT32)mFlag | (UINT32)flag);
+		else
+			mFlag = (SphericalJoint::Flag)((UINT32)mFlag & ~(UINT32)flag);
+
+		if (mInternal != nullptr)
+			_getInternal()->setFlag(flag, enabled);
+	}
+
+	bool CSphericalJoint::hasFlag(SphericalJoint::Flag flag) const
+	{
+		return ((UINT32)mFlag & (UINT32)flag) != 0;
+	}
+
+	SPtr<Joint> CSphericalJoint::createInternal()
+	{
+		return SphericalJoint::create();
+	}
+
+	RTTITypeBase* CSphericalJoint::getRTTIStatic()
+	{
+		return CSphericalJointRTTI::instance();
+	}
+
+	RTTITypeBase* CSphericalJoint::getRTTI() const
+	{
+		return CSphericalJoint::getRTTIStatic();
+	}
+}

+ 2 - 2
BansheeCore/Source/BsJoint.cpp

@@ -44,9 +44,9 @@ namespace BansheeEngine
 		return mInternal->getBreakTorque();
 	}
 
-	void Joint::setBreakToque(float torque)
+	void Joint::setBreakTorque(float torque)
 	{
-		mInternal->setBreakToque(torque);
+		mInternal->setBreakTorque(torque);
 	}
 
 	bool Joint::getEnableCollision() const

+ 9 - 0
BansheeCore/Source/BsSceneObject.cpp

@@ -350,6 +350,15 @@ namespace BansheeEngine
 		return mCachedWorldTfrm;
 	}
 
+	Matrix4 SceneObject::getInvWorldTfrm() const
+	{
+		if (!isCachedWorldTfrmUpToDate())
+			updateWorldTfrm();
+
+		Matrix4 worldToLocal = Matrix4::inverseTRS(mWorldPosition, mWorldRotation, mWorldScale);
+		return worldToLocal;
+	}
+
 	const Matrix4& SceneObject::getLocalTfrm() const
 	{
 		if (!isCachedLocalTfrmUpToDate())

+ 1 - 1
BansheePhysX/Include/BsFPhysXJoint.h

@@ -25,7 +25,7 @@ namespace BansheeEngine
 		void setBreakForce(float force) override;
 
 		float getBreakTorque() const override;
-		void setBreakToque(float torque) override;
+		void setBreakTorque(float torque) override;
 
 		bool getEnableCollision() const override;
 		void setEnableCollision(bool value) override;

+ 1 - 1
BansheePhysX/Include/BsPhysXDistanceJoint.h

@@ -30,7 +30,7 @@ namespace BansheeEngine
 		void setSpring(const Spring& value) override;
 
 		void setFlag(Flag flag, bool enabled) override;
-		bool hasFlag(Flag flag) override;
+		bool hasFlag(Flag flag) const override;
 
 	private:
 		inline physx::PxDistanceJoint* getInternal() const;

+ 2 - 2
BansheePhysX/Include/BsPhysXHingeJoint.h

@@ -22,10 +22,10 @@ namespace BansheeEngine
 		void setLimit(const LimitAngularRange& limit) override;
 
 		Drive getDrive() const override;
-		void setDrive(const Drive& drive) const override;
+		void setDrive(const Drive& drive) override;
 
 		void setFlag(Flag flag, bool enabled) override;
-		bool hasFlag(Flag flag) override;
+		bool hasFlag(Flag flag) const override;
 
 	private:
 		inline physx::PxRevoluteJoint* getInternal() const;

+ 1 - 1
BansheePhysX/Include/BsPhysXSliderJoint.h

@@ -22,7 +22,7 @@ namespace BansheeEngine
 		void setLimit(const LimitLinearRange& limit) override;
 
 		void setFlag(Flag flag, bool enabled) override;
-		bool hasFlag(Flag flag) override;
+		bool hasFlag(Flag flag) const override;
 
 	private:
 		inline physx::PxPrismaticJoint* getInternal() const;

+ 1 - 1
BansheePhysX/Include/BsPhysXSphericalJoint.h

@@ -19,7 +19,7 @@ namespace BansheeEngine
 		void setLimit(const LimitConeRange& limit) override;
 
 		void setFlag(Flag flag, bool enabled) override;
-		bool hasFlag(Flag flag) override;
+		bool hasFlag(Flag flag) const override;
 
 	private:
 		inline physx::PxSphericalJoint* getInternal() const;

+ 1 - 1
BansheePhysX/Source/BsFPhysXJoint.cpp

@@ -108,7 +108,7 @@ namespace BansheeEngine
 		return torque;
 	}
 
-	void FPhysXJoint::setBreakToque(float torque)
+	void FPhysXJoint::setBreakTorque(float torque)
 	{
 		float force = 0.0f;
 		float dummy = 0.0f;

+ 1 - 1
BansheePhysX/Source/BsPhysXDistanceJoint.cpp

@@ -88,7 +88,7 @@ namespace BansheeEngine
 		getInternal()->setDistanceJointFlag(toPxFlag(flag), enabled);
 	}
 
-	bool PhysXDistanceJoint::hasFlag(Flag flag)
+	bool PhysXDistanceJoint::hasFlag(Flag flag) const
 	{
 		return getInternal()->getDistanceJointFlags() & toPxFlag(flag);
 	}

+ 2 - 2
BansheePhysX/Source/BsPhysXHingeJoint.cpp

@@ -78,7 +78,7 @@ namespace BansheeEngine
 		return drive;
 	}
 
-	void PhysXHingeJoint::setDrive(const Drive& drive) const
+	void PhysXHingeJoint::setDrive(const Drive& drive)
 	{
 		getInternal()->setDriveVelocity(drive.speed);
 		getInternal()->setDriveForceLimit(drive.forceLimit);
@@ -91,7 +91,7 @@ namespace BansheeEngine
 		getInternal()->setRevoluteJointFlag(toPxFlag(flag), enabled);
 	}
 
-	bool PhysXHingeJoint::hasFlag(Flag flag)
+	bool PhysXHingeJoint::hasFlag(Flag flag) const
 	{
 		return getInternal()->getRevoluteJointFlags() & toPxFlag(flag);
 	}

+ 1 - 1
BansheePhysX/Source/BsPhysXSliderJoint.cpp

@@ -71,7 +71,7 @@ namespace BansheeEngine
 		getInternal()->setPrismaticJointFlag(toPxFlag(flag), enabled);
 	}
 
-	bool PhysXSliderJoint::hasFlag(Flag flag)
+	bool PhysXSliderJoint::hasFlag(Flag flag) const
 	{
 		return getInternal()->getPrismaticJointFlags() & toPxFlag(flag);
 	}

+ 1 - 1
BansheePhysX/Source/BsPhysXSphericalJoint.cpp

@@ -60,7 +60,7 @@ namespace BansheeEngine
 		getInternal()->setSphericalJointFlag(toPxFlag(flag), enabled);
 	}
 
-	bool PhysXSphericalJoint::hasFlag(Flag flag)
+	bool PhysXSphericalJoint::hasFlag(Flag flag) const
 	{
 		return getInternal()->getSphericalJointFlags() & toPxFlag(flag);
 	}

+ 12 - 0
BansheeUtility/Include/BsRTTIType.h

@@ -22,6 +22,18 @@
 
 namespace BansheeEngine
 {
+#define BS_PLAIN_MEMBER_NAMED(name, field)								\
+	decltype(OwnerType::##field)& get##name(OwnerType* obj) { return obj->##field; }				\
+	void set##name(OwnerType* obj, decltype(OwnerType::##field)& val) { obj->##field = val; } 
+
+#define BS_REFL_MEMBER_NAMED(name, field)								\
+	decltype(OwnerType::##field)& get##name(OwnerType* obj) { return obj->##field; }				\
+	void set##name(OwnerType* obj, decltype(OwnerType::##field)& val) { obj->##field = val; } 
+
+#define BS_REFLPTR_MEMBER_NAMED(name, field)								\
+	decltype(OwnerType::##field) get##name(OwnerType* obj) { return obj->##field; }				\
+	void set##name(OwnerType* obj, decltype(OwnerType::##field) val) { obj->##field = val; } 
+
 #define BS_PLAIN_MEMBER(name)								\
 	decltype(OwnerType::##name)& get##name(OwnerType* obj) { return obj->##name; }				\
 	void set##name(OwnerType* obj, decltype(OwnerType::##name)& val) { obj->##name = val; } 

+ 2 - 0
BansheeUtility/Source/BsQuaternion.cpp

@@ -308,6 +308,8 @@ namespace BansheeEngine
 
     Vector3 Quaternion::rotate(const Vector3& v) const
     {
+		// Note: Does compiler generate fast code here? Perhaps its better to pull all code locally without constructing
+		//       an intermediate matrix.
 		Matrix3 rot;
 		toRotationMatrix(rot);
 		return rot.transform(v);

+ 2 - 2
SBansheeEngine/Source/BsManagedComponent.cpp

@@ -288,9 +288,9 @@ namespace BansheeEngine
 
 		// Find handle to self
 		HManagedComponent componentHandle;
-		if (mParent != nullptr)
+		if (SO() != nullptr)
 		{
-			const Vector<HComponent>& components = mParent->getComponents();
+			const Vector<HComponent>& components = SO()->getComponents();
 			for (auto& component : components)
 			{
 				if (component.get() == this)