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