BulletSim: fix terrain mesh generation for problem with regions that have unequal edge heights. Thanks UBit.

integration
Robert Adams 2012-11-27 10:01:25 -08:00
parent 68fe7dff20
commit a5100cafee
1 changed files with 16 additions and 6 deletions

View File

@ -88,6 +88,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys
// Something is very messed up and a crash is in our future. // Something is very messed up and a crash is in our future.
return; return;
} }
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}",
ID, indicesCount, indices.Length, verticesCount, vertices.Length);
m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
indicesCount, indices, verticesCount, vertices), indicesCount, indices, verticesCount, vertices),
@ -122,10 +124,10 @@ public sealed class BSTerrainMesh : BSTerrainPhys
// Static objects are not very massive. // Static objects are not very massive.
BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero);
// Return the new terrain to the world of physical objects // Put the new terrain to the world of physical objects
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
// redo its bounding box now that it is in the world // Redo its bounding box now that it is in the world
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr);
BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr,
@ -188,6 +190,11 @@ public sealed class BSTerrainMesh : BSTerrainPhys
// Simple mesh creation which assumes magnification == 1. // Simple mesh creation which assumes magnification == 1.
// TODO: do a more general solution that scales, adds new vertices and smoothes the result. // TODO: do a more general solution that scales, adds new vertices and smoothes the result.
// Create an array of vertices that is sizeX+1 by sizeY+1 (note the loop
// from zero to <= sizeX). The triangle indices are then generated as two triangles
// per heightmap point. There are sizeX by sizeY of these squares. The extra row and
// column of vertices are used to complete the triangles of the last row and column
// of the heightmap.
try try
{ {
// One vertice per heightmap value plus the vertices off the top and bottom edge. // One vertice per heightmap value plus the vertices off the top and bottom edge.
@ -200,16 +207,18 @@ public sealed class BSTerrainMesh : BSTerrainPhys
float magY = (float)sizeY / extentY; float magY = (float)sizeY / extentY;
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}",
BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY);
float minHeight = float.MaxValue;
// Note that sizeX+1 vertices are created since there is land between this and the next region. // Note that sizeX+1 vertices are created since there is land between this and the next region.
for (int yy = 0; yy <= sizeY; yy++) for (int yy = 0; yy <= sizeY; yy++)
{ {
for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we go around sizeX + 1 times
{ {
int offset = yy * sizeX + xx; int offset = yy * sizeX + xx;
// Extend the height from the height from the last row or column // Extend the height with the height from the last row or column
if (yy == sizeY) offset -= sizeX; if (yy == sizeY) offset -= sizeX;
if (xx == sizeX) offset -= 1; if (xx == sizeX) offset -= 1;
float height = heightMap[offset]; float height = heightMap[offset];
minHeight = Math.Min(minHeight, height);
vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; vertices[verticesCount + 0] = (float)xx * magX + extentBase.X;
vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y;
vertices[verticesCount + 2] = height + extentBase.Z; vertices[verticesCount + 2] = height + extentBase.Z;
@ -222,7 +231,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
{ {
for (int xx = 0; xx < sizeX; xx++) for (int xx = 0; xx < sizeX; xx++)
{ {
int offset = yy * sizeX + xx; int offset = yy * (sizeX + 1) + xx;
// Each vertices is presumed to be the upper left corner of a box of two triangles // Each vertices is presumed to be the upper left corner of a box of two triangles
indices[indicesCount + 0] = offset; indices[indicesCount + 0] = offset;
indices[indicesCount + 1] = offset + 1; indices[indicesCount + 1] = offset + 1;
@ -233,6 +242,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
indicesCount += 6; indicesCount += 6;
} }
} }
ret = true; ret = true;
} }
catch (Exception e) catch (Exception e)