示例#1
0
        /// <summary>
        /// Generates a basic mesh structure from a primitive
        /// A 'SimpleMesh' is just the prim's overall shape with no material information.
        /// </summary>
        /// <param name="prim">Primitive to generate the mesh from</param>
        /// <param name="lod">Level of detail to generate the mesh at</param>
        /// <returns>The generated mesh or null on failure</returns>
        public OMVR.SimpleMesh GenerateSimpleMesh(OMV.Primitive prim, OMVR.DetailLevel lod)
        {
            LibreMetaverse.PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, false);
            if (newPrim == null)
            {
                return(null);
            }

            SimpleMesh mesh = new SimpleMesh
            {
                Path     = new Path(),
                Prim     = prim,
                Profile  = new Profile(),
                Vertices = new List <Vertex>(newPrim.coords.Count)
            };

            foreach (Coord c in newPrim.coords)
            {
                mesh.Vertices.Add(new Vertex {
                    Position = new Vector3(c.X, c.Y, c.Z)
                });
            }

            mesh.Indices = new List <ushort>(newPrim.faces.Count * 3);
            foreach (LibreMetaverse.PrimMesher.Face face in newPrim.faces)
            {
                mesh.Indices.Add((ushort)face.v1);
                mesh.Indices.Add((ushort)face.v2);
                mesh.Indices.Add((ushort)face.v3);
            }

            return(mesh);
        }
        /// <summary>
        /// Generates a basic mesh structure from a primitive
        /// </summary>
        /// <param name="prim">Primitive to generate the mesh from</param>
        /// <param name="lod">Level of detail to generate the mesh at</param>
        /// <returns>The generated mesh or null on failure</returns>
        public OMVR.SimpleMesh GenerateSimpleMesh(OMV.Primitive prim, OMVR.DetailLevel lod)
        {
            PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, false);
            if (newPrim == null)
            {
                return(null);
            }

            SimpleMesh mesh = new SimpleMesh();

            mesh.Path     = new Path();
            mesh.Prim     = prim;
            mesh.Profile  = new Profile();
            mesh.Vertices = new List <Vertex>(newPrim.coords.Count);
            for (int i = 0; i < newPrim.coords.Count; i++)
            {
                PrimMesher.Coord c = newPrim.coords[i];
                mesh.Vertices.Add(new Vertex {
                    Position = new Vector3(c.X, c.Y, c.Z)
                });
            }

            mesh.Indices = new List <ushort>(newPrim.faces.Count * 3);
            for (int i = 0; i < newPrim.faces.Count; i++)
            {
                PrimMesher.Face face = newPrim.faces[i];
                mesh.Indices.Add((ushort)face.v1);
                mesh.Indices.Add((ushort)face.v2);
                mesh.Indices.Add((ushort)face.v3);
            }

            return(mesh);
        }
        /// <summary>
        /// Create a faceted mesh from prim shape parameters.
        /// Generates a a series of faces, each face containing a mesh and
        /// material metadata.
        /// A prim will turn into multiple faces with each being independent
        /// meshes and each having different material information.
        /// </summary>
        /// <param name="prim">Primitive to generate the mesh from</param>
        /// <param name="lod">Level of detail to generate the mesh at</param>
        /// <returns>The generated mesh</returns >
        public OMVR.FacetedMesh GenerateFacetedMesh(OMV.Primitive prim, OMVR.DetailLevel lod)
        {
            bool isSphere = ((OMV.ProfileCurve)(prim.PrimData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle);

            PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, true);
            if (newPrim == null)
            {
                return(null);
            }

            // copy the vertex information into OMVR.IRendering structures
            OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh();
            omvrmesh.Faces             = new List <OMVR.Face>();
            omvrmesh.Prim              = prim;
            omvrmesh.Profile           = new OMVR.Profile();
            omvrmesh.Profile.Faces     = new List <OMVR.ProfileFace>();
            omvrmesh.Profile.Positions = new List <OMV.Vector3>();
            omvrmesh.Path              = new OMVR.Path();
            omvrmesh.Path.Points       = new List <OMVR.PathPoint>();
            var indexer = newPrim.GetVertexIndexer();

            for (int i = 0; i < indexer.numPrimFaces; i++)
            {
                OMVR.Face oface = new OMVR.Face();
                oface.Vertices    = new List <OMVR.Vertex>();
                oface.Indices     = new List <ushort>();
                oface.TextureFace = prim.Textures.GetFace((uint)i);

                for (int j = 0; j < indexer.viewerVertices[i].Count; j++)
                {
                    var vert = new OMVR.Vertex();
                    var m    = indexer.viewerVertices[i][j];
                    vert.Position = new Vector3(m.v.X, m.v.Y, m.v.Z);
                    vert.Normal   = new Vector3(m.n.X, m.n.Y, m.n.Z);
                    vert.TexCoord = new OMV.Vector2(m.uv.U, 1.0f - m.uv.V);
                    oface.Vertices.Add(vert);
                }

                for (int j = 0; j < indexer.viewerPolygons[i].Count; j++)
                {
                    var p = indexer.viewerPolygons[i][j];
                    // Skip "degenerate faces" where the same vertex appears twice in the same tri
                    if (p.v1 == p.v2 || p.v1 == p.v2 || p.v2 == p.v3)
                    {
                        continue;
                    }
                    oface.Indices.Add((ushort)p.v1);
                    oface.Indices.Add((ushort)p.v2);
                    oface.Indices.Add((ushort)p.v3);
                }

                omvrmesh.Faces.Add(oface);
            }

            return(omvrmesh);
        }
