private PhysX.ConvexMeshGeometry GenerateBasicConvexHull(string primName, PrimitiveBaseShape shape, OpenMetaverse.Vector3 size, float LOD, bool isDynamic) { MeshingResult result = _mesher.CreateMesh(primName, shape, size, LOD, ShapeType.SingleConvex, true); if (result == null) { return(null); } IMesh mesh = result.TriMesh; if (mesh == null) { return(null); } int[] indexes = mesh.getIndexListAsInt(); float[] verts = mesh.getVertexListAsFloat(); if (indexes.Length == 0 || verts.Length == 0) { return(null); } return(GenerateBasicConvexHull(indexes, verts)); }
private MeshingResult ExtractTrimeshFromPrimOrSculpt(string primName, PrimitiveBaseShape primShape, ref OpenMetaverse.Vector3 size, float lod, bool preScale, ulong meshKey) { List <Coord> coords; List <Face> faces; if (primShape.SculptEntry) { //standard sculpt if (!DecodeSculptMesh(primName, primShape, ref size, lod, preScale, out coords, out faces)) { return(null); } } else { if (!GeneratePrimTrimesh(primName, primShape, ref size, lod, preScale, out coords, out faces)) { return(null); } } Mesh mesh = BuildMeshFromCoordsAndFaces(meshKey, coords, faces); TotalProcessedVerts += (ulong)mesh.VertCount; MeshingResult result = new MeshingResult { ResultType = ShapeType.TriMesh, TriMesh = mesh }; return(result); }
public MeshingResult CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, OpenMetaverse.Vector3 size, float lod, ShapeType desiredShape, bool preScale) { Vector3 szvec = new Vector3(size.X, size.Y, size.Z); ulong meshKey = primShape.GetMeshKey(szvec, lod); try { if (primShape.SculptEntry && ((primShape.SculptData == null) || (primShape.SculptData.Length == 0))) { //preload the sculpt/mesh data AssetBase asset = null; Util.ReportIfSlow("[MESHER]: GetAsset for '" + primName + "'", 500, () => { asset = _assetCache.GetAsset(primShape.SculptTexture, AssetRequestInfo.InternalRequest()); }); if (asset == null) { return(null); } primShape.SculptData = asset.Data; } if (primShape.SculptEntry == false || (primShape.SculptEntry == true && (SculptType)primShape.SculptType != SculptType.Mesh)) { MeshingResult result = null; Util.ReportIfSlow("[MESHER]: From prim" + primName + "'", 1000, () => { result = ExtractTrimeshFromPrimOrSculpt(primName, primShape, ref size, lod, preScale, meshKey); }); return(result); } else //mesh { MeshingResult result = null; Util.ReportIfSlow("[MESHER]: From mesh" + primName + "'", 1000, () => { result = ExtractMeshingResultFromMesh(primName, primShape, ref size, lod, preScale, desiredShape, meshKey); }); return(result); } } finally { //we dont need the sculpt data around anymore primShape.SculptData = null; } }
void ThreadedWork() { while (!shouldStop) { if (input.TryDequeue(out order)) { Meshing(); pool.Add(order); order = null; output.Enqueue(result); result = null; } } }
void Meshing() { result = new MeshingResult(); result.position = order.position; result.meshData = new LogicMeshData(); Vector3Int pos = new Vector3Int(); Vector3Int temp = new Vector3Int(); uint block; uint nextBlock; Vector3 DirectionVector; for (int x = 0; x < 32; x++) { pos.x = x; for (int z = 0; z < 32; z++) { pos.z = z; for (int y = 0; y < 32; y++) { pos.y = y; block = 0; nextBlock = 0; block = order.grid[x + 1, y + 1, z + 1]; if (Block.GetId(block) != 0) { for (Direction dir = Direction.North; (int)dir < 6; dir++) { DirectionVector = dir.getVector(); temp.x = pos.x + (int)DirectionVector.x; temp.y = pos.y + (int)DirectionVector.y; temp.z = pos.z + (int)DirectionVector.z; nextBlock = order.grid[temp.x + 1, temp.y + 1, temp.z + 1]; if (Block.GetId(nextBlock) == 0) { result.meshData.AddQuad(pos, dir); } } } } } } }
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.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); } } }