BulletSim: Properly position mesh terrain on creation (fixes terrain not appearing to be working). Centralize terrain shape creation logic. Remove very chatty detail log messages.

connector_plugin
Robert Adams 2012-11-21 13:44:02 -08:00
parent a59368c4a1
commit 4a0de01704
2 changed files with 44 additions and 76 deletions

View File

@ -241,38 +241,20 @@ public sealed class BSTerrainManager
BSTerrainPhys terrainPhys;
if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
{
// If this is terrain we know about, it's easy to update
DetailLog("{0},UpdateTerrain:UpdateExisting,call,terrainBase={1}", BSScene.DetailLogZero, terrainRegionBase);
// There is already a terrain in this spot. Free the old and build the new.
DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords);
PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:UpdateExisting", delegate()
{
// Remove old terrain from the collection
m_terrains.Remove(terrainPhys.TerrainBase);
m_terrains.Remove(terrainRegionBase);
// Release any physical memory it may be using.
terrainPhys.Dispose();
BSTerrainPhys newTerrainPhys = null; ;
if (MegaRegionParentPhysicsScene == null)
{
// TODO: redo terrain implementation selection to be centralized (there is another
// use below) and to accept an asset specification (for a mesh).
switch ((int)PhysicsScene.Params.terrainImplementation)
{
case (int)BSTerrainPhys.TerrainImplementation.Heightmap:
newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id,
heightMap, minCoords, maxCoords);
break;
case (int)BSTerrainPhys.TerrainImplementation.Mesh:
newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id,
heightMap, minCoords, maxCoords);
break;
default:
PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. type={1}/{2}",
LogHeader, (int)PhysicsScene.Params.terrainImplementation, PhysicsScene.Params.terrainImplementation);
break;
}
BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
m_terrains.Add(terrainRegionBase, newTerrainPhys);
m_terrainModified = true;
@ -313,22 +295,7 @@ public sealed class BSTerrainManager
{
DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}",
BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y);
BSTerrainPhys newTerrainPhys = null;
switch ((int)PhysicsScene.Params.terrainImplementation)
{
case (int)BSTerrainPhys.TerrainImplementation.Heightmap:
newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id,
heightMap, minCoords, maxCoords);
break;
case (int)BSTerrainPhys.TerrainImplementation.Mesh:
newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id,
heightMap, minCoords, maxCoords);
break;
default:
PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. type={1}/{2}",
LogHeader, (int)PhysicsScene.Params.terrainImplementation, PhysicsScene.Params.terrainImplementation);
break;
}
BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
m_terrains.Add(terrainRegionBase, newTerrainPhys);
m_terrainModified = true;
@ -336,6 +303,35 @@ public sealed class BSTerrainManager
}
}
// TODO: redo terrain implementation selection to allow other base types than heightMap.
private BSTerrainPhys BuildPhysicalTerrain(Vector3 terrainRegionBase, uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords)
{
PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}",
LogHeader, PhysicsScene.RegionName, terrainRegionBase,
PhysicsScene.Params.terrainImplementation);
BSTerrainPhys newTerrainPhys = null;
switch ((int)PhysicsScene.Params.terrainImplementation)
{
case (int)BSTerrainPhys.TerrainImplementation.Heightmap:
newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id,
heightMap, minCoords, maxCoords);
break;
case (int)BSTerrainPhys.TerrainImplementation.Mesh:
newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id,
heightMap, minCoords, maxCoords);
break;
default:
PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}",
LogHeader,
(int)PhysicsScene.Params.terrainImplementation,
PhysicsScene.Params.terrainImplementation,
PhysicsScene.RegionName, terrainRegionBase);
break;
}
return newTerrainPhys;
}
// Given an X and Y, find the height of the terrain.
// Since we could be handling multiple terrains for a mega-region,
// the base of the region is calcuated assuming all regions are

View File

