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.
parent
498ea76e63
commit
894bb4893b
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue