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 "Components/BsCSliderJoint.h"
4#include "Scene/BsSceneObject.h"
5#include "Components/BsCRigidbody.h"
6#include "Private/RTTI/BsCSliderJointRTTI.h"
7#include "Scene/BsSceneManager.h"
8
9namespace bs
10{
11 CSliderJoint::CSliderJoint()
12 : CJoint(mDesc)
13 {
14 setName("SliderJoint");
15 }
16
17 CSliderJoint::CSliderJoint(const HSceneObject& parent)
18 : CJoint(parent, mDesc)
19 {
20 setName("SliderJoint");
21 }
22
23 float CSliderJoint::getPosition() const
24 {
25 if (mInternal == nullptr)
26 return 0.0f;
27
28 return _getInternal()->getPosition();
29 }
30
31 float CSliderJoint::getSpeed() const
32 {
33 if (mInternal == nullptr)
34 return 0.0f;
35
36 return _getInternal()->getSpeed();
37 }
38
39 LimitLinearRange CSliderJoint::getLimit() const
40 {
41 return mDesc.limit;
42 }
43
44 void CSliderJoint::setLimit(const LimitLinearRange& limit)
45 {
46 if (mDesc.limit == limit)
47 return;
48
49 mDesc.limit = limit;
50
51 if (mInternal != nullptr)
52 _getInternal()->setLimit(limit);
53 }
54
55 void CSliderJoint::setFlag(SliderJointFlag flag, bool enabled)
56 {
57 bool isEnabled = ((UINT32)mDesc.flag & (UINT32)flag) != 0;
58 if (isEnabled == enabled)
59 return;
60
61 if (enabled)
62 mDesc.flag = (SliderJointFlag)((UINT32)mDesc.flag | (UINT32)flag);
63 else
64 mDesc.flag = (SliderJointFlag)((UINT32)mDesc.flag & ~(UINT32)flag);
65
66 if (mInternal != nullptr)
67 _getInternal()->setFlag(flag, enabled);
68 }
69
70 bool CSliderJoint::hasFlag(SliderJointFlag flag) const
71 {
72 return ((UINT32)mDesc.flag & (UINT32)flag) != 0;
73 }
74
75 SPtr<Joint> CSliderJoint::createInternal()
76 {
77 const SPtr<SceneInstance>& scene = SO()->getScene();
78 SPtr<Joint> joint = SliderJoint::create(*scene->getPhysicsScene(), mDesc);
79
80 joint->_setOwner(PhysicsOwnerType::Component, this);
81 return joint;
82 }
83
84 void CSliderJoint::getLocalTransform(JointBody body, Vector3& position, Quaternion& rotation)
85 {
86 position = mPositions[(UINT32)body];
87 rotation = mRotations[(UINT32)body];
88
89 HRigidbody rigidbody = mBodies[(UINT32)body];
90 const Transform& tfrm = SO()->getTransform();
91 if (rigidbody == nullptr) // Get world space transform if no relative to any body
92 {
93 Quaternion worldRot = tfrm.getRotation();
94
95 rotation = worldRot*rotation;
96 position = worldRot.rotate(position) + tfrm.getPosition();
97 }
98 else
99 {
100 const Transform& rigidbodyTfrm = rigidbody->SO()->getTransform();
101
102 // Use only the offset for positioning, but for rotation use both the offset and target SO rotation.
103 // (Needed because we need to rotate the joint SO in order to orient the slider direction, so we need an
104 // additional transform that allows us to orient the object)
105 position = rotation.rotate(position);
106 rotation = (rigidbodyTfrm.getRotation()*rotation).inverse()*tfrm.getRotation();
107 }
108 }
109
110 RTTITypeBase* CSliderJoint::getRTTIStatic()
111 {
112 return CSliderJointRTTI::instance();
113 }
114
115 RTTITypeBase* CSliderJoint::getRTTI() const
116 {
117 return CSliderJoint::getRTTIStatic();
118 }
119}
120