示例#4
0
        // A version of GenerateFacetedMeshMesh that takes LOD spec so it's similar in calling convention of
        //    the other Generate* methods.
        public OMVR.FacetedMesh GenerateFacetedMeshMesh(OMV.Primitive prim, byte[] meshData, OMVR.DetailLevel lod)
        {
            OMVR.FacetedMesh ret      = null;
            string           partName = null;

            switch (lod)
            {
            case OMVR.DetailLevel.Highest:
                partName = "high_lod"; break;

            case OMVR.DetailLevel.High:
                partName = "medium_lod"; break;

            case OMVR.DetailLevel.Medium:
                partName = "low_lod"; break;

            case OMVR.DetailLevel.Low:
                partName = "lowest_lod"; break;
            }
            if (partName != null)
            {
                OSDMap meshParts = UnpackMesh(meshData);
                if (meshParts != null)
                {
                    if (meshParts.ContainsKey(partName))
                    {
                        byte[] meshBytes = meshParts[partName];
                        if (meshBytes != null)
                        {
                            ret = MeshSubMeshAsFacetedMesh(prim, meshBytes);
                        }
                    }
                }
            }
            return(ret);
        }
        /// <summary>
        /// Generates a basic mesh structure from a sculpted primitive
        /// </summary>
        /// <param name="prim">Sculpted primitive to generate the mesh from</param>
        /// <param name="sculptTexture">Sculpt texture</param>
        /// <param name="lod">Level of detail to generate the mesh at</param>
        /// <returns>The generated mesh or null on failure</returns>
        public OMVR.SimpleMesh GenerateSimpleSculptMesh(OMV.Primitive prim, System.Drawing.Bitmap sculptTexture, OMVR.DetailLevel lod)
        {
            OMVR.FacetedMesh faceted = GenerateFacetedSculptMesh(prim, sculptTexture, lod);

            if (faceted != null && faceted.Faces.Count == 1)
            {
                Face face = faceted.Faces[0];

                SimpleMesh mesh = new SimpleMesh();
                mesh.Indices  = face.Indices;
                mesh.Vertices = face.Vertices;
                mesh.Path     = faceted.Path;
                mesh.Prim     = prim;
                mesh.Profile  = faceted.Profile;
                mesh.Vertices = face.Vertices;

                return(mesh);
            }

            return(null);
        }
        /// <summary>
        /// Create a sculpty faceted mesh. The actual scuplt texture is fetched and passed to this
        /// routine since all the context for finding teh texture is elsewhere.
        /// </summary>
        /// <returns>The faceted mesh or null if can't do it</returns>
        public OMVR.FacetedMesh GenerateFacetedSculptMesh(OMV.Primitive prim, System.Drawing.Bitmap scupltTexture, OMVR.DetailLevel lod)
        {
            PrimMesher.SculptMesh.SculptType smSculptType;
            switch (prim.Sculpt.Type)
            {
            case OpenMetaverse.SculptType.Cylinder:
                smSculptType = PrimMesher.SculptMesh.SculptType.cylinder;
                break;

            case OpenMetaverse.SculptType.Plane:
                smSculptType = PrimMesher.SculptMesh.SculptType.plane;
                break;

            case OpenMetaverse.SculptType.Sphere:
                smSculptType = PrimMesher.SculptMesh.SculptType.sphere;
                break;

            case OpenMetaverse.SculptType.Torus:
                smSculptType = PrimMesher.SculptMesh.SculptType.torus;
                break;

            default:
                smSculptType = PrimMesher.SculptMesh.SculptType.plane;
                break;
            }
            // The lod for sculpties is the resolution of the texture passed.
            // The first guess is 1:1 then lower resolutions after that
            // int mesherLod = (int)Math.Sqrt(scupltTexture.Width * scupltTexture.Height);
            int mesherLod = 32; // number used in Idealist viewer

            switch (lod)
            {
            case OMVR.DetailLevel.Highest:
                break;

            case OMVR.DetailLevel.High:
                break;

            case OMVR.DetailLevel.Medium:
                mesherLod /= 2;
                break;

            case OMVR.DetailLevel.Low:
                mesherLod /= 4;
                break;
            }
            PrimMesher.SculptMesh newMesh =
                new PrimMesher.SculptMesh(scupltTexture, smSculptType, mesherLod, true, prim.Sculpt.Mirror, prim.Sculpt.Invert);

            int numPrimFaces = 1;       // a scuplty has only one face

            // copy the vertex information into OMVR.IRendering structures
            OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh();
            omvrmesh.Faces             = new List <OMVR.Face>();
            omvrmesh.Prim              = prim;
            omvrmesh.Profile           = new OMVR.Profile();
            omvrmesh.Profile.Faces     = new List <OMVR.ProfileFace>();
            omvrmesh.Profile.Positions = new List <OMV.Vector3>();
            omvrmesh.Path              = new OMVR.Path();
            omvrmesh.Path.Points       = new List <OMVR.PathPoint>();

            Dictionary <OMVR.Vertex, int> vertexAccount = new Dictionary <OMVR.Vertex, int>();


            for (int ii = 0; ii < numPrimFaces; ii++)
            {
                vertexAccount.Clear();
                OMVR.Face oface = new OMVR.Face();
                oface.Vertices    = new List <OMVR.Vertex>();
                oface.Indices     = new List <ushort>();
                oface.TextureFace = prim.Textures.GetFace((uint)ii);
                int         faceVertices = newMesh.coords.Count;
                OMVR.Vertex vert;

                for (int j = 0; j < faceVertices; j++)
                {
                    vert          = new OMVR.Vertex();
                    vert.Position = new Vector3(newMesh.coords[j].X, newMesh.coords[j].Y, newMesh.coords[j].Z);
                    vert.Normal   = new Vector3(newMesh.normals[j].X, newMesh.normals[j].Y, newMesh.normals[j].Z);
                    vert.TexCoord = new Vector2(newMesh.uvs[j].U, newMesh.uvs[j].V);
                    oface.Vertices.Add(vert);
                }

                for (int j = 0; j < newMesh.faces.Count; j++)
                {
                    oface.Indices.Add((ushort)newMesh.faces[j].v1);
                    oface.Indices.Add((ushort)newMesh.faces[j].v2);
                    oface.Indices.Add((ushort)newMesh.faces[j].v3);
                }

                if (faceVertices > 0)
                {
                    oface.TextureFace = prim.Textures.FaceTextures[ii];
                    if (oface.TextureFace == null)
                    {
                        oface.TextureFace = prim.Textures.DefaultTexture;
                    }
                    oface.ID = ii;
                    omvrmesh.Faces.Add(oface);
                }
            }

            return(omvrmesh);
        }
        /// <summary>
        /// Generates a a series of faces, each face containing a mesh and
        /// metadata
        /// </summary>
        /// <param name="prim">Primitive to generate the mesh from</param>
        /// <param name="lod">Level of detail to generate the mesh at</param>
        /// <returns>The generated mesh</returns >
        public OMVR.FacetedMesh GenerateFacetedMesh(OMV.Primitive prim, OMVR.DetailLevel lod)
        {
            bool isSphere = ((OMV.ProfileCurve)(prim.PrimData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle);

            PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, true);
            if (newPrim == null)
            {
                return(null);
            }

            int numViewerFaces = newPrim.viewerFaces.Count;
            int numPrimFaces   = newPrim.numPrimFaces;

            for (uint i = 0; i < numViewerFaces; i++)
            {
                PrimMesher.ViewerFace vf = newPrim.viewerFaces[(int)i];

                if (isSphere)
                {
                    vf.uv1.U = (vf.uv1.U - 0.5f) * 2.0f;
                    vf.uv2.U = (vf.uv2.U - 0.5f) * 2.0f;
                    vf.uv3.U = (vf.uv3.U - 0.5f) * 2.0f;
                }
            }

            // copy the vertex information into OMVR.IRendering structures
            OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh();
            omvrmesh.Faces             = new List <OMVR.Face>();
            omvrmesh.Prim              = prim;
            omvrmesh.Profile           = new OMVR.Profile();
            omvrmesh.Profile.Faces     = new List <OMVR.ProfileFace>();
            omvrmesh.Profile.Positions = new List <OMV.Vector3>();
            omvrmesh.Path              = new OMVR.Path();
            omvrmesh.Path.Points       = new List <OMVR.PathPoint>();

            Dictionary <OMV.Vector3, int> vertexAccount = new Dictionary <OMV.Vector3, int>();

            for (int ii = 0; ii < numPrimFaces; ii++)
            {
                OMVR.Face oface = new OMVR.Face();
                oface.Vertices    = new List <OMVR.Vertex>();
                oface.Indices     = new List <ushort>();
                oface.TextureFace = prim.Textures.GetFace((uint)ii);
                int faceVertices = 0;
                vertexAccount.Clear();
                OMV.Vector3 pos;
                int         indx;
                OMVR.Vertex vert;
                foreach (PrimMesher.ViewerFace vface in newPrim.viewerFaces)
                {
                    if (vface.primFaceNumber == ii)
                    {
                        faceVertices++;
                        pos = new OMV.Vector3(vface.v1.X, vface.v1.Y, vface.v1.Z);
                        if (vertexAccount.ContainsKey(pos))
                        {
                            // we aleady have this vertex in the list. Just point the index at it
                            oface.Indices.Add((ushort)vertexAccount[pos]);
                        }
                        else
                        {
                            // the vertex is not in the list. Add it and the new index.
                            vert          = new OMVR.Vertex();
                            vert.Position = pos;
                            vert.TexCoord = new OMV.Vector2(vface.uv1.U, 1.0f - vface.uv1.V);
                            vert.Normal   = new OMV.Vector3(vface.n1.X, vface.n1.Y, vface.n1.Z);
                            oface.Vertices.Add(vert);
                            indx = oface.Vertices.Count - 1;
                            vertexAccount.Add(pos, indx);
                            oface.Indices.Add((ushort)indx);
                        }

                        pos = new OMV.Vector3(vface.v2.X, vface.v2.Y, vface.v2.Z);
                        if (vertexAccount.ContainsKey(pos))
                        {
                            oface.Indices.Add((ushort)vertexAccount[pos]);
                        }
                        else
                        {
                            vert          = new OMVR.Vertex();
                            vert.Position = pos;
                            vert.TexCoord = new OMV.Vector2(vface.uv2.U, 1.0f - vface.uv2.V);
                            vert.Normal   = new OMV.Vector3(vface.n2.X, vface.n2.Y, vface.n2.Z);
                            oface.Vertices.Add(vert);
                            indx = oface.Vertices.Count - 1;
                            vertexAccount.Add(pos, indx);
                            oface.Indices.Add((ushort)indx);
                        }

                        pos = new OMV.Vector3(vface.v3.X, vface.v3.Y, vface.v3.Z);
                        if (vertexAccount.ContainsKey(pos))
                        {
                            oface.Indices.Add((ushort)vertexAccount[pos]);
                        }
                        else
                        {
                            vert          = new OMVR.Vertex();
                            vert.Position = pos;
                            vert.TexCoord = new OMV.Vector2(vface.uv3.U, 1.0f - vface.uv3.V);
                            vert.Normal   = new OMV.Vector3(vface.n3.X, vface.n3.Y, vface.n3.Z);
                            oface.Vertices.Add(vert);
                            indx = oface.Vertices.Count - 1;
                            vertexAccount.Add(pos, indx);
                            oface.Indices.Add((ushort)indx);
                        }
                    }
                }
                if (faceVertices > 0)
                {
                    oface.TextureFace = prim.Textures.FaceTextures[ii];
                    if (oface.TextureFace == null)
                    {
                        oface.TextureFace = prim.Textures.DefaultTexture;
                    }
                    oface.ID = ii;
                    omvrmesh.Faces.Add(oface);
                }
            }

            return(omvrmesh);
        }
        private PrimMesher.PrimMesh GeneratePrimMesh(OMV.Primitive prim, OMVR.DetailLevel lod, bool viewerMode)
        {
            OMV.Primitive.ConstructionData primData = prim.PrimData;
            int sides       = 4;
            int hollowsides = 4;

            float profileBegin = primData.ProfileBegin;
            float profileEnd   = primData.ProfileEnd;

            if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.Circle)
            {
                switch (lod)
                {
                case OMVR.DetailLevel.Low:
                    sides = 6;
                    break;

                case OMVR.DetailLevel.Medium:
                    sides = 12;
                    break;

                default:
                    sides = 24;
                    break;
                }
            }
            else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.EqualTriangle)
            {
                sides = 3;
            }
            else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle)
            {
                // half circle, prim is a sphere
                switch (lod)
                {
                case OMVR.DetailLevel.Low:
                    sides = 6;
                    break;

                case OMVR.DetailLevel.Medium:
                    sides = 12;
                    break;

                default:
                    sides = 24;
                    break;
                }
                profileBegin = 0.5f * profileBegin + 0.5f;
                profileEnd   = 0.5f * profileEnd + 0.5f;
            }

            if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Same)
            {
                hollowsides = sides;
            }
            else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Circle)
            {
                switch (lod)
                {
                case OMVR.DetailLevel.Low:
                    hollowsides = 6;
                    break;

                case OMVR.DetailLevel.Medium:
                    hollowsides = 12;
                    break;

                default:
                    hollowsides = 24;
                    break;
                }
            }
            else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Triangle)
            {
                hollowsides = 3;
            }

            PrimMesher.PrimMesh newPrim = new PrimMesher.PrimMesh(sides, profileBegin, profileEnd, (float)primData.ProfileHollow, hollowsides);
            newPrim.viewerMode   = viewerMode;
            newPrim.holeSizeX    = primData.PathScaleX;
            newPrim.holeSizeY    = primData.PathScaleY;
            newPrim.pathCutBegin = primData.PathBegin;
            newPrim.pathCutEnd   = primData.PathEnd;
            newPrim.topShearX    = primData.PathShearX;
            newPrim.topShearY    = primData.PathShearY;
            newPrim.radius       = primData.PathRadiusOffset;
            newPrim.revolutions  = primData.PathRevolutions;
            newPrim.skew         = primData.PathSkew;
            switch (lod)
            {
            case OMVR.DetailLevel.Low:
                newPrim.stepsPerRevolution = 6;
                break;

            case OMVR.DetailLevel.Medium:
                newPrim.stepsPerRevolution = 12;
                break;

            default:
                newPrim.stepsPerRevolution = 24;
                break;
            }

            if ((primData.PathCurve == OMV.PathCurve.Line) || (primData.PathCurve == OMV.PathCurve.Flexible))
            {
                newPrim.taperX     = 1.0f - primData.PathScaleX;
                newPrim.taperY     = 1.0f - primData.PathScaleY;
                newPrim.twistBegin = (int)(180 * primData.PathTwistBegin);
                newPrim.twistEnd   = (int)(180 * primData.PathTwist);
                newPrim.ExtrudeLinear();
            }
            else
            {
                newPrim.taperX     = primData.PathTaperX;
                newPrim.taperY     = primData.PathTaperY;
                newPrim.twistBegin = (int)(360 * primData.PathTwistBegin);
                newPrim.twistEnd   = (int)(360 * primData.PathTwist);
                newPrim.ExtrudeCircular();
            }

            return(newPrim);
        }
        /// <summary>
        /// Create a sculpty faceted mesh. The actual scuplt texture is fetched and passed to this
        /// routine since all the context for finding teh texture is elsewhere.
        /// </summary>
        /// <param name="scupltTexture"></param>
        /// <param name="prim"></param>
        /// <param name="lod"></param>
        /// <returns>the faceted mesh or null if can't do it</returns>
        public OMVR.FacetedMesh GenerateSculptMesh(System.Drawing.Bitmap scupltTexture,
                                                   OMV.Primitive prim, OMVR.DetailLevel lod)
        {
            try {
                byte sculptType = (byte)prim.Sculpt.Type;
                bool mirror     = ((sculptType & 128) != 0);
                bool invert     = ((sculptType & 64) != 0);
                // bool mirror = false; // TODO: libomv doesn't support these and letting them flop around causes problems
                // bool invert = false;
                OMV.SculptType omSculptType = (OMV.SculptType)(sculptType & 0x07);

                PrimMesher.SculptMesh.SculptType smSculptType;
                switch (omSculptType)
                {
                case OpenMetaverse.SculptType.Cylinder:
                    smSculptType = PrimMesher.SculptMesh.SculptType.cylinder;
                    break;

                case OpenMetaverse.SculptType.Plane:
                    smSculptType = PrimMesher.SculptMesh.SculptType.plane;
                    break;

                case OpenMetaverse.SculptType.Sphere:
                    smSculptType = PrimMesher.SculptMesh.SculptType.sphere;
                    break;

                case OpenMetaverse.SculptType.Torus:
                    smSculptType = PrimMesher.SculptMesh.SculptType.torus;
                    break;

                default:
                    smSculptType = PrimMesher.SculptMesh.SculptType.plane;
                    break;
                }
                // The lod for sculpties is the resolution of the texture passed.
                // The first guess is 1:1 then lower resolutions after that
                // int mesherLod = (int)Math.Sqrt(scupltTexture.Width * scupltTexture.Height);
                int mesherLod = 32; // number used in Idealist viewer
                switch (lod)
                {
                case OMVR.DetailLevel.Highest:
                    break;

                case OMVR.DetailLevel.High:
                    break;

                case OMVR.DetailLevel.Medium:
                    mesherLod /= 2;
                    break;

                case OMVR.DetailLevel.Low:
                    mesherLod /= 4;
                    break;
                }
                PrimMesher.SculptMesh newMesh =
                    new PrimMesher.SculptMesh(scupltTexture, smSculptType, mesherLod, true, mirror, invert);

                if (ShouldScaleMesh)
                {
                    newMesh.Scale(prim.Scale.X, prim.Scale.Y, prim.Scale.Z);
                }

                int numPrimFaces = 1;   // a scuplty has only one face

                return(GenerateIRendererMesh(numPrimFaces, prim, newMesh.viewerFaces));
            }
            catch {
                // don't know why we're here but tell the caller nothing was meshed
                return(null);
            }
        }
