Fix crash in BulletSim which sometimes happens making a linkset physical

(like sitting on and activating a vehicle) and crossing borders.
This keeps better bookkeeping on compound shapes so BulletSim can
identify them when being freed.
varregion
Robert Adams 2014-01-10 22:52:31 -08:00
parent b5ef585069
commit 239b85d7ce
1 changed files with 32 additions and 7 deletions

View File

@ -71,7 +71,7 @@ public abstract class BSShape
lastReferenced = DateTime.Now; lastReferenced = DateTime.Now;
} }
// Called when this shape is being used again. // Called when this shape is done being used.
protected virtual void DecrementReference() protected virtual void DecrementReference()
{ {
referenceCount--; referenceCount--;
@ -866,6 +866,8 @@ public class BSShapeHull : BSShape
public class BSShapeCompound : BSShape public class BSShapeCompound : BSShape
{ {
private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]";
public static Dictionary<string, BSShapeCompound> CompoundShapes = new Dictionary<string, BSShapeCompound>();
public BSShapeCompound(BulletShape pShape) : base(pShape) public BSShapeCompound(BulletShape pShape) : base(pShape)
{ {
} }
@ -873,7 +875,9 @@ public class BSShapeCompound : BSShape
{ {
// Base compound shapes are not shared so this returns a raw shape. // Base compound shapes are not shared so this returns a raw shape.
// A built compound shape can be reused in linksets. // A built compound shape can be reused in linksets.
return new BSShapeCompound(CreatePhysicalCompoundShape(physicsScene)); BSShapeCompound ret = new BSShapeCompound(CreatePhysicalCompoundShape(physicsScene));
CompoundShapes.Add(ret.AddrString, ret);
return ret;
} }
public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim) public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim)
{ {
@ -911,10 +915,21 @@ public class BSShapeCompound : BSShape
BulletShape childShape = physicsScene.PE.RemoveChildShapeFromCompoundShapeIndex(physShapeInfo, ii); BulletShape childShape = physicsScene.PE.RemoveChildShapeFromCompoundShapeIndex(physShapeInfo, ii);
DereferenceAnonCollisionShape(physicsScene, childShape); DereferenceAnonCollisionShape(physicsScene, childShape);
} }
lock (CompoundShapes)
CompoundShapes.Remove(physShapeInfo.AddrString);
physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo); physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo);
} }
} }
} }
public static bool TryGetCompoundByPtr(BulletShape pShape, out BSShapeCompound outCompound)
{
lock (CompoundShapes)
{
string addr = pShape.AddrString;
return CompoundShapes.TryGetValue(addr, out outCompound);
}
}
private static BulletShape CreatePhysicalCompoundShape(BSScene physicsScene) private static BulletShape CreatePhysicalCompoundShape(BSScene physicsScene)
{ {
BulletShape cShape = physicsScene.PE.CreateCompoundShape(physicsScene.World, false); BulletShape cShape = physicsScene.PE.CreateCompoundShape(physicsScene.World, false);
@ -926,10 +941,13 @@ public class BSShapeCompound : BSShape
private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape)
{ {
// TODO: figure a better way to go through all the shape types and find a possible instance. // TODO: figure a better way to go through all the shape types and find a possible instance.
physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,shape={1}",
BSScene.DetailLogZero, pShape);
BSShapeMesh meshDesc; BSShapeMesh meshDesc;
if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
{ {
meshDesc.Dereference(physicsScene); meshDesc.Dereference(physicsScene);
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundMesh,shape={1}", BSScene.DetailLogZero, pShape);
} }
else else
{ {
@ -937,13 +955,15 @@ public class BSShapeCompound : BSShape
if (BSShapeHull.TryGetHullByPtr(pShape, out hullDesc)) if (BSShapeHull.TryGetHullByPtr(pShape, out hullDesc))
{ {
hullDesc.Dereference(physicsScene); hullDesc.Dereference(physicsScene);
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundHull,shape={1}", BSScene.DetailLogZero, pShape);
} }
else else
{ {
BSShapeConvexHull chullDesc; BSShapeConvexHull chullDesc;
if (BSShapeConvexHull.TryGetHullByPtr(pShape, out chullDesc)) if (BSShapeConvexHull.TryGetConvexHullByPtr(pShape, out chullDesc))
{ {
chullDesc.Dereference(physicsScene); chullDesc.Dereference(physicsScene);
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundConvexHull,shape={1}", BSScene.DetailLogZero, pShape);
} }
else else
{ {
@ -951,20 +971,23 @@ public class BSShapeCompound : BSShape
if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc)) if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc))
{ {
gImpactDesc.Dereference(physicsScene); gImpactDesc.Dereference(physicsScene);
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundgImpact,shape={1}", BSScene.DetailLogZero, pShape);
} }
else else
{ {
// Didn't find it in the lists of specific types. It could be compound. // Didn't find it in the lists of specific types. It could be compound.
if (physicsScene.PE.IsCompound(pShape)) BSShapeCompound compoundDesc;
if (BSShapeCompound.TryGetCompoundByPtr(pShape, out compoundDesc))
{ {
BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); compoundDesc.Dereference(physicsScene);
recursiveCompound.Dereference(physicsScene); // physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,recursiveCompoundShape,shape={1}", BSScene.DetailLogZero, pShape);
} }
else else
{ {
// If none of the above, maybe it is a simple native shape. // If none of the above, maybe it is a simple native shape.
if (physicsScene.PE.IsNativeShape(pShape)) if (physicsScene.PE.IsNativeShape(pShape))
{ {
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,assumingNative,shape={1}", BSScene.DetailLogZero, pShape);
BSShapeNative nativeShape = new BSShapeNative(pShape); BSShapeNative nativeShape = new BSShapeNative(pShape);
nativeShape.Dereference(physicsScene); nativeShape.Dereference(physicsScene);
} }
@ -1021,6 +1044,8 @@ public class BSShapeConvexHull : BSShape
convexShape = physicsScene.PE.BuildConvexHullShapeFromMesh(physicsScene.World, baseMesh.physShapeInfo); convexShape = physicsScene.PE.BuildConvexHullShapeFromMesh(physicsScene.World, baseMesh.physShapeInfo);
convexShape.shapeKey = newMeshKey; convexShape.shapeKey = newMeshKey;
ConvexHulls.Add(convexShape.shapeKey, retConvexHull); ConvexHulls.Add(convexShape.shapeKey, retConvexHull);
physicsScene.DetailLog("{0},BSShapeConvexHull.GetReference,addingNewlyCreatedShape,shape={1}",
BSScene.DetailLogZero, convexShape);
} }
// Done with the base mesh // Done with the base mesh
@ -1049,7 +1074,7 @@ public class BSShapeConvexHull : BSShape
} }
} }
// Loop through all the known hulls and return the description based on the physical address. // Loop through all the known hulls and return the description based on the physical address.
public static bool TryGetHullByPtr(BulletShape pShape, out BSShapeConvexHull outHull) public static bool TryGetConvexHullByPtr(BulletShape pShape, out BSShapeConvexHull outHull)
{ {
bool ret = false; bool ret = false;
BSShapeConvexHull foundDesc = null; BSShapeConvexHull foundDesc = null;