Use btContinuousConvexCollision instead of btGjkConvexCast (has issues in btCollisionWorld::objectQuerySingle)

Fixes in btHeightfieldTerrainShape, thanks Jay Lee.
This commit is contained in:
ejcoumans
2007-12-11 00:38:13 +00:00
parent a45912e39c
commit c1c01ff1a0
3 changed files with 117 additions and 113 deletions

View File

@@ -412,8 +412,8 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
btConvexShape* convexShape = (btConvexShape*) collisionShape; btConvexShape* convexShape = (btConvexShape*) collisionShape;
btVoronoiSimplexSolver simplexSolver; btVoronoiSimplexSolver simplexSolver;
btGjkConvexCast convexCaster(castShape,convexShape,&simplexSolver); btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
if (convexCaster.calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult)) if (convexCaster.calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
{ {
//add hit //add hit

View File

@@ -18,9 +18,11 @@ subject to the following restrictions:
#include "LinearMath/btTransformUtil.h" #include "LinearMath/btTransformUtil.h"
btHeightfieldTerrainShape::btHeightfieldTerrainShape(int width,int length,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges) btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
:m_width(width), : m_heightStickWidth(heightStickWidth),
m_length(length), m_heightStickLength(heightStickLength),
m_width((btScalar)heightStickWidth-1),
m_length((btScalar)heightStickLength-1),
m_maxHeight(maxHeight), m_maxHeight(maxHeight),
m_heightfieldDataUnknown(heightfieldData), m_heightfieldDataUnknown(heightfieldData),
m_useFloatData(useFloatData), m_useFloatData(useFloatData),
@@ -44,7 +46,7 @@ m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
{ {
halfExtents.setValue( halfExtents.setValue(
btScalar(m_maxHeight), btScalar(m_maxHeight),
btScalar(m_width), btScalar(m_width), //?? don't know if this should change
btScalar(m_length)); btScalar(m_length));
break; break;
} }
@@ -114,11 +116,11 @@ btScalar btHeightfieldTerrainShape::getHeightFieldValue(int x,int y) const
btScalar val = 0.f; btScalar val = 0.f;
if (m_useFloatData) if (m_useFloatData)
{ {
val = m_heightfieldDataFloat[(y*m_width)+x]; val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
} else } else
{ {
//assume unsigned short int //assume unsigned short int
unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_width)+x]; unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
val = heightFieldValue* (m_maxHeight/btScalar(65535)); val = heightFieldValue* (m_maxHeight/btScalar(65535));
} }
return val; return val;
@@ -133,8 +135,8 @@ void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
btAssert(x>=0); btAssert(x>=0);
btAssert(y>=0); btAssert(y>=0);
btAssert(x<m_width); btAssert(x<m_heightStickWidth);
btAssert(y<m_length); btAssert(y<m_heightStickLength);
btScalar height = getHeightFieldValue(x,y); btScalar height = getHeightFieldValue(x,y);
@@ -218,18 +220,18 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
int startX=0; int startX=0;
int endX=m_width-1; int endX=m_heightStickWidth-1;
int startJ=0; int startJ=0;
int endJ=m_length-1; int endJ=m_heightStickLength-1;
switch (m_upAxis) switch (m_upAxis)
{ {
case 0: case 0:
{ {
quantizedAabbMin[1]+=m_width/2-1; quantizedAabbMin[1]+=m_heightStickWidth/2-1;
quantizedAabbMax[1]+=m_width/2+1; quantizedAabbMax[1]+=m_heightStickWidth/2+1;
quantizedAabbMin[2]+=m_length/2-1; quantizedAabbMin[2]+=m_heightStickLength/2-1;
quantizedAabbMax[2]+=m_length/2+1; quantizedAabbMax[2]+=m_heightStickLength/2+1;
if (quantizedAabbMin[1]>startX) if (quantizedAabbMin[1]>startX)
startX = quantizedAabbMin[1]; startX = quantizedAabbMin[1];
@@ -243,10 +245,10 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
} }
case 1: case 1:
{ {
quantizedAabbMin[0]+=m_width/2-1; quantizedAabbMin[0]+=m_heightStickWidth/2-1;
quantizedAabbMax[0]+=m_width/2+1; quantizedAabbMax[0]+=m_heightStickWidth/2+1;
quantizedAabbMin[2]+=m_length/2-1; quantizedAabbMin[2]+=m_heightStickLength/2-1;
quantizedAabbMax[2]+=m_length/2+1; quantizedAabbMax[2]+=m_heightStickLength/2+1;
if (quantizedAabbMin[0]>startX) if (quantizedAabbMin[0]>startX)
startX = quantizedAabbMin[0]; startX = quantizedAabbMin[0];
@@ -260,10 +262,10 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
}; };
case 2: case 2:
{ {
quantizedAabbMin[0]+=m_width/2-1; quantizedAabbMin[0]+=m_heightStickWidth/2-1;
quantizedAabbMax[0]+=m_width/2+1; quantizedAabbMax[0]+=m_heightStickWidth/2+1;
quantizedAabbMin[1]+=m_length/2-1; quantizedAabbMin[1]+=m_heightStickLength/2-1;
quantizedAabbMax[1]+=m_length/2+1; quantizedAabbMax[1]+=m_heightStickLength/2+1;
if (quantizedAabbMin[0]>startX) if (quantizedAabbMin[0]>startX)
startX = quantizedAabbMin[0]; startX = quantizedAabbMin[0];
@@ -290,7 +292,7 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
for(int x=startX; x<endX; x++) for(int x=startX; x<endX; x++)
{ {
btVector3 vertices[3]; btVector3 vertices[3];
if (m_flipQuadEdges || (m_useDiamondSubdivision && ((j+x) & 1))) if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j+x) & 1)))
{ {
//first triangle //first triangle
getVertex(x,j,vertices[0]); getVertex(x,j,vertices[0]);

View File

@@ -1,88 +1,90 @@
/* /*
Bullet Continuous Collision Detection and Physics Library Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty. 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. 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, Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely, including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions: 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. 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.
*/ */
#ifndef HEIGHTFIELD_TERRAIN_SHAPE_H #ifndef HEIGHTFIELD_TERRAIN_SHAPE_H
#define HEIGHTFIELD_TERRAIN_SHAPE_H #define HEIGHTFIELD_TERRAIN_SHAPE_H
#include "btConcaveShape.h" #include "btConcaveShape.h"
///btHeightfieldTerrainShape simulates a 2D heightfield terrain ///btHeightfieldTerrainShape simulates a 2D heightfield terrain
class btHeightfieldTerrainShape : public btConcaveShape class btHeightfieldTerrainShape : public btConcaveShape
{ {
protected: protected:
btVector3 m_localAabbMin; btVector3 m_localAabbMin;
btVector3 m_localAabbMax; btVector3 m_localAabbMax;
///terrain data ///terrain data
int m_width; int m_heightStickWidth;
int m_length; int m_heightStickLength;
btScalar m_maxHeight; btScalar m_maxHeight;
union btScalar m_width;
{ btScalar m_length;
unsigned char* m_heightfieldDataUnsignedChar; union
btScalar* m_heightfieldDataFloat; {
void* m_heightfieldDataUnknown; unsigned char* m_heightfieldDataUnsignedChar;
}; btScalar* m_heightfieldDataFloat;
void* m_heightfieldDataUnknown;
bool m_useFloatData; };
bool m_flipQuadEdges;
bool m_useDiamondSubdivision; bool m_useFloatData;
bool m_flipQuadEdges;
int m_upAxis; bool m_useDiamondSubdivision;
btVector3 m_localScaling; int m_upAxis;
virtual btScalar getHeightFieldValue(int x,int y) const; btVector3 m_localScaling;
void quantizeWithClamp(int* out, const btVector3& point) const;
void getVertex(int x,int y,btVector3& vertex) const; virtual btScalar getHeightFieldValue(int x,int y) const;
void quantizeWithClamp(int* out, const btVector3& point) const;
inline bool testQuantizedAabbAgainstQuantizedAabb(int* aabbMin1, int* aabbMax1,const int* aabbMin2,const int* aabbMax2) const void getVertex(int x,int y,btVector3& vertex) const;
{
bool overlap = true; inline bool testQuantizedAabbAgainstQuantizedAabb(int* aabbMin1, int* aabbMax1,const int* aabbMin2,const int* aabbMax2) const
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; {
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; bool overlap = true;
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
return overlap; overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
} overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
return overlap;
public: }
btHeightfieldTerrainShape(int width,int height,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
public:
virtual ~btHeightfieldTerrainShape(); btHeightfieldTerrainShape(int heightStickWidth,int heightStickHeight,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
virtual ~btHeightfieldTerrainShape();
void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}
virtual int getShapeType() const void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}
{
return TERRAIN_SHAPE_PROXYTYPE; virtual int getShapeType() const
} {
return TERRAIN_SHAPE_PROXYTYPE;
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; }
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
virtual void setLocalScaling(const btVector3& scaling); virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
virtual const btVector3& getLocalScaling() const; virtual void setLocalScaling(const btVector3& scaling);
//debugging virtual const btVector3& getLocalScaling() const;
virtual const char* getName()const {return "HEIGHTFIELD";}
//debugging
}; virtual const char* getName()const {return "HEIGHTFIELD";}
#endif //HEIGHTFIELD_TERRAIN_SHAPE_H };
#endif //HEIGHTFIELD_TERRAIN_SHAPE_H