示例#10
0
        /// <summary>
        /// Create and return a set of meshes/materials that make the passed SOP.
        /// This just deals the making a mesh from the SOP and getting the material/texture of the meshes
        ///    into the caches.
        /// </summary>
        // Returns 'null' if the SOG/SOP could not be converted into a displayable
        public IPromise <Displayable> CreateMeshResource(SceneObjectGroup sog, SceneObjectPart sop,
                                                         OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod)
        {
            var prom = new Promise <Displayable>();

            try {
                if (prim.Sculpt != null)
                {
                    if (prim.Sculpt.Type == OMV.SculptType.Mesh)
                    {
                        BConverterOS.LogBProgress("{0}: CreateMeshResource: creating mesh", _logHeader);
                        ConvOAR.Globals.stats.numMeshAssets++;
                        MeshFromPrimMeshData(sog, sop, prim, assetFetcher, lod)
                        .Then(dispable => {
                            prom.Resolve(new Displayable(dispable, sop));
                        }, e => {
                            // prom.Reject(e);
                            prom.Resolve(null);
                        });
                    }
                    else
                    {
                        BConverterOS.LogBProgress("{0}: CreateMeshResource: creating sculpty", _logHeader);
                        ConvOAR.Globals.stats.numSculpties++;
                        MeshFromPrimSculptData(sog, sop, prim, assetFetcher, lod)
                        .Then(dispable => {
                            prom.Resolve(new Displayable(dispable, sop));
                        }, e => {
                            // prom.Reject(e);
                            prom.Resolve(null);
                        });
                    }
                }
                else
                {
                    BConverterOS.LogBProgress("{0}: CreateMeshResource: creating primshape", _logHeader);
                    ConvOAR.Globals.stats.numSimplePrims++;
                    MeshFromPrimShapeData(sog, sop, prim, assetFetcher, lod)
                    .Then(dispable => {
                        BConverterOS.LogBProgress("{0} CreateMeshResource: prim created", _logHeader);
                        prom.Resolve(new Displayable(dispable, sop));
                    }, e => {
                        // prom.Reject(e);
                        prom.Resolve(null);
                    });
                }
            }
            catch (Exception e) {
                prom.Reject(e);
            }

            return(prom);
        }
