BulletSim: cosmetic changes (comments and renaming). Give mass to terrain to improve interactions.

connector_plugin
Robert Adams 2012-10-10 08:02:37 -07:00
parent 68698975f1
commit a791620622
7 changed files with 74 additions and 52 deletions

View File

@ -263,7 +263,7 @@ public class BSCharacter : BSPhysObject
// A version of the sanity check that also makes sure a new position value is // A version of the sanity check that also makes sure a new position value is
// pushed back to the physics engine. This routine would be used by anyone // pushed back to the physics engine. This routine would be used by anyone
// who is not already pushing the value. // who is not already pushing the value.
private bool PositionSanityCheck2(bool atTaintTime) private bool PositionSanityCheck2(bool inTaintTime)
{ {
bool ret = false; bool ret = false;
if (PositionSanityCheck()) if (PositionSanityCheck())
@ -275,7 +275,7 @@ public class BSCharacter : BSPhysObject
DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation);
}; };
if (atTaintTime) if (inTaintTime)
sanityOperation(); sanityOperation();
else else
PhysicsScene.TaintedObject("BSCharacter.PositionSanityCheck", sanityOperation); PhysicsScene.TaintedObject("BSCharacter.PositionSanityCheck", sanityOperation);

View File

@ -160,6 +160,31 @@ public class BSLinkset
return ret; return ret;
} }
// When physical properties are changed the linkset needs to recalculate
// its internal properties.
// May be called at runtime or taint-time (just pass the appropriate flag).
public void Refresh(BSPhysObject requestor, bool inTaintTime)
{
// If there are no children, there can't be any constraints to recompute
if (!HasAnyChildren)
return;
// Only the root does the recomputation
if (IsRoot(requestor))
{
BSScene.TaintCallback refreshOperation = delegate()
{
RecomputeLinksetConstraintVariables();
DetailLog("{0},BSLinkset.Refresh,complete,rBody={1}",
LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"));
};
if (inTaintTime)
refreshOperation();
else
PhysicsScene.TaintedObject("BSLinkSet.Refresh", refreshOperation);
}
}
// The object is going dynamic (physical). Do any setup necessary // The object is going dynamic (physical). Do any setup necessary
// for a dynamic linkset. // for a dynamic linkset.
// Only the state of the passed object can be modified. The rest of the linkset // Only the state of the passed object can be modified. The rest of the linkset
@ -182,24 +207,19 @@ public class BSLinkset
return false; return false;
} }
// When physical properties are changed the linkset needs to recalculate // If the software is handling the movement of all the objects in a linkset
// its internal properties. // (like if one doesn't use constraints for static linksets), this is called
// Called at runtime. // when an update for the root of the linkset is received.
public void Refresh(BSPhysObject requestor) // Called at taint-time!!
public void UpdateProperties(BSPhysObject physObject)
{ {
// If there are no children, there can't be any constraints to recompute // The root local properties have been updated. Apply to the children if appropriate.
if (!HasAnyChildren) if (IsRoot(physObject) && HasAnyChildren)
return;
// Only the root does the recomputation
if (IsRoot(requestor))
{ {
PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate() if (!physObject.IsPhysical)
{ {
RecomputeLinksetConstraintVariables(); // TODO: implement software linkset update for static object linksets
DetailLog("{0},BSLinkset.Refresh,complete,rBody={1}", }
LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"));
});
} }
} }
@ -236,9 +256,8 @@ public class BSLinkset
return ret; return ret;
} }
// Routine used when rebuilding the body of the root of the linkset // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
// This is called after RemoveAllLinksToRoot() to restore all the constraints. // this routine will restore the removed constraints.
// This is called when the root body has been changed.
// Called at taint-time!! // Called at taint-time!!
public void RestoreBodyDependencies(BSPrim child) public void RestoreBodyDependencies(BSPrim child)
{ {

View File

@ -327,7 +327,7 @@ public sealed class BSPrim : BSPhysObject
// A version of the sanity check that also makes sure a new position value is // A version of the sanity check that also makes sure a new position value is
// pushed back to the physics engine. This routine would be used by anyone // pushed back to the physics engine. This routine would be used by anyone
// who is not already pushing the value. // who is not already pushing the value.
private bool PositionSanityCheck2(bool atTaintTime) private bool PositionSanityCheck2(bool inTaintTime)
{ {
bool ret = false; bool ret = false;
if (PositionSanityCheck()) if (PositionSanityCheck())
@ -339,7 +339,7 @@ public sealed class BSPrim : BSPhysObject
DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation);
}; };
if (atTaintTime) if (inTaintTime)
sanityOperation(); sanityOperation();
else else
PhysicsScene.TaintedObject("BSPrim.PositionSanityCheck", sanityOperation); PhysicsScene.TaintedObject("BSPrim.PositionSanityCheck", sanityOperation);
@ -583,7 +583,7 @@ public sealed class BSPrim : BSPhysObject
// Set up the object physicalness (does gravity and collisions move this object) // Set up the object physicalness (does gravity and collisions move this object)
MakeDynamic(IsStatic); MakeDynamic(IsStatic);
// Update vehicle specific parameters // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
_vehicle.Refresh(); _vehicle.Refresh();
// Arrange for collision events if the simulator wants them // Arrange for collision events if the simulator wants them
@ -606,7 +606,7 @@ public sealed class BSPrim : BSPhysObject
// Recompute any linkset parameters. // Recompute any linkset parameters.
// When going from non-physical to physical, this re-enables the constraints that // When going from non-physical to physical, this re-enables the constraints that
// had been automatically disabled when the mass was set to zero. // had been automatically disabled when the mass was set to zero.
Linkset.Refresh(this); Linkset.Refresh(this, true);
DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}",
LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape); LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape);
@ -1322,6 +1322,8 @@ public sealed class BSPrim : BSPhysObject
PositionSanityCheck2(true); PositionSanityCheck2(true);
Linkset.UpdateProperties(this);
DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);

