BsPhysXHingeJoint.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsPhysXHingeJoint.h"
  4. #include "BsFPhysXJoint.h"
  5. #include "BsPhysXRigidbody.h"
  6. #include "PxRigidDynamic.h"
  7. using namespace physx;
  8. namespace bs
  9. {
  10. PxRevoluteJointFlag::Enum toPxFlag(HingeJointFlag flag)
  11. {
  12. switch (flag)
  13. {
  14. case HingeJointFlag::Limit:
  15. return PxRevoluteJointFlag::eLIMIT_ENABLED;
  16. default:
  17. case HingeJointFlag::Drive:
  18. return PxRevoluteJointFlag::eDRIVE_ENABLED;
  19. }
  20. }
  21. PhysXHingeJoint::PhysXHingeJoint(PxPhysics* physx, const HINGE_JOINT_DESC& desc)
  22. :HingeJoint(desc)
  23. {
  24. PxRigidActor* actor0 = nullptr;
  25. if (desc.bodies[0].body != nullptr)
  26. actor0 = static_cast<PhysXRigidbody*>(desc.bodies[0].body)->_getInternal();
  27. PxRigidActor* actor1 = nullptr;
  28. if (desc.bodies[1].body != nullptr)
  29. actor1 = static_cast<PhysXRigidbody*>(desc.bodies[1].body)->_getInternal();
  30. PxTransform tfrm0 = toPxTransform(desc.bodies[0].position, desc.bodies[0].rotation);
  31. PxTransform tfrm1 = toPxTransform(desc.bodies[1].position, desc.bodies[1].rotation);
  32. PxRevoluteJoint* joint = PxRevoluteJointCreate(*physx, actor0, tfrm0, actor1, tfrm1);
  33. joint->userData = this;
  34. mInternal = bs_new<FPhysXJoint>(joint, desc);
  35. PxRevoluteJointFlags flags;
  36. if (((UINT32)desc.flag & (UINT32)HingeJointFlag::Limit) != 0)
  37. flags |= PxRevoluteJointFlag::eLIMIT_ENABLED;
  38. if (((UINT32)desc.flag & (UINT32)HingeJointFlag::Drive) != 0)
  39. flags |= PxRevoluteJointFlag::eDRIVE_ENABLED;
  40. joint->setRevoluteJointFlags(flags);
  41. // Must be set after global flags, as it will append to them.
  42. // Calls to virtual methods are okay here.
  43. setLimit(desc.limit);
  44. setDrive(desc.drive);
  45. }
  46. PhysXHingeJoint::~PhysXHingeJoint()
  47. {
  48. bs_delete(mInternal);
  49. }
  50. Radian PhysXHingeJoint::getAngle() const
  51. {
  52. return Radian(getInternal()->getAngle());
  53. }
  54. float PhysXHingeJoint::getSpeed() const
  55. {
  56. return getInternal()->getVelocity();
  57. }
  58. LimitAngularRange PhysXHingeJoint::getLimit() const
  59. {
  60. PxJointAngularLimitPair pxLimit = getInternal()->getLimit();
  61. LimitAngularRange limit;
  62. limit.lower = pxLimit.lower;
  63. limit.upper = pxLimit.upper;
  64. limit.contactDist = pxLimit.contactDistance;
  65. limit.restitution = pxLimit.restitution;
  66. limit.spring.stiffness = pxLimit.stiffness;
  67. limit.spring.damping = pxLimit.damping;
  68. return limit;
  69. }
  70. void PhysXHingeJoint::setLimit(const LimitAngularRange& limit)
  71. {
  72. PxJointAngularLimitPair pxLimit(limit.lower.valueRadians(), limit.upper.valueRadians(), limit.contactDist);
  73. pxLimit.stiffness = limit.spring.stiffness;
  74. pxLimit.damping = limit.spring.damping;
  75. pxLimit.restitution = limit.restitution;
  76. getInternal()->setLimit(pxLimit);
  77. }
  78. HingeJointDrive PhysXHingeJoint::getDrive() const
  79. {
  80. HingeJointDrive drive;
  81. drive.speed = getInternal()->getDriveVelocity();
  82. drive.forceLimit = getInternal()->getDriveForceLimit();
  83. drive.gearRatio = getInternal()->getDriveGearRatio();
  84. drive.freeSpin = getInternal()->getRevoluteJointFlags() & PxRevoluteJointFlag::eDRIVE_FREESPIN;
  85. return drive;
  86. }
  87. void PhysXHingeJoint::setDrive(const HingeJointDrive& drive)
  88. {
  89. getInternal()->setDriveVelocity(drive.speed);
  90. getInternal()->setDriveForceLimit(drive.forceLimit);
  91. getInternal()->setDriveGearRatio(drive.gearRatio);
  92. getInternal()->setRevoluteJointFlag(PxRevoluteJointFlag::eDRIVE_FREESPIN, drive.freeSpin);
  93. }
  94. void PhysXHingeJoint::setFlag(HingeJointFlag flag, bool enabled)
  95. {
  96. getInternal()->setRevoluteJointFlag(toPxFlag(flag), enabled);
  97. }
  98. bool PhysXHingeJoint::hasFlag(HingeJointFlag flag) const
  99. {
  100. return getInternal()->getRevoluteJointFlags() & toPxFlag(flag);
  101. }
  102. PxRevoluteJoint* PhysXHingeJoint::getInternal() const
  103. {
  104. FPhysXJoint* internal = static_cast<FPhysXJoint*>(mInternal);
  105. return static_cast<PxRevoluteJoint*>(internal->_getInternal());
  106. }
  107. }