Home | History | Annotate | Download | only in CollisionDispatch
      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.
     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 
    582 SIMD_FORCE_INLINE	int	btCollisionObject::calculateSerializeBufferSize() const
    583 {
    584 	return sizeof(btCollisionObjectData);
    585 }
    586 
    587 
    588 
    589 #endif //BT_COLLISION_OBJECT_H
    590