1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
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_COLLISION_OBJECT_H
17 #define BT_COLLISION_OBJECT_H
18
19 #include <cmath>
20
21 #include "LinearMath/btTransform.h"
22
23 //island management, m_activationState1
24 #define ACTIVE_TAG 1
25 #define ISLAND_SLEEPING 2
26 #define WANTS_DEACTIVATION 3
27 #define DISABLE_DEACTIVATION 4
28 #define DISABLE_SIMULATION 5
29
30 struct btBroadphaseProxy;
31 class btCollisionShape;
32 struct btCollisionShapeData;
33 #include "LinearMath/btMotionState.h"
34 #include "LinearMath/btAlignedAllocator.h"
35 #include "LinearMath/btAlignedObjectArray.h"
36
37 typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
38
39 #ifdef BT_USE_DOUBLE_PRECISION
40 #define btCollisionObjectData btCollisionObjectDoubleData
41 #define btCollisionObjectDataName "btCollisionObjectDoubleData"
42 #else
43 #define btCollisionObjectData btCollisionObjectFloatData
44 #define btCollisionObjectDataName "btCollisionObjectFloatData"
45 #endif
46
47
48 /// btCollisionObject can be used to manage collision detection objects.
49 /// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
50 /// They can be added to the btCollisionWorld.
ATTRIBUTE_ALIGNED16(class)51 ATTRIBUTE_ALIGNED16(class) btCollisionObject
52 {
53
54 protected:
55
56 btTransform m_worldTransform;
57
58 ///m_interpolationWorldTransform is used for CCD and interpolation
59 ///it can be either previous or future (predicted) transform
60 btTransform m_interpolationWorldTransform;
61 //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
62 //without destroying the continuous interpolated motion (which uses this interpolation velocities)
63 btVector3 m_interpolationLinearVelocity;
64 btVector3 m_interpolationAngularVelocity;
65
66 btVector3 m_anisotropicFriction;
67 int m_hasAnisotropicFriction;
68 btScalar m_contactProcessingThreshold;
69
70 btBroadphaseProxy* m_broadphaseHandle;
71 btCollisionShape* m_collisionShape;
72 ///m_extensionPointer is used by some internal low-level Bullet extensions.
73 void* m_extensionPointer;
74
75 ///m_rootCollisionShape is temporarily used to store the original collision shape
76 ///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
77 ///If it is NULL, the m_collisionShape is not temporarily replaced.
78 btCollisionShape* m_rootCollisionShape;
79
80 int m_collisionFlags;
81
82 int m_islandTag1;
83 int m_companionId;
84
85 int m_activationState1;
86 btScalar m_deactivationTime;
87
88 btScalar m_friction;
89 btScalar m_restitution;
90
91 ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
92 ///do not assign your own m_internalType unless you write a new dynamics object class.
93 int m_internalType;
94
95 ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
96 void* m_userObjectPointer;
97
98 ///time of impact calculation
99 btScalar m_hitFraction;
100
101 ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
102 btScalar m_ccdSweptSphereRadius;
103
104 /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
105 btScalar m_ccdMotionThreshold;
106
107 /// If some object should have elaborate collision filtering by sub-classes
108 int m_checkCollideWith;
109
110 virtual bool checkCollideWithOverride(btCollisionObject* /* co */)
111 {
112 return true;
113 }
114
115 public:
116
117 BT_DECLARE_ALIGNED_ALLOCATOR();
118
119 enum CollisionFlags
120 {
121 CF_STATIC_OBJECT= 1,
122 CF_KINEMATIC_OBJECT= 2,
123 CF_NO_CONTACT_RESPONSE = 4,
124 CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
125 CF_CHARACTER_OBJECT = 16,
126 CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing
127 CF_DISABLE_SPU_COLLISION_PROCESSING = 64//disable parallel/SPU processing
128 };
129
130 enum CollisionObjectTypes
131 {
132 CO_COLLISION_OBJECT =1,
133 CO_RIGID_BODY=2,
134 ///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
135 ///It is useful for collision sensors, explosion objects, character controller etc.
136 CO_GHOST_OBJECT=4,
137 CO_SOFT_BODY=8,
138 CO_HF_FLUID=16,
139 CO_USER_TYPE=32
140 };
141
142 SIMD_FORCE_INLINE bool mergesSimulationIslands() const
143 {
144 ///static objects, kinematic and object without contact response don't merge islands
145 return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0);
146 }
147
148 const btVector3& getAnisotropicFriction() const
149 {
150 return m_anisotropicFriction;
151 }
152 void setAnisotropicFriction(const btVector3& anisotropicFriction)
153 {
154 m_anisotropicFriction = anisotropicFriction;
155 m_hasAnisotropicFriction = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f);
156 }
157 bool hasAnisotropicFriction() const
158 {
159 return m_hasAnisotropicFriction!=0;
160 }
161
162 ///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.
163 ///Note that using contacts with positive distance can improve stability. It increases, however, the chance of colliding with degerate contacts, such as 'interior' triangle edges
164 void setContactProcessingThreshold( btScalar contactProcessingThreshold)
165 {
166 m_contactProcessingThreshold = contactProcessingThreshold;
167 }
168 btScalar getContactProcessingThreshold() const
169 {
170 return m_contactProcessingThreshold;
171 }
172
173 SIMD_FORCE_INLINE bool isStaticObject() const {
174 return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
175 }
176
177 SIMD_FORCE_INLINE bool isKinematicObject() const
178 {
179 return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0;
180 }
181
182 SIMD_FORCE_INLINE bool isStaticOrKinematicObject() const
183 {
184 return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ;
185 }
186
187 SIMD_FORCE_INLINE bool hasContactResponse() const {
188 return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0;
189 }
190
191
192 btCollisionObject();
193
194 virtual ~btCollisionObject();
195
196 virtual void setCollisionShape(btCollisionShape* collisionShape)
197 {
198 m_collisionShape = collisionShape;
199 m_rootCollisionShape = collisionShape;
200 }
201
202 SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const
203 {
204 return m_collisionShape;
205 }
206
207 SIMD_FORCE_INLINE btCollisionShape* getCollisionShape()
208 {
209 return m_collisionShape;
210 }
211
212 SIMD_FORCE_INLINE const btCollisionShape* getRootCollisionShape() const
213 {
214 return m_rootCollisionShape;
215 }
216
217 SIMD_FORCE_INLINE btCollisionShape* getRootCollisionShape()
218 {
219 return m_rootCollisionShape;
220 }
221
222 ///Avoid using this internal API call
223 ///internalSetTemporaryCollisionShape is used to temporary replace the actual collision shape by a child collision shape.
224 void internalSetTemporaryCollisionShape(btCollisionShape* collisionShape)
225 {
226 m_collisionShape = collisionShape;
227 }
228
229 ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
230 ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
231 void* internalGetExtensionPointer() const
232 {
233 return m_extensionPointer;
234 }
235 ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions
236 ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
237 void internalSetExtensionPointer(void* pointer)
238 {
239 m_extensionPointer = pointer;
240 }
241
242 SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;}
243
244 void setActivationState(int newState);
245
246 void setDeactivationTime(btScalar time)
247 {
248 m_deactivationTime = time;
249 }
250 btScalar getDeactivationTime() const
251 {
252 return m_deactivationTime;
253 }
254
255 void forceActivationState(int newState);
256
257 void activate(bool forceActivation = false);
258
259 SIMD_FORCE_INLINE bool isActive() const
260 {
261 return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
262 }
263
264 void setRestitution(btScalar rest)
265 {
266 m_restitution = rest;
267 }
268 btScalar getRestitution() const
269 {
270 return m_restitution;
271 }
272 void setFriction(btScalar frict)
273 {
274 m_friction = frict;
275 }
276 btScalar getFriction() const
277 {
278 return m_friction;
279 }
280
281 ///reserved for Bullet internal usage
282 int getInternalType() const
283 {
284 return m_internalType;
285 }
286
287 btTransform& getWorldTransform()
288 {
289 return m_worldTransform;
290 }
291
292 const btTransform& getWorldTransform() const
293 {
294 return m_worldTransform;
295 }
296
297 void setWorldTransform(const btTransform& worldTrans)
298 {
299 btAssert(!std::isnan(worldTrans.getOrigin().getX()));
300 btAssert(!std::isnan(worldTrans.getOrigin().getY()));
301 btAssert(!std::isnan(worldTrans.getOrigin().getZ()));
302 btAssert(!std::isinf(worldTrans.getOrigin().getX()));
303 btAssert(!std::isinf(worldTrans.getOrigin().getY()));
304 btAssert(!std::isinf(worldTrans.getOrigin().getZ()));
305 m_worldTransform = worldTrans;
306 }
307
308
309 SIMD_FORCE_INLINE btBroadphaseProxy* getBroadphaseHandle()
310 {
311 return m_broadphaseHandle;
312 }
313
314 SIMD_FORCE_INLINE const btBroadphaseProxy* getBroadphaseHandle() const
315 {
316 return m_broadphaseHandle;
317 }
318
319 void setBroadphaseHandle(btBroadphaseProxy* handle)
320 {
321 m_broadphaseHandle = handle;
322 }
323
324
325 const btTransform& getInterpolationWorldTransform() const
326 {
327 return m_interpolationWorldTransform;
328 }
329
330 btTransform& getInterpolationWorldTransform()
331 {
332 return m_interpolationWorldTransform;
333 }
334
335 void setInterpolationWorldTransform(const btTransform& trans)
336 {
337 m_interpolationWorldTransform = trans;
338 }
339
340 void setInterpolationLinearVelocity(const btVector3& linvel)
341 {
342 m_interpolationLinearVelocity = linvel;
343 }
344
345 void setInterpolationAngularVelocity(const btVector3& angvel)
346 {
347 m_interpolationAngularVelocity = angvel;
348 }
349
350 const btVector3& getInterpolationLinearVelocity() const
351 {
352 return m_interpolationLinearVelocity;
353 }
354
355 const btVector3& getInterpolationAngularVelocity() const
356 {
357 return m_interpolationAngularVelocity;
358 }
359
360 SIMD_FORCE_INLINE int getIslandTag() const
361 {
362 return m_islandTag1;
363 }
364
365 void setIslandTag(int tag)
366 {
367 m_islandTag1 = tag;
368 }
369
370 SIMD_FORCE_INLINE int getCompanionId() const
371 {
372 return m_companionId;
373 }
374
375 void setCompanionId(int id)
376 {
377 m_companionId = id;
378 }
379
380 SIMD_FORCE_INLINE btScalar getHitFraction() const
381 {
382 return m_hitFraction;
383 }
384
385 void setHitFraction(btScalar hitFraction)
386 {
387 m_hitFraction = hitFraction;
388 }
389
390
391 SIMD_FORCE_INLINE int getCollisionFlags() const
392 {
393 return m_collisionFlags;
394 }
395
396 void setCollisionFlags(int flags)
397 {
398 m_collisionFlags = flags;
399 }
400
401 ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
402 btScalar getCcdSweptSphereRadius() const
403 {
404 return m_ccdSweptSphereRadius;
405 }
406
407 ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
408 void setCcdSweptSphereRadius(btScalar radius)
409 {
410 m_ccdSweptSphereRadius = radius;
411 }
412
413 btScalar getCcdMotionThreshold() const
414 {
415 return m_ccdMotionThreshold;
416 }
417
418 btScalar getCcdSquareMotionThreshold() const
419 {
420 return m_ccdMotionThreshold*m_ccdMotionThreshold;
421 }
422
423
424
425 /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
426 void setCcdMotionThreshold(btScalar ccdMotionThreshold)
427 {
428 m_ccdMotionThreshold = ccdMotionThreshold;
429 }
430
431 ///users can point to their objects, userPointer is not used by Bullet
432 void* getUserPointer() const
433 {
434 return m_userObjectPointer;
435 }
436
437 ///users can point to their objects, userPointer is not used by Bullet
438 void setUserPointer(void* userPointer)
439 {
440 m_userObjectPointer = userPointer;
441 }
442
443
444 inline bool checkCollideWith(btCollisionObject* co)
445 {
446 if (m_checkCollideWith)
447 return checkCollideWithOverride(co);
448
449 return true;
450 }
451
452 virtual int calculateSerializeBufferSize() const;
453
454 ///fills the dataBuffer and returns the struct name (and 0 on failure)
455 virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
456
457 virtual void serializeSingleObject(class btSerializer* serializer) const;
458
459 };
460
461 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
462 struct btCollisionObjectDoubleData
463 {
464 void *m_broadphaseHandle;
465 void *m_collisionShape;
466 btCollisionShapeData *m_rootCollisionShape;
467 char *m_name;
468
469 btTransformDoubleData m_worldTransform;
470 btTransformDoubleData m_interpolationWorldTransform;
471 btVector3DoubleData m_interpolationLinearVelocity;
472 btVector3DoubleData m_interpolationAngularVelocity;
473 btVector3DoubleData m_anisotropicFriction;
474 double m_contactProcessingThreshold;
475 double m_deactivationTime;
476 double m_friction;
477 double m_restitution;
478 double m_hitFraction;
479 double m_ccdSweptSphereRadius;
480 double m_ccdMotionThreshold;
481
482 int m_hasAnisotropicFriction;
483 int m_collisionFlags;
484 int m_islandTag1;
485 int m_companionId;
486 int m_activationState1;
487 int m_internalType;
488 int m_checkCollideWith;
489
490 char m_padding[4];
491 };
492
493 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
494 struct btCollisionObjectFloatData
495 {
496 void *m_broadphaseHandle;
497 void *m_collisionShape;
498 btCollisionShapeData *m_rootCollisionShape;
499 char *m_name;
500
501 btTransformFloatData m_worldTransform;
502 btTransformFloatData m_interpolationWorldTransform;
503 btVector3FloatData m_interpolationLinearVelocity;
504 btVector3FloatData m_interpolationAngularVelocity;
505 btVector3FloatData m_anisotropicFriction;
506 float m_contactProcessingThreshold;
507 float m_deactivationTime;
508 float m_friction;
509 float m_restitution;
510 float m_hitFraction;
511 float m_ccdSweptSphereRadius;
512 float m_ccdMotionThreshold;
513
514 int m_hasAnisotropicFriction;
515 int m_collisionFlags;
516 int m_islandTag1;
517 int m_companionId;
518 int m_activationState1;
519 int m_internalType;
520 int m_checkCollideWith;
521 };
522
523
524
calculateSerializeBufferSize()525 SIMD_FORCE_INLINE int btCollisionObject::calculateSerializeBufferSize() const
526 {
527 return sizeof(btCollisionObjectData);
528 }
529
530
531
532 #endif //BT_COLLISION_OBJECT_H
533