예제 #1
0
        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));
        }
예제 #2
0
        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);
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
    void ThreadedWork()
    {
        while (!shouldStop)
        {
            if (input.TryDequeue(out order))
            {
                Meshing();

                pool.Add(order);
                order = null;

                output.Enqueue(result);
                result = null;
            }
        }
    }
예제 #5
0
    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);
                            }
                        }
                    }
                }
            }
        }
    }
예제 #6
0
        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);
        }
예제 #7
0
        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);
                }
            }
        }