diff options
author | Robert Adams | 2013-05-02 10:06:12 -0700 |
---|---|---|
committer | Robert Adams | 2013-05-02 10:06:12 -0700 |
commit | d9c3947824feccd3522c70a72b75c72a84bab3e0 (patch) | |
tree | 32348167e8aea62420bb3158f790140f38609d2f | |
parent | Merge branch 'master' into bulletsim4 (diff) | |
download | opensim-SC_OLD-d9c3947824feccd3522c70a72b75c72a84bab3e0.zip opensim-SC_OLD-d9c3947824feccd3522c70a72b75c72a84bab3e0.tar.gz opensim-SC_OLD-d9c3947824feccd3522c70a72b75c72a84bab3e0.tar.bz2 opensim-SC_OLD-d9c3947824feccd3522c70a72b75c72a84bab3e0.tar.xz |
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.
4 files changed, 73 insertions, 24 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index f535e50..b9bd909 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -596,6 +596,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
596 | public override void Refresh() | 596 | public override void Refresh() |
597 | { | 597 | { |
598 | // If asking for a refresh, reset the physical parameters before the next simulation step. | 598 | // If asking for a refresh, reset the physical parameters before the next simulation step. |
599 | // Called whether active or not since the active state may be updated before the next step. | ||
599 | m_physicsScene.PostTaintObject("BSDynamics.Refresh", ControllingPrim.LocalID, delegate() | 600 | m_physicsScene.PostTaintObject("BSDynamics.Refresh", ControllingPrim.LocalID, delegate() |
600 | { | 601 | { |
601 | SetPhysicalParameters(); | 602 | SetPhysicalParameters(); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 7e2af78..3d68d7f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -767,7 +767,7 @@ public class BSPrim : BSPhysObject | |||
767 | if (!PhysBody.HasPhysicalBody) | 767 | if (!PhysBody.HasPhysicalBody) |
768 | { | 768 | { |
769 | // This would only happen if updates are called for during initialization when the body is not set up yet. | 769 | // This would only happen if updates are called for during initialization when the body is not set up yet. |
770 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,calledWithNoPhysBody", LocalID); | 770 | // DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,calledWithNoPhysBody", LocalID); |
771 | return; | 771 | return; |
772 | } | 772 | } |
773 | 773 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index a4250be..809435d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -227,16 +227,41 @@ public sealed class BSShapeCollection : IDisposable | |||
227 | if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) | 227 | if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) |
228 | { | 228 | { |
229 | // Update prim.BSShape to reference a hull of this shape. | 229 | // Update prim.BSShape to reference a hull of this shape. |
230 | DereferenceExistingShape(prim, shapeCallback); | 230 | BSShape potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim); |
231 | prim.PhysShape = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim); | 231 | // If the current shape is not what is on the prim at the moment, time to change. |
232 | if (!prim.PhysShape.HasPhysicalShape | ||
233 | || potentialHull.ShapeType != prim.PhysShape.ShapeType | ||
234 | || potentialHull.physShapeInfo.shapeKey != prim.PhysShape.physShapeInfo.shapeKey) | ||
235 | { | ||
236 | DereferenceExistingShape(prim, shapeCallback); | ||
237 | prim.PhysShape = potentialHull; | ||
238 | ret = true; | ||
239 | } | ||
240 | else | ||
241 | { | ||
242 | potentialHull.Dereference(m_physicsScene); | ||
243 | } | ||
232 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", | 244 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", |
233 | prim.LocalID, prim.PhysShape, prim.PhysShape.physShapeInfo.shapeKey.ToString("X")); | 245 | prim.LocalID, prim.PhysShape, prim.PhysShape.physShapeInfo.shapeKey.ToString("X")); |
234 | } | 246 | } |
235 | else | 247 | else |
236 | { | 248 | { |
237 | // Update prim.BSShape to reference a mesh of this shape. | 249 | // Update prim.BSShape to reference a mesh of this shape. |
238 | DereferenceExistingShape(prim, shapeCallback); | 250 | BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim); |
239 | prim.PhysShape = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim); | 251 | // If the current shape is not what is on the prim at the moment, time to change. |
252 | if (!prim.PhysShape.HasPhysicalShape | ||
253 | || potentialMesh.ShapeType != prim.PhysShape.ShapeType | ||
254 | || potentialMesh.physShapeInfo.shapeKey != prim.PhysShape.physShapeInfo.shapeKey) | ||
255 | { | ||
256 | DereferenceExistingShape(prim, shapeCallback); | ||
257 | prim.PhysShape = potentialMesh; | ||
258 | ret = true; | ||
259 | } | ||
260 | else | ||
261 | { | ||
262 | // We don't need this reference to the mesh that is already being using. | ||
263 | potentialMesh.Dereference(m_physicsScene); | ||
264 | } | ||
240 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", | 265 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", |
241 | prim.LocalID, prim.PhysShape, prim.PhysShape.physShapeInfo.shapeKey.ToString("X")); | 266 | prim.LocalID, prim.PhysShape, prim.PhysShape.physShapeInfo.shapeKey.ToString("X")); |
242 | } | 267 | } |
@@ -320,7 +345,7 @@ public sealed class BSShapeCollection : IDisposable | |||
320 | if (prim.IsSolid) | 345 | if (prim.IsSolid) |
321 | { | 346 | { |
322 | aBody = m_physicsScene.PE.CreateBodyFromShape(sim, prim.PhysShape.physShapeInfo, prim.LocalID, prim.RawPosition, prim.RawOrientation); | 347 | aBody = m_physicsScene.PE.CreateBodyFromShape(sim, prim.PhysShape.physShapeInfo, prim.LocalID, prim.RawPosition, prim.RawOrientation); |
323 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,body={1}", prim.LocalID, aBody); | 348 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,rigid,body={1}", prim.LocalID, aBody); |
324 | } | 349 | } |
325 | else | 350 | else |
326 | { | 351 | { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 2962249..3346626 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | |||
@@ -115,10 +115,15 @@ public abstract class BSShape | |||
115 | public override string ToString() | 115 | public override string ToString() |
116 | { | 116 | { |
117 | StringBuilder buff = new StringBuilder(); | 117 | StringBuilder buff = new StringBuilder(); |
118 | buff.Append("<t="); | 118 | if (physShapeInfo == null) |
119 | buff.Append(ShapeType.ToString()); | 119 | { |
120 | buff.Append(",p="); | 120 | buff.Append(",noPhys"); |
121 | buff.Append(AddrString); | 121 | } |
122 | else | ||
123 | { | ||
124 | buff.Append(",phy="); | ||
125 | buff.Append(physShapeInfo.ToString()); | ||
126 | } | ||
122 | buff.Append(",c="); | 127 | buff.Append(",c="); |
123 | buff.Append(referenceCount.ToString()); | 128 | buff.Append(referenceCount.ToString()); |
124 | buff.Append(">"); | 129 | buff.Append(">"); |
@@ -184,21 +189,21 @@ public abstract class BSShape | |||
184 | BSPhysObject xprim = prim; | 189 | BSPhysObject xprim = prim; |
185 | Util.FireAndForget(delegate | 190 | Util.FireAndForget(delegate |
186 | { | 191 | { |
187 | physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,inFireAndForget", xprim.LocalID); | 192 | // physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,inFireAndForget", xprim.LocalID); |
188 | RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod; | 193 | RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod; |
189 | if (assetProvider != null) | 194 | if (assetProvider != null) |
190 | { | 195 | { |
191 | BSPhysObject yprim = xprim; // probably not necessary, but, just in case. | 196 | BSPhysObject yprim = xprim; // probably not necessary, but, just in case. |
192 | assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) | 197 | assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) |
193 | { | 198 | { |
194 | physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID); | 199 | // physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID); |
195 | bool assetFound = false; | 200 | bool assetFound = false; |
196 | string mismatchIDs = String.Empty; // DEBUG DEBUG | 201 | string mismatchIDs = String.Empty; // DEBUG DEBUG |
197 | if (asset != null && yprim.BaseShape.SculptEntry) | 202 | if (asset != null && yprim.BaseShape.SculptEntry) |
198 | { | 203 | { |
199 | if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) | 204 | if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) |
200 | { | 205 | { |
201 | yprim.BaseShape.SculptData = (byte[])asset.Data.Clone(); | 206 | yprim.BaseShape.SculptData = asset.Data; |
202 | // This will cause the prim to see that the filler shape is not the right | 207 | // This will cause the prim to see that the filler shape is not the right |
203 | // one and try again to build the object. | 208 | // one and try again to build the object. |
204 | // No race condition with the normal shape setting since the rebuild is at taint time. | 209 | // No race condition with the normal shape setting since the rebuild is at taint time. |
@@ -290,7 +295,7 @@ public class BSShapeNative : BSShape | |||
290 | { | 295 | { |
291 | if (physShapeInfo.HasPhysicalShape) | 296 | if (physShapeInfo.HasPhysicalShape) |
292 | { | 297 | { |
293 | physicsScene.DetailLog("{0},BSShapeNative.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); | 298 | physicsScene.DetailLog("{0},BSShapeNative.Dereference,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); |
294 | physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo); | 299 | physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo); |
295 | } | 300 | } |
296 | physShapeInfo.Clear(); | 301 | physShapeInfo.Clear(); |
@@ -347,9 +352,8 @@ public class BSShapeMesh : BSShape | |||
347 | float lod; | 352 | float lod; |
348 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | 353 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
349 | 354 | ||
350 | physicsScene.DetailLog("{0},BSShapeMesh,getReference,oldKey={1},newKey={2},size={3},lod={4}", | 355 | physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}", |
351 | prim.LocalID, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"), | 356 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); |
352 | newMeshKey.ToString("X"), prim.Size, lod); | ||
353 | 357 | ||
354 | BSShapeMesh retMesh = null; | 358 | BSShapeMesh retMesh = null; |
355 | lock (Meshes) | 359 | lock (Meshes) |
@@ -389,6 +393,7 @@ public class BSShapeMesh : BSShape | |||
389 | lock (Meshes) | 393 | lock (Meshes) |
390 | { | 394 | { |
391 | this.DecrementReference(); | 395 | this.DecrementReference(); |
396 | physicsScene.DetailLog("{0},BSShapeMesh.Dereference,shape={1}", BSScene.DetailLogZero, this); | ||
392 | // TODO: schedule aging and destruction of unused meshes. | 397 | // TODO: schedule aging and destruction of unused meshes. |
393 | } | 398 | } |
394 | } | 399 | } |
@@ -425,6 +430,12 @@ public class BSShapeMesh : BSShape | |||
425 | 430 | ||
426 | if (meshData != null) | 431 | if (meshData != null) |
427 | { | 432 | { |
433 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) | ||
434 | { | ||
435 | // Release the fetched asset data once it has been used. | ||
436 | pbs.SculptData = new byte[0]; | ||
437 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown; | ||
438 | } | ||
428 | 439 | ||
429 | int[] indices = meshData.getIndexListAsInt(); | 440 | int[] indices = meshData.getIndexListAsInt(); |
430 | int realIndicesIndex = indices.Length; | 441 | int realIndicesIndex = indices.Length; |
@@ -462,8 +473,8 @@ public class BSShapeMesh : BSShape | |||
462 | } | 473 | } |
463 | } | 474 | } |
464 | } | 475 | } |
465 | physicsScene.DetailLog("{0},BSShapeMesh.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}", | 476 | physicsScene.DetailLog("{0},BSShapeMesh.CreatePhysicalMesh,key={1},origTri={2},realTri={3},numVerts={4}", |
466 | BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3); | 477 | BSScene.DetailLogZero, newMeshKey.ToString("X"), indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3); |
467 | 478 | ||
468 | if (realIndicesIndex != 0) | 479 | if (realIndicesIndex != 0) |
469 | { | 480 | { |
@@ -496,8 +507,8 @@ public class BSShapeHull : BSShape | |||
496 | float lod; | 507 | float lod; |
497 | System.UInt64 newHullKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | 508 | System.UInt64 newHullKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
498 | 509 | ||
499 | physicsScene.DetailLog("{0},BSShapeHull,getReference,oldKey={1},newKey={2},size={3},lod={4}", | 510 | physicsScene.DetailLog("{0},BSShapeHull,getReference,newKey={1},size={2},lod={3}", |
500 | prim.LocalID, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"), newHullKey.ToString("X"), prim.Size, lod); | 511 | prim.LocalID, newHullKey.ToString("X"), prim.Size, lod); |
501 | 512 | ||
502 | BSShapeHull retHull = null; | 513 | BSShapeHull retHull = null; |
503 | lock (Hulls) | 514 | lock (Hulls) |
@@ -537,6 +548,7 @@ public class BSShapeHull : BSShape | |||
537 | lock (Hulls) | 548 | lock (Hulls) |
538 | { | 549 | { |
539 | this.DecrementReference(); | 550 | this.DecrementReference(); |
551 | physicsScene.DetailLog("{0},BSShapeHull.Dereference,shape={1}", BSScene.DetailLogZero, this); | ||
540 | // TODO: schedule aging and destruction of unused meshes. | 552 | // TODO: schedule aging and destruction of unused meshes. |
541 | } | 553 | } |
542 | } | 554 | } |
@@ -549,6 +561,8 @@ public class BSShapeHull : BSShape | |||
549 | 561 | ||
550 | if (BSParam.ShouldUseBulletHACD) | 562 | if (BSParam.ShouldUseBulletHACD) |
551 | { | 563 | { |
564 | // Build the hull shape from an existing mesh shape. | ||
565 | // The mesh should have already been created in Bullet. | ||
552 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID); | 566 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID); |
553 | BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); | 567 | BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); |
554 | 568 | ||
@@ -568,18 +582,26 @@ public class BSShapeHull : BSShape | |||
568 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); | 582 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); |
569 | newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); | 583 | newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); |
570 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 584 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); |
585 | |||
586 | // Now done with the mesh shape. | ||
587 | meshShape.Dereference(physicsScene); | ||
571 | } | 588 | } |
572 | // Now done with the mesh shape. | ||
573 | meshShape.Dereference(physicsScene); | ||
574 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 589 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); |
575 | } | 590 | } |
576 | if (!newShape.HasPhysicalShape) | 591 | if (!newShape.HasPhysicalShape) |
577 | { | 592 | { |
578 | // Build a new hull in the physical world. | 593 | // Build a new hull in the physical world using the C# HACD algorigthm. |
579 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | 594 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed |
580 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); | 595 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); |
581 | if (meshData != null) | 596 | if (meshData != null) |
582 | { | 597 | { |
598 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) | ||
599 | { | ||
600 | // Release the fetched asset data once it has been used. | ||
601 | pbs.SculptData = new byte[0]; | ||
602 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown; | ||
603 | } | ||
604 | |||
583 | int[] indices = meshData.getIndexListAsInt(); | 605 | int[] indices = meshData.getIndexListAsInt(); |
584 | List<OMV.Vector3> vertices = meshData.getVertexList(); | 606 | List<OMV.Vector3> vertices = meshData.getVertexList(); |
585 | 607 | ||
@@ -740,6 +762,7 @@ public class BSShapeCompound : BSShape | |||
740 | lock (physShapeInfo) | 762 | lock (physShapeInfo) |
741 | { | 763 | { |
742 | this.DecrementReference(); | 764 | this.DecrementReference(); |
765 | physicsScene.DetailLog("{0},BSShapeCompound.Dereference,shape={1}", BSScene.DetailLogZero, this); | ||
743 | if (referenceCount <= 0) | 766 | if (referenceCount <= 0) |
744 | { | 767 | { |
745 | if (!physicsScene.PE.IsCompound(physShapeInfo)) | 768 | if (!physicsScene.PE.IsCompound(physShapeInfo)) |