BulletSim: remember to release the physical body and shape when a prim is destroyed. This fixes many problems with physical linksets.

connector_plugin
Robert Adams 2012-09-28 12:34:50 -07:00
parent 6f89975526
commit 76e9cc41bd
2 changed files with 16 additions and 16 deletions

View File

@ -154,8 +154,9 @@ public sealed class BSPrim : BSPhysObject
PhysicsScene.TaintedObject("BSPrim.destroy", delegate() PhysicsScene.TaintedObject("BSPrim.destroy", delegate()
{ {
DetailLog("{0},BSPrim.Destroy,taint,", LocalID); DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff. // If there are physical body and shape, release my use of same.
BulletSimAPI.DestroyObject(PhysicsScene.WorldID, LocalID); PhysicsScene.Shapes.DereferenceBody(BSBody, true, null);
PhysicsScene.Shapes.DereferenceShape(BSShape, true, null);
}); });
} }
@ -251,9 +252,6 @@ public sealed class BSPrim : BSPhysObject
_rotationalVelocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero;
// Zero some other properties directly into the physics engine // Zero some other properties directly into the physics engine
BulletSimAPI.SetLinearVelocity2(BSBody.ptr, OMV.Vector3.Zero);
BulletSimAPI.SetAngularVelocity2(BSBody.ptr, OMV.Vector3.Zero);
BulletSimAPI.SetInterpolationVelocity2(BSBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero);
BulletSimAPI.ClearForces2(BSBody.ptr); BulletSimAPI.ClearForces2(BSBody.ptr);
} }
@ -1108,9 +1106,8 @@ public sealed class BSPrim : BSPhysObject
ShapeData shapeData; ShapeData shapeData;
FillShapeInfo(out shapeData); FillShapeInfo(out shapeData);
// Undo me from any possible linkset so, if body is rebuilt, the link will get restored. // If this prim is part of a linkset, we must remove and restore the physical
// NOTE that the new linkset is not set. This saves the handle to the linkset // links of the body is rebuilt.
// so we can add ourselves back when shape mangling is complete.
bool needToRestoreLinkset = false; bool needToRestoreLinkset = false;
// Create the correct physical representation for this type of object. // Create the correct physical representation for this type of object.
@ -1119,12 +1116,15 @@ public sealed class BSPrim : BSPhysObject
null, delegate(BulletBody dBody) null, delegate(BulletBody dBody)
{ {
// Called if the current prim body is about to be destroyed. // Called if the current prim body is about to be destroyed.
// The problem is the constraints for Linksets which need to be updated for the new body. // Remove all the physical dependencies on the old body.
needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); needToRestoreLinkset = Linkset.RemoveBodyDependencies(this);
}); });
if (needToRestoreLinkset) if (needToRestoreLinkset)
{
// If physical body dependencies were removed, restore them
Linkset.RestoreBodyDependencies(this); Linkset.RestoreBodyDependencies(this);
}
// Make sure the properties are set on the new object // Make sure the properties are set on the new object
UpdatePhysicalParameters(); UpdatePhysicalParameters();

View File

@ -120,25 +120,25 @@ public class BSShapeCollection : IDisposable
// 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 reference count is either 1 or 0. // Bodies only have one user so the reference count is either 1 or 0.
public void ReferenceBody(BulletBody shape, bool atTaintTime) public void ReferenceBody(BulletBody body, bool atTaintTime)
{ {
lock (m_collectionActivityLock) lock (m_collectionActivityLock)
{ {
BodyDesc bodyDesc; BodyDesc bodyDesc;
if (Bodies.TryGetValue(shape.ID, out bodyDesc)) if (Bodies.TryGetValue(body.ID, out bodyDesc))
{ {
bodyDesc.referenceCount++; bodyDesc.referenceCount++;
DetailLog("{0},BSShapeCollection.ReferenceBody,existingBody,ref={1}", shape.ID, bodyDesc.referenceCount); DetailLog("{0},BSShapeCollection.ReferenceBody,existingBody,body={1},ref={2}", body.ID, body, bodyDesc.referenceCount);
} }
else else
{ {
// New entry // New entry
bodyDesc.ptr = shape.ptr; bodyDesc.ptr = body.ptr;
bodyDesc.referenceCount = 1; bodyDesc.referenceCount = 1;
DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={1}", shape.ID, bodyDesc.referenceCount); DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={1}", body.ID, body, bodyDesc.referenceCount);
} }
bodyDesc.lastReferenced = System.DateTime.Now; bodyDesc.lastReferenced = System.DateTime.Now;
Bodies[shape.ID] = bodyDesc; Bodies[body.ID] = bodyDesc;
} }
} }
@ -256,7 +256,7 @@ public class BSShapeCollection : IDisposable
// Release the usage of a shape. // Release the usage of a shape.
// The collisionObject is released since it is a copy of the real collision shape. // The collisionObject is released since it is a copy of the real collision shape.
private void DereferenceShape(BulletShape shape, bool atTaintTime, ShapeDestructionCallback shapeCallback) public void DereferenceShape(BulletShape shape, bool atTaintTime, ShapeDestructionCallback shapeCallback)
{ {
if (shape.ptr == IntPtr.Zero) if (shape.ptr == IntPtr.Zero)
return; return;