BulletSim: add parameter for terrain collision margin.
Add locking around unlikely but possible race conditions on terrain list.connector_plugin^2
parent
4ae30873ad
commit
c3f30fef96
|
@ -93,7 +93,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
||||||
{
|
{
|
||||||
m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID,
|
m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID,
|
||||||
m_mapInfo.minCoords, m_mapInfo.maxCoords,
|
m_mapInfo.minCoords, m_mapInfo.maxCoords,
|
||||||
m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN);
|
m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin);
|
||||||
|
|
||||||
// Create the terrain shape from the mapInfo
|
// Create the terrain shape from the mapInfo
|
||||||
m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr),
|
m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr),
|
||||||
|
|
|
@ -80,8 +80,6 @@ public sealed class BSTerrainManager
|
||||||
// amount to make sure that a bounding box is built for the terrain.
|
// amount to make sure that a bounding box is built for the terrain.
|
||||||
public const float HEIGHT_EQUAL_FUDGE = 0.2f;
|
public const float HEIGHT_EQUAL_FUDGE = 0.2f;
|
||||||
|
|
||||||
public const float TERRAIN_COLLISION_MARGIN = 0.0f;
|
|
||||||
|
|
||||||
// Until the whole simulator is changed to pass us the region size, we rely on constants.
|
// Until the whole simulator is changed to pass us the region size, we rely on constants.
|
||||||
public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
|
public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
|
||||||
|
|
||||||
|
@ -129,7 +127,8 @@ public sealed class BSTerrainManager
|
||||||
{
|
{
|
||||||
// The ground plane is here to catch things that are trying to drop to negative infinity
|
// The ground plane is here to catch things that are trying to drop to negative infinity
|
||||||
BulletShape groundPlaneShape = new BulletShape(
|
BulletShape groundPlaneShape = new BulletShape(
|
||||||
BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN),
|
BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f,
|
||||||
|
PhysicsScene.Params.terrainCollisionMargin),
|
||||||
BSPhysicsShapeType.SHAPE_GROUNDPLANE);
|
BSPhysicsShapeType.SHAPE_GROUNDPLANE);
|
||||||
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
|
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
|
||||||
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
|
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
|
||||||
|
@ -165,17 +164,22 @@ public sealed class BSTerrainManager
|
||||||
// Release all the terrain we have allocated
|
// Release all the terrain we have allocated
|
||||||
public void ReleaseTerrain()
|
public void ReleaseTerrain()
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains)
|
lock (m_terrains)
|
||||||
{
|
{
|
||||||
kvp.Value.Dispose();
|
foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains)
|
||||||
|
{
|
||||||
|
kvp.Value.Dispose();
|
||||||
|
}
|
||||||
|
m_terrains.Clear();
|
||||||
}
|
}
|
||||||
m_terrains.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The simulator wants to set a new heightmap for the terrain.
|
// The simulator wants to set a new heightmap for the terrain.
|
||||||
public void SetTerrain(float[] heightMap) {
|
public void SetTerrain(float[] heightMap) {
|
||||||
float[] localHeightMap = heightMap;
|
float[] localHeightMap = heightMap;
|
||||||
PhysicsScene.TaintedObject("TerrainManager.SetTerrain", delegate()
|
// If there are multiple requests for changes to the same terrain between ticks,
|
||||||
|
// only do that last one.
|
||||||
|
PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate()
|
||||||
{
|
{
|
||||||
if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null)
|
if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null)
|
||||||
{
|
{
|
||||||
|
@ -211,6 +215,7 @@ public sealed class BSTerrainManager
|
||||||
// terrain shape is created and added to the body.
|
// terrain shape is created and added to the body.
|
||||||
// This call is most often used to update the heightMap and parameters of the terrain.
|
// This call is most often used to update the heightMap and parameters of the terrain.
|
||||||
// (The above does suggest that some simplification/refactoring is in order.)
|
// (The above does suggest that some simplification/refactoring is in order.)
|
||||||
|
// Called during taint-time.
|
||||||
private void UpdateTerrain(uint id, float[] heightMap,
|
private void UpdateTerrain(uint id, float[] heightMap,
|
||||||
Vector3 minCoords, Vector3 maxCoords, bool inTaintTime)
|
Vector3 minCoords, Vector3 maxCoords, bool inTaintTime)
|
||||||
{
|
{
|
||||||
|
@ -220,7 +225,7 @@ public sealed class BSTerrainManager
|
||||||
// Find high and low points of passed heightmap.
|
// Find high and low points of passed heightmap.
|
||||||
// The min and max passed in is usually the area objects can be in (maximum
|
// The min and max passed in is usually the area objects can be in (maximum
|
||||||
// object height, for instance). The terrain wants the bounding box for the
|
// object height, for instance). The terrain wants the bounding box for the
|
||||||
// terrain so we replace passed min and max Z with the actual terrain min/max Z.
|
// terrain so replace passed min and max Z with the actual terrain min/max Z.
|
||||||
float minZ = float.MaxValue;
|
float minZ = float.MaxValue;
|
||||||
float maxZ = float.MinValue;
|
float maxZ = float.MinValue;
|
||||||
foreach (float height in heightMap)
|
foreach (float height in heightMap)
|
||||||
|
@ -238,15 +243,15 @@ public sealed class BSTerrainManager
|
||||||
|
|
||||||
Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f);
|
Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f);
|
||||||
|
|
||||||
BSTerrainPhys terrainPhys;
|
lock (m_terrains)
|
||||||
if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
|
|
||||||
{
|
{
|
||||||
// There is already a terrain in this spot. Free the old and build the new.
|
BSTerrainPhys terrainPhys;
|
||||||
DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
|
if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
|
||||||
BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords);
|
|
||||||
|
|
||||||
PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:UpdateExisting", delegate()
|
|
||||||
{
|
{
|
||||||
|
// 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);
|
||||||
|
|
||||||
// Remove old terrain from the collection
|
// Remove old terrain from the collection
|
||||||
m_terrains.Remove(terrainRegionBase);
|
m_terrains.Remove(terrainRegionBase);
|
||||||
// Release any physical memory it may be using.
|
// Release any physical memory it may be using.
|
||||||
|
@ -271,35 +276,24 @@ public sealed class BSTerrainManager
|
||||||
// I hate doing this, but just bail
|
// I hate doing this, but just bail
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
// We don't know about this terrain so either we are creating a new terrain or
|
|
||||||
// our mega-prim child is giving us a new terrain to add to the phys world
|
|
||||||
|
|
||||||
// if this is a child terrain, calculate a unique terrain id
|
|
||||||
uint newTerrainID = id;
|
|
||||||
if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
|
|
||||||
newTerrainID = ++m_terrainCount;
|
|
||||||
|
|
||||||
float[] heightMapX = heightMap;
|
|
||||||
Vector3 minCoordsX = minCoords;
|
|
||||||
Vector3 maxCoordsX = maxCoords;
|
|
||||||
|
|
||||||
DetailLog("{0},UpdateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}",
|
|
||||||
BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
|
|
||||||
|
|
||||||
// Code that must happen at taint-time
|
|
||||||
PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:NewTerrain", delegate()
|
|
||||||
{
|
{
|
||||||
DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}",
|
// We don't know about this terrain so either we are creating a new terrain or
|
||||||
BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y);
|
// our mega-prim child is giving us a new terrain to add to the phys world
|
||||||
|
|
||||||
|
// if this is a child terrain, calculate a unique terrain id
|
||||||
|
uint newTerrainID = id;
|
||||||
|
if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
|
||||||
|
newTerrainID = ++m_terrainCount;
|
||||||
|
|
||||||
|
DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}",
|
||||||
|
BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
|
||||||
BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
|
BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
|
||||||
m_terrains.Add(terrainRegionBase, newTerrainPhys);
|
m_terrains.Add(terrainRegionBase, newTerrainPhys);
|
||||||
|
|
||||||
m_terrainModified = true;
|
m_terrainModified = true;
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,6 +343,7 @@ public sealed class BSTerrainManager
|
||||||
// with the same parameters as last time.
|
// with the same parameters as last time.
|
||||||
if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
|
if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
|
||||||
return lastHeight;
|
return lastHeight;
|
||||||
|
m_terrainModified = false;
|
||||||
|
|
||||||
lastHeightTX = tX;
|
lastHeightTX = tX;
|
||||||
lastHeightTY = tY;
|
lastHeightTY = tY;
|
||||||
|
@ -358,19 +353,19 @@ public sealed class BSTerrainManager
|
||||||
int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
|
int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
|
||||||
Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
|
Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
|
||||||
|
|
||||||
BSTerrainPhys physTerrain;
|
lock (m_terrains)
|
||||||
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
|
|
||||||
{
|
{
|
||||||
ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ);
|
BSTerrainPhys physTerrain;
|
||||||
DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,loc={1},base={2},height={3}",
|
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
|
||||||
BSScene.DetailLogZero, loc, terrainBaseXYZ, ret);
|
{
|
||||||
|
ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
||||||
|
LogHeader, PhysicsScene.RegionName, tX, tY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
|
||||||
LogHeader, PhysicsScene.RegionName, tX, tY);
|
|
||||||
}
|
|
||||||
m_terrainModified = false;
|
|
||||||
lastHeight = ret;
|
lastHeight = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,8 +217,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
verticesCount = verticesCount / 3;
|
verticesCount = verticesCount / 3;
|
||||||
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}",
|
|
||||||
BSScene.DetailLogZero, verticesCount);
|
|
||||||
|
|
||||||
for (int yy = 0; yy < sizeY; yy++)
|
for (int yy = 0; yy < sizeY; yy++)
|
||||||
{
|
{
|
||||||
|
@ -235,8 +233,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
||||||
indicesCount += 6;
|
indicesCount += 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG
|
|
||||||
LogHeader, indicesCount); // DEBUG
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
Loading…
Reference in New Issue