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 PhysX.ConvexMeshGeometry GenerateBasicConvexHull(int[] indexes, float[] verts) { try { PhysX.ConvexMeshDesc convexMeshDesc = new PhysX.ConvexMeshDesc() { Flags = PhysX.ConvexFlag.InflateConvex | PhysX.ConvexFlag.ComputeConvex }; convexMeshDesc.SetPositions(PhysUtil.FloatArrayToVectorArray(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); }
public void FillVerticesFromRaw() { Vertices = PhysUtil.FloatArrayToVectorArray(_rawVerts); _rawVerts = null; }
public static HacdConvexHull[] DecomposeToConvexHulls(ulong meshHash, bool useCache, HacdPreset preset, float[] verts, int[] indicies) { if (verts.Length % 3 != 0) { throw new InvalidOperationException("Number of verticies must be divisble by 3"); } if (indicies.Length % 3 != 0) { throw new InvalidOperationException("Number of indicies must be divisble by 3"); } if (IsCacheCandidate(useCache, verts.Length)) { //try cache try { HacdConvexHull[] cachedHulls; if (MeshingStage.HullCache.TryGetHulls(meshHash, out cachedHulls)) { return(cachedHulls); } } catch (Exception e) { m_log.ErrorFormat("[InWorldz.PhysX.HACD] Failure retrieving HACD hulls from cache: {0}: {1}", e, e.Message); } } IntPtr session = Decompose(verts, indicies, verts.Length, indicies.Length, preset.DEFAULT_CC_CONNECT_DIST, preset.MIN_HULL_COUNT, preset.CONCAVITY, preset.TARGET_TRIANGLES_IN_FULL_MESH, preset.MAX_VERTS_PER_HULL, true, true, preset.VOLUME_WEIGHT, preset.SMALL_CLUSTER_THRESHOLD); if (session == IntPtr.Zero) { return(null); } HacdConvexHull[] retHulls; try { int hullCount = GetConvexHullCount(session); retHulls = new HacdConvexHull[hullCount]; for (int hullNum = 0; hullNum < hullCount; ++hullNum) { int vertexCount = GetVertexCount(session, hullNum); int indexCount = GetIndexCount(session, hullNum); float[] hullVerts = new float[vertexCount]; int[] hullIndexes = new int[indexCount]; if (!GetConvexVertsAndIndexes(session, hullNum, hullVerts, hullIndexes)) { return(null); } HacdConvexHull hull = new HacdConvexHull { Vertices = PhysUtil.FloatArrayToVectorArray(hullVerts), _rawVerts = IsCacheCandidate(useCache, verts.Length) ? hullVerts : null, Indicies = hullIndexes }; retHulls[hullNum] = hull; } //store in cache for later if (IsCacheCandidate(useCache, verts.Length)) { try { MeshingStage.HullCache.CacheHulls(meshHash, retHulls); } catch (Exception e) { m_log.ErrorFormat("[InWorldz.PhysX.HACD] Failure storing HACD results in cache: {0}: {1}", e, e.Message); } } return(retHulls); } finally { FreeSession(session); } }
private PhysX.TriangleMeshGeometry GeneratePhysXTrimeshShape(string primName, PrimitiveBaseShape shape, OpenMetaverse.Vector3 size, float LOD, bool isDynamic) { MeshingResult result = _mesher.CreateMesh(primName, shape, size, LOD, ShapeType.TriMesh, true); if (result == null) { return(null); } IMesh mesh = result.TriMesh; if (mesh == null) { return(null); } int[] indexes = mesh.getIndexListAsInt(); PhysX.Math.Vector3[] verts = PhysUtil.OmvVectorArrayToPhysx(mesh.getVertexListAsArray()); mesh.ReleaseSourceMeshData(); PhysX.TriangleMeshDesc desc = new PhysX.TriangleMeshDesc { Points = verts, Triangles = indexes, }; if (!desc.IsValid()) { m_log.Warn("[InWorldz.PhysxPhysics] Unable to create trimesh for shape. Invalid description."); return(null); } using (MemoryStream ms = new MemoryStream()) { try { if (!_cooking.CookTriangleMesh(desc, ms)) { m_log.Warn("[InWorldz.PhysxPhysics] Unable to create trimesh for shape."); return(null); } } catch (Exception e) { m_log.Warn("[InWorldz.PhysxPhysics] Unable to create trimesh for shape: {0}", e); return(null); } ms.Position = 0; try { PhysX.TriangleMesh triMesh = _scene.Physics.CreateTriangleMesh(ms); //m_log.DebugFormat("Trimesh Created: {0} {1}", triMesh.GetHashCode(), primName); PhysX.TriangleMeshGeometry triGeom = new PhysX.TriangleMeshGeometry(triMesh); return(triGeom); } catch (Exception e) { m_log.WarnFormat("[InWorldz.PhysxPhysics] Unable to create trimesh for shape: {0}", e); return(null); } } }