View File

@ -39,7 +39,6 @@ using log4net;
using OpenMetaverse; using OpenMetaverse;
// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
// Move all logic out of the C++ code and into the C# code for easier future modifications.
// Test sculpties (verified that they don't work) // Test sculpties (verified that they don't work)
// Compute physics FPS reasonably // Compute physics FPS reasonably
// Based on material, set density and friction // Based on material, set density and friction
@ -493,7 +492,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
int numSubSteps = 0; int numSubSteps = 0;
// DEBUG // DEBUG
DetailLog("{0},BSScene.Simulate,beforeStep,ntaimts={1},step={2}", DetailLogZero, numTaints, m_simulationStep); // DetailLog("{0},BSScene.Simulate,beforeStep,ntaimts={1},step={2}", DetailLogZero, numTaints, m_simulationStep);
try try
{ {
@ -503,8 +502,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
DetailLog("{0},Simulate,call, nTaints={1}, simTime={2}, substeps={3}, updates={4}, colliders={5}", DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}",
DetailLogZero, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount);
} }
catch (Exception e) catch (Exception e)
{ {
@ -855,7 +854,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
(s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); }, (s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); },
(s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ), (s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ),
new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects",
ConfigurationParameters.numericFalse, ConfigurationParameters.numericTrue,
(s,cf,p,v) => { s.ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, s.BoolNumeric(v)); }, (s,cf,p,v) => { s.ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, s.BoolNumeric(v)); },
(s) => { return s.NumericBool(s.ShouldUseHullsForPhysicalObjects); }, (s) => { return s.NumericBool(s.ShouldUseHullsForPhysicalObjects); },
(s,p,l,v) => { s.ShouldUseHullsForPhysicalObjects = s.BoolNumeric(v); } ), (s,p,l,v) => { s.ShouldUseHullsForPhysicalObjects = s.BoolNumeric(v); } ),

View File

