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