BulletSim: Add detailed and voluminous debug logging that is enabled

with an ini configuration parameter.
Correct computation of relative offsets of children in a linkset.
Remove a prim from any link relationship before deleting it.
Minor code flow cleanups.
0.7.4.1
Robert Adams 2012-07-12 11:29:45 -07:00
parent ecf7bb268c
commit f9913b6ef7
2 changed files with 65 additions and 40 deletions

View File

@ -42,6 +42,8 @@ public sealed class BSPrim : PhysicsActor
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS PRIM]"; private static readonly string LogHeader = "[BULLETS PRIM]";
private void DebugLog(string mm, params Object[] xx) { if (_scene.shouldDebugLog) m_log.DebugFormat(mm, xx); }
private IMesh _mesh; private IMesh _mesh;
private PrimitiveBaseShape _pbs; private PrimitiveBaseShape _pbs;
private ShapeData.PhysicsShapeType _shapeType; private ShapeData.PhysicsShapeType _shapeType;
@ -86,8 +88,8 @@ public sealed class BSPrim : PhysicsActor
private bool _kinematic; private bool _kinematic;
private float _buoyancy; private float _buoyancy;
private List<BSPrim> _childrenPrims;
private BSPrim _parentPrim; private BSPrim _parentPrim;
private List<BSPrim> _childrenPrims;
private int _subscribedEventsMs = 0; private int _subscribedEventsMs = 0;
private int _nextCollisionOkTime = 0; private int _nextCollisionOkTime = 0;
@ -148,6 +150,15 @@ public sealed class BSPrim : PhysicsActor
// Undo any vehicle properties // Undo any vehicle properties
_vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
_scene.RemoveVehiclePrim(this); // just to make sure _scene.RemoveVehiclePrim(this); // just to make sure
// undo any dependance with/on other objects
if (_parentPrim != null)
{
// If I'm someone's child, tell them to forget about me.
_parentPrim.RemoveChildFromLinkset(this);
_parentPrim = null;
}
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff. // everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
@ -202,7 +213,7 @@ public sealed class BSPrim : PhysicsActor
// link me to the specified parent // link me to the specified parent
public override void link(PhysicsActor obj) { public override void link(PhysicsActor obj) {
BSPrim parent = obj as BSPrim; BSPrim parent = obj as BSPrim;
// m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
// TODO: decide if this parent checking needs to happen at taint time // TODO: decide if this parent checking needs to happen at taint time
if (_parentPrim == null) if (_parentPrim == null)
{ {
@ -225,7 +236,7 @@ public sealed class BSPrim : PhysicsActor
else else
{ {
// asking to reparent a prim should not happen // asking to reparent a prim should not happen
m_log.ErrorFormat("{0}: Reparenting a prim. ", LogHeader); m_log.ErrorFormat("{0}: link(): Reparenting a prim. ", LogHeader);
} }
} }
} }
@ -236,7 +247,8 @@ public sealed class BSPrim : PhysicsActor
public override void delink() { public override void delink() {
// TODO: decide if this parent checking needs to happen at taint time // TODO: decide if this parent checking needs to happen at taint time
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
// m_log.DebugFormat("{0}: delink {1}/{2}", LogHeader, _avName, _localID); DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
(_parentPrim==null ? "NULL" : _parentPrim._avName+"/"+_parentPrim.LocalID.ToString()));
if (_parentPrim != null) if (_parentPrim != null)
{ {
_parentPrim.RemoveChildFromLinkset(this); _parentPrim.RemoveChildFromLinkset(this);
@ -252,8 +264,9 @@ public sealed class BSPrim : PhysicsActor
{ {
if (!_childrenPrims.Contains(child)) if (!_childrenPrims.Contains(child))
{ {
DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, this.LocalID);
_childrenPrims.Add(child); _childrenPrims.Add(child);
child.ParentPrim = this; // the child has gained a parent child._parentPrim = this; // the child has gained a parent
RecreateGeomAndObject(); // rebuild my shape with the new child added RecreateGeomAndObject(); // rebuild my shape with the new child added
} }
}); });
@ -269,9 +282,13 @@ public sealed class BSPrim : PhysicsActor
{ {
if (_childrenPrims.Contains(child)) if (_childrenPrims.Contains(child))
{ {
BulletSimAPI.RemoveConstraint(_scene.WorldID, child.LocalID, this.LocalID); DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
if (!BulletSimAPI.RemoveConstraintByID(_scene.WorldID, child.LocalID))
{
m_log.ErrorFormat("{0}: RemoveChildFromLinkset: Failed remove constraint for {1}", LogHeader, child.LocalID);
}
_childrenPrims.Remove(child); _childrenPrims.Remove(child);
child.ParentPrim = null; // the child has lost its parent child._parentPrim = null; // the child has lost its parent
RecreateGeomAndObject(); // rebuild my shape with the child removed RecreateGeomAndObject(); // rebuild my shape with the child removed
} }
else else
@ -282,11 +299,6 @@ public sealed class BSPrim : PhysicsActor
return; return;
} }
public BSPrim ParentPrim
{
set { _parentPrim = value; }
}
// return true if we are the root of a linkset (there are children to manage) // return true if we are the root of a linkset (there are children to manage)
public bool IsRootOfLinkset public bool IsRootOfLinkset
{ {
@ -981,7 +993,6 @@ public sealed class BSPrim : PhysicsActor
int vi = 0; int vi = 0;
foreach (OMV.Vector3 vv in vertices) foreach (OMV.Vector3 vv in vertices)
{ {
// m_log.DebugFormat("{0}: {1}: <{2:0.00}, {3:0.00}, {4:0.00}>", LogHeader, vi / 3, vv.X, vv.Y, vv.Z);
verticesAsFloats[vi++] = vv.X; verticesAsFloats[vi++] = vv.X;
verticesAsFloats[vi++] = vv.Y; verticesAsFloats[vi++] = vv.Y;
verticesAsFloats[vi++] = vv.Z; verticesAsFloats[vi++] = vv.Z;
@ -1129,7 +1140,6 @@ public sealed class BSPrim : PhysicsActor
if (IsRootOfLinkset) if (IsRootOfLinkset)
{ {
// Create a linkset around this object // Create a linkset around this object
// CreateLinksetWithCompoundHull();
CreateLinksetWithConstraints(); CreateLinksetWithConstraints();
} }
else else
@ -1191,33 +1201,33 @@ public sealed class BSPrim : PhysicsActor
// TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added // TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added
void CreateLinksetWithConstraints() void CreateLinksetWithConstraints()
{ {
// m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
// remove any constraints that might be in place // remove any constraints that might be in place
foreach (BSPrim prim in _childrenPrims) foreach (BSPrim prim in _childrenPrims)
{ {
// m_log.DebugFormat("{0}: CreateLinkset: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); DebugLog("{0}: CreateLinkset: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID); BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID);
} }
// create constraints between the root prim and each of the children // create constraints between the root prim and each of the children
foreach (BSPrim prim in _childrenPrims) foreach (BSPrim prim in _childrenPrims)
{ {
// m_log.DebugFormat("{0}: CreateLinkset: AddConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
// Zero motion for children so they don't interpolate // Zero motion for children so they don't interpolate
prim.ZeroMotion(); prim.ZeroMotion();
// relative position normalized to the root prim // relative position normalized to the root prim
OMV.Vector3 childRelativePosition = (prim._position - this._position) * OMV.Quaternion.Inverse(this._orientation); OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation);
OMV.Vector3 childRelativePosition = (prim._position - this._position) * invThisOrientation;
// relative rotation of the child to the parent // relative rotation of the child to the parent
OMV.Quaternion relativeRotation = OMV.Quaternion.Inverse(prim._orientation) * this._orientation; OMV.Quaternion childRelativeRotation = invThisOrientation * prim._orientation;
// this is a constraint that allows no freedom of movement between the two objects // this is a constraint that allows no freedom of movement between the two objects
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID, BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID,
childRelativePosition, childRelativePosition,
relativeRotation, childRelativeRotation,
OMV.Vector3.Zero, OMV.Vector3.Zero,
OMV.Quaternion.Identity, OMV.Quaternion.Identity,
OMV.Vector3.Zero, OMV.Vector3.Zero, OMV.Vector3.Zero, OMV.Vector3.Zero,

View File

@ -72,6 +72,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS SCENE]"; private static readonly string LogHeader = "[BULLETS SCENE]";
private void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); }
public string BulletSimVersion = "?"; public string BulletSimVersion = "?";
private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
@ -147,6 +149,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
ConfigurationParameters[] m_params; ConfigurationParameters[] m_params;
GCHandle m_paramsHandle; GCHandle m_paramsHandle;
public bool shouldDebugLog { get; private set; }
private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
public BSScene(string identifier) public BSScene(string identifier)
@ -209,6 +213,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
m_meshLOD = 8f; m_meshLOD = 8f;
m_sculptLOD = 32f; m_sculptLOD = 32f;
shouldDebugLog = false;
m_detailedStatsStep = 0; // disabled m_detailedStatsStep = 0; // disabled
m_maxSubSteps = 10; m_maxSubSteps = 10;
@ -261,7 +266,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
_meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim); _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim);
_forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing); _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing);
shouldDebugLog = pConfig.GetBoolean("ShouldDebugLog", shouldDebugLog);
m_detailedStatsStep = pConfig.GetInt("DetailedStatsStep", m_detailedStatsStep); m_detailedStatsStep = pConfig.GetInt("DetailedStatsStep", m_detailedStatsStep);
m_meshLOD = pConfig.GetFloat("MeshLevelOfDetail", m_meshLOD); m_meshLOD = pConfig.GetFloat("MeshLevelOfDetail", m_meshLOD);
m_sculptLOD = pConfig.GetFloat("SculptLevelOfDetail", m_sculptLOD); m_sculptLOD = pConfig.GetFloat("SculptLevelOfDetail", m_sculptLOD);
@ -347,10 +354,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public override void RemoveAvatar(PhysicsActor actor) public override void RemoveAvatar(PhysicsActor actor)
{ {
// m_log.DebugFormat("{0}: RemoveAvatar", LogHeader); // m_log.DebugFormat("{0}: RemoveAvatar", LogHeader);
if (actor is BSCharacter) BSCharacter bsactor = actor as BSCharacter;
if (bsactor != null)
{ {
((BSCharacter)actor).Destroy();
}
try try
{ {
lock (m_avatars) m_avatars.Remove(actor.LocalID); lock (m_avatars) m_avatars.Remove(actor.LocalID);
@ -359,22 +365,31 @@ public class BSScene : PhysicsScene, IPhysicsParameters
{ {
m_log.WarnFormat("{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e); m_log.WarnFormat("{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e);
} }
bsactor.Destroy();
// bsactor.dispose();
}
} }
public override void RemovePrim(PhysicsActor prim) public override void RemovePrim(PhysicsActor prim)
{ {
// m_log.DebugFormat("{0}: RemovePrim", LogHeader); BSPrim bsprim = prim as BSPrim;
if (prim is BSPrim) if (bsprim != null)
{ {
((BSPrim)prim).Destroy(); m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
}
try try
{ {
lock (m_prims) m_prims.Remove(prim.LocalID); lock (m_prims) m_prims.Remove(bsprim.LocalID);
} }
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat("{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e); m_log.ErrorFormat("{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e);
}
bsprim.Destroy();
// bsprim.dispose();
}
else
{
m_log.ErrorFormat("{0}: Attempt to remove prim that is not a BSPrim type.", LogHeader);
} }
} }