1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "BsFPhysXJoint.h"
4#include "BsPhysXRigidbody.h"
5#include "Physics/BsJoint.h"
6#include "PxRigidDynamic.h"
7
8using namespace physx;
9
10namespace bs
11{
12 PxJointActorIndex::Enum toJointActor(JointBody body)
13 {
14 if (body == JointBody::Target)
15 return PxJointActorIndex::eACTOR0;
16
17 return PxJointActorIndex::eACTOR1;
18 }
19
20 FPhysXJoint::FPhysXJoint(physx::PxJoint* joint, const JOINT_DESC& desc)
21 :FJoint(desc), mJoint(joint)
22 {
23 mJoint->setBreakForce(desc.breakForce, desc.breakTorque);
24 mJoint->setConstraintFlag(PxConstraintFlag::eCOLLISION_ENABLED, desc.enableCollision);
25 }
26
27 FPhysXJoint::~FPhysXJoint()
28 {
29 mJoint->userData = nullptr;
30 mJoint->release();
31 }
32
33 Rigidbody* FPhysXJoint::getBody(JointBody body) const
34 {
35 PxRigidActor* actorA = nullptr;
36 PxRigidActor* actorB = nullptr;
37
38 mJoint->getActors(actorA, actorB);
39
40 PxRigidActor* wantedActor = body == JointBody::Target ? actorA : actorB;
41 if (wantedActor == nullptr)
42 return nullptr;
43
44 return (Rigidbody*)wantedActor->userData;
45 }
46
47 void FPhysXJoint::setBody(JointBody body, Rigidbody* value)
48 {
49 PxRigidActor* actorA = nullptr;
50 PxRigidActor* actorB = nullptr;
51
52 mJoint->getActors(actorA, actorB);
53
54 PxRigidActor* actor = nullptr;
55 if (value != nullptr)
56 actor = static_cast<PhysXRigidbody*>(value)->_getInternal();
57
58 if (body == JointBody::Target)
59 actorA = actor;
60 else
61 actorB = actor;
62
63 mJoint->setActors(actorA, actorB);
64 }
65
66 Vector3 FPhysXJoint::getPosition(JointBody body) const
67 {
68 PxVec3 position = mJoint->getLocalPose(toJointActor(body)).p;
69
70 return fromPxVector(position);
71 }
72
73 Quaternion FPhysXJoint::getRotation(JointBody body) const
74 {
75 PxQuat rotation = mJoint->getLocalPose(toJointActor(body)).q;
76
77 return fromPxQuaternion(rotation);
78 }
79
80 void FPhysXJoint::setTransform(JointBody body, const Vector3& position, const Quaternion& rotation)
81 {
82 PxTransform transform = toPxTransform(position, rotation);
83
84 mJoint->setLocalPose(toJointActor(body), transform);
85 }
86
87 float FPhysXJoint::getBreakForce() const
88 {
89 float force = 0.0f;
90 float torque = 0.0f;
91
92 mJoint->getBreakForce(force, torque);
93 return force;
94 }
95
96 void FPhysXJoint::setBreakForce(float force)
97 {
98 float dummy = 0.0f;
99 float torque = 0.0f;
100
101 mJoint->getBreakForce(dummy, torque);
102 mJoint->setBreakForce(force, torque);
103 }
104
105 float FPhysXJoint::getBreakTorque() const
106 {
107 float force = 0.0f;
108 float torque = 0.0f;
109
110 mJoint->getBreakForce(force, torque);
111 return torque;
112 }
113
114 void FPhysXJoint::setBreakTorque(float torque)
115 {
116 float force = 0.0f;
117 float dummy = 0.0f;
118
119 mJoint->getBreakForce(force, dummy);
120 mJoint->setBreakForce(force, torque);
121 }
122
123 bool FPhysXJoint::getEnableCollision() const
124 {
125 return mJoint->getConstraintFlags() & PxConstraintFlag::eCOLLISION_ENABLED;
126 }
127
128 void FPhysXJoint::setEnableCollision(bool value)
129 {
130 mJoint->setConstraintFlag(PxConstraintFlag::eCOLLISION_ENABLED, value);
131 }
132}