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 | |
9 | namespace 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 |