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 "BsPhysXDistanceJoint.h"
4#include "BsFPhysXJoint.h"
5#include "BsPhysXRigidbody.h"
6#include "PxRigidDynamic.h"
7
8using namespace physx;
9
10namespace bs
11{
12 PxDistanceJointFlag::Enum toPxFlag(DistanceJointFlag flag)
13 {
14 switch (flag)
15 {
16 case DistanceJointFlag::MaxDistance:
17 return PxDistanceJointFlag::eMAX_DISTANCE_ENABLED;
18 case DistanceJointFlag::MinDistance:
19 return PxDistanceJointFlag::eMIN_DISTANCE_ENABLED;
20 default:
21 case DistanceJointFlag::Spring:
22 return PxDistanceJointFlag::eSPRING_ENABLED;
23 }
24 }
25
26 PhysXDistanceJoint::PhysXDistanceJoint(PxPhysics* physx, const DISTANCE_JOINT_DESC& desc)
27 :DistanceJoint(desc)
28 {
29 PxRigidActor* actor0 = nullptr;
30 if (desc.bodies[0].body != nullptr)
31 actor0 = static_cast<PhysXRigidbody*>(desc.bodies[0].body)->_getInternal();
32
33 PxRigidActor* actor1 = nullptr;
34 if (desc.bodies[1].body != nullptr)
35 actor1 = static_cast<PhysXRigidbody*>(desc.bodies[1].body)->_getInternal();
36
37 PxTransform tfrm0 = toPxTransform(desc.bodies[0].position, desc.bodies[0].rotation);
38 PxTransform tfrm1 = toPxTransform(desc.bodies[1].position, desc.bodies[1].rotation);
39
40 PxDistanceJoint* joint = PxDistanceJointCreate(*physx, actor0, tfrm0, actor1, tfrm1);
41 joint->userData = this;
42
43 mInternal = bs_new<FPhysXJoint>(joint, desc);
44
45 // Calls to virtual methods are okay here
46 setMinDistance(desc.minDistance);
47 setMaxDistance(desc.maxDistance);
48 setTolerance(desc.tolerance);
49 setSpring(desc.spring);
50
51 PxDistanceJointFlags flags;
52
53 if(((UINT32)desc.flag & (UINT32)DistanceJointFlag::MaxDistance) != 0)
54 flags |= PxDistanceJointFlag::eMAX_DISTANCE_ENABLED;
55
56 if (((UINT32)desc.flag & (UINT32)DistanceJointFlag::MinDistance) != 0)
57 flags |= PxDistanceJointFlag::eMIN_DISTANCE_ENABLED;
58
59 if (((UINT32)desc.flag & (UINT32)DistanceJointFlag::Spring) != 0)
60 flags |= PxDistanceJointFlag::eSPRING_ENABLED;
61
62 joint->setDistanceJointFlags(flags);
63 }
64
65 PhysXDistanceJoint::~PhysXDistanceJoint()
66 {
67 bs_delete(mInternal);
68 }
69
70 float PhysXDistanceJoint::getDistance() const
71 {
72 return getInternal()->getDistance();
73 }
74
75 float PhysXDistanceJoint::getMinDistance() const
76 {
77 return getInternal()->getMinDistance();
78 }
79
80 void PhysXDistanceJoint::setMinDistance(float value)
81 {
82 getInternal()->setMinDistance(value);
83 }
84
85 float PhysXDistanceJoint::getMaxDistance() const
86 {
87 return getInternal()->getMaxDistance();
88 }
89
90 void PhysXDistanceJoint::setMaxDistance(float value)
91 {
92 getInternal()->setMaxDistance(value);
93 }
94
95 float PhysXDistanceJoint::getTolerance() const
96 {
97 return getInternal()->getTolerance();
98 }
99
100 void PhysXDistanceJoint::setTolerance(float value)
101 {
102 getInternal()->setTolerance(value);
103 }
104
105 Spring PhysXDistanceJoint::getSpring() const
106 {
107 float damping = getInternal()->getDamping();
108 float stiffness = getInternal()->getStiffness();
109
110 return Spring(stiffness, damping);
111 }
112
113 void PhysXDistanceJoint::setSpring(const Spring& value)
114 {
115 getInternal()->setDamping(value.damping);
116 getInternal()->setStiffness(value.stiffness);
117 }
118
119 void PhysXDistanceJoint::setFlag(DistanceJointFlag flag, bool enabled)
120 {
121 getInternal()->setDistanceJointFlag(toPxFlag(flag), enabled);
122 }
123
124 bool PhysXDistanceJoint::hasFlag(DistanceJointFlag flag) const
125 {
126 return getInternal()->getDistanceJointFlags() & toPxFlag(flag);
127 }
128
129 PxDistanceJoint* PhysXDistanceJoint::getInternal() const
130 {
131 FPhysXJoint* internal = static_cast<FPhysXJoint*>(mInternal);
132
133 return static_cast<PxDistanceJoint*>(internal->_getInternal());
134 }
135}