Example #1
0
        public virtual object LoadLodMesh(int level, string filename)
        {
            if (filename != "avatar_eye_1.llm")
            {
                ReferenceMesh refMesh = new ReferenceMesh();
                refMesh.LoadMesh(filename);
                LodMeshes[level] = refMesh;
                return(refMesh);
            }

            LindenMesh fullMesh = new LindenMesh("");

            fullMesh.LoadMesh(filename);
            LodMeshes[level] = fullMesh;
            return(fullMesh);
        }
        public virtual object LoadLodMesh(int level, string filename)
        {
            if (filename != "avatar_eye_1.llm")
            {
                ReferenceMesh refMesh = new ReferenceMesh();
                refMesh.LoadMesh(filename);
                LodMeshes[level] = refMesh;
                return refMesh;
            }

            LindenMesh fullMesh = new LindenMesh("");
            fullMesh.LoadMesh(filename);
            LodMeshes[level] = fullMesh;
            return fullMesh;
        }
        /// <summary>
        /// Create a mesh for the avatar. We either use the specified avatar mesh or create the
        /// mesh from the LAD definition file.
        /// </summary>
        public bool CreateAvatarMeshResource(float priority, IEntity ent, string meshName, EntityName contextEntity)
        {
            if (m_defaultAvatarMesh != null && m_defaultAvatarMesh.Length > 0) {
            return CreateAvatarMeshFromDefault(priority, ent, meshName, contextEntity);
            }

            string meshInfoDir = LookingGlassBase.Instance.AppParams.ParamString("Renderer.Avatar.Mesh.InfoDir");
            string meshInfoDefn = LookingGlassBase.Instance.AppParams.ParamString("Renderer.Avatar.Mesh.Description");
            string meshDescriptionDir = LookingGlassBase.Instance.AppParams.ParamString("Renderer.Avatar.Mesh.DescriptionDir");

            Dictionary<string, OMVR.LindenMesh> meshTypes = new Dictionary<string, OMVR.LindenMesh>();

            XmlDocument lad = new XmlDocument();
            lad.Load(Path.Combine(meshInfoDir, meshInfoDefn));

            XmlNodeList meshes = lad.GetElementsByTagName("mesh");
            foreach (XmlNode meshNode in meshes) {
            string type = meshNode.Attributes.GetNamedItem("type").Value;
            int lod = Int32.Parse(meshNode.Attributes.GetNamedItem("lod").Value);
            string fileName = meshNode.Attributes.GetNamedItem("file_name").Value;
            //string minPixelWidth = meshNode.Attributes.GetNamedItem("min_pixel_width").Value;

            // for the moment, ignore the skirt
            if (type == "skirtMesh") continue;

            if (lod == 0) {
                // only collect the meshes with the highest resolution
                try {
                    fileName = Path.Combine(meshDescriptionDir, fileName);
                    if (!meshTypes.ContainsKey(type)) {
                        OMVR.LindenMesh lmesh = new OMVR.LindenMesh(type);
                        lmesh.LoadMesh(fileName);
                        meshTypes.Add(type, lmesh);
                    }
                }
                catch (Exception e) {
                    m_log.Log(LogLevel.DBADERROR, "Failure reading avatar defn file {0}: {1}", fileName, e);
                }
            }
            }
            // meshTypes now contains the pieces of the avatar.

            string[] meshOrder = {
                    "headMesh", "upperBodyMesh", "lowerBodyMesh",
                    "eyeBallLeftMesh", "hairMesh", "skirtMesh",
                    "eyelashMesh", "eyeBallRightMesh"
            };

            // Assemble into one mesh for passing to lower system
            // TODO: get and pass the skeleton information
            if (!CreateAvatarTextures(ent, false)) {
            // something about the textures can't be built yet. Try again later.
            return false;
            }

            const int faceCountsStride = 6;
            const int verticesStride = 8;
            const int indicesStride = 3;
            const int vertexColorStride = 4;
            // calculate how many floating point numbers we're pushing over
            int[] faceCounts = new int[meshTypes.Count * faceCountsStride + 2];
            faceCounts[0] = faceCounts.Length;
            faceCounts[1] = meshTypes.Count;
            int totalVertices = 0;

            try {
            for (int jj=0; jj < meshTypes.Count; jj++) {
                if (!meshTypes.ContainsKey(meshOrder[jj])) continue;
                OMVR.LindenMesh lmesh = meshTypes[meshOrder[jj]];
                int faceBase = jj * faceCountsStride + 2;
                faceCounts[faceBase + 0] = totalVertices;
                faceCounts[faceBase + 1] = lmesh.NumVertices;
                faceCounts[faceBase + 2] = verticesStride;
                totalVertices += vertexColorStride + lmesh.NumVertices * verticesStride;
                faceCounts[faceBase + 3] = totalVertices;
                faceCounts[faceBase + 4] = lmesh.NumFaces * indicesStride;
                faceCounts[faceBase + 5] = indicesStride;
                totalVertices += lmesh.NumFaces * indicesStride;
            }

            float[] faceVertices = new float[totalVertices + 2];
            faceVertices[0] = faceVertices.Length;
            int vertI = 1;
            for (int jj=0; jj < meshTypes.Count; jj++) {
                if (!meshTypes.ContainsKey(meshOrder[jj])) continue;
                OMVR.LindenMesh lmesh = meshTypes[meshOrder[jj]];
                faceVertices[vertI + 0] = 0.6f;
                faceVertices[vertI + 1] = 0.6f;
                faceVertices[vertI + 2] = 0.6f;
                faceVertices[vertI + 3] = 0.5f;
                vertI += vertexColorStride;

                for (int k = 0; k < lmesh.NumVertices; k++) {
                    OMVR.LindenMesh.Vertex thisVert = lmesh.Vertices[k];
                    // m_log.Log(LogLevel.DRENDERDETAIL, "CreateMesh: vertices: p={0}, t={1}, n={2}",
                    //     thisVert.Position.ToString(), thisVert.TexCoord.ToString(), thisVert.Normal.ToString());
                    faceVertices[vertI + 0] = thisVert.Coord.X;
                    faceVertices[vertI + 1] = thisVert.Coord.Y;
                    faceVertices[vertI + 2] = thisVert.Coord.Z;
                    faceVertices[vertI + 3] = thisVert.TexCoord.X;
                    faceVertices[vertI + 4] = thisVert.TexCoord.Y;
                    faceVertices[vertI + 5] = thisVert.Normal.X;
                    faceVertices[vertI + 6] = thisVert.Normal.Y;
                    faceVertices[vertI + 7] = thisVert.Normal.Z;
                    vertI += verticesStride;
                }
                for (int k = 0; k < lmesh.NumFaces; k++) {
                    faceVertices[vertI + 0] = lmesh.Faces[k].Indices[0];
                    faceVertices[vertI + 1] = lmesh.Faces[k].Indices[1];
                    faceVertices[vertI + 2] = lmesh.Faces[k].Indices[2];
                    vertI += indicesStride;
                }
            }
            m_log.Log(LogLevel.DRENDERDETAIL,
                "RenderOgreLL.CreateAvatarMeshResource: {0}, fcs={1}, fs={2}, vi={3}",
                ent.Name, faceCounts.Length, faceVertices.Length, vertI
                );

            // We were passed a 'context' entity. Create a scene node name to pass to
            // Ogre. If the scene node is not found, nothing bad happens.
            string contextSceneNode = EntityNameOgre.ConvertToOgreSceneNodeName(contextEntity);

            // Now create the mesh
            Ogr.CreateMeshResourceBF(priority, meshName, contextSceneNode, faceCounts, faceVertices);
            }
            catch (Exception e) {
            m_log.Log(LogLevel.DBADERROR, "Failure building avatar mesh: {0}", e);
            }

            return true;
        }