mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 15:44:36 +00:00
Merge pull request #1876 from GarageGames/BulletHolyTerrain
Fixes Bullet not supporting holes in terrain.
This commit is contained in:
commit
db7d044f32
1 changed files with 158 additions and 7 deletions
|
|
@ -28,6 +28,42 @@
|
||||||
#include "T3D/physics/bullet/bt.h"
|
#include "T3D/physics/bullet/bt.h"
|
||||||
#include "T3D/physics/bullet/btCasts.h"
|
#include "T3D/physics/bullet/btCasts.h"
|
||||||
|
|
||||||
|
class btHeightfieldTerrainShapeCustom : public btHeightfieldTerrainShape
|
||||||
|
{
|
||||||
|
bool* mHoles;
|
||||||
|
|
||||||
|
public:
|
||||||
|
btHeightfieldTerrainShapeCustom(const bool *holes,
|
||||||
|
int heightStickWidth,
|
||||||
|
int heightStickLength,
|
||||||
|
const void* heightfieldData,
|
||||||
|
btScalar heightScale,
|
||||||
|
btScalar minHeight,
|
||||||
|
btScalar maxHeight,
|
||||||
|
int upAxis,
|
||||||
|
PHY_ScalarType heightDataType,
|
||||||
|
bool flipQuadEdges) : btHeightfieldTerrainShape(heightStickWidth,
|
||||||
|
heightStickLength,
|
||||||
|
heightfieldData,
|
||||||
|
heightScale,
|
||||||
|
minHeight,
|
||||||
|
maxHeight,
|
||||||
|
upAxis,
|
||||||
|
heightDataType,
|
||||||
|
flipQuadEdges)
|
||||||
|
{
|
||||||
|
mHoles = new bool[heightStickWidth * heightStickLength];
|
||||||
|
dMemcpy(mHoles, holes, heightStickWidth * heightStickLength * sizeof(bool));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~btHeightfieldTerrainShapeCustom()
|
||||||
|
{
|
||||||
|
delete[] mHoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
BtCollision::BtCollision()
|
BtCollision::BtCollision()
|
||||||
: mCompound( NULL ),
|
: mCompound( NULL ),
|
||||||
|
|
@ -170,13 +206,15 @@ bool BtCollision::addHeightfield( const U16 *heights,
|
||||||
const F32 minHeight = 0;
|
const F32 minHeight = 0;
|
||||||
const F32 maxHeight = 65535 * heightScale;
|
const F32 maxHeight = 65535 * heightScale;
|
||||||
|
|
||||||
btHeightfieldTerrainShape *shape = new btHeightfieldTerrainShape( blockSize, blockSize,
|
btHeightfieldTerrainShapeCustom* shape = new btHeightfieldTerrainShapeCustom(holes,
|
||||||
(void*)heights,
|
blockSize, blockSize,
|
||||||
heightScale,
|
reinterpret_cast<const void*>(heights),
|
||||||
minHeight, maxHeight,
|
heightScale,
|
||||||
2, // Z up!
|
0, 0xFFFF * heightScale,
|
||||||
PHY_SHORT,
|
2, // Z up!
|
||||||
false );
|
PHY_SHORT,
|
||||||
|
false);
|
||||||
|
|
||||||
shape->setMargin( 0.01f );
|
shape->setMargin( 0.01f );
|
||||||
shape->setLocalScaling( btVector3( metersPerSample, metersPerSample, 1.0f ) );
|
shape->setLocalScaling( btVector3( metersPerSample, metersPerSample, 1.0f ) );
|
||||||
shape->setUseDiamondSubdivision( true );
|
shape->setUseDiamondSubdivision( true );
|
||||||
|
|
@ -203,3 +241,116 @@ bool BtCollision::addHeightfield( const U16 *heights,
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void btHeightfieldTerrainShapeCustom::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const
|
||||||
|
{
|
||||||
|
// scale down the input aabb's so they are in local (non-scaled) coordinates
|
||||||
|
btVector3 localAabbMin = aabbMin * btVector3(1.f / m_localScaling[0], 1.f / m_localScaling[1], 1.f / m_localScaling[2]);
|
||||||
|
btVector3 localAabbMax = aabbMax * btVector3(1.f / m_localScaling[0], 1.f / m_localScaling[1], 1.f / m_localScaling[2]);
|
||||||
|
|
||||||
|
// account for local origin
|
||||||
|
localAabbMin += m_localOrigin;
|
||||||
|
localAabbMax += m_localOrigin;
|
||||||
|
|
||||||
|
//quantize the aabbMin and aabbMax, and adjust the start/end ranges
|
||||||
|
int quantizedAabbMin[3];
|
||||||
|
int quantizedAabbMax[3];
|
||||||
|
quantizeWithClamp(quantizedAabbMin, localAabbMin, 0);
|
||||||
|
quantizeWithClamp(quantizedAabbMax, localAabbMax, 1);
|
||||||
|
|
||||||
|
// expand the min/max quantized values
|
||||||
|
// this is to catch the case where the input aabb falls between grid points!
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
quantizedAabbMin[i]--;
|
||||||
|
quantizedAabbMax[i]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int startX = 0;
|
||||||
|
int endX = m_heightStickWidth - 1;
|
||||||
|
int startJ = 0;
|
||||||
|
int endJ = m_heightStickLength - 1;
|
||||||
|
|
||||||
|
switch (m_upAxis)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
if (quantizedAabbMin[1] > startX)
|
||||||
|
startX = quantizedAabbMin[1];
|
||||||
|
if (quantizedAabbMax[1] < endX)
|
||||||
|
endX = quantizedAabbMax[1];
|
||||||
|
if (quantizedAabbMin[2] > startJ)
|
||||||
|
startJ = quantizedAabbMin[2];
|
||||||
|
if (quantizedAabbMax[2] < endJ)
|
||||||
|
endJ = quantizedAabbMax[2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
if (quantizedAabbMin[0] > startX)
|
||||||
|
startX = quantizedAabbMin[0];
|
||||||
|
if (quantizedAabbMax[0] < endX)
|
||||||
|
endX = quantizedAabbMax[0];
|
||||||
|
if (quantizedAabbMin[2] > startJ)
|
||||||
|
startJ = quantizedAabbMin[2];
|
||||||
|
if (quantizedAabbMax[2] < endJ)
|
||||||
|
endJ = quantizedAabbMax[2];
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
if (quantizedAabbMin[0] > startX)
|
||||||
|
startX = quantizedAabbMin[0];
|
||||||
|
if (quantizedAabbMax[0] < endX)
|
||||||
|
endX = quantizedAabbMax[0];
|
||||||
|
if (quantizedAabbMin[1] > startJ)
|
||||||
|
startJ = quantizedAabbMin[1];
|
||||||
|
if (quantizedAabbMax[1] < endJ)
|
||||||
|
endJ = quantizedAabbMax[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
//need to get valid m_upAxis
|
||||||
|
btAssert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = startJ; j < endJ; j++)
|
||||||
|
{
|
||||||
|
for (int x = startX; x < endX; x++)
|
||||||
|
{
|
||||||
|
U32 index = (m_heightStickLength - (m_heightStickLength - x - 1)) + (j * m_heightStickWidth);
|
||||||
|
|
||||||
|
if (mHoles && mHoles[getMax((S32)index - 1, 0)])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
btVector3 vertices[3];
|
||||||
|
if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j + x) & 1)) || (m_useZigzagSubdivision && !(j & 1)))
|
||||||
|
{
|
||||||
|
//first triangle
|
||||||
|
getVertex(x, j, vertices[0]);
|
||||||
|
getVertex(x, j + 1, vertices[1]);
|
||||||
|
getVertex(x + 1, j + 1, vertices[2]);
|
||||||
|
callback->processTriangle(vertices, x, j);
|
||||||
|
//second triangle
|
||||||
|
// getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman
|
||||||
|
getVertex(x + 1, j + 1, vertices[1]);
|
||||||
|
getVertex(x + 1, j, vertices[2]);
|
||||||
|
callback->processTriangle(vertices, x, j);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//first triangle
|
||||||
|
getVertex(x, j, vertices[0]);
|
||||||
|
getVertex(x, j + 1, vertices[1]);
|
||||||
|
getVertex(x + 1, j, vertices[2]);
|
||||||
|
callback->processTriangle(vertices, x, j);
|
||||||
|
//second triangle
|
||||||
|
getVertex(x + 1, j, vertices[0]);
|
||||||
|
//getVertex(x,j+1,vertices[1]);
|
||||||
|
getVertex(x + 1, j + 1, vertices[2]);
|
||||||
|
callback->processTriangle(vertices, x, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue