Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp')
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp298
1 files changed, 271 insertions, 27 deletions
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
index 5a359c0cff1..94be43c88e2 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
@@ -18,9 +18,66 @@ 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,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
+:m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
+m_width(width),
+m_length(length),
+m_heightfieldDataUnknown(heightfieldData),
+m_maxHeight(maxHeight),
+m_upAxis(upAxis),
+m_useFloatData(useFloatData),
+m_flipQuadEdges(flipQuadEdges),
+m_useDiamondSubdivision(false)
{
+
+
+ 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;
+
}
@@ -30,51 +87,238 @@ 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(-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;
+
+
+}
+
+btScalar btHeightfieldTerrainShape::getHeightFieldValue(int x,int y) const
{
- aabbMin.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
- aabbMax.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+ btScalar val = 0.f;
+ if (m_useFloatData)
+ {
+ val = m_heightfieldDataFloat[(y*m_width)+x];
+ } else
+ {
+ //assume unsigned short int
+ unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_width)+x];
+ val = heightFieldValue* (m_maxHeight/btScalar(65535));
+ }
+ return val;
}
+
+void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
+{
+
+ btAssert(x>=0);
+ btAssert(y>=0);
+ btAssert(x<m_width);
+ btAssert(y<m_length);
+
+
+ btScalar height = getHeightFieldValue(x,y);
+
+ switch (m_upAxis)
+ {
+ case 0:
+ {
+ vertex.setValue(
+ height,
+ (-m_width/2 ) + x,
+ (-m_length/2 ) + y
+ );
+ break;
+ }
+ case 1:
+ {
+ vertex.setValue(
+ (-m_width/2 ) + x,
+ height,
+ (-m_length/2 ) + y
+ );
+ break;
+ };
+ case 2:
+ {
+ vertex.setValue(
+ (-m_width/2 ) + x,
+ (-m_length/2 ) + y,
+ height
+ );
+ break;
+ }
+ default:
+ {
+ //need to get valid m_upAxis
+ btAssert(0);
+ }
+ }
+
+ vertex*=m_localScaling;
+
+}
+
+
+void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point) const
+{
+
+
+ btVector3 clampedPoint(point);
+ clampedPoint.setMax(m_localAabbMin);
+ clampedPoint.setMin(m_localAabbMax);
+
+ btVector3 v = (clampedPoint );// * m_quantization;
+
+ out[0] = (int)(v.getX());
+ out[1] = (int)(v.getY());
+ out[2] = (int)(v.getZ());
+ //correct for
+
+}
+
+
void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
(void)callback;
(void)aabbMax;
(void)aabbMin;
- /*
- btVector3 halfExtents = (aabbMax - aabbMin) * btScalar(0.5);
- btVector3 center = (aabbMax + aabbMin) * btScalar(0.5);
+ //quantize the aabbMin and aabbMax, and adjust the start/end ranges
+
+ int quantizedAabbMin[3];
+ int quantizedAabbMax[3];
+
+ 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]);
+
+ quantizeWithClamp(quantizedAabbMin, localAabbMin);
+ quantizeWithClamp(quantizedAabbMax, localAabbMax);
+
- //TODO
- //this is where the triangles are generated, given AABB and plane equation (normal/constant)
- btVector3 tangentDir0,tangentDir1;
+ int startX=0;
+ int endX=m_width-1;
+ int startJ=0;
+ int endJ=m_length-1;
- //tangentDir0/tangentDir1 can be precalculated
- btPlaneSpace1(m_planeNormal,tangentDir0,tangentDir1);
+ 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;
- btVector3 supVertex0,supVertex1;
+ 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:
+ {
+ quantizedAabbMin[0]+=m_width/2-1;
+ quantizedAabbMax[0]+=m_width/2+1;
+ quantizedAabbMin[2]+=m_length/2-1;
+ quantizedAabbMax[2]+=m_length/2+1;
- btVector3 projectedCenter = center - (m_planeNormal.dot(center) - m_planeConstant)*m_planeNormal;
-
- btVector3 triangle[3];
- btScalar radius = halfExtents.length();
- triangle[0] = projectedCenter + tangentDir0*radius + tangentDir1*radius;
- triangle[1] = projectedCenter + tangentDir0*radius - tangentDir1*radius;
- triangle[2] = projectedCenter - tangentDir0*radius - tangentDir1*radius;
+ 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:
+ {
+ quantizedAabbMin[0]+=m_width/2-1;
+ quantizedAabbMax[0]+=m_width/2+1;
+ quantizedAabbMin[1]+=m_length/2-1;
+ quantizedAabbMax[1]+=m_length/2+1;
- callback->processTriangle(triangle,0,0);
+ 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);
+ }
+ }
- triangle[0] = projectedCenter - tangentDir0*radius - tangentDir1*radius;
- triangle[1] = projectedCenter - tangentDir0*radius + tangentDir1*radius;
- triangle[2] = projectedCenter + tangentDir0*radius + tangentDir1*radius;
+
+
- callback->processTriangle(triangle,0,1);
-*/
+ for(int j=startJ; j<endJ; j++)
+ {
+ for(int x=startX; x<endX; x++)
+ {
+ btVector3 vertices[3];
+ if (m_flipQuadEdges || (m_useDiamondSubdivision && ((j+x) & 1)))
+ {
+ //first triangle
+ getVertex(x,j,vertices[0]);
+ getVertex(x+1,j,vertices[1]);
+ getVertex(x+1,j+1,vertices[2]);
+ callback->processTriangle(vertices,x,j);
+ //second triangle
+ getVertex(x,j,vertices[0]);
+ getVertex(x+1,j+1,vertices[1]);
+ getVertex(x,j+1,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);
+ }
+ }
+ }
+
+
}