BulletSim: fix crash caused when linksets were rebuilt. A problem added
when individual child pos/rot changes were implementated a week or so ago. Remove some passing of inTaintTime flag when it was never false.user_profiles
parent
ed71c939fc
commit
75a05c16c5
|
@ -126,9 +126,9 @@ public sealed class BSCharacter : BSPhysObject
|
|||
DetailLog("{0},BSCharacter.Destroy", LocalID);
|
||||
PhysicsScene.TaintedObject("BSCharacter.destroy", delegate()
|
||||
{
|
||||
PhysicsScene.Shapes.DereferenceBody(PhysBody, true /* inTaintTime */, null /* bodyCallback */);
|
||||
PhysicsScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */);
|
||||
PhysBody.Clear();
|
||||
PhysicsScene.Shapes.DereferenceShape(PhysShape, true /* inTaintTime */, null /* bodyCallback */);
|
||||
PhysicsScene.Shapes.DereferenceShape(PhysShape, null /* bodyCallback */);
|
||||
PhysShape.Clear();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -219,28 +219,45 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
{
|
||||
// Gather the child info. It might not be there if the linkset is in transition.
|
||||
BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo;
|
||||
|
||||
// The linksetInfo will need to be rebuilt either here or when the linkset is rebuilt
|
||||
if (LinksetRoot.PhysShape.HasPhysicalShape && lsi != null)
|
||||
{
|
||||
if (PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape))
|
||||
{
|
||||
BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index);
|
||||
if (linksetChildShape.HasPhysicalShape)
|
||||
int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape);
|
||||
if (lsi.Index < numLinksetChildren)
|
||||
{
|
||||
// Compute the offset from the center-of-gravity
|
||||
BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement);
|
||||
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index,
|
||||
newLsi.OffsetFromCenterOfMass,
|
||||
newLsi.OffsetRot,
|
||||
true /* shouldRecalculateLocalAabb */);
|
||||
DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}",
|
||||
updated.LocalID, whichUpdated, newLsi);
|
||||
updated.LinksetInfo = newLsi;
|
||||
updatedChild = true;
|
||||
// It is possible that the linkset is still under construction and the child is not yet
|
||||
// inserted into the compound shape. A rebuild of the linkset in a pre-step action will
|
||||
// build the whole thing with the new position or rotation.
|
||||
// This must be checked for because Bullet references the child array but does no validity
|
||||
// checking of the child index passed.
|
||||
BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index);
|
||||
if (linksetChildShape.HasPhysicalShape)
|
||||
{
|
||||
// Compute the offset from the center-of-gravity
|
||||
BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement);
|
||||
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index,
|
||||
newLsi.OffsetFromCenterOfMass,
|
||||
newLsi.OffsetRot,
|
||||
true /* shouldRecalculateLocalAabb */);
|
||||
updated.LinksetInfo = newLsi;
|
||||
updatedChild = true;
|
||||
DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}",
|
||||
updated.LocalID, whichUpdated, newLsi);
|
||||
}
|
||||
else // DEBUG DEBUG
|
||||
{ // DEBUG DEBUG
|
||||
DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}",
|
||||
updated.LocalID, linksetChildShape);
|
||||
} // DEBUG DEBUG
|
||||
}
|
||||
else // DEBUG DEBUG
|
||||
{ // DEBUG DEBUG
|
||||
DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}",
|
||||
updated.LocalID, linksetChildShape);
|
||||
// the child is not yet in the compound shape. This is non-fatal.
|
||||
DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}",
|
||||
updated.LocalID, numLinksetChildren, lsi.Index);
|
||||
} // DEBUG DEBUG
|
||||
}
|
||||
else // DEBUG DEBUG
|
||||
|
@ -256,6 +273,9 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
if (!updatedChild)
|
||||
{
|
||||
// If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info.
|
||||
// Note that there are several ways through this code that will not update the child that can
|
||||
// occur if the linkset is being rebuilt. In this case, scheduling a rebuild is a NOOP since
|
||||
// there will already be a rebuild scheduled.
|
||||
DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}",
|
||||
updated.LocalID, whichUpdated);
|
||||
updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed.
|
||||
|
|
|
@ -146,9 +146,9 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
|
||||
// If there are physical body and shape, release my use of same.
|
||||
PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null);
|
||||
PhysicsScene.Shapes.DereferenceBody(PhysBody, null);
|
||||
PhysBody.Clear();
|
||||
PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null);
|
||||
PhysicsScene.Shapes.DereferenceShape(PhysShape, null);
|
||||
PhysShape.Clear();
|
||||
});
|
||||
}
|
||||
|
@ -181,11 +181,19 @@ public sealed class BSPrim : BSPhysObject
|
|||
|
||||
public override bool ForceBodyShapeRebuild(bool inTaintTime)
|
||||
{
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate()
|
||||
if (inTaintTime)
|
||||
{
|
||||
_mass = CalculateMass(); // changing the shape changes the mass
|
||||
CreateGeomAndObject(true);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.ForceBodyShapeRebuild", delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing the shape changes the mass
|
||||
CreateGeomAndObject(true);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public override bool Grabbed {
|
||||
|
|
|
@ -133,48 +133,44 @@ public sealed class BSShapeCollection : IDisposable
|
|||
// 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)
|
||||
private void ReferenceBody(BulletBody body)
|
||||
{
|
||||
lock (m_collectionActivityLock)
|
||||
{
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body);
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate()
|
||||
if (!PhysicsScene.PE.IsInWorld(PhysicsScene.World, body))
|
||||
{
|
||||
if (!PhysicsScene.PE.IsInWorld(PhysicsScene.World, body))
|
||||
{
|
||||
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, body);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body);
|
||||
}
|
||||
});
|
||||
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, body);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Release the usage of a body.
|
||||
// Called when releasing use of a BSBody. BSShape is handled separately.
|
||||
public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback )
|
||||
// Called in taint time.
|
||||
public void DereferenceBody(BulletBody body, BodyDestructionCallback bodyCallback )
|
||||
{
|
||||
if (!body.HasPhysicalBody)
|
||||
return;
|
||||
|
||||
PhysicsScene.AssertInTaintTime("BSShapeCollection.DereferenceBody");
|
||||
|
||||
lock (m_collectionActivityLock)
|
||||
{
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate()
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1}", body.ID, body);
|
||||
// If the caller needs to know the old body is going away, pass the event up.
|
||||
if (bodyCallback != null) bodyCallback(body);
|
||||
|
||||
if (PhysicsScene.PE.IsInWorld(PhysicsScene.World, body))
|
||||
{
|
||||
if (DDetail) 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);
|
||||
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, body);
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body);
|
||||
}
|
||||
|
||||
if (PhysicsScene.PE.IsInWorld(PhysicsScene.World, body))
|
||||
{
|
||||
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, body);
|
||||
if (DDetail) 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.
|
||||
PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, null);
|
||||
PhysicsScene.PE.DestroyObject(PhysicsScene.World, body);
|
||||
});
|
||||
// Zero any reference to the shape so it is not freed when the body is deleted.
|
||||
PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, null);
|
||||
PhysicsScene.PE.DestroyObject(PhysicsScene.World, body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,44 +241,43 @@ public sealed class BSShapeCollection : IDisposable
|
|||
}
|
||||
|
||||
// Release the usage of a shape.
|
||||
public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback)
|
||||
public void DereferenceShape(BulletShape shape, ShapeDestructionCallback shapeCallback)
|
||||
{
|
||||
if (!shape.HasPhysicalShape)
|
||||
return;
|
||||
|
||||
PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate()
|
||||
PhysicsScene.AssertInTaintTime("BSShapeCollection.DereferenceShape");
|
||||
|
||||
if (shape.HasPhysicalShape)
|
||||
{
|
||||
if (shape.HasPhysicalShape)
|
||||
if (shape.isNativeShape)
|
||||
{
|
||||
if (shape.isNativeShape)
|
||||
// Native shapes are not tracked and are released immediately
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1}",
|
||||
BSScene.DetailLogZero, shape.AddrString);
|
||||
if (shapeCallback != null) shapeCallback(shape);
|
||||
PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (shape.type)
|
||||
{
|
||||
// Native shapes are not tracked and are released immediately
|
||||
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}",
|
||||
BSScene.DetailLogZero, shape.AddrString, inTaintTime);
|
||||
if (shapeCallback != null) shapeCallback(shape);
|
||||
PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (shape.type)
|
||||
{
|
||||
case BSPhysicsShapeType.SHAPE_HULL:
|
||||
DereferenceHull(shape, shapeCallback);
|
||||
break;
|
||||
case BSPhysicsShapeType.SHAPE_MESH:
|
||||
DereferenceMesh(shape, shapeCallback);
|
||||
break;
|
||||
case BSPhysicsShapeType.SHAPE_COMPOUND:
|
||||
DereferenceCompound(shape, shapeCallback);
|
||||
break;
|
||||
case BSPhysicsShapeType.SHAPE_UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case BSPhysicsShapeType.SHAPE_HULL:
|
||||
DereferenceHull(shape, shapeCallback);
|
||||
break;
|
||||
case BSPhysicsShapeType.SHAPE_MESH:
|
||||
DereferenceMesh(shape, shapeCallback);
|
||||
break;
|
||||
case BSPhysicsShapeType.SHAPE_COMPOUND:
|
||||
DereferenceCompound(shape, shapeCallback);
|
||||
break;
|
||||
case BSPhysicsShapeType.SHAPE_UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Count down the reference count for a mesh shape
|
||||
|
@ -393,7 +388,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
|
||||
if (shapeInfo.type != BSPhysicsShapeType.SHAPE_UNKNOWN)
|
||||
{
|
||||
DereferenceShape(shapeInfo, true, null);
|
||||
DereferenceShape(shapeInfo, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -543,7 +538,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
ShapeDestructionCallback shapeCallback)
|
||||
{
|
||||
// release any previous shape
|
||||
DereferenceShape(prim.PhysShape, true, shapeCallback);
|
||||
DereferenceShape(prim.PhysShape, shapeCallback);
|
||||
|
||||
BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey);
|
||||
|
||||
|
@ -611,7 +606,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"));
|
||||
|
||||
// Since we're recreating new, get rid of the reference to the previous shape
|
||||
DereferenceShape(prim.PhysShape, true, shapeCallback);
|
||||
DereferenceShape(prim.PhysShape, shapeCallback);
|
||||
|
||||
newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, prim.BaseShape, prim.Size, lod);
|
||||
// Take evasive action if the mesh was not constructed.
|
||||
|
@ -682,7 +677,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X"));
|
||||
|
||||
// Remove usage of the previous shape.
|
||||
DereferenceShape(prim.PhysShape, true, shapeCallback);
|
||||
DereferenceShape(prim.PhysShape, shapeCallback);
|
||||
|
||||
newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod);
|
||||
newShape = VerifyMeshCreated(newShape, prim);
|
||||
|
@ -817,7 +812,6 @@ public sealed class BSShapeCollection : IDisposable
|
|||
// Don't need to do this as the shape is freed when the new root shape is created below.
|
||||
// DereferenceShape(prim.PhysShape, true, shapeCallback);
|
||||
|
||||
|
||||
BulletShape cShape = PhysicsScene.PE.CreateCompoundShape(PhysicsScene.World, false);
|
||||
|
||||
// Create the shape for the root prim and add it to the compound shape. Cannot be a native shape.
|
||||
|
@ -956,7 +950,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
if (mustRebuild || forceRebuild)
|
||||
{
|
||||
// Free any old body
|
||||
DereferenceBody(prim.PhysBody, true, bodyCallback);
|
||||
DereferenceBody(prim.PhysBody, bodyCallback);
|
||||
|
||||
BulletBody aBody;
|
||||
if (prim.IsSolid)
|
||||
|
@ -970,7 +964,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.LocalID, aBody);
|
||||
}
|
||||
|
||||
ReferenceBody(aBody, true);
|
||||
ReferenceBody(aBody);
|
||||
|
||||
prim.PhysBody = aBody;
|
||||
|
||||
|
|
|
@ -65,6 +65,10 @@ Vehicle attributes are not restored when a vehicle is rezzed on region creation
|
|||
|
||||
GENERAL TODO LIST:
|
||||
=================================================
|
||||
Collisions are inconsistant: arrows are supposed to hit and report collision. Often don't.
|
||||
If arrow show at prim, collision reported about 1/3 of time. If collision reported,
|
||||
both arrow and prim report it. The arrow bounces off the prim 9 out of 10 times.
|
||||
Shooting 5m sphere "arrows" at 60m/s.
|
||||
llMoveToTarget objects are not effected by gravity until target is removed.
|
||||
Compute CCD parameters based on body size
|
||||
Can solver iterations be changed per body/shape? Can be for constraints but what
|
||||
|
|
Loading…
Reference in New Issue