public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) { float lod; System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}", prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); BSShapeConvexHull retConvexHull = null; lock (ConvexHulls) { if (ConvexHulls.TryGetValue(newMeshKey, out retConvexHull)) { // The mesh has already been created. Return a new reference to same. retConvexHull.IncrementReference(); } else { retConvexHull = new BSShapeConvexHull(new BulletShape()); BulletShape convexShape = null; // Get a handle to a mesh to build the hull from BSShape baseMesh = BSShapeMesh.GetReference(physicsScene, false /* forceRebuild */, prim); if (baseMesh.physShapeInfo.isNativeShape) { // We get here if the mesh was not creatable. Could be waiting for an asset from the disk. // In the short term, we return the native shape and a later ForceBodyShapeRebuild should // get back to this code with a buildable mesh. // TODO: not sure the temp native shape is freed when the mesh is rebuilt. When does this get freed? convexShape = baseMesh.physShapeInfo; } else { convexShape = physicsScene.PE.BuildConvexHullShapeFromMesh(physicsScene.World, baseMesh.physShapeInfo); convexShape.shapeKey = newMeshKey; ConvexHulls.Add(convexShape.shapeKey, retConvexHull); } // Done with the base mesh baseMesh.Dereference(physicsScene); retConvexHull.physShapeInfo = convexShape; } } return(retConvexHull); }
private void ReportShapeGeom(BSPrim prim) { if (prim != null) { if (prim.PhysShape.HasPhysicalShape) { BSShape physShape = prim.PhysShape; string shapeType = physShape.GetType().ToString(); switch (shapeType) { case "OpenSim.Region.Physics.BulletSPlugin.BSShapeNative": BSShapeNative nShape = physShape as BSShapeNative; prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType); break; case "OpenSim.Region.Physics.BulletSPlugin.BSShapeMesh": BSShapeMesh mShape = physShape as BSShapeMesh; prim.PhysScene.DetailLog("{0}, mesh, shapeInfo={1}", prim.Name, mShape.shapeInfo); break; case "OpenSim.Region.Physics.BulletSPlugin.BSShapeHull": // BSShapeHull hShape = physShape as BSShapeHull; // prim.PhysScene.DetailLog("{0}, hull, shapeInfo={1}", prim.Name, hShape.shapeInfo); break; case "OpenSim.Region.Physics.BulletSPlugin.BSShapeConvexHull": BSShapeConvexHull chShape = physShape as BSShapeConvexHull; prim.PhysScene.DetailLog("{0}, convexHull, shapeInfo={1}", prim.Name, chShape.shapeInfo); break; case "OpenSim.Region.Physics.BulletSPlugin.BSShapeCompound": BSShapeCompound cShape = physShape as BSShapeCompound; prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType); break; default: prim.PhysScene.DetailLog("{0}, type={1}", prim.Name, shapeType); break; } } } }
// Loop through all the known hulls and return the description based on the physical address. public static bool TryGetHullByPtr(BulletShape pShape, out BSShapeConvexHull outHull) { bool ret = false; BSShapeConvexHull foundDesc = null; lock (ConvexHulls) { foreach (BSShapeConvexHull sh in ConvexHulls.Values) { if (sh.physShapeInfo.ReferenceSame(pShape)) { foundDesc = sh; ret = true; break; } } } outHull = foundDesc; return(ret); }
// Sometimes we have a pointer to a collision shape but don't know what type it is. // Figure out type and call the correct dereference routine. // Called at taint-time. private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) { BSShapeMesh meshDesc; if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) { meshDesc.Dereference(physicsScene); } else { BSShapeHull hullDesc; if (BSShapeHull.TryGetHullByPtr(pShape, out hullDesc)) { hullDesc.Dereference(physicsScene); } else { BSShapeConvexHull chullDesc; if (BSShapeConvexHull.TryGetHullByPtr(pShape, out chullDesc)) { chullDesc.Dereference(physicsScene); } else { if (physicsScene.PE.IsCompound(pShape)) { BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); recursiveCompound.Dereference(physicsScene); } else { if (physicsScene.PE.IsNativeShape(pShape)) { BSShapeNative nativeShape = new BSShapeNative(pShape); nativeShape.Dereference(physicsScene); } } } } } }
// return 'true' if the prim's shape was changed. private bool CreateGeomMeshOrHull(BSPhysObject prim, PhysicalDestructionCallback shapeCallback) { bool ret = false; // Note that if it's a native shape, the check for physical/non-physical is not // made. Native shapes work in either case. if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) { // Use a simple, single mesh convex hull shape if the object is simple enough BSShape potentialHull = null; PrimitiveBaseShape pbs = prim.BaseShape; // Use a simple, one section convex shape for prims that are probably convex (no cuts or twists) if (BSParam.ShouldUseSingleConvexHullForPrims && pbs != null && !pbs.SculptEntry && PrimHasNoCuts(pbs) ) { potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim); } // Use the GImpact shape if it is a prim that has some concaveness if (potentialHull == null && BSParam.ShouldUseGImpactShapeForPrims && pbs != null && !pbs.SculptEntry ) { potentialHull = BSShapeGImpact.GetReference(m_physicsScene, false /* forceRebuild */, prim); } // If not any of the simple cases, just make a hull if (potentialHull == null) { 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); prim.PhysShape = potentialHull; ret = true; } else { // The current shape on the prim is the correct one. We don't need the potential reference. potentialHull.Dereference(m_physicsScene); } if (DDetail) { DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1}", prim.LocalID, prim.PhysShape); } } else { // Non-physical objects should be just meshes. 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); 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}", prim.LocalID, prim.PhysShape); } } return(ret); }