private bool TryGenerateFallbackHullFromTrimesh(List <PhysX.ConvexMeshGeometry> ret, Exception e, IMesh mesh) { int[] indexes = mesh.getIndexListAsInt(); float[] verts = mesh.getVertexListAsFloat(); // fall back to basic convex hull PhysX.ConvexMeshGeometry fallbackHull = this.GenerateBasicConvexHull(indexes, verts); if (fallbackHull != null) { ret.Add(fallbackHull); } else { m_log.WarnFormat("[InWorldz.PhysxPhysics] Fallback hull generation failed, giving up", e); return(false); } return(true); }
private bool TryGenerateFallbackHullFromHullData(List <PhysX.ConvexMeshGeometry> ret, Exception e, List <OpenMetaverse.Vector3> vertList) { PhysX.Math.Vector3[] verts = new PhysX.Math.Vector3[vertList.Count]; for (int i = 0; i < vertList.Count; i++) { verts[i] = PhysUtil.OmvVectorToPhysx(vertList[i]); } // fall back to basic convex hull PhysX.ConvexMeshGeometry fallbackHull = this.GenerateBasicConvexHull(null, verts); if (fallbackHull != null) { ret.Add(fallbackHull); } else { m_log.WarnFormat("[InWorldz.PhysxPhysics] Fallback hull generation failed, giving up", e); return(false); } return(true); }
private void GenerateSingleConvexAndComplete(MeshingStage meshingStage, ulong meshHash) { PhysicsShape phyShape; //we need to mesh this object into convex hulls appropriate for dynamic objects PhysX.ConvexMeshGeometry convex = meshingStage.GenerateBasicConvexHull(PrimName, Shape, Size, MeshingStage.SCULPT_MESH_LOD, IsDynamic); if (convex == null) { //meshing or one of its prereq steps failed, generate a bounding box PhysX.Geometry geom = meshingStage.GeneratePhysXBoxShape(Shape); //basic shapes are not cached phyShape = new PhysicsShape(geom, ShapeType.PrimitiveBox, meshHash); } else { phyShape = CreatePhysicsShapeFromSingleConvexAndCache(meshingStage, meshHash, convex); } //we are done here, call back to caller this.CompletedDelegate(phyShape); }
private PhysX.ConvexMeshGeometry GenerateBasicConvexHull(int[] indexes, PhysX.Math.Vector3[] verts) { try { PhysX.ConvexMeshDesc convexMeshDesc = new PhysX.ConvexMeshDesc() { Flags = PhysX.ConvexFlag.InflateConvex | PhysX.ConvexFlag.ComputeConvex }; convexMeshDesc.SetPositions(verts); if (indexes != null) { convexMeshDesc.SetTriangles(indexes); } using (MemoryStream ms = new MemoryStream()) { if (!_cooking.CookConvexMesh(convexMeshDesc, ms)) { throw new PhysxSdkException("GenerateBasicConvexHull: CookConvexMesh() failed"); } ms.Position = 0; PhysX.ConvexMesh convexMesh = _scene.Physics.CreateConvexMesh(ms); PhysX.ConvexMeshGeometry convexShapeGeom = new PhysX.ConvexMeshGeometry(convexMesh); return(convexShapeGeom); } } catch (Exception e) { m_log.WarnFormat("[InWorldz.PhysxPhysics] Unable to fallback to convex hull for shape: {0}", e); } return(null); }
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); }
private PhysX.ConvexMeshGeometry GenerateBasicConvexHull(int[] indexes, PhysX.Math.Vector3[] verts) { try { PhysX.ConvexMeshDesc convexMeshDesc = new PhysX.ConvexMeshDesc() { Flags = PhysX.ConvexFlag.InflateConvex | PhysX.ConvexFlag.ComputeConvex }; convexMeshDesc.SetPositions(verts); if (indexes != null) convexMeshDesc.SetTriangles(indexes); using (MemoryStream ms = new MemoryStream()) { if (!_cooking.CookConvexMesh(convexMeshDesc, ms)) { throw new PhysxSdkException("GenerateBasicConvexHull: CookConvexMesh() failed"); } ms.Position = 0; PhysX.ConvexMesh convexMesh = _scene.Physics.CreateConvexMesh(ms); PhysX.ConvexMeshGeometry convexShapeGeom = new PhysX.ConvexMeshGeometry(convexMesh); return convexShapeGeom; } } catch (Exception e) { m_log.WarnFormat("[InWorldz.PhysxPhysics] Unable to fallback to convex hull for shape: {0}", e); } return null; }
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; }
private static PhysicsShape CreatePhysicsShapeFromSingleConvexAndCache(MeshingStage meshingStage, ulong meshHash, PhysX.ConvexMeshGeometry convex) { PhysicsShape phyShape; phyShape = new PhysicsShape(new List <PhysX.ConvexMeshGeometry> { convex }, meshHash, true); phyShape.AddRef(); //complex shapes are cached meshingStage.CacheShape(meshHash, phyShape, ShapeType.SingleConvex); return(phyShape); }