示例#11
0
        private Promise <DisplayableRenderable> MeshFromPrimMeshData(SceneObjectGroup sog, SceneObjectPart sop,
                                                                     OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod)
        {
            EntityHandleUUID meshHandle = new EntityHandleUUID(prim.Sculpt.SculptTexture);

            return(new Promise <DisplayableRenderable>((resolve, reject) => {
                assetFetcher.FetchRawAsset(meshHandle)
                .Then(meshBytes => {
                    // OMVA.AssetMesh meshAsset = new OMVA.AssetMesh(prim.ID, meshBytes);
                    // if (OMVR.FacetedMesh.TryDecodeFromAsset(prim, meshAsset, lod, out fMesh)) {
                    OMVR.FacetedMesh fMesh = null;
                    try {
                        fMesh = _mesher.GenerateFacetedMeshMesh(prim, meshBytes);
                    }
                    catch (Exception e) {
                        ConvOAR.Globals.log.ErrorFormat("{0} Exception in GenerateFacetedMeshMesh: {1}", _logHeader, e);
                    }
                    if (fMesh != null)
                    {
                        DisplayableRenderable dr = ConvertFacetedMeshToDisplayable(assetFetcher, fMesh, prim.Textures.DefaultTexture, prim.Scale);
                        // Don't know the hash of the DisplayableRenderable until after it has been created.
                        // Now use the hash to see if this has already been done.
                        // If this DisplayableRenderable has already been built, use the other one and throw this away.
                        BHash drHash = dr.GetBHash();
                        DisplayableRenderable realDR = assetFetcher.GetRenderable(drHash, () => { return dr; });
                        resolve(realDR);
                    }
                    else
                    {
                        reject(new Exception("MeshFromPrimMeshData: could not decode mesh information from asset. ID="
                                             + prim.ID.ToString()));
                    }
                }, e => {
                    ConvOAR.Globals.log.ErrorFormat("{0} MeshFromPrimMeshData: exception: {1}", _logHeader, e);
                    reject(e);
                });
            }));
        }
