BulletSim: Rebuild physical body if physical shape changes for mesh and hull.
Properly rebuilds collision caches. Release asset data fetched when building mesh or hulls.user_profiles
parent
a9480aed85
commit
d9c3947824
|
@ -596,6 +596,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
public override void Refresh()
|
public override void Refresh()
|
||||||
{
|
{
|
||||||
// If asking for a refresh, reset the physical parameters before the next simulation step.
|
// If asking for a refresh, reset the physical parameters before the next simulation step.
|
||||||
|
// Called whether active or not since the active state may be updated before the next step.
|
||||||
m_physicsScene.PostTaintObject("BSDynamics.Refresh", ControllingPrim.LocalID, delegate()
|
m_physicsScene.PostTaintObject("BSDynamics.Refresh", ControllingPrim.LocalID, delegate()
|
||||||
{
|
{
|
||||||
SetPhysicalParameters();
|
SetPhysicalParameters();
|
||||||
|
|
|
@ -767,7 +767,7 @@ public class BSPrim : BSPhysObject
|
||||||
if (!PhysBody.HasPhysicalBody)
|
if (!PhysBody.HasPhysicalBody)
|
||||||
{
|
{
|
||||||
// This would only happen if updates are called for during initialization when the body is not set up yet.
|
// This would only happen if updates are called for during initialization when the body is not set up yet.
|
||||||
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,calledWithNoPhysBody", LocalID);
|
// DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,calledWithNoPhysBody", LocalID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,16 +227,41 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects)
|
if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects)
|
||||||
{
|
{
|
||||||
// Update prim.BSShape to reference a hull of this shape.
|
// Update prim.BSShape to reference a hull of this shape.
|
||||||
|
BSShape potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
|
||||||
|
// If the current shape is not what is on the prim at the moment, time to change.
|
||||||
|
if (!prim.PhysShape.HasPhysicalShape
|
||||||
|
|| potentialHull.ShapeType != prim.PhysShape.ShapeType
|
||||||
|
|| potentialHull.physShapeInfo.shapeKey != prim.PhysShape.physShapeInfo.shapeKey)
|
||||||
|
{
|
||||||
DereferenceExistingShape(prim, shapeCallback);
|
DereferenceExistingShape(prim, shapeCallback);
|
||||||
prim.PhysShape = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
|
prim.PhysShape = potentialHull;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
potentialHull.Dereference(m_physicsScene);
|
||||||
|
}
|
||||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
|
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
|
||||||
prim.LocalID, prim.PhysShape, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"));
|
prim.LocalID, prim.PhysShape, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Update prim.BSShape to reference a mesh of this shape.
|
// Update prim.BSShape to reference a mesh of this shape.
|
||||||
|
BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
|
||||||
|
// If the current shape is not what is on the prim at the moment, time to change.
|
||||||
|
if (!prim.PhysShape.HasPhysicalShape
|
||||||
|
|| potentialMesh.ShapeType != prim.PhysShape.ShapeType
|
||||||
|
|| potentialMesh.physShapeInfo.shapeKey != prim.PhysShape.physShapeInfo.shapeKey)
|
||||||
|
{
|
||||||
DereferenceExistingShape(prim, shapeCallback);
|
DereferenceExistingShape(prim, shapeCallback);
|
||||||
prim.PhysShape = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
|
prim.PhysShape = potentialMesh;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We don't need this reference to the mesh that is already being using.
|
||||||
|
potentialMesh.Dereference(m_physicsScene);
|
||||||
|
}
|
||||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
|
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
|
||||||
prim.LocalID, prim.PhysShape, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"));
|
prim.LocalID, prim.PhysShape, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"));
|
||||||
}
|
}
|
||||||
|
@ -320,7 +345,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (prim.IsSolid)
|
if (prim.IsSolid)
|
||||||
{
|
{
|
||||||
aBody = m_physicsScene.PE.CreateBodyFromShape(sim, prim.PhysShape.physShapeInfo, prim.LocalID, prim.RawPosition, prim.RawOrientation);
|
aBody = m_physicsScene.PE.CreateBodyFromShape(sim, prim.PhysShape.physShapeInfo, prim.LocalID, prim.RawPosition, prim.RawOrientation);
|
||||||
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,body={1}", prim.LocalID, aBody);
|
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,rigid,body={1}", prim.LocalID, aBody);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -115,10 +115,15 @@ public abstract class BSShape
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
StringBuilder buff = new StringBuilder();
|
StringBuilder buff = new StringBuilder();
|
||||||
buff.Append("<t=");
|
if (physShapeInfo == null)
|
||||||
buff.Append(ShapeType.ToString());
|
{
|
||||||
buff.Append(",p=");
|
buff.Append(",noPhys");
|
||||||
buff.Append(AddrString);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buff.Append(",phy=");
|
||||||
|
buff.Append(physShapeInfo.ToString());
|
||||||
|
}
|
||||||
buff.Append(",c=");
|
buff.Append(",c=");
|
||||||
buff.Append(referenceCount.ToString());
|
buff.Append(referenceCount.ToString());
|
||||||
buff.Append(">");
|
buff.Append(">");
|
||||||
|
@ -184,21 +189,21 @@ public abstract class BSShape
|
||||||
BSPhysObject xprim = prim;
|
BSPhysObject xprim = prim;
|
||||||
Util.FireAndForget(delegate
|
Util.FireAndForget(delegate
|
||||||
{
|
{
|
||||||
physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,inFireAndForget", xprim.LocalID);
|
// physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,inFireAndForget", xprim.LocalID);
|
||||||
RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod;
|
RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod;
|
||||||
if (assetProvider != null)
|
if (assetProvider != null)
|
||||||
{
|
{
|
||||||
BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
|
BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
|
||||||
assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
|
assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
|
||||||
{
|
{
|
||||||
physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID);
|
// physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID);
|
||||||
bool assetFound = false;
|
bool assetFound = false;
|
||||||
string mismatchIDs = String.Empty; // DEBUG DEBUG
|
string mismatchIDs = String.Empty; // DEBUG DEBUG
|
||||||
if (asset != null && yprim.BaseShape.SculptEntry)
|
if (asset != null && yprim.BaseShape.SculptEntry)
|
||||||
{
|
{
|
||||||
if (yprim.BaseShape.SculptTexture.ToString() == asset.ID)
|
if (yprim.BaseShape.SculptTexture.ToString() == asset.ID)
|
||||||
{
|
{
|
||||||
yprim.BaseShape.SculptData = (byte[])asset.Data.Clone();
|
yprim.BaseShape.SculptData = asset.Data;
|
||||||
// This will cause the prim to see that the filler shape is not the right
|
// This will cause the prim to see that the filler shape is not the right
|
||||||
// one and try again to build the object.
|
// one and try again to build the object.
|
||||||
// No race condition with the normal shape setting since the rebuild is at taint time.
|
// No race condition with the normal shape setting since the rebuild is at taint time.
|
||||||
|
@ -290,7 +295,7 @@ public class BSShapeNative : BSShape
|
||||||
{
|
{
|
||||||
if (physShapeInfo.HasPhysicalShape)
|
if (physShapeInfo.HasPhysicalShape)
|
||||||
{
|
{
|
||||||
physicsScene.DetailLog("{0},BSShapeNative.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this);
|
physicsScene.DetailLog("{0},BSShapeNative.Dereference,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this);
|
||||||
physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo);
|
physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo);
|
||||||
}
|
}
|
||||||
physShapeInfo.Clear();
|
physShapeInfo.Clear();
|
||||||
|
@ -347,9 +352,8 @@ public class BSShapeMesh : BSShape
|
||||||
float lod;
|
float lod;
|
||||||
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||||
|
|
||||||
physicsScene.DetailLog("{0},BSShapeMesh,getReference,oldKey={1},newKey={2},size={3},lod={4}",
|
physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}",
|
||||||
prim.LocalID, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"),
|
prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
|
||||||
newMeshKey.ToString("X"), prim.Size, lod);
|
|
||||||
|
|
||||||
BSShapeMesh retMesh = null;
|
BSShapeMesh retMesh = null;
|
||||||
lock (Meshes)
|
lock (Meshes)
|
||||||
|
@ -389,6 +393,7 @@ public class BSShapeMesh : BSShape
|
||||||
lock (Meshes)
|
lock (Meshes)
|
||||||
{
|
{
|
||||||
this.DecrementReference();
|
this.DecrementReference();
|
||||||
|
physicsScene.DetailLog("{0},BSShapeMesh.Dereference,shape={1}", BSScene.DetailLogZero, this);
|
||||||
// TODO: schedule aging and destruction of unused meshes.
|
// TODO: schedule aging and destruction of unused meshes.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,6 +430,12 @@ public class BSShapeMesh : BSShape
|
||||||
|
|
||||||
if (meshData != null)
|
if (meshData != null)
|
||||||
{
|
{
|
||||||
|
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
||||||
|
{
|
||||||
|
// Release the fetched asset data once it has been used.
|
||||||
|
pbs.SculptData = new byte[0];
|
||||||
|
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
int[] indices = meshData.getIndexListAsInt();
|
int[] indices = meshData.getIndexListAsInt();
|
||||||
int realIndicesIndex = indices.Length;
|
int realIndicesIndex = indices.Length;
|
||||||
|
@ -462,8 +473,8 @@ public class BSShapeMesh : BSShape
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
physicsScene.DetailLog("{0},BSShapeMesh.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}",
|
physicsScene.DetailLog("{0},BSShapeMesh.CreatePhysicalMesh,key={1},origTri={2},realTri={3},numVerts={4}",
|
||||||
BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3);
|
BSScene.DetailLogZero, newMeshKey.ToString("X"), indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3);
|
||||||
|
|
||||||
if (realIndicesIndex != 0)
|
if (realIndicesIndex != 0)
|
||||||
{
|
{
|
||||||
|
@ -496,8 +507,8 @@ public class BSShapeHull : BSShape
|
||||||
float lod;
|
float lod;
|
||||||
System.UInt64 newHullKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
System.UInt64 newHullKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||||
|
|
||||||
physicsScene.DetailLog("{0},BSShapeHull,getReference,oldKey={1},newKey={2},size={3},lod={4}",
|
physicsScene.DetailLog("{0},BSShapeHull,getReference,newKey={1},size={2},lod={3}",
|
||||||
prim.LocalID, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"), newHullKey.ToString("X"), prim.Size, lod);
|
prim.LocalID, newHullKey.ToString("X"), prim.Size, lod);
|
||||||
|
|
||||||
BSShapeHull retHull = null;
|
BSShapeHull retHull = null;
|
||||||
lock (Hulls)
|
lock (Hulls)
|
||||||
|
@ -537,6 +548,7 @@ public class BSShapeHull : BSShape
|
||||||
lock (Hulls)
|
lock (Hulls)
|
||||||
{
|
{
|
||||||
this.DecrementReference();
|
this.DecrementReference();
|
||||||
|
physicsScene.DetailLog("{0},BSShapeHull.Dereference,shape={1}", BSScene.DetailLogZero, this);
|
||||||
// TODO: schedule aging and destruction of unused meshes.
|
// TODO: schedule aging and destruction of unused meshes.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -549,6 +561,8 @@ public class BSShapeHull : BSShape
|
||||||
|
|
||||||
if (BSParam.ShouldUseBulletHACD)
|
if (BSParam.ShouldUseBulletHACD)
|
||||||
{
|
{
|
||||||
|
// Build the hull shape from an existing mesh shape.
|
||||||
|
// The mesh should have already been created in Bullet.
|
||||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID);
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID);
|
||||||
BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim);
|
BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim);
|
||||||
|
|
||||||
|
@ -568,18 +582,26 @@ public class BSShapeHull : BSShape
|
||||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
|
||||||
newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms);
|
newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms);
|
||||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||||
}
|
|
||||||
// Now done with the mesh shape.
|
// Now done with the mesh shape.
|
||||||
meshShape.Dereference(physicsScene);
|
meshShape.Dereference(physicsScene);
|
||||||
|
}
|
||||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||||
}
|
}
|
||||||
if (!newShape.HasPhysicalShape)
|
if (!newShape.HasPhysicalShape)
|
||||||
{
|
{
|
||||||
// Build a new hull in the physical world.
|
// Build a new hull in the physical world using the C# HACD algorigthm.
|
||||||
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
||||||
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
|
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
|
||||||
if (meshData != null)
|
if (meshData != null)
|
||||||
{
|
{
|
||||||
|
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
||||||
|
{
|
||||||
|
// Release the fetched asset data once it has been used.
|
||||||
|
pbs.SculptData = new byte[0];
|
||||||
|
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
int[] indices = meshData.getIndexListAsInt();
|
int[] indices = meshData.getIndexListAsInt();
|
||||||
List<OMV.Vector3> vertices = meshData.getVertexList();
|
List<OMV.Vector3> vertices = meshData.getVertexList();
|
||||||
|
|
||||||
|
@ -740,6 +762,7 @@ public class BSShapeCompound : BSShape
|
||||||
lock (physShapeInfo)
|
lock (physShapeInfo)
|
||||||
{
|
{
|
||||||
this.DecrementReference();
|
this.DecrementReference();
|
||||||
|
physicsScene.DetailLog("{0},BSShapeCompound.Dereference,shape={1}", BSScene.DetailLogZero, this);
|
||||||
if (referenceCount <= 0)
|
if (referenceCount <= 0)
|
||||||
{
|
{
|
||||||
if (!physicsScene.PE.IsCompound(physShapeInfo))
|
if (!physicsScene.PE.IsCompound(physShapeInfo))
|
||||||
|
|
Loading…
Reference in New Issue