diff options
Diffstat (limited to '')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 229 |
1 files changed, 119 insertions, 110 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 892c34b..b4f764b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -45,7 +45,7 @@ public sealed class BSShapeCollection : IDisposable | |||
45 | // Description of a Mesh | 45 | // Description of a Mesh |
46 | private struct MeshDesc | 46 | private struct MeshDesc |
47 | { | 47 | { |
48 | public IntPtr ptr; | 48 | public BulletShape shape; |
49 | public int referenceCount; | 49 | public int referenceCount; |
50 | public DateTime lastReferenced; | 50 | public DateTime lastReferenced; |
51 | public UInt64 shapeKey; | 51 | public UInt64 shapeKey; |
@@ -55,7 +55,7 @@ public sealed class BSShapeCollection : IDisposable | |||
55 | // Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations. | 55 | // Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations. |
56 | private struct HullDesc | 56 | private struct HullDesc |
57 | { | 57 | { |
58 | public IntPtr ptr; | 58 | public BulletShape shape; |
59 | public int referenceCount; | 59 | public int referenceCount; |
60 | public DateTime lastReferenced; | 60 | public DateTime lastReferenced; |
61 | public UInt64 shapeKey; | 61 | public UInt64 shapeKey; |
@@ -65,9 +65,16 @@ public sealed class BSShapeCollection : IDisposable | |||
65 | private Dictionary<System.UInt64, MeshDesc> Meshes = new Dictionary<System.UInt64, MeshDesc>(); | 65 | private Dictionary<System.UInt64, MeshDesc> Meshes = new Dictionary<System.UInt64, MeshDesc>(); |
66 | private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>(); | 66 | private Dictionary<System.UInt64, HullDesc> Hulls = new Dictionary<System.UInt64, HullDesc>(); |
67 | 67 | ||
68 | private bool DDetail = false; | ||
69 | |||
68 | public BSShapeCollection(BSScene physScene) | 70 | public BSShapeCollection(BSScene physScene) |
69 | { | 71 | { |
70 | PhysicsScene = physScene; | 72 | PhysicsScene = physScene; |
73 | // Set the next to 'true' for very detailed shape update detailed logging (detailed details?) | ||
74 | // While detailed debugging is still active, this is better than commenting out all the | ||
75 | // DetailLog statements. When debugging slows down, this and the protected logging | ||
76 | // statements can be commented/removed. | ||
77 | DDetail = true; | ||
71 | } | 78 | } |
72 | 79 | ||
73 | public void Dispose() | 80 | public void Dispose() |
@@ -91,7 +98,7 @@ public sealed class BSShapeCollection : IDisposable | |||
91 | // higher level dependencies on the shape or body. Mostly used for LinkSets to | 98 | // higher level dependencies on the shape or body. Mostly used for LinkSets to |
92 | // remove the physical constraints before the body is destroyed. | 99 | // remove the physical constraints before the body is destroyed. |
93 | // Called at taint-time!! | 100 | // Called at taint-time!! |
94 | public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, | 101 | public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, |
95 | ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) | 102 | ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) |
96 | { | 103 | { |
97 | PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); | 104 | PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); |
@@ -119,6 +126,11 @@ public sealed class BSShapeCollection : IDisposable | |||
119 | return ret; | 126 | return ret; |
120 | } | 127 | } |
121 | 128 | ||
129 | public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim) | ||
130 | { | ||
131 | return GetBodyAndShape(forceRebuild, sim, prim, null, null); | ||
132 | } | ||
133 | |||
122 | // Track another user of a body. | 134 | // Track another user of a body. |
123 | // We presume the caller has allocated the body. | 135 | // We presume the caller has allocated the body. |
124 | // Bodies only have one user so the body is just put into the world if not already there. | 136 | // Bodies only have one user so the body is just put into the world if not already there. |
@@ -126,13 +138,13 @@ public sealed class BSShapeCollection : IDisposable | |||
126 | { | 138 | { |
127 | lock (m_collectionActivityLock) | 139 | lock (m_collectionActivityLock) |
128 | { | 140 | { |
129 | DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); | 141 | if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); |
130 | PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() | 142 | PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() |
131 | { | 143 | { |
132 | if (!BulletSimAPI.IsInWorld2(body.ptr)) | 144 | if (!PhysicsScene.PE.IsInWorld(PhysicsScene.World, body)) |
133 | { | 145 | { |
134 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); | 146 | PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, body); |
135 | DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); | 147 | if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); |
136 | } | 148 | } |
137 | }); | 149 | }); |
138 | } | 150 | } |
@@ -142,27 +154,27 @@ public sealed class BSShapeCollection : IDisposable | |||
142 | // Called when releasing use of a BSBody. BSShape is handled separately. | 154 | // Called when releasing use of a BSBody. BSShape is handled separately. |
143 | public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback ) | 155 | public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback ) |
144 | { | 156 | { |
145 | if (body.ptr == IntPtr.Zero) | 157 | if (!body.HasPhysicalBody) |
146 | return; | 158 | return; |
147 | 159 | ||
148 | lock (m_collectionActivityLock) | 160 | lock (m_collectionActivityLock) |
149 | { | 161 | { |
150 | PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate() | 162 | PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate() |
151 | { | 163 | { |
152 | DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}", | 164 | if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}", |
153 | body.ID, body, inTaintTime); | 165 | body.ID, body, inTaintTime); |
154 | // If the caller needs to know the old body is going away, pass the event up. | 166 | // If the caller needs to know the old body is going away, pass the event up. |
155 | if (bodyCallback != null) bodyCallback(body); | 167 | if (bodyCallback != null) bodyCallback(body); |
156 | 168 | ||
157 | if (BulletSimAPI.IsInWorld2(body.ptr)) | 169 | if (PhysicsScene.PE.IsInWorld(PhysicsScene.World, body)) |
158 | { | 170 | { |
159 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); | 171 | PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, body); |
160 | DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); | 172 | if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); |
161 | } | 173 | } |
162 | 174 | ||
163 | // Zero any reference to the shape so it is not freed when the body is deleted. | 175 | // Zero any reference to the shape so it is not freed when the body is deleted. |
164 | BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero); | 176 | PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, null); |
165 | BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); | 177 | PhysicsScene.PE.DestroyObject(PhysicsScene.World, body); |
166 | }); | 178 | }); |
167 | } | 179 | } |
168 | } | 180 | } |
@@ -184,17 +196,17 @@ public sealed class BSShapeCollection : IDisposable | |||
184 | { | 196 | { |
185 | // There is an existing instance of this mesh. | 197 | // There is an existing instance of this mesh. |
186 | meshDesc.referenceCount++; | 198 | meshDesc.referenceCount++; |
187 | DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}", | 199 | if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}", |
188 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); | 200 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); |
189 | } | 201 | } |
190 | else | 202 | else |
191 | { | 203 | { |
192 | // This is a new reference to a mesh | 204 | // This is a new reference to a mesh |
193 | meshDesc.ptr = shape.ptr; | 205 | meshDesc.shape = shape.Clone(); |
194 | meshDesc.shapeKey = shape.shapeKey; | 206 | meshDesc.shapeKey = shape.shapeKey; |
195 | // We keep a reference to the underlying IMesh data so a hull can be built | 207 | // We keep a reference to the underlying IMesh data so a hull can be built |
196 | meshDesc.referenceCount = 1; | 208 | meshDesc.referenceCount = 1; |
197 | DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", | 209 | if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", |
198 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); | 210 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); |
199 | ret = true; | 211 | ret = true; |
200 | } | 212 | } |
@@ -207,16 +219,16 @@ public sealed class BSShapeCollection : IDisposable | |||
207 | { | 219 | { |
208 | // There is an existing instance of this hull. | 220 | // There is an existing instance of this hull. |
209 | hullDesc.referenceCount++; | 221 | hullDesc.referenceCount++; |
210 | DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}", | 222 | if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}", |
211 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); | 223 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); |
212 | } | 224 | } |
213 | else | 225 | else |
214 | { | 226 | { |
215 | // This is a new reference to a hull | 227 | // This is a new reference to a hull |
216 | hullDesc.ptr = shape.ptr; | 228 | hullDesc.shape = shape.Clone(); |
217 | hullDesc.shapeKey = shape.shapeKey; | 229 | hullDesc.shapeKey = shape.shapeKey; |
218 | hullDesc.referenceCount = 1; | 230 | hullDesc.referenceCount = 1; |
219 | DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", | 231 | if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", |
220 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); | 232 | BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); |
221 | ret = true; | 233 | ret = true; |
222 | 234 | ||
@@ -236,20 +248,20 @@ public sealed class BSShapeCollection : IDisposable | |||
236 | // Release the usage of a shape. | 248 | // Release the usage of a shape. |
237 | public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) | 249 | public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) |
238 | { | 250 | { |
239 | if (shape.ptr == IntPtr.Zero) | 251 | if (!shape.HasPhysicalShape) |
240 | return; | 252 | return; |
241 | 253 | ||
242 | PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate() | 254 | PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate() |
243 | { | 255 | { |
244 | if (shape.ptr != IntPtr.Zero) | 256 | if (shape.HasPhysicalShape) |
245 | { | 257 | { |
246 | if (shape.isNativeShape) | 258 | if (shape.isNativeShape) |
247 | { | 259 | { |
248 | // Native shapes are not tracked and are released immediately | 260 | // Native shapes are not tracked and are released immediately |
249 | DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", | 261 | if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", |
250 | BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime); | 262 | BSScene.DetailLogZero, shape.AddrString, inTaintTime); |
251 | if (shapeCallback != null) shapeCallback(shape); | 263 | if (shapeCallback != null) shapeCallback(shape); |
252 | BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); | 264 | PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape); |
253 | } | 265 | } |
254 | else | 266 | else |
255 | { | 267 | { |
@@ -286,7 +298,7 @@ public sealed class BSShapeCollection : IDisposable | |||
286 | if (shapeCallback != null) shapeCallback(shape); | 298 | if (shapeCallback != null) shapeCallback(shape); |
287 | meshDesc.lastReferenced = System.DateTime.Now; | 299 | meshDesc.lastReferenced = System.DateTime.Now; |
288 | Meshes[shape.shapeKey] = meshDesc; | 300 | Meshes[shape.shapeKey] = meshDesc; |
289 | DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}", | 301 | if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}", |
290 | BSScene.DetailLogZero, shape, meshDesc.referenceCount); | 302 | BSScene.DetailLogZero, shape, meshDesc.referenceCount); |
291 | 303 | ||
292 | } | 304 | } |
@@ -307,7 +319,7 @@ public sealed class BSShapeCollection : IDisposable | |||
307 | 319 | ||
308 | hullDesc.lastReferenced = System.DateTime.Now; | 320 | hullDesc.lastReferenced = System.DateTime.Now; |
309 | Hulls[shape.shapeKey] = hullDesc; | 321 | Hulls[shape.shapeKey] = hullDesc; |
310 | DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}", | 322 | if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}", |
311 | BSScene.DetailLogZero, shape, hullDesc.referenceCount); | 323 | BSScene.DetailLogZero, shape, hullDesc.referenceCount); |
312 | } | 324 | } |
313 | } | 325 | } |
@@ -320,57 +332,56 @@ public sealed class BSShapeCollection : IDisposable | |||
320 | // Called at taint-time. | 332 | // Called at taint-time. |
321 | private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback) | 333 | private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback) |
322 | { | 334 | { |
323 | if (!BulletSimAPI.IsCompound2(shape.ptr)) | 335 | if (!PhysicsScene.PE.IsCompound(shape)) |
324 | { | 336 | { |
325 | // Failed the sanity check!! | 337 | // Failed the sanity check!! |
326 | PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", | 338 | PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", |
327 | LogHeader, shape.type, shape.ptr.ToString("X")); | 339 | LogHeader, shape.type, shape.AddrString); |
328 | DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", | 340 | if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", |
329 | BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X")); | 341 | BSScene.DetailLogZero, shape.type, shape.AddrString); |
330 | return; | 342 | return; |
331 | } | 343 | } |
332 | 344 | ||
333 | int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr); | 345 | int numChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(shape); |
334 | DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); | 346 | if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); |
335 | 347 | ||
336 | for (int ii = numChildren - 1; ii >= 0; ii--) | 348 | for (int ii = numChildren - 1; ii >= 0; ii--) |
337 | { | 349 | { |
338 | IntPtr childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii); | 350 | BulletShape childShape = PhysicsScene.PE.RemoveChildShapeFromCompoundShapeIndex(shape, ii); |
339 | DereferenceAnonCollisionShape(childShape); | 351 | DereferenceAnonCollisionShape(childShape); |
340 | } | 352 | } |
341 | BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); | 353 | PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape); |
342 | } | 354 | } |
343 | 355 | ||
344 | // Sometimes we have a pointer to a collision shape but don't know what type it is. | 356 | // Sometimes we have a pointer to a collision shape but don't know what type it is. |
345 | // Figure out type and call the correct dereference routine. | 357 | // Figure out type and call the correct dereference routine. |
346 | // Called at taint-time. | 358 | // Called at taint-time. |
347 | private void DereferenceAnonCollisionShape(IntPtr cShape) | 359 | private void DereferenceAnonCollisionShape(BulletShape shapeInfo) |
348 | { | 360 | { |
349 | MeshDesc meshDesc; | 361 | MeshDesc meshDesc; |
350 | HullDesc hullDesc; | 362 | HullDesc hullDesc; |
351 | 363 | ||
352 | BulletShape shapeInfo = new BulletShape(cShape); | 364 | if (TryGetMeshByPtr(shapeInfo, out meshDesc)) |
353 | if (TryGetMeshByPtr(cShape, out meshDesc)) | ||
354 | { | 365 | { |
355 | shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH; | 366 | shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH; |
356 | shapeInfo.shapeKey = meshDesc.shapeKey; | 367 | shapeInfo.shapeKey = meshDesc.shapeKey; |
357 | } | 368 | } |
358 | else | 369 | else |
359 | { | 370 | { |
360 | if (TryGetHullByPtr(cShape, out hullDesc)) | 371 | if (TryGetHullByPtr(shapeInfo, out hullDesc)) |
361 | { | 372 | { |
362 | shapeInfo.type = BSPhysicsShapeType.SHAPE_HULL; | 373 | shapeInfo.type = BSPhysicsShapeType.SHAPE_HULL; |
363 | shapeInfo.shapeKey = hullDesc.shapeKey; | 374 | shapeInfo.shapeKey = hullDesc.shapeKey; |
364 | } | 375 | } |
365 | else | 376 | else |
366 | { | 377 | { |
367 | if (BulletSimAPI.IsCompound2(cShape)) | 378 | if (PhysicsScene.PE.IsCompound(shapeInfo)) |
368 | { | 379 | { |
369 | shapeInfo.type = BSPhysicsShapeType.SHAPE_COMPOUND; | 380 | shapeInfo.type = BSPhysicsShapeType.SHAPE_COMPOUND; |
370 | } | 381 | } |
371 | else | 382 | else |
372 | { | 383 | { |
373 | if (BulletSimAPI.IsNativeShape2(cShape)) | 384 | if (PhysicsScene.PE.IsNativeShape(shapeInfo)) |
374 | { | 385 | { |
375 | shapeInfo.isNativeShape = true; | 386 | shapeInfo.isNativeShape = true; |
376 | shapeInfo.type = BSPhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) | 387 | shapeInfo.type = BSPhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) |
@@ -379,7 +390,7 @@ public sealed class BSShapeCollection : IDisposable | |||
379 | } | 390 | } |
380 | } | 391 | } |
381 | 392 | ||
382 | DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); | 393 | if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); |
383 | 394 | ||
384 | if (shapeInfo.type != BSPhysicsShapeType.SHAPE_UNKNOWN) | 395 | if (shapeInfo.type != BSPhysicsShapeType.SHAPE_UNKNOWN) |
385 | { | 396 | { |
@@ -388,7 +399,7 @@ public sealed class BSShapeCollection : IDisposable | |||
388 | else | 399 | else |
389 | { | 400 | { |
390 | PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}", | 401 | PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}", |
391 | LogHeader, PhysicsScene.RegionName, cShape.ToString("X")); | 402 | LogHeader, PhysicsScene.RegionName, shapeInfo.AddrString); |
392 | } | 403 | } |
393 | } | 404 | } |
394 | 405 | ||
@@ -408,19 +419,18 @@ public sealed class BSShapeCollection : IDisposable | |||
408 | if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) | 419 | if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) |
409 | { | 420 | { |
410 | // an avatar capsule is close to a native shape (it is not shared) | 421 | // an avatar capsule is close to a native shape (it is not shared) |
411 | ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, | 422 | GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE, shapeCallback); |
412 | FixedShapeKey.KEY_CAPSULE, shapeCallback); | 423 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); |
413 | DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); | ||
414 | ret = true; | 424 | ret = true; |
415 | haveShape = true; | 425 | haveShape = true; |
416 | } | 426 | } |
417 | 427 | ||
418 | // Compound shapes are handled special as they are rebuilt from scratch. | 428 | // Compound shapes are handled special as they are rebuilt from scratch. |
419 | // This isn't too great a hardship since most of the child shapes will already been created. | 429 | // This isn't too great a hardship since most of the child shapes will have already been created. |
420 | if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) | 430 | if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) |
421 | { | 431 | { |
422 | ret = GetReferenceToCompoundShape(prim, shapeCallback); | 432 | ret = GetReferenceToCompoundShape(prim, shapeCallback); |
423 | DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); | 433 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); |
424 | haveShape = true; | 434 | haveShape = true; |
425 | } | 435 | } |
426 | 436 | ||
@@ -433,7 +443,7 @@ public sealed class BSShapeCollection : IDisposable | |||
433 | } | 443 | } |
434 | 444 | ||
435 | // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'. | 445 | // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'. |
436 | private bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) | 446 | public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) |
437 | { | 447 | { |
438 | bool ret = false; | 448 | bool ret = false; |
439 | bool haveShape = false; | 449 | bool haveShape = false; |
@@ -443,8 +453,9 @@ public sealed class BSShapeCollection : IDisposable | |||
443 | // If the prim attributes are simple, this could be a simple Bullet native shape | 453 | // If the prim attributes are simple, this could be a simple Bullet native shape |
444 | if (!haveShape | 454 | if (!haveShape |
445 | && pbs != null | 455 | && pbs != null |
456 | && !pbs.SculptEntry | ||
446 | && nativeShapePossible | 457 | && nativeShapePossible |
447 | && ((pbs.SculptEntry && !PhysicsScene.ShouldMeshSculptedPrim) | 458 | && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) |
448 | || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 | 459 | || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 |
449 | && pbs.ProfileHollow == 0 | 460 | && pbs.ProfileHollow == 0 |
450 | && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 | 461 | && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 |
@@ -453,19 +464,27 @@ public sealed class BSShapeCollection : IDisposable | |||
453 | && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 | 464 | && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 |
454 | && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) | 465 | && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) |
455 | { | 466 | { |
467 | // Get the scale of any existing shape so we can see if the new shape is same native type and same size. | ||
468 | OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; | ||
469 | if (prim.PhysShape.HasPhysicalShape) | ||
470 | scaleOfExistingShape = PhysicsScene.PE.GetLocalScaling(prim.PhysShape); | ||
471 | |||
472 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}", | ||
473 | prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type); | ||
474 | |||
456 | // It doesn't look like Bullet scales spheres so make sure the scales are all equal | 475 | // It doesn't look like Bullet scales spheres so make sure the scales are all equal |
457 | if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) | 476 | if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) |
458 | && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z) | 477 | && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z) |
459 | { | 478 | { |
460 | haveShape = true; | 479 | haveShape = true; |
461 | if (forceRebuild | 480 | if (forceRebuild |
462 | || prim.Scale != prim.Size | 481 | || prim.Scale != scaleOfExistingShape |
463 | || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_SPHERE | 482 | || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_SPHERE |
464 | ) | 483 | ) |
465 | { | 484 | { |
466 | ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE, | 485 | ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE, |
467 | FixedShapeKey.KEY_SPHERE, shapeCallback); | 486 | FixedShapeKey.KEY_SPHERE, shapeCallback); |
468 | DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", | 487 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", |
469 | prim.LocalID, forceRebuild, prim.PhysShape); | 488 | prim.LocalID, forceRebuild, prim.PhysShape); |
470 | } | 489 | } |
471 | } | 490 | } |
@@ -473,13 +492,13 @@ public sealed class BSShapeCollection : IDisposable | |||
473 | { | 492 | { |
474 | haveShape = true; | 493 | haveShape = true; |
475 | if (forceRebuild | 494 | if (forceRebuild |
476 | || prim.Scale != prim.Size | 495 | || prim.Scale != scaleOfExistingShape |
477 | || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_BOX | 496 | || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_BOX |
478 | ) | 497 | ) |
479 | { | 498 | { |
480 | ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX, | 499 | ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX, |
481 | FixedShapeKey.KEY_BOX, shapeCallback); | 500 | FixedShapeKey.KEY_BOX, shapeCallback); |
482 | DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", | 501 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", |
483 | prim.LocalID, forceRebuild, prim.PhysShape); | 502 | prim.LocalID, forceRebuild, prim.PhysShape); |
484 | } | 503 | } |
485 | } | 504 | } |
@@ -500,17 +519,17 @@ public sealed class BSShapeCollection : IDisposable | |||
500 | bool ret = false; | 519 | bool ret = false; |
501 | // Note that if it's a native shape, the check for physical/non-physical is not | 520 | // Note that if it's a native shape, the check for physical/non-physical is not |
502 | // made. Native shapes work in either case. | 521 | // made. Native shapes work in either case. |
503 | if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) | 522 | if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) |
504 | { | 523 | { |
505 | // Update prim.BSShape to reference a hull of this shape. | 524 | // Update prim.BSShape to reference a hull of this shape. |
506 | ret = GetReferenceToHull(prim,shapeCallback); | 525 | ret = GetReferenceToHull(prim,shapeCallback); |
507 | DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", | 526 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", |
508 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); | 527 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); |
509 | } | 528 | } |
510 | else | 529 | else |
511 | { | 530 | { |
512 | ret = GetReferenceToMesh(prim, shapeCallback); | 531 | ret = GetReferenceToMesh(prim, shapeCallback); |
513 | DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", | 532 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", |
514 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); | 533 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); |
515 | } | 534 | } |
516 | return ret; | 535 | return ret; |
@@ -528,9 +547,10 @@ public sealed class BSShapeCollection : IDisposable | |||
528 | BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); | 547 | BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); |
529 | 548 | ||
530 | // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. | 549 | // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. |
531 | DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", | 550 | if (DDetail) DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", |
532 | prim.LocalID, newShape, prim.Scale); | 551 | prim.LocalID, newShape, prim.Scale); |
533 | 552 | ||
553 | // native shapes are scaled by Bullet | ||
534 | prim.PhysShape = newShape; | 554 | prim.PhysShape = newShape; |
535 | return true; | 555 | return true; |
536 | } | 556 | } |
@@ -550,20 +570,17 @@ public sealed class BSShapeCollection : IDisposable | |||
550 | 570 | ||
551 | if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) | 571 | if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) |
552 | { | 572 | { |
553 | // The proper scale has been calculated in the prim. | 573 | |
554 | newShape = new BulletShape( | 574 | newShape = PhysicsScene.PE.BuildCapsuleShape(PhysicsScene.World, 1f, 1f, prim.Scale); |
555 | BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) | 575 | if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); |
556 | , shapeType); | ||
557 | DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); | ||
558 | } | 576 | } |
559 | else | 577 | else |
560 | { | 578 | { |
561 | // Native shapes are scaled in Bullet so set the scaling to the size | 579 | // Native shapes are scaled in Bullet so set the scaling to the size |
562 | prim.Scale = prim.Size; | 580 | newShape = PhysicsScene.PE.BuildNativeShape(PhysicsScene.World, nativeShapeData); |
563 | nativeShapeData.Scale = prim.Scale; | 581 | |
564 | newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType); | ||
565 | } | 582 | } |
566 | if (newShape.ptr == IntPtr.Zero) | 583 | if (!newShape.HasPhysicalShape) |
567 | { | 584 | { |
568 | PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", | 585 | PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", |
569 | LogHeader, prim.LocalID, shapeType); | 586 | LogHeader, prim.LocalID, shapeType); |
@@ -580,7 +597,7 @@ public sealed class BSShapeCollection : IDisposable | |||
580 | // Called at taint-time! | 597 | // Called at taint-time! |
581 | private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback) | 598 | private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback) |
582 | { | 599 | { |
583 | BulletShape newShape = new BulletShape(IntPtr.Zero); | 600 | BulletShape newShape = new BulletShape(); |
584 | 601 | ||
585 | float lod; | 602 | float lod; |
586 | System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | 603 | System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
@@ -589,7 +606,7 @@ public sealed class BSShapeCollection : IDisposable | |||
589 | if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) | 606 | if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) |
590 | return false; | 607 | return false; |
591 | 608 | ||
592 | DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", | 609 | if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", |
593 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); | 610 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); |
594 | 611 | ||
595 | // Since we're recreating new, get rid of the reference to the previous shape | 612 | // Since we're recreating new, get rid of the reference to the previous shape |
@@ -601,8 +618,6 @@ public sealed class BSShapeCollection : IDisposable | |||
601 | 618 | ||
602 | ReferenceShape(newShape); | 619 | ReferenceShape(newShape); |
603 | 620 | ||
604 | // meshes are already scaled by the meshmerizer | ||
605 | prim.Scale = new OMV.Vector3(1f, 1f, 1f); | ||
606 | prim.PhysShape = newShape; | 621 | prim.PhysShape = newShape; |
607 | 622 | ||
608 | return true; // 'true' means a new shape has been added to this prim | 623 | return true; // 'true' means a new shape has been added to this prim |
@@ -610,18 +625,18 @@ public sealed class BSShapeCollection : IDisposable | |||
610 | 625 | ||
611 | private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 626 | private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
612 | { | 627 | { |
628 | BulletShape newShape = new BulletShape(); | ||
613 | IMesh meshData = null; | 629 | IMesh meshData = null; |
614 | IntPtr meshPtr = IntPtr.Zero; | 630 | |
615 | MeshDesc meshDesc; | 631 | MeshDesc meshDesc; |
616 | if (Meshes.TryGetValue(newMeshKey, out meshDesc)) | 632 | if (Meshes.TryGetValue(newMeshKey, out meshDesc)) |
617 | { | 633 | { |
618 | // If the mesh has already been built just use it. | 634 | // If the mesh has already been built just use it. |
619 | meshPtr = meshDesc.ptr; | 635 | newShape = meshDesc.shape.Clone(); |
620 | } | 636 | } |
621 | else | 637 | else |
622 | { | 638 | { |
623 | // Pass false for physicalness as this creates some sort of bounding box which we don't need | 639 | meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false, false, false); |
624 | meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, false); | ||
625 | 640 | ||
626 | if (meshData != null) | 641 | if (meshData != null) |
627 | { | 642 | { |
@@ -640,11 +655,10 @@ public sealed class BSShapeCollection : IDisposable | |||
640 | // m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", | 655 | // m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", |
641 | // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); | 656 | // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); |
642 | 657 | ||
643 | meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, | 658 | newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, |
644 | indices.GetLength(0), indices, vertices.Count, verticesAsFloats); | 659 | indices.GetLength(0), indices, vertices.Count, verticesAsFloats); |
645 | } | 660 | } |
646 | } | 661 | } |
647 | BulletShape newShape = new BulletShape(meshPtr, BSPhysicsShapeType.SHAPE_MESH); | ||
648 | newShape.shapeKey = newMeshKey; | 662 | newShape.shapeKey = newMeshKey; |
649 | 663 | ||
650 | return newShape; | 664 | return newShape; |
@@ -663,7 +677,7 @@ public sealed class BSShapeCollection : IDisposable | |||
663 | if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL) | 677 | if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL) |
664 | return false; | 678 | return false; |
665 | 679 | ||
666 | DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", | 680 | if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", |
667 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X")); | 681 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X")); |
668 | 682 | ||
669 | // Remove usage of the previous shape. | 683 | // Remove usage of the previous shape. |
@@ -674,8 +688,6 @@ public sealed class BSShapeCollection : IDisposable | |||
674 | 688 | ||
675 | ReferenceShape(newShape); | 689 | ReferenceShape(newShape); |
676 | 690 | ||
677 | // hulls are already scaled by the meshmerizer | ||
678 | prim.Scale = new OMV.Vector3(1f, 1f, 1f); | ||
679 | prim.PhysShape = newShape; | 691 | prim.PhysShape = newShape; |
680 | return true; // 'true' means a new shape has been added to this prim | 692 | return true; // 'true' means a new shape has been added to this prim |
681 | } | 693 | } |
@@ -684,18 +696,20 @@ public sealed class BSShapeCollection : IDisposable | |||
684 | private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 696 | private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
685 | { | 697 | { |
686 | 698 | ||
699 | BulletShape newShape = new BulletShape(); | ||
687 | IntPtr hullPtr = IntPtr.Zero; | 700 | IntPtr hullPtr = IntPtr.Zero; |
701 | |||
688 | HullDesc hullDesc; | 702 | HullDesc hullDesc; |
689 | if (Hulls.TryGetValue(newHullKey, out hullDesc)) | 703 | if (Hulls.TryGetValue(newHullKey, out hullDesc)) |
690 | { | 704 | { |
691 | // If the hull shape already is created, just use it. | 705 | // If the hull shape already is created, just use it. |
692 | hullPtr = hullDesc.ptr; | 706 | newShape = hullDesc.shape.Clone(); |
693 | } | 707 | } |
694 | else | 708 | else |
695 | { | 709 | { |
696 | // Build a new hull in the physical world | 710 | // Build a new hull in the physical world |
697 | // Pass false for physicalness as this creates some sort of bounding box which we don't need | 711 | // Pass true for physicalness as this creates some sort of bounding box which we don't need |
698 | IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, false); | 712 | IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false, false, false); |
699 | if (meshData != null) | 713 | if (meshData != null) |
700 | { | 714 | { |
701 | 715 | ||
@@ -777,14 +791,13 @@ public sealed class BSShapeCollection : IDisposable | |||
777 | } | 791 | } |
778 | } | 792 | } |
779 | // create the hull data structure in Bullet | 793 | // create the hull data structure in Bullet |
780 | hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.ptr, hullCount, convHulls); | 794 | newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls); |
781 | } | 795 | } |
782 | } | 796 | } |
783 | 797 | ||
784 | BulletShape newShape = new BulletShape(hullPtr, BSPhysicsShapeType.SHAPE_HULL); | ||
785 | newShape.shapeKey = newHullKey; | 798 | newShape.shapeKey = newHullKey; |
786 | 799 | ||
787 | return newShape; // 'true' means a new shape has been added to this prim | 800 | return newShape; |
788 | } | 801 | } |
789 | 802 | ||
790 | // Callback from convex hull creater with a newly created hull. | 803 | // Callback from convex hull creater with a newly created hull. |
@@ -803,13 +816,13 @@ public sealed class BSShapeCollection : IDisposable | |||
803 | // Don't need to do this as the shape is freed when the new root shape is created below. | 816 | // Don't need to do this as the shape is freed when the new root shape is created below. |
804 | // DereferenceShape(prim.PhysShape, true, shapeCallback); | 817 | // DereferenceShape(prim.PhysShape, true, shapeCallback); |
805 | 818 | ||
806 | BulletShape cShape = new BulletShape( | 819 | |
807 | BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), BSPhysicsShapeType.SHAPE_COMPOUND); | 820 | BulletShape cShape = PhysicsScene.PE.CreateCompoundShape(PhysicsScene.World, false); |
808 | 821 | ||
809 | // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. | 822 | // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. |
810 | CreateGeomMeshOrHull(prim, shapeCallback); | 823 | CreateGeomMeshOrHull(prim, shapeCallback); |
811 | BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity); | 824 | PhysicsScene.PE.AddChildShapeToCompoundShape(cShape, prim.PhysShape, OMV.Vector3.Zero, OMV.Quaternion.Identity); |
812 | DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}", | 825 | if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}", |
813 | prim.LocalID, cShape, prim.PhysShape); | 826 | prim.LocalID, cShape, prim.PhysShape); |
814 | 827 | ||
815 | prim.PhysShape = cShape; | 828 | prim.PhysShape = cShape; |
@@ -822,14 +835,14 @@ public sealed class BSShapeCollection : IDisposable | |||
822 | private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) | 835 | private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) |
823 | { | 836 | { |
824 | // level of detail based on size and type of the object | 837 | // level of detail based on size and type of the object |
825 | float lod = PhysicsScene.MeshLOD; | 838 | float lod = BSParam.MeshLOD; |
826 | if (pbs.SculptEntry) | 839 | if (pbs.SculptEntry) |
827 | lod = PhysicsScene.SculptLOD; | 840 | lod = BSParam.SculptLOD; |
828 | 841 | ||
829 | // Mega prims usually get more detail because one can interact with shape approximations at this size. | 842 | // Mega prims usually get more detail because one can interact with shape approximations at this size. |
830 | float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z)); | 843 | float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z)); |
831 | if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) | 844 | if (maxAxis > BSParam.MeshMegaPrimThreshold) |
832 | lod = PhysicsScene.MeshMegaPrimLOD; | 845 | lod = BSParam.MeshMegaPrimLOD; |
833 | 846 | ||
834 | retLod = lod; | 847 | retLod = lod; |
835 | return pbs.GetMeshKey(size, lod); | 848 | return pbs.GetMeshKey(size, lod); |
@@ -851,7 +864,7 @@ public sealed class BSShapeCollection : IDisposable | |||
851 | private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) | 864 | private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) |
852 | { | 865 | { |
853 | // If the shape was successfully created, nothing more to do | 866 | // If the shape was successfully created, nothing more to do |
854 | if (newShape.ptr != IntPtr.Zero) | 867 | if (newShape.HasPhysicalShape) |
855 | return newShape; | 868 | return newShape; |
856 | 869 | ||
857 | // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset | 870 | // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset |
@@ -904,19 +917,19 @@ public sealed class BSShapeCollection : IDisposable | |||
904 | // Updates prim.BSBody with the information about the new body if one is created. | 917 | // Updates prim.BSBody with the information about the new body if one is created. |
905 | // Returns 'true' if an object was actually created. | 918 | // Returns 'true' if an object was actually created. |
906 | // Called at taint-time. | 919 | // Called at taint-time. |
907 | private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape, | 920 | private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletWorld sim, BulletShape shape, |
908 | BodyDestructionCallback bodyCallback) | 921 | BodyDestructionCallback bodyCallback) |
909 | { | 922 | { |
910 | bool ret = false; | 923 | bool ret = false; |
911 | 924 | ||
912 | // the mesh, hull or native shape must have already been created in Bullet | 925 | // the mesh, hull or native shape must have already been created in Bullet |
913 | bool mustRebuild = (prim.PhysBody.ptr == IntPtr.Zero); | 926 | bool mustRebuild = !prim.PhysBody.HasPhysicalBody; |
914 | 927 | ||
915 | // If there is an existing body, verify it's of an acceptable type. | 928 | // If there is an existing body, verify it's of an acceptable type. |
916 | // If not a solid object, body is a GhostObject. Otherwise a RigidBody. | 929 | // If not a solid object, body is a GhostObject. Otherwise a RigidBody. |
917 | if (!mustRebuild) | 930 | if (!mustRebuild) |
918 | { | 931 | { |
919 | CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.PhysBody.ptr); | 932 | CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(prim.PhysBody); |
920 | if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY | 933 | if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY |
921 | || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT) | 934 | || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT) |
922 | { | 935 | { |
@@ -931,20 +944,16 @@ public sealed class BSShapeCollection : IDisposable | |||
931 | DereferenceBody(prim.PhysBody, true, bodyCallback); | 944 | DereferenceBody(prim.PhysBody, true, bodyCallback); |
932 | 945 | ||
933 | BulletBody aBody; | 946 | BulletBody aBody; |
934 | IntPtr bodyPtr = IntPtr.Zero; | ||
935 | if (prim.IsSolid) | 947 | if (prim.IsSolid) |
936 | { | 948 | { |
937 | bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, | 949 | aBody = PhysicsScene.PE.CreateBodyFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation); |
938 | prim.LocalID, prim.RawPosition, prim.RawOrientation); | 950 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,body={1}", prim.LocalID, aBody); |
939 | DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); | ||
940 | } | 951 | } |
941 | else | 952 | else |
942 | { | 953 | { |
943 | bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, | 954 | aBody = PhysicsScene.PE.CreateGhostFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation); |
944 | prim.LocalID, prim.RawPosition, prim.RawOrientation); | 955 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.LocalID, aBody); |
945 | DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); | ||
946 | } | 956 | } |
947 | aBody = new BulletBody(prim.LocalID, bodyPtr); | ||
948 | 957 | ||
949 | ReferenceBody(aBody, true); | 958 | ReferenceBody(aBody, true); |
950 | 959 | ||
@@ -956,13 +965,13 @@ public sealed class BSShapeCollection : IDisposable | |||
956 | return ret; | 965 | return ret; |
957 | } | 966 | } |
958 | 967 | ||
959 | private bool TryGetMeshByPtr(IntPtr addr, out MeshDesc outDesc) | 968 | private bool TryGetMeshByPtr(BulletShape shape, out MeshDesc outDesc) |
960 | { | 969 | { |
961 | bool ret = false; | 970 | bool ret = false; |
962 | MeshDesc foundDesc = new MeshDesc(); | 971 | MeshDesc foundDesc = new MeshDesc(); |
963 | foreach (MeshDesc md in Meshes.Values) | 972 | foreach (MeshDesc md in Meshes.Values) |
964 | { | 973 | { |
965 | if (md.ptr == addr) | 974 | if (md.shape.ReferenceSame(shape)) |
966 | { | 975 | { |
967 | foundDesc = md; | 976 | foundDesc = md; |
968 | ret = true; | 977 | ret = true; |
@@ -974,13 +983,13 @@ public sealed class BSShapeCollection : IDisposable | |||
974 | return ret; | 983 | return ret; |
975 | } | 984 | } |
976 | 985 | ||
977 | private bool TryGetHullByPtr(IntPtr addr, out HullDesc outDesc) | 986 | private bool TryGetHullByPtr(BulletShape shape, out HullDesc outDesc) |
978 | { | 987 | { |
979 | bool ret = false; | 988 | bool ret = false; |
980 | HullDesc foundDesc = new HullDesc(); | 989 | HullDesc foundDesc = new HullDesc(); |
981 | foreach (HullDesc hd in Hulls.Values) | 990 | foreach (HullDesc hd in Hulls.Values) |
982 | { | 991 | { |
983 | if (hd.ptr == addr) | 992 | if (hd.shape.ReferenceSame(shape)) |
984 | { | 993 | { |
985 | foundDesc = hd; | 994 | foundDesc = hd; |
986 | ret = true; | 995 | ret = true; |