示例#12
0
 private Promise <DisplayableRenderable> MeshFromPrimSculptData(SceneObjectGroup sog, SceneObjectPart sop,
                                                                OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod)
 {
     return(new Promise <DisplayableRenderable>((resolve, reject) => {
         // Get the asset that the sculpty is built on
         EntityHandleUUID texHandle = new EntityHandleUUID(prim.Sculpt.SculptTexture);
         assetFetcher.FetchTexture(texHandle)
         .Then((bm) => {
             OMVR.FacetedMesh fMesh = _mesher.GenerateFacetedSculptMesh(prim, bm.Image.ExportBitmap(), lod);
             DisplayableRenderable dr =
                 ConvertFacetedMeshToDisplayable(assetFetcher, fMesh, prim.Textures.DefaultTexture, prim.Scale);
             BHash drHash = dr.GetBHash();
             DisplayableRenderable realDR = assetFetcher.GetRenderable(drHash, () => { return dr; });
             BConverterOS.LogBProgress("{0} MeshFromPrimSculptData. numFaces={1}, numGenedMeshed={2}",
                                       _logHeader, fMesh.Faces.Count, ((RenderableMeshGroup)realDR).meshes.Count);
             resolve(realDR);
         }, (e) => {
             ConvOAR.Globals.log.ErrorFormat("{0} MeshFromPrimSculptData: Rejected FetchTexture: {1}: {2}", _logHeader, texHandle, e);
             reject(null);
         });
     }));
 }
