122 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			122 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | /*
 | ||
|  | Bullet Continuous Collision Detection and Physics Library | ||
|  | Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 | ||
|  | 
 | ||
|  | This software is provided 'as-is', without any express or implied warranty. | ||
|  | In no event will the authors be held liable for any damages arising from the use of this software. | ||
|  | Permission is granted to anyone to use this software for any purpose,  | ||
|  | including commercial applications, and to alter it and redistribute it freely,  | ||
|  | subject to the following restrictions: | ||
|  | 
 | ||
|  | 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. | ||
|  | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | ||
|  | 3. This notice may not be removed or altered from any source distribution. | ||
|  | */ | ||
|  | #include "BulletCollision/CollisionShapes/btCollisionShape.h"
 | ||
|  | #include "LinearMath/btSerializer.h"
 | ||
|  | 
 | ||
|  | /*
 | ||
|  |   Make sure this dummy function never changes so that it | ||
|  |   can be used by probes that are checking whether the | ||
|  |   library is actually installed. | ||
|  | */ | ||
|  | extern "C"  | ||
|  | { | ||
|  | void btBulletCollisionProbe (); | ||
|  | 
 | ||
|  | void btBulletCollisionProbe () {} | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | void	btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) const | ||
|  | { | ||
|  | 	btTransform tr; | ||
|  | 	tr.setIdentity(); | ||
|  | 	btVector3 aabbMin,aabbMax; | ||
|  | 
 | ||
|  | 	getAabb(tr,aabbMin,aabbMax); | ||
|  | 
 | ||
|  | 	radius = (aabbMax-aabbMin).length()*btScalar(0.5); | ||
|  | 	center = (aabbMin+aabbMax)*btScalar(0.5); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | btScalar	btCollisionShape::getContactBreakingThreshold(btScalar defaultContactThreshold) const | ||
|  | { | ||
|  | 	return getAngularMotionDisc() * defaultContactThreshold; | ||
|  | } | ||
|  | 
 | ||
|  | btScalar	btCollisionShape::getAngularMotionDisc() const | ||
|  | { | ||
|  | 	///@todo cache this value, to improve performance
 | ||
|  | 	btVector3	center; | ||
|  | 	btScalar disc; | ||
|  | 	getBoundingSphere(center,disc); | ||
|  | 	disc += (center).length(); | ||
|  | 	return disc; | ||
|  | } | ||
|  | 
 | ||
|  | void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const | ||
|  | { | ||
|  | 	//start with static aabb
 | ||
|  | 	getAabb(curTrans,temporalAabbMin,temporalAabbMax); | ||
|  | 
 | ||
|  | 	btScalar temporalAabbMaxx = temporalAabbMax.getX(); | ||
|  | 	btScalar temporalAabbMaxy = temporalAabbMax.getY(); | ||
|  | 	btScalar temporalAabbMaxz = temporalAabbMax.getZ(); | ||
|  | 	btScalar temporalAabbMinx = temporalAabbMin.getX(); | ||
|  | 	btScalar temporalAabbMiny = temporalAabbMin.getY(); | ||
|  | 	btScalar temporalAabbMinz = temporalAabbMin.getZ(); | ||
|  | 
 | ||
|  | 	// add linear motion
 | ||
|  | 	btVector3 linMotion = linvel*timeStep; | ||
|  | 	///@todo: simd would have a vector max/min operation, instead of per-element access
 | ||
|  | 	if (linMotion.x() > btScalar(0.)) | ||
|  | 		temporalAabbMaxx += linMotion.x();  | ||
|  | 	else | ||
|  | 		temporalAabbMinx += linMotion.x(); | ||
|  | 	if (linMotion.y() > btScalar(0.)) | ||
|  | 		temporalAabbMaxy += linMotion.y();  | ||
|  | 	else | ||
|  | 		temporalAabbMiny += linMotion.y(); | ||
|  | 	if (linMotion.z() > btScalar(0.)) | ||
|  | 		temporalAabbMaxz += linMotion.z();  | ||
|  | 	else | ||
|  | 		temporalAabbMinz += linMotion.z(); | ||
|  | 
 | ||
|  | 	//add conservative angular motion
 | ||
|  | 	btScalar angularMotion = angvel.length() * getAngularMotionDisc() * timeStep; | ||
|  | 	btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion); | ||
|  | 	temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz); | ||
|  | 	temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz); | ||
|  | 
 | ||
|  | 	temporalAabbMin -= angularMotion3d; | ||
|  | 	temporalAabbMax += angularMotion3d; | ||
|  | } | ||
|  | 
 | ||
|  | ///fills the dataBuffer and returns the struct name (and 0 on failure)
 | ||
|  | const char*	btCollisionShape::serialize(void* dataBuffer, btSerializer* serializer) const | ||
|  | { | ||
|  | 	btCollisionShapeData* shapeData = (btCollisionShapeData*) dataBuffer; | ||
|  | 	char* name = (char*) serializer->findNameForPointer(this); | ||
|  | 	shapeData->m_name = (char*)serializer->getUniquePointer(name); | ||
|  | 	if (shapeData->m_name) | ||
|  | 	{ | ||
|  | 		serializer->serializeName(name); | ||
|  | 	} | ||
|  | 	shapeData->m_shapeType = m_shapeType; | ||
|  | 
 | ||
|  | 	// Fill padding with zeros to appease msan.
 | ||
|  | 	memset(shapeData->m_padding, 0, sizeof(shapeData->m_padding)); | ||
|  | 
 | ||
|  | 	return "btCollisionShapeData"; | ||
|  | } | ||
|  | 
 | ||
|  | void	btCollisionShape::serializeSingleShape(btSerializer* serializer) const | ||
|  | { | ||
|  | 	int len = calculateSerializeBufferSize(); | ||
|  | 	btChunk* chunk = serializer->allocate(len,1); | ||
|  | 	const char* structType = serialize(chunk->m_oldPtr, serializer); | ||
|  | 	serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,(void*)this); | ||
|  | } |