BulletSim: search the mesh and hull lists to find shapes if type is not known. This makes sure the correct accounting is done for the particular shape.

integration
Robert Adams 2012-11-03 18:26:00 -07:00
parent 498ea76e63
commit 894bb4893b
4 changed files with 96 additions and 20 deletions

View File

@ -134,7 +134,7 @@ public sealed class BSLinksetCompound : BSLinkset
}
// Routine called when rebuilding the body of some member of the linkset.
// Since we don't keep in-physical world relationships, do nothing unless it's a child changing.
// Since we don't keep in world relationships, do nothing unless it's a child changing.
// Returns 'true' of something was actually removed and would need restoring
// Called at taint-time!!
public override bool RemoveBodyDependencies(BSPrim child)
@ -221,10 +221,12 @@ public sealed class BSLinksetCompound : BSLinkset
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
// Add a shape for each of the other children in the linkset
ForEachMember(delegate(BSPhysObject cPrim)
{
if (!IsRoot(cPrim))
{
// Each child position and rotation is given relative to the root.
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
@ -245,7 +247,7 @@ public sealed class BSLinksetCompound : BSLinkset
}
else
{
// For the shared shapes (meshes and hulls) just use the shape in the child
// For the shared shapes (meshes and hulls), just use the shape in the child.
if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape))
{
PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
@ -254,10 +256,10 @@ public sealed class BSLinksetCompound : BSLinkset
BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot);
}
}
return false;
return false; // 'false' says to move onto the next child in the list
});
// With all of the linkset packed into the root prim, it has the mass of everyone.
float linksetMass = LinksetMass;
LinksetRoot.UpdatePhysicalMassProperties(linksetMass);

View File

@ -1472,7 +1472,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
public void DetailLog(string msg, params Object[] args)
{
PhysicsLogging.Write(msg, args);
// Add the Flush() if debugging crashes to get all the messages written out.
// Add the Flush() if debugging crashes. Gets all the messages written out.
PhysicsLogging.Flush();
}
// Used to fill in the LocalID when there isn't one. It's the correct number of characters.

View File

@ -48,6 +48,7 @@ public sealed class BSShapeCollection : IDisposable
public IntPtr ptr;
public int referenceCount;
public DateTime lastReferenced;
public UInt64 shapeKey;
}
// Description of a hull.
@ -57,6 +58,7 @@ public sealed class BSShapeCollection : IDisposable
public IntPtr ptr;
public int referenceCount;
public DateTime lastReferenced;
public UInt64 shapeKey;
}
// The sharable set of meshes and hulls. Indexed by their shape hash.
@ -116,7 +118,7 @@ public sealed class BSShapeCollection : IDisposable
return ret;
}
// Track another user of a body
// Track another user of a body.
// We presume the caller has allocated the body.
// Bodies only have one user so the body is just put into the world if not already there.
public void ReferenceBody(BulletBody body, bool inTaintTime)
@ -146,13 +148,16 @@ public sealed class BSShapeCollection : IDisposable
{
PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate()
{
DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}",
body.ID, body.ptr.ToString("X"), inTaintTime);
DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}",
body.ID, body, inTaintTime);
// If the caller needs to know the old body is going away, pass the event up.
if (bodyCallback != null) bodyCallback(body);
// It may have already been removed from the world in which case the next is a NOOP.
if (BulletSimAPI.IsInWorld2(body.ptr))
{
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body);
}
// Zero any reference to the shape so it is not freed when the body is deleted.
BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
@ -185,6 +190,7 @@ public sealed class BSShapeCollection : IDisposable
{
// This is a new reference to a mesh
meshDesc.ptr = shape.ptr;
meshDesc.shapeKey = shape.shapeKey;
// We keep a reference to the underlying IMesh data so a hull can be built
meshDesc.referenceCount = 1;
DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}",
@ -207,6 +213,7 @@ public sealed class BSShapeCollection : IDisposable
{
// This is a new reference to a hull
hullDesc.ptr = shape.ptr;
hullDesc.shapeKey = shape.shapeKey;
hullDesc.referenceCount = 1;
DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}",
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
@ -306,7 +313,7 @@ public sealed class BSShapeCollection : IDisposable
// Remove a reference to a compound shape.
// Taking a compound shape apart is a little tricky because if you just delete the
// physical object, it will free all the underlying children. We can't do that because
// physical shape, it will free all the underlying children. We can't do that because
// they could be shared. So, this removes each of the children from the compound and
// dereferences them separately before destroying the compound collision object itself.
// Called at taint-time.
@ -335,23 +342,54 @@ public sealed class BSShapeCollection : IDisposable
// Sometimes we have a pointer to a collision shape but don't know what type it is.
// Figure out type and call the correct dereference routine.
// This is coming from a compound shape that we created so we know it is either native or mesh.
// Called at taint-time.
private void DereferenceAnonCollisionShape(IntPtr cShape)
{
BulletShape shapeInfo = new BulletShape(cShape, ShapeData.PhysicsShapeType.SHAPE_MESH);
if (BulletSimAPI.IsCompound2(cShape))
shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_COMPOUND;
MeshDesc meshDesc;
HullDesc hullDesc;
BulletShape shapeInfo = new BulletShape(cShape);
if (TryGetMeshByPtr(cShape, out meshDesc))
{
shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_MESH;
shapeInfo.shapeKey = meshDesc.shapeKey;
}
else
{
if (TryGetHullByPtr(cShape, out hullDesc))
{
shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_HULL;
shapeInfo.shapeKey = hullDesc.shapeKey;
}
else
{
if (BulletSimAPI.IsCompound2(cShape))
{
shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_COMPOUND;
}
else
{
if (BulletSimAPI.IsNativeShape2(cShape))
{
shapeInfo.isNativeShape = true;
shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter)
}
}
}
}
DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo);
if (shapeInfo.type != ShapeData.PhysicsShapeType.SHAPE_UNKNOWN)
{
DereferenceShape(shapeInfo, true, null);
}
else
{
PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}",
LogHeader, PhysicsScene.RegionName, cShape.ToString("X"));
}
}
// Create the geometry information in Bullet for later use.
// The objects needs a hull if it's physical otherwise a mesh is enough.
@ -913,6 +951,42 @@ public sealed class BSShapeCollection : IDisposable
return ret;
}
private bool TryGetMeshByPtr(IntPtr addr, out MeshDesc outDesc)
{
bool ret = false;
MeshDesc foundDesc = new MeshDesc();
foreach (MeshDesc md in Meshes.Values)
{
if (md.ptr == addr)
{
foundDesc = md;
ret = true;
break;
}
}
outDesc = foundDesc;
return ret;
}
private bool TryGetHullByPtr(IntPtr addr, out HullDesc outDesc)
{
bool ret = false;
HullDesc foundDesc = new HullDesc();
foreach (HullDesc hd in Hulls.Values)
{
if (hd.ptr == addr)
{
foundDesc = hd;
ret = true;
break;
}
}
outDesc = foundDesc;
return ret;
}
private void DetailLog(string msg, params Object[] args)
{
if (PhysicsScene.PhysicsLogging.Enabled)