internal bool TryGetCachedShape(ulong meshHash, OpenSim.Framework.PrimitiveBaseShape shape, bool isDynamic, out PhysicsShape phyShape) { ShapeCache cache = FindCorrespondingCache(ShapeDeterminer.FindBestShape(shape, isDynamic)); if (cache != null) { return(cache.TryGetShape(meshHash, out phyShape)); } phyShape = null; return(false); }
public void Execute(MeshingStage meshingStage) { //short circuit null shapes if (Shape.PreferredPhysicsShape == OpenMetaverse.PhysicsShapeType.None) { this.CompletedDelegate(PhysicsShape.Null); return; } ulong meshHash = Shape.GetMeshKey(Size, MeshingStage.SCULPT_MESH_LOD); //check to see if we have this shape in the cache PhysicsShape phyShape; if (meshingStage.TryGetCachedShape(meshHash, Shape, IsDynamic, out phyShape)) { phyShape.AddRef(); //we are done here, call back to caller this.CompletedDelegate(phyShape); return; } int meshingBegan = Environment.TickCount; var bestShape = ShapeDeterminer.FindBestShape(Shape, IsDynamic); //first try to extract serialized shapes if (!TryExtractSerializedShapes(meshingStage, meshHash, bestShape)) { //failure, generate GenerateShapes(meshingStage, meshHash, bestShape); } if (Settings.Instance.InstrumentMeshing) { m_log.InfoFormat("[STATS]: PHYSX_MESHING_TIME,{0},{1}", bestShape, Environment.TickCount - meshingBegan); } }
private List <PhysX.ConvexMeshGeometry> GenerateComplexPhysXShape(ulong meshHash, string primName, PrimitiveBaseShape shape, OpenMetaverse.Vector3 size, float LOD, bool isDynamic) { //create the mesh and do not prescale it. the ACD algorithm can then cache the output hulls and //scale as appropriate MeshingResult result = _mesher.CreateMesh(primName, shape, size, LOD, ShapeType.DecomposedConvexHulls, false); if (result == null) { return(null); } HacdConvexHull[] hulls = null; if (result.ResultType == ShapeType.TriMesh) { IMesh mesh = result.TriMesh; if (mesh == null) { return(null); } //Debugging.VrmlGenerator.SaveToVrmlFile("lastMesh.wrl", mesh.getVertexListAsArray(), mesh.getTriangleList()); switch (ShapeDeterminer.FindBestAcdAlgorithm(shape)) { case ShapeDeterminer.AcdAlgorithm.HACD: hulls = DecomposeWithHACD(shape, LOD, mesh); break; case ShapeDeterminer.AcdAlgorithm.RATCLIFF: hulls = DecomposeWithRatcliff(shape, LOD, mesh); break; default: throw new PhysxSdkException("GenerateComplexPhysXShape(): Specified ACD algorithm does not exist"); } if (hulls == null) { return(null); } } else if (result.ResultType == ShapeType.DecomposedConvexHulls) { hulls = new HacdConvexHull[result.ConvexVerts.Count]; for (int i = 0; i < result.ConvexVerts.Count; i++) { hulls[i] = new HacdConvexHull { Vertices = new PhysX.Math.Vector3[result.ConvexVerts[i].Count] }; for (int j = 0; j < result.ConvexVerts[i].Count; j++) { var vert = result.ConvexVerts[i][j]; hulls[i].Vertices[j] = new PhysX.Math.Vector3(vert.X, vert.Y, vert.Z); } } } else { return(null); } HacdConvexHull.Scale(size, hulls); List <PhysX.ConvexMeshGeometry> ret = new List <PhysX.ConvexMeshGeometry>(); try { foreach (HacdConvexHull hull in hulls) { PhysX.ConvexMeshDesc convexMeshDesc = new PhysX.ConvexMeshDesc() { Flags = PhysX.ConvexFlag.InflateConvex }; if (hull.Indicies == null) { convexMeshDesc.Flags |= PhysX.ConvexFlag.ComputeConvex; } convexMeshDesc.SetPositions(hull.Vertices); if (hull.Indicies != null) { convexMeshDesc.SetTriangles(hull.Indicies); } if (!convexMeshDesc.IsValid()) { throw new PhysxSdkException("GenerateComplexPhysXShape: Convex mesh description is invalid"); } using (MemoryStream ms = new MemoryStream()) { if (!_cooking.CookConvexMesh(convexMeshDesc, ms)) { throw new PhysxSdkException("GenerateComplexPhysXShape: CookConvexMesh() failed"); } ms.Position = 0; PhysX.ConvexMesh convexMesh = _scene.Physics.CreateConvexMesh(ms); PhysX.ConvexMeshGeometry convexShapeGeom = new PhysX.ConvexMeshGeometry(convexMesh); ret.Add(convexShapeGeom); } } } catch (Exception e) { m_log.WarnFormat("[InWorldz.PhysxPhysics] Unable to create convex hullset for shape: {0}", e); result = _mesher.CreateMesh(primName, shape, size, LOD, ShapeType.SingleConvex, true); if (result == null) { m_log.WarnFormat("[InWorldz.PhysxPhysics] Fallback hull generation failed, giving up", e); return(null); } //direct convex available? if (result.ResultType == ShapeType.SingleConvex) { if (!TryGenerateFallbackHullFromHullData(ret, e, result.SingleConvex)) { return(null); } } else if (result.ResultType == ShapeType.TriMesh) { IMesh mesh = result.TriMesh; if (mesh == null) { m_log.WarnFormat("[InWorldz.PhysxPhysics] Fallback hull generation failed, giving up", e); return(null); } if (!TryGenerateFallbackHullFromTrimesh(ret, e, mesh)) { return(null); } } } return(ret); }