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