@ -67,8 +67,8 @@ public class BSShapeCollection : IDisposable
public DateTime lastReferenced; public DateTime lastReferenced;
} }
private Dictionary<ulong, MeshDesc> Meshes = new Dictionary<ulong, MeshDesc>(); private Dictionary<System.UInt64, MeshDesc> Meshes = new Dictionary<System.UInt64, MeshDesc>();
private Dictionary<ulong, HullDesc> Hulls = new Dictionary<ulong, HullDesc>(); private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>();
private Dictionary<uint, BodyDesc> Bodies = new Dictionary<uint, BodyDesc>(); private Dictionary<uint, BodyDesc> Bodies = new Dictionary<uint, BodyDesc>();
public BSShapeCollection(BSScene physScene) public BSShapeCollection(BSScene physScene)
@ -121,7 +121,7 @@ public class BSShapeCollection : IDisposable
// Track another user of a body // Track another user of a body
// We presume the caller has allocated the body. // We presume the caller has allocated the body.
// Bodies only have one user so the reference count is either 1 or 0. // Bodies only have one user so the reference count is either 1 or 0.
public void ReferenceBody(BulletBody body, bool atTaintTime) public void ReferenceBody(BulletBody body, bool inTaintTime)
{ {
lock (m_collectionActivityLock) lock (m_collectionActivityLock)
{ {
@ -147,7 +147,7 @@ public class BSShapeCollection : IDisposable
body.ID, body); body.ID, body);
} }
}; };
if (atTaintTime) if (inTaintTime)
createOperation(); createOperation();
else else
PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation); PhysicsScene.TaintedObject("BSShapeCollection.ReferenceBody", createOperation);
@ -272,7 +272,7 @@ public class BSShapeCollection : IDisposable
// Release the usage of a shape. // Release the usage of a shape.
// The collisionObject is released since it is a copy of the real collision shape. // The collisionObject is released since it is a copy of the real collision shape.
public void DereferenceShape(BulletShape shape, bool atTaintTime, ShapeDestructionCallback shapeCallback) public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback)
{ {
if (shape.ptr == IntPtr.Zero) if (shape.ptr == IntPtr.Zero)
return; return;
@ -294,14 +294,14 @@ public class BSShapeCollection : IDisposable
if (shape.ptr != IntPtr.Zero & shape.isNativeShape) if (shape.ptr != IntPtr.Zero & shape.isNativeShape)
{ {
DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}",
BSScene.DetailLogZero, shape.ptr.ToString("X"), atTaintTime); BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime);
if (shapeCallback != null) shapeCallback(shape); if (shapeCallback != null) shapeCallback(shape);
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
} }
break; break;
} }
}; };
if (atTaintTime) if (inTaintTime)
{ {
lock (m_collectionActivityLock) lock (m_collectionActivityLock)
{ {
@ -441,7 +441,7 @@ public class BSShapeCollection : IDisposable
// Native shapes are always built independently. // Native shapes are always built independently.
newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType);
newShape.shapeKey = (ulong)shapeKey; newShape.shapeKey = (System.UInt64)shapeKey;
newShape.isNativeShape = true; newShape.isNativeShape = true;
// Don't need to do a 'ReferenceShape()' here because native shapes are not tracked. // Don't need to do a 'ReferenceShape()' here because native shapes are not tracked.
@ -461,7 +461,7 @@ public class BSShapeCollection : IDisposable
BulletShape newShape = new BulletShape(IntPtr.Zero); BulletShape newShape = new BulletShape(IntPtr.Zero);
float lod; float lod;
ulong newMeshKey = ComputeShapeKey(shapeData, pbs, out lod); System.UInt64 newMeshKey = ComputeShapeKey(shapeData, pbs, out lod);
// if this new shape is the same as last time, don't recreate the mesh // if this new shape is the same as last time, don't recreate the mesh
if (newMeshKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) if (newMeshKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH)
@ -484,7 +484,7 @@ public class BSShapeCollection : IDisposable
return true; // 'true' means a new shape has been added to this prim return true; // 'true' means a new shape has been added to this prim
} }
private BulletShape CreatePhysicalMesh(string objName, ulong newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
{ {
IMesh meshData = null; IMesh meshData = null;
IntPtr meshPtr; IntPtr meshPtr;
@ -531,7 +531,7 @@ public class BSShapeCollection : IDisposable
BulletShape newShape; BulletShape newShape;
float lod; float lod;
ulong newHullKey = ComputeShapeKey(shapeData, pbs, out lod); System.UInt64 newHullKey = ComputeShapeKey(shapeData, pbs, out lod);
// if the hull hasn't changed, don't rebuild it // if the hull hasn't changed, don't rebuild it
if (newHullKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) if (newHullKey == prim.BSShape.shapeKey && prim.BSShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL)
@ -554,7 +554,7 @@ public class BSShapeCollection : IDisposable
} }
List<ConvexResult> m_hulls; List<ConvexResult> m_hulls;
private BulletShape CreatePhysicalHull(string objName, ulong newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
{ {
IntPtr hullPtr; IntPtr hullPtr;
@ -667,7 +667,7 @@ public class BSShapeCollection : IDisposable
// Create a hash of all the shape parameters to be used as a key // Create a hash of all the shape parameters to be used as a key
// for this particular shape. // for this particular shape.
private ulong ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod) private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod)
{ {
// level of detail based on size and type of the object // level of detail based on size and type of the object
float lod = PhysicsScene.MeshLOD; float lod = PhysicsScene.MeshLOD;
@ -680,10 +680,10 @@ public class BSShapeCollection : IDisposable
lod = PhysicsScene.MeshMegaPrimLOD; lod = PhysicsScene.MeshMegaPrimLOD;
retLod = lod; retLod = lod;
return (ulong)pbs.GetMeshKey(shapeData.Size, lod); return pbs.GetMeshKey(shapeData.Size, lod);
} }
// For those who don't want the LOD // For those who don't want the LOD
private ulong ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs) private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs)
{ {
float lod; float lod;
return ComputeShapeKey(shapeData, pbs, out lod); return ComputeShapeKey(shapeData, pbs, out lod);
@ -717,6 +717,7 @@ public class BSShapeCollection : IDisposable
if (mustRebuild || forceRebuild) if (mustRebuild || forceRebuild)
{ {
// Free any old body
DereferenceBody(prim.BSBody, true, bodyCallback); DereferenceBody(prim.BSBody, true, bodyCallback);
BulletBody aBody; BulletBody aBody;

View File

@ -201,10 +201,10 @@ public class BSTerrainManager
// The 'doNow' boolean says whether to do all the unmanaged activities right now (like when // The 'doNow' boolean says whether to do all the unmanaged activities right now (like when
// calling this routine from initialization or taint-time routines) or whether to delay // calling this routine from initialization or taint-time routines) or whether to delay
// all the unmanaged activities to taint-time. // all the unmanaged activities to taint-time.
private void UpdateOrCreateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords, bool atTaintTime) private void UpdateOrCreateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords, bool inTaintTime)
{ {
DetailLog("{0},BSTerrainManager.UpdateOrCreateTerrain,call,minC={1},maxC={2},atTaintTime={3}", DetailLog("{0},BSTerrainManager.UpdateOrCreateTerrain,call,minC={1},maxC={2},inTaintTime={3}",
BSScene.DetailLogZero, minCoords, maxCoords, atTaintTime); BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime);
float minZ = float.MaxValue; float minZ = float.MaxValue;
float maxZ = float.MinValue; float maxZ = float.MinValue;
@ -320,7 +320,9 @@ public class BSTerrainManager
BulletSimAPI.SetRestitution2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); BulletSimAPI.SetRestitution2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution);
BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
BulletSimAPI.SetMassProps2(mapInfo.terrainBody.ptr, 0f, Vector3.Zero); float terrainMass = 1000;
Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(mapInfo.terrainBody.ptr, terrainMass);
BulletSimAPI.SetMassProps2(mapInfo.terrainBody.ptr, terrainMass, localInertia);
BulletSimAPI.UpdateInertiaTensor2(mapInfo.terrainBody.ptr); BulletSimAPI.UpdateInertiaTensor2(mapInfo.terrainBody.ptr);
// Return the new terrain to the world of physical objects // Return the new terrain to the world of physical objects
@ -342,7 +344,7 @@ public class BSTerrainManager
// There is the option to do the changes now (we're already in 'taint time'), or // There is the option to do the changes now (we're already in 'taint time'), or
// to do the Bullet operations later. // to do the Bullet operations later.
if (atTaintTime) if (inTaintTime)
rebuildOperation(); rebuildOperation();
else else
PhysicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:UpdateExisting", rebuildOperation); PhysicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:UpdateExisting", rebuildOperation);
@ -381,7 +383,7 @@ public class BSTerrainManager
}; };
// If already in taint-time, just call Bullet. Otherwise queue the operations for the safe time. // If already in taint-time, just call Bullet. Otherwise queue the operations for the safe time.
if (atTaintTime) if (inTaintTime)
createOperation(); createOperation();
else else
PhysicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:NewTerrain", createOperation); PhysicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:NewTerrain", createOperation);

View File

@ -101,9 +101,8 @@ public struct BulletShape
} }
public IntPtr ptr; public IntPtr ptr;
public ShapeData.PhysicsShapeType type; public ShapeData.PhysicsShapeType type;
public ulong shapeKey; public System.UInt64 shapeKey;
public bool isNativeShape; public bool isNativeShape;
// Hulls have an underlying mesh. A pointer to it is hidden here.
public override string ToString() public override string ToString()
{ {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();