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;
}
// Called when this shape is being used again.
// Called when this shape is done being used.
protected virtual void DecrementReference()
{
referenceCount--;
@ -866,6 +866,8 @@ public class BSShapeHull : BSShape
public class BSShapeCompound : BSShape
{
private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]";
public static Dictionary<string, BSShapeCompound> CompoundShapes = new Dictionary<string, BSShapeCompound>();
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.
// 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)
{
@ -911,10 +915,21 @@ public class BSShapeCompound : BSShape
BulletShape childShape = physicsScene.PE.RemoveChildShapeFromCompoundShapeIndex(physShapeInfo, ii);
DereferenceAnonCollisionShape(physicsScene, childShape);
}
lock (CompoundShapes)
CompoundShapes.Remove(physShapeInfo.AddrString);
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)
{
BulletShape cShape = physicsScene.PE.CreateCompoundShape(physicsScene.World, false);
@ -926,10 +941,13 @@ public class BSShapeCompound : BSShape
private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape)
{
// 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;
if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
{
meshDesc.Dereference(physicsScene);
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundMesh,shape={1}", BSScene.DetailLogZero, pShape);
}
else
{
@ -937,13 +955,15 @@ public class BSShapeCompound : BSShape
if (BSShapeHull.TryGetHullByPtr(pShape, out hullDesc))
{
hullDesc.Dereference(physicsScene);
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundHull,shape={1}", BSScene.DetailLogZero, pShape);
}
else
{
BSShapeConvexHull chullDesc;
if (BSShapeConvexHull.TryGetHullByPtr(pShape, out chullDesc))
if (BSShapeConvexHull.TryGetConvexHullByPtr(pShape, out chullDesc))
{
chullDesc.Dereference(physicsScene);
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundConvexHull,shape={1}", BSScene.DetailLogZero, pShape);
}
else
{
@ -951,20 +971,23 @@ public class BSShapeCompound : BSShape
if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc))
{
gImpactDesc.Dereference(physicsScene);
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundgImpact,shape={1}", BSScene.DetailLogZero, pShape);
}
else
{
// 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);
recursiveCompound.Dereference(physicsScene);
compoundDesc.Dereference(physicsScene);
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,recursiveCompoundShape,shape={1}", BSScene.DetailLogZero, pShape);
}
else
{
// If none of the above, maybe it is a simple native shape.
if (physicsScene.PE.IsNativeShape(pShape))
{
// physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,assumingNative,shape={1}", BSScene.DetailLogZero, pShape);
BSShapeNative nativeShape = new BSShapeNative(pShape);
nativeShape.Dereference(physicsScene);
}
@ -1021,6 +1044,8 @@ public class BSShapeConvexHull : BSShape
convexShape = physicsScene.PE.BuildConvexHullShapeFromMesh(physicsScene.World, baseMesh.physShapeInfo);
convexShape.shapeKey = newMeshKey;
ConvexHulls.Add(convexShape.shapeKey, retConvexHull);
physicsScene.DetailLog("{0},BSShapeConvexHull.GetReference,addingNewlyCreatedShape,shape={1}",
BSScene.DetailLogZero, convexShape);
}
// 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.
public static bool TryGetHullByPtr(BulletShape pShape, out BSShapeConvexHull outHull)
public static bool TryGetConvexHullByPtr(BulletShape pShape, out BSShapeConvexHull outHull)
{
bool ret = false;
BSShapeConvexHull foundDesc = null;