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 "BsPhysXSliderJoint.h"
4#include "BsFPhysXJoint.h"
5#include "BsPhysX.h"
6#include "BsPhysXRigidbody.h"
7#include "PxRigidDynamic.h"
8
9using namespace physx;
10
11namespace bs
12{
13 PxPrismaticJointFlag::Enum toPxFlag(SliderJointFlag flag)
14 {
15 switch (flag)
16 {
17 default:
18 case SliderJointFlag::Limit:
19 return PxPrismaticJointFlag::eLIMIT_ENABLED;
20 }
21 }
22
23 PhysXSliderJoint::PhysXSliderJoint(PxPhysics* physx, const SLIDER_JOINT_DESC& desc)
24 :SliderJoint(desc)
25 {
26 PxRigidActor* actor0 = nullptr;
27 if (desc.bodies[0].body != nullptr)
28 actor0 = static_cast<PhysXRigidbody*>(desc.bodies[0].body)->_getInternal();
29
30 PxRigidActor* actor1 = nullptr;
31 if (desc.bodies[1].body != nullptr)
32 actor1 = static_cast<PhysXRigidbody*>(desc.bodies[1].body)->_getInternal();
33
34 PxTransform tfrm0 = toPxTransform(desc.bodies[0].position, desc.bodies[0].rotation);
35 PxTransform tfrm1 = toPxTransform(desc.bodies[1].position, desc.bodies[1].rotation);
36
37 PxPrismaticJoint* joint = PxPrismaticJointCreate(*physx, actor0, tfrm0, actor1, tfrm1);
38 joint->userData = this;
39
40 mInternal = bs_new<FPhysXJoint>(joint, desc);
41
42 PxPrismaticJointFlags flags;
43
44 if (((UINT32)desc.flag & (UINT32)SliderJointFlag::Limit) != 0)
45 flags |= PxPrismaticJointFlag::eLIMIT_ENABLED;
46
47 joint->setPrismaticJointFlags(flags);
48
49 // Calls to virtual methods are okay here
50 setLimit(desc.limit);
51 }
52
53 PhysXSliderJoint::~PhysXSliderJoint()
54 {
55 bs_delete(mInternal);
56 }
57
58 float PhysXSliderJoint::getPosition() const
59 {
60 return getInternal()->getPosition();
61 }
62
63 float PhysXSliderJoint::getSpeed() const
64 {
65 return getInternal()->getVelocity();
66 }
67
68 LimitLinearRange PhysXSliderJoint::getLimit() const
69 {
70 PxJointLinearLimitPair pxLimit = getInternal()->getLimit();
71
72 LimitLinearRange limit;
73 limit.lower = pxLimit.lower;
74 limit.upper = pxLimit.upper;
75 limit.contactDist = pxLimit.contactDistance;
76 limit.restitution = pxLimit.restitution;
77 limit.spring.stiffness = pxLimit.stiffness;
78 limit.spring.damping = pxLimit.damping;
79
80 return limit;
81 }
82
83 void PhysXSliderJoint::setLimit(const LimitLinearRange& limit)
84 {
85 PxJointLinearLimitPair pxLimit(gPhysX().getScale(), limit.lower, limit.upper, limit.contactDist);
86 pxLimit.stiffness = limit.spring.stiffness;
87 pxLimit.damping = limit.spring.damping;
88 pxLimit.restitution = limit.restitution;
89
90 getInternal()->setLimit(pxLimit);
91 }
92
93 void PhysXSliderJoint::setFlag(SliderJointFlag flag, bool enabled)
94 {
95 getInternal()->setPrismaticJointFlag(toPxFlag(flag), enabled);
96 }
97
98 bool PhysXSliderJoint::hasFlag(SliderJointFlag flag) const
99 {
100 return getInternal()->getPrismaticJointFlags() & toPxFlag(flag);
101 }
102
103 PxPrismaticJoint* PhysXSliderJoint::getInternal() const
104 {
105 FPhysXJoint* internal = static_cast<FPhysXJoint*>(mInternal);
106
107 return static_cast<PxPrismaticJoint*>(internal->_getInternal());
108 }
109}