aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs203
1 files changed, 148 insertions, 55 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
index e427dbc..a7b3f02 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
@@ -39,6 +39,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
39{ 39{
40public abstract class BSShape 40public abstract class BSShape
41{ 41{
42 private static string LogHeader = "[BULLETSIM SHAPE]";
43
42 public int referenceCount { get; set; } 44 public int referenceCount { get; set; }
43 public DateTime lastReferenced { get; set; } 45 public DateTime lastReferenced { get; set; }
44 public BulletShape physShapeInfo { get; set; } 46 public BulletShape physShapeInfo { get; set; }
@@ -56,49 +58,6 @@ public abstract class BSShape
56 physShapeInfo = pShape; 58 physShapeInfo = pShape;
57 } 59 }
58 60
59 // Get a reference to a physical shape. Create if it doesn't exist
60 public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
61 {
62 BSShape ret = null;
63
64 if (prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE)
65 {
66 // an avatar capsule is close to a native shape (it is not shared)
67 ret = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_CAPSULE,
68 FixedShapeKey.KEY_CAPSULE);
69 physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret);
70 }
71
72 // Compound shapes are handled special as they are rebuilt from scratch.
73 // This isn't too great a hardship since most of the child shapes will have already been created.
74 if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
75 {
76 // Getting a reference to a compound shape gets you the compound shape with the root prim shape added
77 ret = BSShapeCompound.GetReference(physicsScene, prim);
78 physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret);
79 }
80
81 // Avatars have their own unique shape
82 if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_AVATAR)
83 {
84 // Getting a reference to a compound shape gets you the compound shape with the root prim shape added
85 ret = BSShapeAvatar.GetReference(prim);
86 physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,avatarShape,shape={1}", prim.LocalID, ret);
87 }
88
89 if (ret == null)
90 ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim);
91
92 return ret;
93 }
94 private static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
95 {
96 // TODO: work needed here!!
97 BSShapeMesh.GetReference(physicsScene, forceRebuild, prim);
98 BSShapeHull.GetReference(physicsScene, forceRebuild, prim);
99 return null;
100 }
101
102 // Called when this shape is being used again. 61 // Called when this shape is being used again.
103 public virtual void IncrementReference() 62 public virtual void IncrementReference()
104 { 63 {
@@ -116,6 +75,27 @@ public abstract class BSShape
116 // Release the use of a physical shape. 75 // Release the use of a physical shape.
117 public abstract void Dereference(BSScene physicsScene); 76 public abstract void Dereference(BSScene physicsScene);
118 77
78 // Return 'true' if there is an allocated physics physical shape under this class instance.
79 public virtual bool HasPhysicalShape
80 {
81 get
82 {
83 if (physShapeInfo != null)
84 return physShapeInfo.HasPhysicalShape;
85 return false;
86 }
87 }
88 public virtual BSPhysicsShapeType ShapeType
89 {
90 get
91 {
92 BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
93 if (physShapeInfo != null && physShapeInfo.HasPhysicalShape)
94 ret = physShapeInfo.shapeType;
95 return ret;
96 }
97 }
98
119 // Returns a string for debugging that uniquily identifies the memory used by this instance 99 // Returns a string for debugging that uniquily identifies the memory used by this instance
120 public virtual string AddrString 100 public virtual string AddrString
121 { 101 {
@@ -132,6 +112,119 @@ public abstract class BSShape
132 buff.Append(">"); 112 buff.Append(">");
133 return buff.ToString(); 113 return buff.ToString();
134 } 114 }
115
116 // Create a hash of all the shape parameters to be used as a key for this particular shape.
117 public static System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod)
118 {
119 // level of detail based on size and type of the object
120 float lod = BSParam.MeshLOD;
121 if (pbs.SculptEntry)
122 lod = BSParam.SculptLOD;
123
124 // Mega prims usually get more detail because one can interact with shape approximations at this size.
125 float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z));
126 if (maxAxis > BSParam.MeshMegaPrimThreshold)
127 lod = BSParam.MeshMegaPrimLOD;
128
129 retLod = lod;
130 return pbs.GetMeshKey(size, lod);
131 }
132
133 // The creation of a mesh or hull can fail if an underlying asset is not available.
134 // There are two cases: 1) the asset is not in the cache and it needs to be fetched;
135 // and 2) the asset cannot be converted (like failed decompression of JPEG2000s).
136 // The first case causes the asset to be fetched. The second case requires
137 // us to not loop forever.
138 // Called after creating a physical mesh or hull. If the physical shape was created,
139 // just return.
140 public static BulletShape VerifyMeshCreated(BSScene physicsScene, BulletShape newShape, BSPhysObject prim)
141 {
142 // If the shape was successfully created, nothing more to do
143 if (newShape.HasPhysicalShape)
144 return newShape;
145
146 // VerifyMeshCreated is called after trying to create the mesh. If we think the asset had been
147 // fetched but we end up here again, the meshing of the asset must have failed.
148 // Prevent trying to keep fetching the mesh by declaring failure.
149 if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
150 {
151 prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
152 physicsScene.Logger.WarnFormat("{0} Fetched asset would not mesh. {1}, texture={2}",
153 LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture);
154 }
155 else
156 {
157 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
158 if (prim.BaseShape.SculptEntry
159 && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed
160 && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting
161 && prim.BaseShape.SculptTexture != OMV.UUID.Zero
162 )
163 {
164 physicsScene.DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID);
165 // Multiple requestors will know we're waiting for this asset
166 prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting;
167
168 BSPhysObject xprim = prim;
169 Util.FireAndForget(delegate
170 {
171 RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod;
172 if (assetProvider != null)
173 {
174 BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
175 assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
176 {
177 bool assetFound = false;
178 string mismatchIDs = String.Empty; // DEBUG DEBUG
179 if (asset != null && yprim.BaseShape.SculptEntry)
180 {
181 if (yprim.BaseShape.SculptTexture.ToString() == asset.ID)
182 {
183 yprim.BaseShape.SculptData = asset.Data;
184 // This will cause the prim to see that the filler shape is not the right
185 // one and try again to build the object.
186 // No race condition with the normal shape setting since the rebuild is at taint time.
187 yprim.ForceBodyShapeRebuild(false /* inTaintTime */);
188 assetFound = true;
189 }
190 else
191 {
192 mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID;
193 }
194 }
195 if (assetFound)
196 yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched;
197 else
198 yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
199 physicsScene.DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}",
200 yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs );
201 });
202 }
203 else
204 {
205 xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
206 physicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}",
207 LogHeader, physicsScene.Name);
208 }
209 });
210 }
211 else
212 {
213 if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed)
214 {
215 physicsScene.Logger.WarnFormat("{0} Mesh failed to fetch asset. obj={1}, texture={2}",
216 LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture);
217 }
218 }
219 }
220
221 // While we wait for the mesh defining asset to be loaded, stick in a simple box for the object.
222 BSShape fillShape = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
223 physicsScene.DetailLog("{0},BSShapeCollection.VerifyMeshCreated,boxTempShape", prim.LocalID);
224
225 return fillShape.physShapeInfo;
226 }
227
135} 228}
136 229
137// ============================================================================================================ 230// ============================================================================================================
@@ -199,7 +292,7 @@ public class BSShapeNative : BSShape
199 physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", 292 physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
200 LogHeader, prim.LocalID, shapeType); 293 LogHeader, prim.LocalID, shapeType);
201 } 294 }
202 newShape.type = shapeType; 295 newShape.shapeType = shapeType;
203 newShape.isNativeShape = true; 296 newShape.isNativeShape = true;
204 newShape.shapeKey = (UInt64)shapeKey; 297 newShape.shapeKey = (UInt64)shapeKey;
205 return newShape; 298 return newShape;
@@ -219,10 +312,11 @@ public class BSShapeMesh : BSShape
219 public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) 312 public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
220 { 313 {
221 float lod; 314 float lod;
222 System.UInt64 newMeshKey = BSShapeCollection.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); 315 System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
223 316
224 physicsScene.DetailLog("{0},BSShapeMesh,getReference,oldKey={1},newKey={2},size={3},lod={4}", 317 physicsScene.DetailLog("{0},BSShapeMesh,getReference,oldKey={1},newKey={2},size={3},lod={4}",
225 prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod); 318 prim.LocalID, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"),
319 newMeshKey.ToString("X"), prim.Size, lod);
226 320
227 BSShapeMesh retMesh = new BSShapeMesh(new BulletShape()); 321 BSShapeMesh retMesh = new BSShapeMesh(new BulletShape());
228 lock (Meshes) 322 lock (Meshes)
@@ -238,8 +332,8 @@ public class BSShapeMesh : BSShape
238 BulletShape newShape = retMesh.CreatePhysicalMesh(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); 332 BulletShape newShape = retMesh.CreatePhysicalMesh(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod);
239 333
240 // Check to see if mesh was created (might require an asset). 334 // Check to see if mesh was created (might require an asset).
241 newShape = BSShapeCollection.VerifyMeshCreated(physicsScene, newShape, prim); 335 newShape = VerifyMeshCreated(physicsScene, newShape, prim);
242 if (newShape.type == BSPhysicsShapeType.SHAPE_MESH) 336 if (newShape.shapeType == BSPhysicsShapeType.SHAPE_MESH)
243 { 337 {
244 // If a mesh was what was created, remember the built shape for later sharing. 338 // If a mesh was what was created, remember the built shape for later sharing.
245 Meshes.Add(newMeshKey, retMesh); 339 Meshes.Add(newMeshKey, retMesh);
@@ -360,10 +454,10 @@ public class BSShapeHull : BSShape
360 public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) 454 public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
361 { 455 {
362 float lod; 456 float lod;
363 System.UInt64 newHullKey = BSShapeCollection.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); 457 System.UInt64 newHullKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
364 458
365 physicsScene.DetailLog("{0},BSShapeHull,getReference,oldKey={1},newKey={2},size={3},lod={4}", 459 physicsScene.DetailLog("{0},BSShapeHull,getReference,oldKey={1},newKey={2},size={3},lod={4}",
366 prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X"), prim.Size, lod); 460 prim.LocalID, prim.PhysShape.physShapeInfo.shapeKey.ToString("X"), newHullKey.ToString("X"), prim.Size, lod);
367 461
368 BSShapeHull retHull = new BSShapeHull(new BulletShape()); 462 BSShapeHull retHull = new BSShapeHull(new BulletShape());
369 lock (Hulls) 463 lock (Hulls)
@@ -379,8 +473,8 @@ public class BSShapeHull : BSShape
379 BulletShape newShape = retHull.CreatePhysicalHull(physicsScene, prim, newHullKey, prim.BaseShape, prim.Size, lod); 473 BulletShape newShape = retHull.CreatePhysicalHull(physicsScene, prim, newHullKey, prim.BaseShape, prim.Size, lod);
380 474
381 // Check to see if mesh was created (might require an asset). 475 // Check to see if mesh was created (might require an asset).
382 newShape = BSShapeCollection.VerifyMeshCreated(physicsScene, newShape, prim); 476 newShape = VerifyMeshCreated(physicsScene, newShape, prim);
383 if (newShape.type == BSPhysicsShapeType.SHAPE_MESH) 477 if (newShape.shapeType == BSPhysicsShapeType.SHAPE_MESH)
384 { 478 {
385 // If a mesh was what was created, remember the built shape for later sharing. 479 // If a mesh was what was created, remember the built shape for later sharing.
386 Hulls.Add(newHullKey, retHull); 480 Hulls.Add(newHullKey, retHull);
@@ -569,7 +663,6 @@ public class BSShapeHull : BSShape
569 } 663 }
570} 664}
571 665
572
573// ============================================================================================================ 666// ============================================================================================================
574public class BSShapeCompound : BSShape 667public class BSShapeCompound : BSShape
575{ 668{
@@ -589,9 +682,9 @@ public class BSShapeCompound : BSShape
589 { 682 {
590 // Failed the sanity check!! 683 // Failed the sanity check!!
591 physicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", 684 physicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}",
592 LogHeader, physShapeInfo.type, physShapeInfo.AddrString); 685 LogHeader, physShapeInfo.shapeType, physShapeInfo.AddrString);
593 physicsScene.DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", 686 physicsScene.DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}",
594 BSScene.DetailLogZero, physShapeInfo.type, physShapeInfo.AddrString); 687 BSScene.DetailLogZero, physShapeInfo.shapeType, physShapeInfo.AddrString);
595 return; 688 return;
596 } 689 }
597 690