@ -76,7 +76,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys
m_sizeX = (int)(maxCoords.X - minCoords.X);
m_sizeY = (int)(maxCoords.Y - minCoords.Y);
if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY,
if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap,
m_sizeX, m_sizeY,
(float)m_sizeX, (float)m_sizeY,
Vector3.Zero, 1.0f,
out indicesCount, out indices, out verticesCount, out vertices))
@ -87,8 +88,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys
// Something is very messed up and a crash is in our future.
return;
}
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterConvertHeightmapToMesh,ver={1},ind={2}",
ID, verticesCount, indicesCount);
m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
indicesCount, indices, verticesCount, vertices),
@ -101,18 +100,11 @@ public sealed class BSTerrainMesh : BSTerrainPhys
// Something is very messed up and a crash is in our future.
return;
}
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateShape,shape={1}", ID, m_terrainShape);
// The terrain object initial position is at the center of the object
Vector3 centerPos;
centerPos.X = minCoords.X + (m_sizeX / 2f);
centerPos.Y = minCoords.Y + (m_sizeY / 2f);
centerPos.Z = minCoords.Z + ((maxCoords.Z - minCoords.Z) / 2f);
Vector3 pos = regionBase;
Quaternion rot = Quaternion.Identity;
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,creatingBody,centerPos={1},rot={2}", ID, centerPos, rot);
m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2(
m_terrainShape.ptr, ID, centerPos, rot));
m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot));
if (m_terrainBody.ptr == IntPtr.Zero)
{
// DISASTER!!
@ -120,7 +112,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys
// Something is very messed up and a crash is in our future.
return;
}
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateBody,body={1}", ID, m_terrainBody);
// Set current terrain attributes
BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction);
@ -194,7 +185,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
int[] indices = new int[0];
float[] vertices = new float[0];
// Simple mesh creation which assumes magnification == 1, sizeX == extentX and sizeY == extentY.
// Simple mesh creation which assumes magnification == 1.
// TODO: do a more general solution that scales, adds new vertices and smoothes the result.
try
@ -205,10 +196,10 @@ public sealed class BSTerrainMesh : BSTerrainPhys
int totalIndices = sizeX * sizeY * 6;
indices = new int[totalIndices];
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2}",
BSScene.DetailLogZero, totalVertices, totalIndices);
float magX = (float)sizeX / extentX;
float magY = (float)sizeY / extentY;
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}",
BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY);
// Note that sizeX+1 vertices are created since there is land between this and the next region.
for (int yy = 0; yy <= sizeY; yy++)
{
@ -222,15 +213,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys
vertices[verticesCount + 0] = (float)xx * magX + extentBase.X;
vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y;
vertices[verticesCount + 2] = height + extentBase.Z;
if (physicsScene.PhysicsLogging.Enabled && verticesCount < 900) // DEBUG DEBUG DEBUG
{
Vector3 genVertex = new Vector3(
vertices[verticesCount + 0],
vertices[verticesCount + 1],
vertices[verticesCount + 2]);
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,ii={1},vertex={2}",
BSScene.DetailLogZero, verticesCount/3, genVertex);
}
verticesCount += 3;
}
}
@ -250,16 +232,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys
indices[indicesCount + 3] = offset + 1;
indices[indicesCount + 4] = offset + sizeX + 2;
indices[indicesCount + 5] = offset + sizeX + 1;
if (indicesCount < (300 * 6)) // DEBUG DEBUG DEBUG
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,i0={1},i1={2},i2={3},i3={4},i4={5},i5={6}", // DEEBUG DEBUG DEBUG
BSScene.DetailLogZero,
indices[indicesCount + 0],
indices[indicesCount + 1],
indices[indicesCount + 2],
indices[indicesCount + 3],
indices[indicesCount + 4],
indices[indicesCount + 5]
);
indicesCount += 6;
}
}
@ -269,8 +241,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys
}
catch (Exception e)
{
physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. Base={1}, e={2}",
LogHeader, extentBase, e);
physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}",
LogHeader, physicsScene.RegionName, extentBase, e);
}
indicesCountO = indicesCount;