forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			283 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			283 lines
		
	
	
		
			7.4 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 "btCylinderShape.h"
 | ||
|  | 
 | ||
|  | btCylinderShape::btCylinderShape (const btVector3& halfExtents) | ||
|  | :btConvexInternalShape(), | ||
|  | m_upAxis(1) | ||
|  | { | ||
|  | 	btVector3 margin(getMargin(),getMargin(),getMargin()); | ||
|  | 	m_implicitShapeDimensions = (halfExtents * m_localScaling) - margin; | ||
|  | 
 | ||
|  | 	setSafeMargin(halfExtents); | ||
|  | 
 | ||
|  | 	m_shapeType = CYLINDER_SHAPE_PROXYTYPE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents) | ||
|  | :btCylinderShape(halfExtents) | ||
|  | { | ||
|  | 	m_upAxis = 0; | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents) | ||
|  | :btCylinderShape(halfExtents) | ||
|  | { | ||
|  | 	m_upAxis = 2; | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const | ||
|  | { | ||
|  | 	btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax); | ||
|  | } | ||
|  | 
 | ||
|  | void	btCylinderShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const | ||
|  | { | ||
|  | 
 | ||
|  | //Until Bullet 2.77 a box approximation was used, so uncomment this if you need backwards compatibility
 | ||
|  | //#define USE_BOX_INERTIA_APPROXIMATION 1
 | ||
|  | #ifndef USE_BOX_INERTIA_APPROXIMATION
 | ||
|  | 
 | ||
|  | 	/*
 | ||
|  | 	cylinder is defined as following: | ||
|  | 	* | ||
|  | 	* - principle axis aligned along y by default, radius in x, z-value not used | ||
|  | 	* - for btCylinderShapeX: principle axis aligned along x, radius in y direction, z-value not used | ||
|  | 	* - for btCylinderShapeZ: principle axis aligned along z, radius in x direction, y-value not used | ||
|  | 	* | ||
|  | 	*/ | ||
|  | 
 | ||
|  | 	btScalar radius2;	// square of cylinder radius
 | ||
|  | 	btScalar height2;	// square of cylinder height
 | ||
|  | 	btVector3 halfExtents = getHalfExtentsWithMargin();	// get cylinder dimension
 | ||
|  | 	btScalar div12 = mass / 12.f; | ||
|  | 	btScalar div4 = mass / 4.f; | ||
|  | 	btScalar div2 = mass / 2.f; | ||
|  | 	int idxRadius, idxHeight; | ||
|  | 
 | ||
|  | 	switch (m_upAxis)	// get indices of radius and height of cylinder
 | ||
|  | 	{ | ||
|  | 		case 0:		// cylinder is aligned along x
 | ||
|  | 			idxRadius = 1; | ||
|  | 			idxHeight = 0; | ||
|  | 			break; | ||
|  | 		case 2:		// cylinder is aligned along z
 | ||
|  | 			idxRadius = 0; | ||
|  | 			idxHeight = 2; | ||
|  | 			break; | ||
|  | 		default:	// cylinder is aligned along y
 | ||
|  | 			idxRadius = 0; | ||
|  | 			idxHeight = 1; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// calculate squares
 | ||
|  | 	radius2 = halfExtents[idxRadius] * halfExtents[idxRadius]; | ||
|  | 	height2 = btScalar(4.) * halfExtents[idxHeight] * halfExtents[idxHeight]; | ||
|  | 
 | ||
|  | 	// calculate tensor terms
 | ||
|  | 	btScalar t1 = div12 * height2 + div4 * radius2; | ||
|  | 	btScalar t2 = div2 * radius2; | ||
|  | 
 | ||
|  | 	switch (m_upAxis)	// set diagonal elements of inertia tensor
 | ||
|  | 	{ | ||
|  | 		case 0:		// cylinder is aligned along x
 | ||
|  | 			inertia.setValue(t2,t1,t1); | ||
|  | 			break; | ||
|  | 		case 2:		// cylinder is aligned along z
 | ||
|  | 			inertia.setValue(t1,t1,t2); | ||
|  | 			break; | ||
|  | 		default:	// cylinder is aligned along y
 | ||
|  | 			inertia.setValue(t1,t2,t1); | ||
|  | 	} | ||
|  | #else //USE_BOX_INERTIA_APPROXIMATION
 | ||
|  | 	//approximation of box shape
 | ||
|  | 	btVector3 halfExtents = getHalfExtentsWithMargin(); | ||
|  | 
 | ||
|  | 	btScalar lx=btScalar(2.)*(halfExtents.x()); | ||
|  | 	btScalar ly=btScalar(2.)*(halfExtents.y()); | ||
|  | 	btScalar lz=btScalar(2.)*(halfExtents.z()); | ||
|  | 
 | ||
|  | 	inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), | ||
|  | 					mass/(btScalar(12.0)) * (lx*lx + lz*lz), | ||
|  | 					mass/(btScalar(12.0)) * (lx*lx + ly*ly)); | ||
|  | #endif //USE_BOX_INERTIA_APPROXIMATION
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v)  | ||
|  | { | ||
|  | const int cylinderUpAxis = 0; | ||
|  | const int XX = 1; | ||
|  | const int YY = 0; | ||
|  | const int ZZ = 2; | ||
|  | 
 | ||
|  | 	//mapping depends on how cylinder local orientation is
 | ||
|  | 	// extents of the cylinder is: X,Y is for radius, and Z for height
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 	btScalar radius = halfExtents[XX]; | ||
|  | 	btScalar halfHeight = halfExtents[cylinderUpAxis]; | ||
|  | 
 | ||
|  | 
 | ||
|  |     btVector3 tmp; | ||
|  | 	btScalar d ; | ||
|  | 
 | ||
|  |     btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); | ||
|  |     if (s != btScalar(0.0)) | ||
|  | 	{ | ||
|  |         d = radius / s;   | ||
|  | 		tmp[XX] = v[XX] * d; | ||
|  | 		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; | ||
|  | 		tmp[ZZ] = v[ZZ] * d; | ||
|  | 		return tmp; | ||
|  | 	} | ||
|  |     else | ||
|  | 	{ | ||
|  | 	    tmp[XX] = radius; | ||
|  | 		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; | ||
|  | 		tmp[ZZ] = btScalar(0.0); | ||
|  | 		return tmp; | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | inline  btVector3 CylinderLocalSupportY(const btVector3& halfExtents,const btVector3& v)  | ||
|  | { | ||
|  | 
 | ||
|  | const int cylinderUpAxis = 1; | ||
|  | const int XX = 0; | ||
|  | const int YY = 1; | ||
|  | const int ZZ = 2; | ||
|  | 
 | ||
|  | 
 | ||
|  | 	btScalar radius = halfExtents[XX]; | ||
|  | 	btScalar halfHeight = halfExtents[cylinderUpAxis]; | ||
|  | 
 | ||
|  | 
 | ||
|  |     btVector3 tmp; | ||
|  | 	btScalar d ; | ||
|  | 
 | ||
|  |     btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); | ||
|  |     if (s != btScalar(0.0)) | ||
|  | 	{ | ||
|  |         d = radius / s;   | ||
|  | 		tmp[XX] = v[XX] * d; | ||
|  | 		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; | ||
|  | 		tmp[ZZ] = v[ZZ] * d; | ||
|  | 		return tmp; | ||
|  | 	} | ||
|  |     else | ||
|  | 	{ | ||
|  | 	    tmp[XX] = radius; | ||
|  | 		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; | ||
|  | 		tmp[ZZ] = btScalar(0.0); | ||
|  | 		return tmp; | ||
|  |     } | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents,const btVector3& v)  | ||
|  | { | ||
|  | const int cylinderUpAxis = 2; | ||
|  | const int XX = 0; | ||
|  | const int YY = 2; | ||
|  | const int ZZ = 1; | ||
|  | 
 | ||
|  | 	//mapping depends on how cylinder local orientation is
 | ||
|  | 	// extents of the cylinder is: X,Y is for radius, and Z for height
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 	btScalar radius = halfExtents[XX]; | ||
|  | 	btScalar halfHeight = halfExtents[cylinderUpAxis]; | ||
|  | 
 | ||
|  | 
 | ||
|  |     btVector3 tmp; | ||
|  | 	btScalar d ; | ||
|  | 
 | ||
|  |     btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); | ||
|  |     if (s != btScalar(0.0)) | ||
|  | 	{ | ||
|  |         d = radius / s;   | ||
|  | 		tmp[XX] = v[XX] * d; | ||
|  | 		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; | ||
|  | 		tmp[ZZ] = v[ZZ] * d; | ||
|  | 		return tmp; | ||
|  | 	} | ||
|  |     else | ||
|  | 	{ | ||
|  | 	    tmp[XX] = radius; | ||
|  | 		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; | ||
|  | 		tmp[ZZ] = btScalar(0.0); | ||
|  | 		return tmp; | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | btVector3	btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec)const | ||
|  | { | ||
|  | 	return CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vec); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | btVector3	btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec)const | ||
|  | { | ||
|  | 	return CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vec); | ||
|  | } | ||
|  | btVector3	btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const | ||
|  | { | ||
|  | 	return CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vec); | ||
|  | } | ||
|  | 
 | ||
|  | void	btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const | ||
|  | { | ||
|  | 	for (int i=0;i<numVectors;i++) | ||
|  | 	{ | ||
|  | 		supportVerticesOut[i] = CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vectors[i]); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void	btCylinderShapeZ::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const | ||
|  | { | ||
|  | 	for (int i=0;i<numVectors;i++) | ||
|  | 	{ | ||
|  | 		supportVerticesOut[i] = CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vectors[i]); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | void	btCylinderShapeX::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const | ||
|  | { | ||
|  | 	for (int i=0;i<numVectors;i++) | ||
|  | 	{ | ||
|  | 		supportVerticesOut[i] = CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vectors[i]); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | 
 |