示例#13
0
 private Promise <DisplayableRenderable> MeshFromPrimShapeData(SceneObjectGroup sog, SceneObjectPart sop,
                                                               OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod)
 {
     return(new Promise <DisplayableRenderable>((resolve, reject) => {
         OMVR.FacetedMesh mesh = _mesher.GenerateFacetedMesh(prim, lod);
         DisplayableRenderable dr = ConvertFacetedMeshToDisplayable(assetFetcher, mesh, prim.Textures.DefaultTexture, prim.Scale);
         BHash drHash = dr.GetBHash();
         DisplayableRenderable realDR = assetFetcher.GetRenderable(drHash, () => { return dr; });
         BConverterOS.LogBProgress("{0} MeshFromPrimShapeData. numGenedMeshed={1}",
                                   _logHeader, ((RenderableMeshGroup)realDR).meshes.Count);
         resolve(realDR);
     }));
 }
示例#14
0
        /// <summary>
        /// Create a sculpty faceted mesh. The actual scuplt texture is fetched and passed to this
        /// routine since all the context for finding teh texture is elsewhere.
        /// </summary>
        /// <returns>The faceted mesh or null if can't do it</returns>
        public OMVR.FacetedMesh GenerateFacetedSculptMesh(OMV.Primitive prim, System.Drawing.Bitmap scupltTexture, OMVR.DetailLevel lod)
        {
            byte sculptType = (byte)prim.Sculpt.Type;
            bool mirror     = ((sculptType & 128) != 0);
            bool invert     = ((sculptType & 64) != 0);

            // mirror = false; // TODO: libomv doesn't support these and letting them flop around causes problems
            // invert = false;
            OMV.SculptType omSculptType = (OMV.SculptType)(sculptType & 0x07);

            PrimMesher.SculptMesh.SculptType smSculptType;
            switch (omSculptType)
            {
            case OpenMetaverse.SculptType.Cylinder:
                smSculptType = PrimMesher.SculptMesh.SculptType.cylinder;
                break;

            case OpenMetaverse.SculptType.Plane:
                smSculptType = PrimMesher.SculptMesh.SculptType.plane;
                break;

            case OpenMetaverse.SculptType.Sphere:
                smSculptType = PrimMesher.SculptMesh.SculptType.sphere;
                break;

            case OpenMetaverse.SculptType.Torus:
                smSculptType = PrimMesher.SculptMesh.SculptType.torus;
                break;

            default:
                smSculptType = PrimMesher.SculptMesh.SculptType.plane;
                break;
            }
            // The lod for sculpties is the resolution of the texture passed.
            // The first guess is 1:1 then lower resolutions after that
            // int mesherLod = (int)Math.Sqrt(scupltTexture.Width * scupltTexture.Height);
            int mesherLod = 32; // number used in Idealist viewer

            switch (lod)
            {
            case OMVR.DetailLevel.Highest:
                break;

            case OMVR.DetailLevel.High:
                break;

            case OMVR.DetailLevel.Medium:
                mesherLod /= 2;
                break;

            case OMVR.DetailLevel.Low:
                mesherLod /= 4;
                break;
            }
            PrimMesher.SculptMesh newMesh =
                new PrimMesher.SculptMesh(scupltTexture, smSculptType, mesherLod, true, mirror, invert);

            int numPrimFaces = 1;       // a scuplty has only one face

            // copy the vertex information into OMVR.IRendering structures
            OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh();
            omvrmesh.Faces             = new List <OMVR.Face>();
            omvrmesh.Prim              = prim;
            omvrmesh.Profile           = new OMVR.Profile();
            omvrmesh.Profile.Faces     = new List <OMVR.ProfileFace>();
            omvrmesh.Profile.Positions = new List <OMV.Vector3>();
            omvrmesh.Path              = new OMVR.Path();
            omvrmesh.Path.Points       = new List <OMVR.PathPoint>();

            for (int ii = 0; ii < numPrimFaces; ii++)
            {
                OMVR.Face oface = new OMVR.Face();
                oface.Vertices    = new List <OMVR.Vertex>();
                oface.Indices     = new List <ushort>();
                oface.TextureFace = prim.Textures.GetFace((uint)ii);
                int faceVertices = 0;
                foreach (PrimMesher.ViewerFace vface in newMesh.viewerFaces)
                {
                    OMVR.Vertex vert = new OMVR.Vertex();
                    vert.Position = new OMV.Vector3(vface.v1.X, vface.v1.Y, vface.v1.Z);
                    vert.TexCoord = new OMV.Vector2(vface.uv1.U, 1.0f - vface.uv1.V);
                    vert.Normal   = new OMV.Vector3(vface.n1.X, vface.n1.Y, vface.n1.Z);
                    oface.Vertices.Add(vert);

                    vert          = new OMVR.Vertex();
                    vert.Position = new OMV.Vector3(vface.v2.X, vface.v2.Y, vface.v2.Z);
                    vert.TexCoord = new OMV.Vector2(vface.uv2.U, 1.0f - vface.uv2.V);
                    vert.Normal   = new OMV.Vector3(vface.n2.X, vface.n2.Y, vface.n2.Z);
                    oface.Vertices.Add(vert);

                    vert          = new OMVR.Vertex();
                    vert.Position = new OMV.Vector3(vface.v3.X, vface.v3.Y, vface.v3.Z);
                    vert.TexCoord = new OMV.Vector2(vface.uv3.U, 1.0f - vface.uv3.V);
                    vert.Normal   = new OMV.Vector3(vface.n3.X, vface.n3.Y, vface.n3.Z);
                    oface.Vertices.Add(vert);

                    oface.Indices.Add((ushort)(faceVertices * 3 + 0));
                    oface.Indices.Add((ushort)(faceVertices * 3 + 1));
                    oface.Indices.Add((ushort)(faceVertices * 3 + 2));
                    faceVertices++;
                }
                if (faceVertices > 0)
                {
                    oface.TextureFace = prim.Textures.FaceTextures[ii];
                    if (oface.TextureFace == null)
                    {
                        oface.TextureFace = prim.Textures.DefaultTexture;
                    }
                    oface.ID = ii;
                    omvrmesh.Faces.Add(oface);
                }
            }

            return(omvrmesh);
        }