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. // 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 // Returns 'true' of something was actually removed and would need restoring
// Called at taint-time!! // Called at taint-time!!
public override bool RemoveBodyDependencies(BSPrim child) 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}", DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
// Add a shape for each of the other children in the linkset
ForEachMember(delegate(BSPhysObject cPrim) ForEachMember(delegate(BSPhysObject cPrim)
{ {
if (!IsRoot(cPrim)) if (!IsRoot(cPrim))
{ {
// Each child position and rotation is given relative to the root.
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
@ -245,7 +247,7 @@ public sealed class BSLinksetCompound : BSLinkset
} }
else 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)) if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape))
{ {
PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", 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); 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; float linksetMass = LinksetMass;
LinksetRoot.UpdatePhysicalMassProperties(linksetMass); LinksetRoot.UpdatePhysicalMassProperties(linksetMass);

View File

@ -294,7 +294,7 @@ public sealed class BSLinksetConstraints : BSLinkset
float linksetMass = LinksetMass; float linksetMass = LinksetMass;
LinksetRoot.UpdatePhysicalMassProperties(linksetMass); LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
// DEBUG: see of inter-linkset collisions are causing problems // DEBUG: see of inter-linkset collisions are causing problems
// BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
// (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",

View File

@ -1472,7 +1472,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
public void DetailLog(string msg, params Object[] args) public void DetailLog(string msg, params Object[] args)
{ {
PhysicsLogging.Write(msg, 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(); PhysicsLogging.Flush();
} }
// Used to fill in the LocalID when there isn't one. It's the correct number of characters. // 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 IntPtr ptr;
public int referenceCount; public int referenceCount;
public DateTime lastReferenced; public DateTime lastReferenced;
public UInt64 shapeKey;
} }
// Description of a hull. // Description of a hull.
@ -57,6 +58,7 @@ public sealed class BSShapeCollection : IDisposable
public IntPtr ptr; public IntPtr ptr;
public int referenceCount; public int referenceCount;
public DateTime lastReferenced; public DateTime lastReferenced;
public UInt64 shapeKey;
} }
// The sharable set of meshes and hulls. Indexed by their shape hash. // The sharable set of meshes and hulls. Indexed by their shape hash.
@ -116,7 +118,7 @@ public sealed class BSShapeCollection : IDisposable
return ret; return ret;
} }
// 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 body is just put into the world if not already there. // 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) public void ReferenceBody(BulletBody body, bool inTaintTime)
@ -146,13 +148,16 @@ public sealed class BSShapeCollection : IDisposable
{ {
PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate() PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate()
{ {
DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}, inTaintTime={2}", DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}",
body.ID, body.ptr.ToString("X"), inTaintTime); body.ID, body, inTaintTime);
// If the caller needs to know the old body is going away, pass the event up. // If the caller needs to know the old body is going away, pass the event up.
if (bodyCallback != null) bodyCallback(body); 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); {
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. // 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); 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 // This is a new reference to a mesh
meshDesc.ptr = shape.ptr; meshDesc.ptr = shape.ptr;
meshDesc.shapeKey = shape.shapeKey;
// We keep a reference to the underlying IMesh data so a hull can be built // We keep a reference to the underlying IMesh data so a hull can be built
meshDesc.referenceCount = 1; meshDesc.referenceCount = 1;
DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", 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 // This is a new reference to a hull
hullDesc.ptr = shape.ptr; hullDesc.ptr = shape.ptr;
hullDesc.shapeKey = shape.shapeKey;
hullDesc.referenceCount = 1; hullDesc.referenceCount = 1;
DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}",
BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount);
@ -306,7 +313,7 @@ public sealed class BSShapeCollection : IDisposable
// Remove a reference to a compound shape. // Remove a reference to a compound shape.
// Taking a compound shape apart is a little tricky because if you just delete the // 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 // 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. // dereferences them separately before destroying the compound collision object itself.
// Called at taint-time. // Called at taint-time.
@ -335,22 +342,53 @@ public sealed class BSShapeCollection : IDisposable
// Sometimes we have a pointer to a collision shape but don't know what type it is. // 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. // 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. // Called at taint-time.
private void DereferenceAnonCollisionShape(IntPtr cShape) private void DereferenceAnonCollisionShape(IntPtr cShape)
{ {
BulletShape shapeInfo = new BulletShape(cShape, ShapeData.PhysicsShapeType.SHAPE_MESH); MeshDesc meshDesc;
if (BulletSimAPI.IsCompound2(cShape)) HullDesc hullDesc;
shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_COMPOUND;
if (BulletSimAPI.IsNativeShape2(cShape)) BulletShape shapeInfo = new BulletShape(cShape);
if (TryGetMeshByPtr(cShape, out meshDesc))
{ {
shapeInfo.isNativeShape = true; shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_MESH;
shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) 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); DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo);
DereferenceShape(shapeInfo, true, null); 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. // Create the geometry information in Bullet for later use.
@ -913,6 +951,42 @@ public sealed class BSShapeCollection : IDisposable
return ret; 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) private void DetailLog(string msg, params Object[] args)
{ {
if (PhysicsScene.PhysicsLogging.Enabled) if (PhysicsScene.PhysicsLogging.Enabled)