BsPhysXD6Joint.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsPhysXD6Joint.h"
  4. #include "BsFPhysXJoint.h"
  5. #include "BsPhysX.h"
  6. #include "BsPhysXRigidbody.h"
  7. #include "PxRigidDynamic.h"
  8. using namespace physx;
  9. namespace bs
  10. {
  11. PxD6Axis::Enum toPxAxis(D6JointAxis axis)
  12. {
  13. switch(axis)
  14. {
  15. default:
  16. case D6JointAxis::X:
  17. return PxD6Axis::eX;
  18. case D6JointAxis::Y:
  19. return PxD6Axis::eY;
  20. case D6JointAxis::Z:
  21. return PxD6Axis::eZ;
  22. case D6JointAxis::Twist:
  23. return PxD6Axis::eTWIST;
  24. case D6JointAxis::SwingY:
  25. return PxD6Axis::eSWING1;
  26. case D6JointAxis::SwingZ:
  27. return PxD6Axis::eSWING2;
  28. }
  29. }
  30. PxD6Motion::Enum toPxMotion(D6JointMotion motion)
  31. {
  32. switch(motion)
  33. {
  34. default:
  35. case D6JointMotion::Free:
  36. return PxD6Motion::eFREE;
  37. case D6JointMotion::Limited:
  38. return PxD6Motion::eLIMITED;
  39. case D6JointMotion::Locked:
  40. return PxD6Motion::eLOCKED;
  41. }
  42. }
  43. PxD6Drive::Enum toPxDrive(D6JointDriveType drive)
  44. {
  45. switch(drive)
  46. {
  47. default:
  48. case D6JointDriveType::X:
  49. return PxD6Drive::eX;
  50. case D6JointDriveType::Y:
  51. return PxD6Drive::eY;
  52. case D6JointDriveType::Z:
  53. return PxD6Drive::eZ;
  54. case D6JointDriveType::Swing:
  55. return PxD6Drive::eSWING;
  56. case D6JointDriveType::Twist:
  57. return PxD6Drive::eTWIST;
  58. case D6JointDriveType::SLERP:
  59. return PxD6Drive::eSLERP;
  60. }
  61. }
  62. D6JointMotion fromPxMotion(PxD6Motion::Enum motion)
  63. {
  64. switch (motion)
  65. {
  66. default:
  67. case PxD6Motion::eFREE:
  68. return D6JointMotion::Free;
  69. case PxD6Motion::eLIMITED:
  70. return D6JointMotion::Limited;
  71. case PxD6Motion::eLOCKED:
  72. return D6JointMotion::Locked;
  73. }
  74. }
  75. D6JointDriveType fromPxDrive(PxD6Drive::Enum drive)
  76. {
  77. switch (drive)
  78. {
  79. default:
  80. case PxD6Drive::eX:
  81. return D6JointDriveType::X;
  82. case PxD6Drive::eY:
  83. return D6JointDriveType::Y;
  84. case PxD6Drive::eZ:
  85. return D6JointDriveType::Z;
  86. case PxD6Drive::eSWING:
  87. return D6JointDriveType::Swing;
  88. case PxD6Drive::eTWIST:
  89. return D6JointDriveType::Twist;
  90. case PxD6Drive::eSLERP:
  91. return D6JointDriveType::SLERP;
  92. }
  93. }
  94. PhysXD6Joint::PhysXD6Joint(PxPhysics* physx, const D6_JOINT_DESC& desc)
  95. :D6Joint(desc)
  96. {
  97. PxRigidActor* actor0 = nullptr;
  98. if (desc.bodies[0].body != nullptr)
  99. actor0 = static_cast<PhysXRigidbody*>(desc.bodies[0].body)->_getInternal();
  100. PxRigidActor* actor1 = nullptr;
  101. if (desc.bodies[1].body != nullptr)
  102. actor1 = static_cast<PhysXRigidbody*>(desc.bodies[1].body)->_getInternal();
  103. PxTransform tfrm0 = toPxTransform(desc.bodies[0].position, desc.bodies[0].rotation);
  104. PxTransform tfrm1 = toPxTransform(desc.bodies[1].position, desc.bodies[1].rotation);
  105. PxD6Joint* joint = PxD6JointCreate(*physx, actor0, tfrm0, actor1, tfrm1);
  106. joint->userData = this;
  107. mInternal = bs_new<FPhysXJoint>(joint, desc);
  108. // Calls to virtual methods are okay here
  109. for (UINT32 i = 0; i < (UINT32)D6JointAxis::Count; i++)
  110. setMotion((D6JointAxis)i, desc.motion[i]);
  111. for (UINT32 i = 0; i < (UINT32)D6JointDriveType::Count; i++)
  112. setDrive((D6JointDriveType)i, desc.drive[i]);
  113. setLimitLinear(desc.limitLinear);
  114. setLimitTwist(desc.limitTwist);
  115. setLimitSwing(desc.limitSwing);
  116. setDriveTransform(desc.drivePosition, desc.driveRotation);
  117. setDriveVelocity(desc.driveLinearVelocity, desc.driveAngularVelocity);
  118. }
  119. PhysXD6Joint::~PhysXD6Joint()
  120. {
  121. bs_delete(mInternal);
  122. }
  123. D6JointMotion PhysXD6Joint::getMotion(D6JointAxis axis) const
  124. {
  125. return fromPxMotion(getInternal()->getMotion(toPxAxis(axis)));
  126. }
  127. void PhysXD6Joint::setMotion(D6JointAxis axis, D6JointMotion motion)
  128. {
  129. getInternal()->setMotion(toPxAxis(axis), toPxMotion(motion));
  130. }
  131. Radian PhysXD6Joint::getTwist() const
  132. {
  133. return Radian(getInternal()->getTwist());
  134. }
  135. Radian PhysXD6Joint::getSwingY() const
  136. {
  137. return Radian(getInternal()->getSwingYAngle());
  138. }
  139. Radian PhysXD6Joint::getSwingZ() const
  140. {
  141. return Radian(getInternal()->getSwingZAngle());
  142. }
  143. LimitLinear PhysXD6Joint::getLimitLinear() const
  144. {
  145. PxJointLinearLimit pxLimit = getInternal()->getLinearLimit();
  146. LimitLinear limit;
  147. limit.extent = pxLimit.value;
  148. limit.contactDist = pxLimit.contactDistance;
  149. limit.restitution = pxLimit.restitution;
  150. limit.spring.stiffness = pxLimit.stiffness;
  151. limit.spring.damping = pxLimit.damping;
  152. return limit;
  153. }
  154. void PhysXD6Joint::setLimitLinear(const LimitLinear& limit)
  155. {
  156. PxJointLinearLimit pxLimit(gPhysX().getScale(), limit.extent, limit.contactDist);
  157. pxLimit.stiffness = limit.spring.stiffness;
  158. pxLimit.damping = limit.spring.damping;
  159. pxLimit.restitution = limit.restitution;
  160. getInternal()->setLinearLimit(pxLimit);
  161. }
  162. LimitAngularRange PhysXD6Joint::getLimitTwist() const
  163. {
  164. PxJointAngularLimitPair pxLimit = getInternal()->getTwistLimit();
  165. LimitAngularRange limit;
  166. limit.lower = pxLimit.lower;
  167. limit.upper = pxLimit.upper;
  168. limit.contactDist = pxLimit.contactDistance;
  169. limit.restitution = pxLimit.restitution;
  170. limit.spring.stiffness = pxLimit.stiffness;
  171. limit.spring.damping = pxLimit.damping;
  172. return limit;
  173. }
  174. void PhysXD6Joint::setLimitTwist(const LimitAngularRange& limit)
  175. {
  176. PxJointAngularLimitPair pxLimit(limit.lower.valueRadians(), limit.upper.valueRadians(), limit.contactDist);
  177. pxLimit.stiffness = limit.spring.stiffness;
  178. pxLimit.damping = limit.spring.damping;
  179. pxLimit.restitution = limit.restitution;
  180. getInternal()->setTwistLimit(pxLimit);
  181. }
  182. LimitConeRange PhysXD6Joint::getLimitSwing() const
  183. {
  184. PxJointLimitCone pxLimit = getInternal()->getSwingLimit();
  185. LimitConeRange limit;
  186. limit.yLimitAngle = pxLimit.yAngle;
  187. limit.zLimitAngle = pxLimit.zAngle;
  188. limit.contactDist = pxLimit.contactDistance;
  189. limit.restitution = pxLimit.restitution;
  190. limit.spring.stiffness = pxLimit.stiffness;
  191. limit.spring.damping = pxLimit.damping;
  192. return limit;
  193. }
  194. void PhysXD6Joint::setLimitSwing(const LimitConeRange& limit)
  195. {
  196. PxJointLimitCone pxLimit(limit.yLimitAngle.valueRadians(), limit.zLimitAngle.valueRadians(), limit.contactDist);
  197. pxLimit.stiffness = limit.spring.stiffness;
  198. pxLimit.damping = limit.spring.damping;
  199. pxLimit.restitution = limit.restitution;
  200. getInternal()->setSwingLimit(pxLimit);
  201. }
  202. D6JointDrive PhysXD6Joint::getDrive(D6JointDriveType type) const
  203. {
  204. PxD6JointDrive pxDrive = getInternal()->getDrive(toPxDrive(type));
  205. D6JointDrive drive;
  206. drive.acceleration = pxDrive.flags & PxD6JointDriveFlag::eACCELERATION;
  207. drive.stiffness = pxDrive.stiffness;
  208. drive.damping = pxDrive.damping;
  209. drive.forceLimit = pxDrive.forceLimit;
  210. return drive;
  211. }
  212. void PhysXD6Joint::setDrive(D6JointDriveType type, const D6JointDrive& drive)
  213. {
  214. PxD6JointDrive pxDrive;
  215. if(drive.acceleration)
  216. pxDrive.flags = PxD6JointDriveFlag::eACCELERATION;
  217. pxDrive.stiffness = drive.stiffness;
  218. pxDrive.damping = drive.damping;
  219. pxDrive.forceLimit = drive.forceLimit;
  220. getInternal()->setDrive(toPxDrive(type), pxDrive);
  221. }
  222. Vector3 PhysXD6Joint::getDrivePosition() const
  223. {
  224. return fromPxVector(getInternal()->getDrivePosition().p);
  225. }
  226. Quaternion PhysXD6Joint::getDriveRotation() const
  227. {
  228. return fromPxQuaternion(getInternal()->getDrivePosition().q);
  229. }
  230. void PhysXD6Joint::setDriveTransform(const Vector3& position, const Quaternion& rotation)
  231. {
  232. getInternal()->setDrivePosition(toPxTransform(position, rotation));
  233. }
  234. Vector3 PhysXD6Joint::getDriveLinearVelocity() const
  235. {
  236. PxVec3 linear;
  237. PxVec3 angular;
  238. getInternal()->getDriveVelocity(linear, angular);
  239. return fromPxVector(linear);
  240. }
  241. Vector3 PhysXD6Joint::getDriveAngularVelocity() const
  242. {
  243. PxVec3 linear;
  244. PxVec3 angular;
  245. getInternal()->getDriveVelocity(linear, angular);
  246. return fromPxVector(angular);
  247. }
  248. void PhysXD6Joint::setDriveVelocity(const Vector3& linear, const Vector3& angular)
  249. {
  250. getInternal()->setDriveVelocity(toPxVector(linear), toPxVector(angular));
  251. }
  252. PxD6Joint* PhysXD6Joint::getInternal() const
  253. {
  254. FPhysXJoint* internal = static_cast<FPhysXJoint*>(mInternal);
  255. return static_cast<PxD6Joint*>(internal->_getInternal());
  256. }
  257. }