From 3ca6d7385e7bd85683a622dbf0ed9bb10c084565 Mon Sep 17 00:00:00 2001 From: ejcoumans Date: Wed, 27 Jun 2007 03:19:34 +0000 Subject: [PATCH] basic support for height fields. They are producing temporary triangles, similar to the plane shape. --- .../btHeightfieldTerrainShape.cpp | 271 ++++++++++++++++-- .../btHeightfieldTerrainShape.h | 23 +- 2 files changed, 262 insertions(+), 32 deletions(-) diff --git a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp index c1de8e67f..de3f304b3 100644 --- a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp +++ b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp @@ -18,9 +18,65 @@ subject to the following restrictions: #include "LinearMath/btTransformUtil.h" -btHeightfieldTerrainShape::btHeightfieldTerrainShape() -:m_localScaling(btScalar(0.),btScalar(0.),btScalar(0.)) +btHeightfieldTerrainShape::btHeightfieldTerrainShape(int width,int length,unsigned char* heightfieldData,btScalar maxHeight,int upAxis) +:m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)), +m_width(width), +m_length(length), +m_heightfieldData(heightfieldData), +m_maxHeight(maxHeight), +m_upAxis(upAxis) { + + + btScalar quantizationMargin = 1.f; + + //enlarge the AABB to avoid division by zero when initializing the quantization values + btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin); + + btVector3 halfExtents(0,0,0); + + switch (m_upAxis) + { + case 0: + { + halfExtents.setValue( + m_maxHeight, + m_width, + m_length); + break; + } + case 1: + { + halfExtents.setValue( + m_width, + m_maxHeight, + m_length); + break; + }; + case 2: + { + halfExtents.setValue( + m_width, + m_length, + m_maxHeight + ); + break; + } + default: + { + //need to get valid m_upAxis + btAssert(0); + } + } + + halfExtents*= btScalar(0.5); + + m_localAabbMin = -halfExtents - clampValue; + m_localAabbMax = halfExtents + clampValue; + btVector3 aabbSize = m_localAabbMax - m_localAabbMin; + + m_quantization = btVector3(btScalar(65535.0),btScalar(65535.0),btScalar(65535.0)) / aabbSize; + } @@ -30,51 +86,206 @@ btHeightfieldTerrainShape::~btHeightfieldTerrainShape() -void btHeightfieldTerrainShape::getAabb(const btTransform& ,btVector3& aabbMin,btVector3& aabbMax) const +void btHeightfieldTerrainShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const { - aabbMin.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); - aabbMax.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); +/* + aabbMin.setValue(-1e30f,-1e30f,-1e30f); + aabbMax.setValue(1e30f,1e30f,1e30f); +*/ + + btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5); + + btMatrix3x3 abs_b = t.getBasis().absolute(); + btPoint3 center = t.getOrigin(); + btVector3 extent = btVector3(abs_b[0].dot(halfExtents), + abs_b[1].dot(halfExtents), + abs_b[2].dot(halfExtents)); + extent += btVector3(getMargin(),getMargin(),getMargin()); + + aabbMin = center - extent; + aabbMax = center + extent; + + } +void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const +{ + + btAssert(x>=0); + btAssert(y>=0); + btAssert(xprocessTriangle(triangle,0,0); + int startX=0; + int endX=m_width-1; + int startJ=0; + int endJ=m_length-1; - triangle[0] = projectedCenter - tangentDir0*radius - tangentDir1*radius; - triangle[1] = projectedCenter - tangentDir0*radius + tangentDir1*radius; - triangle[2] = projectedCenter + tangentDir0*radius + tangentDir1*radius; + switch (m_upAxis) + { + case 0: + { + quantizedAabbMin[1]+=m_width/2-1; + quantizedAabbMax[1]+=m_width/2+1; + quantizedAabbMin[2]+=m_length/2-1; + quantizedAabbMax[2]+=m_length/2+1; - callback->processTriangle(triangle,0,1); -*/ + if (quantizedAabbMin[1]>startX) + startX = quantizedAabbMin[1]; + if (quantizedAabbMax[1]startJ) + startJ = quantizedAabbMin[2]; + if (quantizedAabbMax[2]startX) + startX = quantizedAabbMin[0]; + if (quantizedAabbMax[0]startJ) + startJ = quantizedAabbMin[2]; + if (quantizedAabbMax[2]startX) + startX = quantizedAabbMin[0]; + if (quantizedAabbMax[0]startJ) + startJ = quantizedAabbMin[1]; + if (quantizedAabbMax[1]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); + } + } + + } diff --git a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h index dc45bbb5f..31bb7121d 100644 --- a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h +++ b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h @@ -25,12 +25,31 @@ protected: btVector3 m_localAabbMin; btVector3 m_localAabbMax; - //todo: terrain data + ///terrain data + int m_width; + int m_length; + btScalar m_maxHeight; + unsigned char* m_heightfieldData; + int m_upAxis; + + btVector3 m_quantization; btVector3 m_localScaling; + void quantizeWithClamp(short* out, const btVector3& point) const; + void getVertex(int x,int y,btVector3& vertex) const; + + inline bool testQuantizedAabbAgainstQuantizedAabb(short int* aabbMin1,short int* aabbMax1,const short int* aabbMin2,const short int* aabbMax2) const + { + bool overlap = true; + overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : 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(); + btHeightfieldTerrainShape(int width,int height,unsigned char* heightfieldData, btScalar maxHeight,int upAxis); virtual ~btHeightfieldTerrainShape();