28 using System.Collections.Generic;
30 using OMV = OpenMetaverse;
31 using OpenSim.Framework;
32 using OpenSim.Region.PhysicsModules.SharedBase;
34 namespace OpenSim.
Region.PhysicsModule.BulletS
38 #pragma warning disable 414
39 private static string LogHeader =
"[BULLETSIM SHAPE COLLECTION]";
40 #pragma warning restore 414
42 private BSScene m_physicsScene {
get; set; }
44 private Object m_collectionActivityLock =
new Object();
46 private bool DDetail =
false;
50 m_physicsScene = physScene;
78 m_physicsScene.AssertInTaintTime(
"BSShapeCollection.GetBodyAndShape");
83 lock (m_collectionActivityLock)
88 bool newGeom = CreateGeom(forceRebuild, prim, bodyCallback);
93 bool newBody = CreateBody((newGeom || forceRebuild), prim, m_physicsScene.World, bodyCallback);
94 ret = newGeom || newBody;
96 DetailLog(
"{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}",
104 return GetBodyAndShape(forceRebuild, sim, prim, null);
109 private void DereferenceExistingShape(
BSPhysObject prim, PhysicalDestructionCallback shapeCallback)
113 if (shapeCallback != null)
115 prim.PhysShape.Dereference(m_physicsScene);
117 prim.PhysShape =
new BSShapeNull();
128 public const int AvatarShapeCapsule = 0;
129 public const int AvatarShapeCube = 1;
130 public const int AvatarShapeOvoid = 2;
131 public const int AvatarShapeMesh = 3;
132 private bool CreateGeom(
bool forceRebuild,
BSPhysObject prim, PhysicalDestructionCallback shapeCallback)
135 bool haveShape =
false;
136 bool nativeShapePossible =
true;
144 DereferenceExistingShape(prim, shapeCallback);
145 switch (BSParam.AvatarShape)
147 case AvatarShapeCapsule:
148 prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
149 BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE);
153 case AvatarShapeCube:
154 prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
155 BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_CAPSULE);
159 case AvatarShapeOvoid:
161 prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
162 BSPhysicsShapeType.SHAPE_SPHERE, FixedShapeKey.KEY_CAPSULE);
166 case AvatarShapeMesh:
176 && nativeShapePossible
178 && PrimHasNoCuts(pbs)
179 && ( !pbs.SculptEntry || (pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) )
183 OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero;
185 scaleOfExistingShape = m_physicsScene.PE.GetLocalScaling(prim.PhysShape.physShapeInfo);
187 if (DDetail) DetailLog(
"{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}",
199 DereferenceExistingShape(prim, shapeCallback);
200 prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
201 BSPhysicsShapeType.SHAPE_SPHERE, FixedShapeKey.KEY_SPHERE);
204 if (DDetail) DetailLog(
"{0},BSShapeCollection.CreateGeom,sphere,force={1},rebuilt={2},shape={3}",
212 || prim.
Scale != scaleOfExistingShape
216 DereferenceExistingShape(prim, shapeCallback);
217 prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
218 BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
221 if (DDetail) DetailLog(
"{0},BSShapeCollection.CreateGeom,box,force={1},rebuilt={2},shape={3}",
227 if (!haveShape && pbs != null)
229 ret = CreateGeomMeshOrHull(prim, shapeCallback);
238 return pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
239 && pbs.ProfileHollow == 0
240 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
241 && pbs.PathBegin == 0 && pbs.PathEnd == 0
242 && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
243 && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
244 && pbs.PathShearX == 0 && pbs.PathShearY == 0;
248 private bool CreateGeomMeshOrHull(
BSPhysObject prim, PhysicalDestructionCallback shapeCallback)
254 if (prim.
IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects)
261 if (BSParam.ShouldUseSingleConvexHullForPrims
264 && PrimHasNoCuts(pbs)
267 potentialHull = BSShapeConvexHull.GetReference(m_physicsScene,
false , prim);
270 if (potentialHull == null
271 && BSParam.ShouldUseGImpactShapeForPrims
276 potentialHull = BSShapeGImpact.GetReference(m_physicsScene,
false , prim);
279 if (potentialHull == null)
281 potentialHull = BSShapeHull.GetReference(m_physicsScene,
false , prim);
289 DereferenceExistingShape(prim, shapeCallback);
290 prim.PhysShape = potentialHull;
296 potentialHull.Dereference(m_physicsScene);
298 if (DDetail) DetailLog(
"{0},BSShapeCollection.CreateGeom,hull,shape={1}", prim.
LocalID, prim.
PhysShape);
303 BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene,
false , prim);
309 DereferenceExistingShape(prim, shapeCallback);
310 prim.PhysShape = potentialMesh;
316 potentialMesh.Dereference(m_physicsScene);
318 if (DDetail) DetailLog(
"{0},BSShapeCollection.CreateGeom,mesh,shape={1}", prim.
LocalID, prim.
PhysShape);
326 private void ReferenceBody(BulletBody body)
328 lock (m_collectionActivityLock)
330 if (DDetail) DetailLog(
"{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body);
331 if (!m_physicsScene.PE.IsInWorld(m_physicsScene.World, body))
333 m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, body);
334 if (DDetail) DetailLog(
"{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body);
347 m_physicsScene.AssertInTaintTime(
"BSShapeCollection.DereferenceBody");
349 lock (m_collectionActivityLock)
351 if (DDetail) DetailLog(
"{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1}", body.
ID, body);
353 if (bodyCallback != null)
354 bodyCallback(body, null);
357 m_physicsScene.PE.RemoveObjectFromWorld(m_physicsScene.World, body);
360 m_physicsScene.PE.SetCollisionShape(m_physicsScene.World, body, null);
362 m_physicsScene.PE.DestroyObject(m_physicsScene.World, body);
370 private bool CreateBody(
bool forceRebuild,
BSPhysObject prim,
BulletWorld sim, PhysicalDestructionCallback bodyCallback)
375 bool mustRebuild = !prim.PhysBody.HasPhysicalBody;
387 if (DDetail) DetailLog(
"{0},BSShapeCollection.CreateBody,forceRebuildBecauseChangingBodyType,bodyType={1}", prim.
LocalID, bodyType);
391 if (mustRebuild || forceRebuild)
394 DereferenceBody(prim.
PhysBody, bodyCallback);
399 aBody = m_physicsScene.PE.CreateBodyFromShape(sim, prim.PhysShape.physShapeInfo, prim.LocalID, prim.RawPosition, prim.RawOrientation);
400 if (DDetail) DetailLog(
"{0},BSShapeCollection.CreateBody,rigid,body={1}", prim.
LocalID, aBody);
404 aBody = m_physicsScene.PE.CreateGhostFromShape(sim, prim.PhysShape.physShapeInfo, prim.LocalID, prim.RawPosition, prim.RawOrientation);
405 if (DDetail) DetailLog(
"{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.
LocalID, aBody);
408 ReferenceBody(aBody);
410 prim.PhysBody = aBody;
418 private void DetailLog(
string msg, params Object[] args)
420 if (m_physicsScene.PhysicsLogging.Enabled)
421 m_physicsScene.DetailLog(msg, args);
static bool PrimHasNoCuts(PrimitiveBaseShape pbs)
bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, PhysicalDestructionCallback bodyCallback)
BulletShape physShapeInfo
BSShapeCollection(BSScene physScene)
virtual OMV.Vector3 Scale
bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim)
virtual bool HasPhysicalShape
virtual BSPhysicsShapeType ShapeType
ProfileShape ProfileShape
virtual bool HasPhysicalBody
void DereferenceBody(BulletBody body, PhysicalDestructionCallback bodyCallback)
BSPhysicsShapeType shapeType