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
OpenSim/Region/Physics/BulletSPlugin
|
@ -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);
|
||||
|
||||
|
|
|
@ -294,7 +294,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
|||
float linksetMass = 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,
|
||||
// (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
|
||||
DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
|
||||
|
|
|
@ -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.
|
||||
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
|
||||
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,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.
|
||||
// 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;
|
||||
|
||||
if (BulletSimAPI.IsNativeShape2(cShape))
|
||||
BulletShape shapeInfo = new BulletShape(cShape);
|
||||
if (TryGetMeshByPtr(cShape, out meshDesc))
|
||||
{
|
||||
shapeInfo.isNativeShape = true;
|
||||
shapeInfo.type = ShapeData.PhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter)
|
||||
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);
|
||||
|
||||
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.
|
||||
|
@ -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