[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / src / BulletDynamics / Featherstone / btMultiBodyLinkCollider.h
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2013 Erwin Coumans  http://bulletphysics.org
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #ifndef BT_FEATHERSTONE_LINK_COLLIDER_H
17 #define BT_FEATHERSTONE_LINK_COLLIDER_H
18
19 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
20
21 #include "btMultiBody.h"
22 #include "LinearMath/btSerializer.h"
23
24 #ifdef BT_USE_DOUBLE_PRECISION
25 #define btMultiBodyLinkColliderData btMultiBodyLinkColliderDoubleData
26 #define btMultiBodyLinkColliderDataName "btMultiBodyLinkColliderDoubleData"
27 #else
28 #define btMultiBodyLinkColliderData btMultiBodyLinkColliderFloatData
29 #define btMultiBodyLinkColliderDataName "btMultiBodyLinkColliderFloatData"
30 #endif
31
32 class btMultiBodyLinkCollider : public btCollisionObject
33 {
34         //protected:
35 public:
36         btMultiBody* m_multiBody;
37         int m_link;
38
39         virtual ~btMultiBodyLinkCollider()
40         {
41
42         }
43         btMultiBodyLinkCollider(btMultiBody* multiBody, int link)
44                 : m_multiBody(multiBody),
45                   m_link(link)
46         {
47                 m_checkCollideWith = true;
48                 //we need to remove the 'CF_STATIC_OBJECT' flag, otherwise links/base doesn't merge islands
49                 //this means that some constraints might point to bodies that are not in the islands, causing crashes
50                 //if (link>=0 || (multiBody && !multiBody->hasFixedBase()))
51                 {
52                         m_collisionFlags &= (~btCollisionObject::CF_STATIC_OBJECT);
53                 }
54                 // else
55                 //{
56                 //      m_collisionFlags |= (btCollisionObject::CF_STATIC_OBJECT);
57                 //}
58
59                 m_internalType = CO_FEATHERSTONE_LINK;
60         }
61         static btMultiBodyLinkCollider* upcast(btCollisionObject* colObj)
62         {
63                 if (colObj->getInternalType() & btCollisionObject::CO_FEATHERSTONE_LINK)
64                         return (btMultiBodyLinkCollider*)colObj;
65                 return 0;
66         }
67         static const btMultiBodyLinkCollider* upcast(const btCollisionObject* colObj)
68         {
69                 if (colObj->getInternalType() & btCollisionObject::CO_FEATHERSTONE_LINK)
70                         return (btMultiBodyLinkCollider*)colObj;
71                 return 0;
72         }
73
74         virtual bool checkCollideWithOverride(const btCollisionObject* co) const
75         {
76                 const btMultiBodyLinkCollider* other = btMultiBodyLinkCollider::upcast(co);
77                 if (!other)
78                         return true;
79                 if (other->m_multiBody != this->m_multiBody)
80                         return true;
81                 if (!m_multiBody->hasSelfCollision())
82                         return false;
83
84                 //check if 'link' has collision disabled
85                 if (m_link >= 0)
86                 {
87                         const btMultibodyLink& link = m_multiBody->getLink(this->m_link);
88                         if (link.m_flags & BT_MULTIBODYLINKFLAGS_DISABLE_ALL_PARENT_COLLISION)
89                         {
90                                 int parent_of_this = m_link;
91                                 while (1)
92                                 {
93                                         if (parent_of_this == -1)
94                                                 break;
95                                         parent_of_this = m_multiBody->getLink(parent_of_this).m_parent;
96                                         if (parent_of_this == other->m_link)
97                                         {
98                                                 return false;
99                                         }
100                                 }
101                         }
102                         else if (link.m_flags & BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION)
103                         {
104                                 if (link.m_parent == other->m_link)
105                                         return false;
106                         }
107                 }
108
109                 if (other->m_link >= 0)
110                 {
111                         const btMultibodyLink& otherLink = other->m_multiBody->getLink(other->m_link);
112                         if (otherLink.m_flags & BT_MULTIBODYLINKFLAGS_DISABLE_ALL_PARENT_COLLISION)
113                         {
114                                 int parent_of_other = other->m_link;
115                                 while (1)
116                                 {
117                                         if (parent_of_other == -1)
118                                                 break;
119                                         parent_of_other = m_multiBody->getLink(parent_of_other).m_parent;
120                                         if (parent_of_other == this->m_link)
121                                                 return false;
122                                 }
123                         }
124                         else if (otherLink.m_flags & BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION)
125                         {
126                                 if (otherLink.m_parent == this->m_link)
127                                         return false;
128                         }
129                 }
130                 return true;
131         }
132
133         bool isStaticOrKinematic() const
134         {
135                 return isStaticOrKinematicObject();
136         }
137
138         bool isKinematic() const
139         {
140                 return isKinematicObject();
141         }
142
143         void setDynamicType(int dynamicType)
144         {
145                 int oldFlags = getCollisionFlags();
146                 oldFlags &= ~(btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_KINEMATIC_OBJECT);
147                 setCollisionFlags(oldFlags | dynamicType);
148         }
149
150         virtual int calculateSerializeBufferSize() const;
151
152         ///fills the dataBuffer and returns the struct name (and 0 on failure)
153         virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
154 };
155
156 // clang-format off
157
158 struct  btMultiBodyLinkColliderFloatData
159 {
160         btCollisionObjectFloatData m_colObjData;
161         btMultiBodyFloatData    *m_multiBody;
162         int                     m_link;
163         char            m_padding[4];
164 };
165
166 struct  btMultiBodyLinkColliderDoubleData
167 {
168         btCollisionObjectDoubleData m_colObjData;
169         btMultiBodyDoubleData           *m_multiBody;
170         int                     m_link;
171         char            m_padding[4];
172 };
173
174 // clang-format on
175
176 SIMD_FORCE_INLINE int btMultiBodyLinkCollider::calculateSerializeBufferSize() const
177 {
178         return sizeof(btMultiBodyLinkColliderData);
179 }
180
181 SIMD_FORCE_INLINE const char* btMultiBodyLinkCollider::serialize(void* dataBuffer, class btSerializer* serializer) const
182 {
183         btMultiBodyLinkColliderData* dataOut = (btMultiBodyLinkColliderData*)dataBuffer;
184         btCollisionObject::serialize(&dataOut->m_colObjData, serializer);
185
186         dataOut->m_link = this->m_link;
187         dataOut->m_multiBody = (btMultiBodyData*)serializer->getUniquePointer(m_multiBody);
188
189         // Fill padding with zeros to appease msan.
190         memset(dataOut->m_padding, 0, sizeof(dataOut->m_padding));
191
192         return btMultiBodyLinkColliderDataName;
193 }
194
195 #endif  //BT_FEATHERSTONE_LINK_COLLIDER_H