Exemplo n.º 1
0
        /// <summary>
        /// Cargar estructura de esqueleto
        /// </summary>
        private TgcSkeletalBone[] loadSkeleton(TgcSkeletalMeshData meshData)
        {
            //Crear huesos
            TgcSkeletalBone[] bones = new TgcSkeletalBone[meshData.bones.Length];
            for (int i = 0; i < bones.Length; i++)
            {
                TgcSkeletalBoneData boneData = meshData.bones[i];

                TgcSkeletalBone bone = new TgcSkeletalBone(i, boneData.name,
                                                           new Vector3(boneData.startPosition[0], boneData.startPosition[1], boneData.startPosition[2]),
                                                           new Quaternion(boneData.startRotation[0], boneData.startRotation[1], boneData.startRotation[2], boneData.startRotation[3])
                                                           );
                bones[i] = bone;
            }

            //Cargar padres en huesos
            for (int i = 0; i < bones.Length; i++)
            {
                TgcSkeletalBoneData boneData = meshData.bones[i];
                if (boneData.parentId == -1)
                {
                    bones[i].ParentBone = null;
                }
                else
                {
                    bones[i].ParentBone = bones[boneData.parentId];
                }
            }

            return(bones);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Carga un modelo a partir del string del XML
        /// </summary>
        /// <param name="xmlString">contenido del XML</param>
        /// <param name="mediaPath">Path a partir del cual hay que buscar las Texturas</param>
        /// <returns>Modelo cargado</returns>
        public TgcSkeletalMesh loadMeshFromString(string xmlString, string mediaPath)
        {
            TgcSkeletalParser   parser   = new TgcSkeletalParser();
            TgcSkeletalMeshData meshData = parser.parseMeshFromString(xmlString);

            return(loadMesh(meshData, mediaPath));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Crea un mesh sin texturas, solo con VertexColors
        /// </summary>
        /// <param name="meshData"></param>
        private TgcSkeletalMesh crearMeshSoloColor(TgcSkeletalMeshData meshData)
        {
            //Crear Mesh
            Mesh mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, VertexColorVertexElements, device);

            //Cargar VertexBuffer
            using (VertexBuffer vb = mesh.VertexBuffer)
            {
                GraphicsStream data = vb.Lock(0, 0, LockFlags.None);
                for (int j = 0; j < meshData.coordinatesIndices.Length; j++)
                {
                    VertexColorVertex v = new VertexColorVertex();

                    //vertices
                    int coordIdx = meshData.coordinatesIndices[j] * 3;
                    v.Position = new Vector3(
                        meshData.verticesCoordinates[coordIdx],
                        meshData.verticesCoordinates[coordIdx + 1],
                        meshData.verticesCoordinates[coordIdx + 2]
                        );

                    //color
                    int colorIdx = meshData.colorIndices[j];
                    v.Color = meshData.verticesColors[colorIdx];

                    data.Write(v);
                }
                vb.Unlock();
            }

            //Cargar indexBuffer en forma plana
            using (IndexBuffer ib = mesh.IndexBuffer)
            {
                short[] indices = new short[meshData.coordinatesIndices.Length];
                for (int i = 0; i < indices.Length; i++)
                {
                    indices[i] = (short)i;
                }
                ib.SetData(indices, 0, LockFlags.None);
            }

            //Cargar esqueleto
            TgcSkeletalBone[]         bones           = loadSkeleton(meshData);
            TgcSkeletalVertexWeight[] verticesWeights = loadVerticesWeights(meshData, bones);

            //Cargar datos de meshData que interesan mantener como originales
            TgcSkeletalMesh.OriginalData origData = new TgcSkeletalMesh.OriginalData();
            origData.coordinatesIndices    = meshData.coordinatesIndices;
            origData.verticesCoordinates   = meshData.verticesCoordinates;
            origData.colorIndices          = meshData.colorIndices;
            origData.verticesColors        = meshData.verticesColors;
            origData.texCoordinatesIndices = null;
            origData.textureCoordinates    = null;

            //Crear mesh de TGC
            TgcSkeletalMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcSkeletalMesh.MeshRenderType.VERTEX_COLOR, origData, bones, verticesWeights);

            return(tgcMesh);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Cargar Weights de vertices
        /// </summary>
        /// <param name="meshData"></param>
        /// <returns></returns>
        private TgcSkeletalVertexWeight[] loadVerticesWeights(TgcSkeletalMeshData meshData, TgcSkeletalBone[] bones)
        {
            //Crear un array de Weights para cada uno de los vertices de la malla
            TgcSkeletalVertexWeight[] weights = new TgcSkeletalVertexWeight[meshData.verticesCoordinates.Length / 3];
            float[] vertexWeightTotals        = new float[weights.Length];
            for (int i = 0; i < weights.Length; i++)
            {
                weights[i]            = new TgcSkeletalVertexWeight();
                vertexWeightTotals[i] = 0;
            }

            //Cargar los weights de cada vertice
            int weightsCount = meshData.verticesWeights.Length / 3;

            for (int i = 0; i < weightsCount; i++)
            {
                int   vertexIdx = (int)meshData.verticesWeights[i * 3];
                int   boneIdx   = (int)meshData.verticesWeights[i * 3 + 1];
                float weightVal = meshData.verticesWeights[i * 3 + 2];

                TgcSkeletalBone bone = bones[boneIdx];
                TgcSkeletalVertexWeight.BoneWeight weight = new TgcSkeletalVertexWeight.BoneWeight(bone, weightVal);

                weights[vertexIdx].Weights.Add(weight);

                //acumular total de weight para ese vertice, para luego poder normalizar
                vertexWeightTotals[vertexIdx] += weightVal;
            }

            //Normalizar weights de cada vertice
            for (int i = 0; i < weights.Length; i++)
            {
                TgcSkeletalVertexWeight vertexWeight = weights[i];
                float vTotal = vertexWeightTotals[i];

                //Normalizar cada valor segun el total acumulado en el vertice
                foreach (TgcSkeletalVertexWeight.BoneWeight w in vertexWeight.Weights)
                {
                    w.Weight = w.Weight / vTotal;
                }
            }

            return(weights);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Crea un mesh con uno o varios DiffuseMap
        /// </summary>
        /// <returns></returns>
        private TgcSkeletalMesh crearMeshDiffuseMap(TgcSkeletalLoaderMaterialAux[] materialsArray, TgcSkeletalMeshData meshData)
        {
            //Crear Mesh
            Mesh mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, DiffuseMapVertexElements, device);

            //Cargar esqueleto
            TgcSkeletalBone[] bones = loadSkeleton(meshData);
            TgcSkeletalVertexWeight[] verticesWeights = loadVerticesWeights(meshData, bones);

            //Cargar VertexBuffer
            using (VertexBuffer vb = mesh.VertexBuffer)
            {
                GraphicsStream data = vb.Lock(0, 0, LockFlags.None);
                for (int j = 0; j < meshData.coordinatesIndices.Length; j++)
                {
                    DiffuseMapVertex v = new DiffuseMapVertex();

                    //vertices
                    int coordIdx = meshData.coordinatesIndices[j] * 3;
                    v.Position = new Vector3(
                        meshData.verticesCoordinates[coordIdx],
                        meshData.verticesCoordinates[coordIdx + 1],
                        meshData.verticesCoordinates[coordIdx + 2]
                        );

                    //texture coordinates diffuseMap
                    int texCoordIdx = meshData.texCoordinatesIndices[j] * 2;
                    v.Tu = meshData.textureCoordinates[texCoordIdx];
                    v.Tv = meshData.textureCoordinates[texCoordIdx + 1];

                    //color
                    int colorIdx = meshData.colorIndices[j];
                    v.Color = meshData.verticesColors[colorIdx];

                    //normal
                    if (meshData.verticesNormals != null)
                    {
                        v.Normal = new Vector3(
                            meshData.verticesNormals[coordIdx],
                            meshData.verticesNormals[coordIdx + 1],
                            meshData.verticesNormals[coordIdx + 2]
                            );
                    }
                    else
                    {
                        v.Normal = new Vector3(0, 0, 0);
                    }

                    //tangent
                    if (meshData.verticesTangents != null)
                    {
                        v.Tangent = new Vector3(
                            meshData.verticesTangents[coordIdx],
                            meshData.verticesTangents[coordIdx + 1],
                            meshData.verticesTangents[coordIdx + 2]
                            );
                    }
                    else
                    {
                        v.Tangent = new Vector3(0, 0, 0);
                    }

                    //binormal
                    if (meshData.verticesBinormals != null)
                    {
                        v.Binormal = new Vector3(
                            meshData.verticesBinormals[coordIdx],
                            meshData.verticesBinormals[coordIdx + 1],
                            meshData.verticesBinormals[coordIdx + 2]
                            );
                    }
                    else
                    {
                        v.Binormal = new Vector3(0, 0, 0);
                    }
                    


                    //BlendWeights y BlendIndices
                    TgcSkeletalVertexWeight vWeight = verticesWeights[meshData.coordinatesIndices[j]];
                    vWeight.createVector4WeightsAndIndices(out v.BlendWeights, out v.BlendIndices);



                    data.Write(v);
                }
                vb.Unlock();
            }

            //Cargar IndexBuffer en forma plana
            using (IndexBuffer ib = mesh.IndexBuffer)
            {
                short[] indices = new short[meshData.coordinatesIndices.Length];
                for (int j = 0; j < indices.Length; j++)
                {
                    indices[j] = (short)j;
                }
                ib.SetData(indices, 0, LockFlags.None);
            }

            //Configurar Material y Textura para un solo SubSet
            TgcSkeletalLoaderMaterialAux matAux = materialsArray[meshData.materialId];
            Material[] meshMaterials;
            TgcTexture[] meshTextures;
            if (matAux.subMaterials == null)
            {
                meshMaterials = new Material[] { matAux.materialId };
                meshTextures = new TgcTexture[] { matAux.texture };
            }

            //Configurar Material y Textura para varios SubSet
            else
            {
                //Cargar attributeBuffer con los id de las texturas de cada triángulo
                int[] attributeBuffer = mesh.LockAttributeBufferArray(LockFlags.None);
                Array.Copy(meshData.materialsIds, attributeBuffer, attributeBuffer.Length);
                mesh.UnlockAttributeBuffer(attributeBuffer);

                //Cargar array de Materials y Texturas
                meshMaterials = new Material[matAux.subMaterials.Length];
                meshTextures = new TgcTexture[matAux.subMaterials.Length];
                for (int m = 0; m < matAux.subMaterials.Length; m++)
                {
                    meshMaterials[m] = matAux.subMaterials[m].materialId;
                    meshTextures[m] = matAux.subMaterials[m].texture;
                }
            }

            //Crear mesh de TGC
            TgcSkeletalMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcSkeletalMesh.MeshRenderType.DIFFUSE_MAP, bones);
            tgcMesh.Materials = meshMaterials;
            tgcMesh.DiffuseMaps = meshTextures;
            return tgcMesh;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Cargar Weights de vertices
        /// </summary>
        /// <param name="meshData"></param>
        /// <returns></returns>
        private TgcSkeletalVertexWeight[] loadVerticesWeights(TgcSkeletalMeshData meshData, TgcSkeletalBone[] bones)
        {
            int maxWeights = 4;
            TgcSkeletalVertexWeight.BoneWeight.GreaterComparer weightComparer = new TgcSkeletalVertexWeight.BoneWeight.GreaterComparer();

            //Crear un array de Weights para cada uno de los vertices de la malla
            TgcSkeletalVertexWeight[] weights = new TgcSkeletalVertexWeight[meshData.verticesCoordinates.Length / 3];
            for (int i = 0; i < weights.Length; i++)
			{
			    weights[i] = new TgcSkeletalVertexWeight();
			}

            //Cargar los weights de cada vertice
            int weightsCount = meshData.verticesWeights.Length / 3;
            for (int i = 0; i < weightsCount; i++)
            {
                int vertexIdx = (int)meshData.verticesWeights[i * 3];
                int boneIdx = (int)meshData.verticesWeights[i * 3 + 1];
                float weightVal = meshData.verticesWeights[i * 3 + 2];

                TgcSkeletalBone bone = bones[boneIdx];
                TgcSkeletalVertexWeight.BoneWeight weight = new TgcSkeletalVertexWeight.BoneWeight(bone, weightVal);

                weights[vertexIdx].Weights.Add(weight);
            }

            //Normalizar weights de cada vertice
            for (int i = 0; i < weights.Length; i++)
            {
                TgcSkeletalVertexWeight vertexWeight = weights[i];

                //Se soportan hasta 4 weights por vertice. Si hay mas se quitan y se reparten las influencias entre el resto de los huesos
                if (vertexWeight.Weights.Count > maxWeights)
                {
                    //Ordenar por weight de menor a mayor y luego revertir, para que quede de mayor a menor peso
                    vertexWeight.Weights.Sort(weightComparer);
                    vertexWeight.Weights.Reverse();
                    
                    //Quitar los ultimos los weight que superan 4
                    while (vertexWeight.Weights.Count > maxWeights)
                    {
                        vertexWeight.Weights.RemoveAt(vertexWeight.Weights.Count - 1);
                    }
                }

                //Sumar el total de todos los weights de este vertice
                float weightTotal = 0;
                foreach (TgcSkeletalVertexWeight.BoneWeight w in vertexWeight.Weights)
                {
                    weightTotal += w.Weight;
                }

                //Normalizar cada valor segun el total acumulado en el vertice
                foreach (TgcSkeletalVertexWeight.BoneWeight w in vertexWeight.Weights)
                {
                    w.Weight = w.Weight / weightTotal;
                }
            }

            return weights;
        }
Exemplo n.º 7
0
        /// <summary>
        /// Cargar estructura de esqueleto
        /// </summary>
        private TgcSkeletalBone[] loadSkeleton(TgcSkeletalMeshData meshData)
        {
            //Crear huesos
            TgcSkeletalBone[] bones = new TgcSkeletalBone[meshData.bones.Length];
            for (int i = 0; i < bones.Length; i++)
            {
                TgcSkeletalBoneData boneData = meshData.bones[i];

                TgcSkeletalBone bone = new TgcSkeletalBone(i, boneData.name,
                    new Vector3(boneData.startPosition[0], boneData.startPosition[1], boneData.startPosition[2]),
                    new Quaternion(boneData.startRotation[0], boneData.startRotation[1], boneData.startRotation[2], boneData.startRotation[3])
                    );
                bones[i] = bone;
            }

            //Cargar padres en huesos
            for (int i = 0; i < bones.Length; i++)
            {
                TgcSkeletalBoneData boneData = meshData.bones[i];
                if (boneData.parentId == -1)
                {
                    bones[i].ParentBone = null;
                }
                else
                {
                    bones[i].ParentBone = bones[boneData.parentId];
                }
            }

            return bones;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Carga un Modelo a partir de un objeto TgcSkeletalMeshData ya parseado
        /// </summary>
        /// <param name="meshData">Objeto con datos ya parseados</param>
        /// <param name="mediaPath">Path a partir del cual hay que buscar las Texturas</param>
        /// <returns>Modelo cargado</returns>
        public TgcSkeletalMesh loadMesh(TgcSkeletalMeshData meshData, string mediaPath)
        {
            //Cargar Texturas
            TgcSkeletalLoaderMaterialAux[] materialsArray = new TgcSkeletalLoaderMaterialAux[meshData.materialsData.Length];
            for (int i = 0; i < meshData.materialsData.Length; i++)
            {
                TgcMaterialData materialData = meshData.materialsData[i];
                string texturesPath = mediaPath + meshData.texturesDir + "\\";

                //Crear StandardMaterial
                if (materialData.type.Equals(TgcMaterialData.StandardMaterial))
                {
                    materialsArray[i] = createTextureAndMaterial(materialData, texturesPath);
                }

                //Crear MultiMaterial
                else if (materialData.type.Equals(TgcMaterialData.MultiMaterial))
                {
                    TgcSkeletalLoaderMaterialAux matAux = new TgcSkeletalLoaderMaterialAux();
                    materialsArray[i] = matAux;
                    matAux.subMaterials = new TgcSkeletalLoaderMaterialAux[materialData.subMaterials.Length];
                    for (int j = 0; j < materialData.subMaterials.Length; j++)
                    {
                        matAux.subMaterials[j] = createTextureAndMaterial(materialData.subMaterials[j], texturesPath);
                    }
                }
            }


            //Crear Mesh
            TgcSkeletalMesh tgcMesh = null;

            //Crear mesh que no tiene Material, con un color simple
            if (meshData.materialId == -1)
            {
                tgcMesh = crearMeshSoloColor(meshData);
            }


            //Crear mesh con DiffuseMap
            else
            {
                tgcMesh = crearMeshDiffuseMap(materialsArray, meshData);
            }


            //Crear BoundingBox, aprovechar lo que viene del XML o crear uno por nuestra cuenta
            if (meshData.pMin != null && meshData.pMax != null)
            {
                tgcMesh.BoundingBox = new TgcBoundingBox(
                        TgcParserUtils.float3ArrayToVector3(meshData.pMin),
                        TgcParserUtils.float3ArrayToVector3(meshData.pMax)
                        );
            }
            else
            {
                tgcMesh.createBoundingBox();
            }


            tgcMesh.Enabled = true;
            return tgcMesh;
        }
        /// <summary>
        /// Levanta la informacion del mesh a partir de un XML
        /// </summary>
        /// <param name="xmlString">contenido del XML</param>
        /// <returns></returns>
        public TgcSkeletalMeshData parseMeshFromString(string xmlString)
        {
            XmlDocument dom = new XmlDocument();

            dom.LoadXml(xmlString);
            XmlElement root = dom.DocumentElement;

            TgcSkeletalMeshData meshData = new TgcSkeletalMeshData();

            //Ver si tiene exportacion de texturas
            XmlNode texturesExportNode    = root.GetElementsByTagName("texturesExport")[0];
            bool    texturesExportEnabled = bool.Parse(texturesExportNode.Attributes["enabled"].InnerText);

            if (texturesExportEnabled)
            {
                meshData.texturesDir = texturesExportNode.Attributes["dir"].InnerText;
            }

            //Parsear Texturas
            XmlNodeList materialNodes = root.GetElementsByTagName("materials")[0].ChildNodes;

            meshData.materialsData = new TgcMaterialData[materialNodes.Count];
            int i = 0;

            foreach (XmlElement matNode in materialNodes)
            {
                //determinar tipo de Material
                TgcMaterialData material = new TgcMaterialData();
                material.type = matNode.Attributes["type"].InnerText;

                //Standard Material
                if (material.type.Equals(TgcMaterialData.StandardMaterial))
                {
                    parseStandardMaterial(material, matNode);
                }

                //Multi Material
                else if (material.type.Equals(TgcMaterialData.MultiMaterial))
                {
                    material.name = matNode.Attributes["name"].InnerText;
                    XmlNodeList subMaterialsNodes = matNode.GetElementsByTagName("subM");
                    material.subMaterials = new TgcMaterialData[subMaterialsNodes.Count];
                    for (int j = 0; j < subMaterialsNodes.Count; j++)
                    {
                        TgcMaterialData subMaterial = new TgcMaterialData();
                        parseStandardMaterial(subMaterial, (XmlElement)subMaterialsNodes[j]);
                        material.subMaterials[j] = subMaterial;
                    }
                }

                meshData.materialsData[i++] = material;
            }


            //Parsear Mesh
            XmlElement meshNode = (XmlElement)root.GetElementsByTagName("mesh")[0];

            //parser y convertir valores
            meshData.name       = meshNode.Attributes["name"].InnerText;
            meshData.materialId = int.Parse(meshNode.Attributes["matId"].InnerText);
            meshData.color      = TgcParserUtils.parseFloat3Array(meshNode.Attributes["color"].InnerText);

            //TODO: formatear bien visibility
            string visibilityStr = meshNode.Attributes["visibility"].InnerText;

            //boundingBox, si esta
            XmlNodeList boundingBoxNodes = root.GetElementsByTagName("boundingBox");

            if (boundingBoxNodes != null && boundingBoxNodes.Count == 1)
            {
                XmlNode boundingBoxNode = boundingBoxNodes[0];
                meshData.pMin = TgcParserUtils.parseFloat3Array(boundingBoxNode.Attributes["min"].InnerText);
                meshData.pMax = TgcParserUtils.parseFloat3Array(boundingBoxNode.Attributes["max"].InnerText);
            }


            int count;

            //parsear coordinatesIdx
            XmlNode coordinatesIdxNode = meshNode.GetElementsByTagName("coordinatesIdx")[0];

            count = int.Parse(coordinatesIdxNode.Attributes["count"].InnerText);
            meshData.coordinatesIndices = TgcParserUtils.parseIntStream(coordinatesIdxNode.InnerText, count);

            //parsear textCoordsIdx
            XmlNode textCoordsIdxNode = meshNode.GetElementsByTagName("textCoordsIdx")[0];

            count = int.Parse(textCoordsIdxNode.Attributes["count"].InnerText);
            meshData.texCoordinatesIndices = TgcParserUtils.parseIntStream(textCoordsIdxNode.InnerText, count);

            //parsear colorsIdx
            XmlNode colorsIdxNode = meshNode.GetElementsByTagName("colorsIdx")[0];

            count = int.Parse(colorsIdxNode.Attributes["count"].InnerText);
            meshData.colorIndices = TgcParserUtils.parseIntStream(colorsIdxNode.InnerText, count);

            //parsear matIds
            if (meshData.materialsData.Length > 0)
            {
                XmlNode matIdsNode = meshNode.GetElementsByTagName("matIds")[0];
                count = int.Parse(matIdsNode.Attributes["count"].InnerText);
                meshData.materialsIds = TgcParserUtils.parseIntStream(matIdsNode.InnerText, count);
            }

            //parsear vertices
            XmlNode verticesNode = meshNode.GetElementsByTagName("vertices")[0];

            count = int.Parse(verticesNode.Attributes["count"].InnerText);
            meshData.verticesCoordinates = TgcParserUtils.parseFloatStream(verticesNode.InnerText, count);

            //parsear texCoords
            XmlNode texCoordsNode = meshNode.GetElementsByTagName("texCoords")[0];

            count = int.Parse(texCoordsNode.Attributes["count"].InnerText);
            meshData.textureCoordinates = TgcParserUtils.parseFloatStream(texCoordsNode.InnerText, count);

            //parsear colors
            XmlNode colorsNode = meshNode.GetElementsByTagName("colors")[0];

            count = int.Parse(colorsNode.Attributes["count"].InnerText);
            float[] colorsArray = TgcParserUtils.parseFloatStream(colorsNode.InnerText, count);
            //convertir a format TV
            meshData.verticesColors = new int[count / 3];
            for (int j = 0; j < meshData.verticesColors.Length; j++)
            {
                meshData.verticesColors[j] = Color.FromArgb(
                    (int)colorsArray[j * 3],
                    (int)colorsArray[j * 3 + 1],
                    (int)colorsArray[j * 3 + 2]).ToArgb();
            }

            //parsear esqueleto
            XmlNode skeletonNode = meshNode.GetElementsByTagName("skeleton")[0];

            TgcSkeletalBoneData[] bonesData = new TgcSkeletalBoneData[skeletonNode.ChildNodes.Count];
            int boneCount = 0;

            foreach (XmlElement boneNode in skeletonNode.ChildNodes)
            {
                TgcSkeletalBoneData boneData = new TgcSkeletalBoneData();
                boneData.id            = int.Parse(boneNode.Attributes["id"].InnerText);
                boneData.name          = boneNode.Attributes["name"].InnerText;
                boneData.parentId      = int.Parse(boneNode.Attributes["parentId"].InnerText);
                boneData.startPosition = TgcParserUtils.parseFloat3Array(boneNode.Attributes["pos"].InnerText);
                boneData.startRotation = TgcParserUtils.parseFloat4Array(boneNode.Attributes["rotQuat"].InnerText);

                bonesData[boneCount++] = boneData;
            }
            meshData.bones = bonesData;

            //parsear Weights
            XmlNode weightsNode = meshNode.GetElementsByTagName("weights")[0];

            count = int.Parse(weightsNode.Attributes["count"].InnerText);
            meshData.verticesWeights = TgcParserUtils.parseFloatStream(weightsNode.InnerText, count);


            return(meshData);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Cargar Weights de vertices
        /// </summary>
        /// <param name="meshData"></param>
        /// <returns></returns>
        private TgcSkeletalVertexWeight[] loadVerticesWeights(TgcSkeletalMeshData meshData, TgcSkeletalBone[] bones)
        {
            //Crear un array de Weights para cada uno de los vertices de la malla
            TgcSkeletalVertexWeight[] weights = new TgcSkeletalVertexWeight[meshData.verticesCoordinates.Length / 3];
            float[] vertexWeightTotals = new float[weights.Length];
            for (int i = 0; i < weights.Length; i++)
            {
                weights[i] = new TgcSkeletalVertexWeight();
                vertexWeightTotals[i] = 0;
            }

            //Cargar los weights de cada vertice
            int weightsCount = meshData.verticesWeights.Length / 3;
            for (int i = 0; i < weightsCount; i++)
            {
                int vertexIdx = (int)meshData.verticesWeights[i * 3];
                int boneIdx = (int)meshData.verticesWeights[i * 3 + 1];
                float weightVal = meshData.verticesWeights[i * 3 + 2];

                TgcSkeletalBone bone = bones[boneIdx];
                TgcSkeletalVertexWeight.BoneWeight weight = new TgcSkeletalVertexWeight.BoneWeight(bone, weightVal);

                weights[vertexIdx].Weights.Add(weight);

                //acumular total de weight para ese vertice, para luego poder normalizar
                vertexWeightTotals[vertexIdx] += weightVal;
            }

            //Normalizar weights de cada vertice
            for (int i = 0; i < weights.Length; i++)
            {
                TgcSkeletalVertexWeight vertexWeight = weights[i];
                float vTotal = vertexWeightTotals[i];

                //Normalizar cada valor segun el total acumulado en el vertice
                foreach (TgcSkeletalVertexWeight.BoneWeight w in vertexWeight.Weights)
                {
                    w.Weight = w.Weight / vTotal;
                }
            }

            return weights;
        }
Exemplo n.º 11
0
        /// <summary>
        /// Crea un mesh sin texturas, solo con VertexColors
        /// </summary>
        /// <param name="meshData"></param>
        private TgcSkeletalMesh crearMeshSoloColor(TgcSkeletalMeshData meshData)
        {
            //Crear Mesh
            Mesh mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, VertexColorVertexElements, device);

            //Cargar esqueleto
            TgcSkeletalBone[]         bones           = loadSkeleton(meshData);
            TgcSkeletalVertexWeight[] verticesWeights = loadVerticesWeights(meshData, bones);

            //Cargar VertexBuffer
            using (VertexBuffer vb = mesh.VertexBuffer)
            {
                GraphicsStream data = vb.Lock(0, 0, LockFlags.None);
                for (int j = 0; j < meshData.coordinatesIndices.Length; j++)
                {
                    VertexColorVertex v = new VertexColorVertex();

                    //vertices
                    int coordIdx = meshData.coordinatesIndices[j] * 3;
                    v.Position = new Vector3(
                        meshData.verticesCoordinates[coordIdx],
                        meshData.verticesCoordinates[coordIdx + 1],
                        meshData.verticesCoordinates[coordIdx + 2]
                        );

                    //color
                    int colorIdx = meshData.colorIndices[j];
                    v.Color = meshData.verticesColors[colorIdx];

                    //normal
                    if (meshData.verticesNormals != null)
                    {
                        v.Normal = new Vector3(
                            meshData.verticesNormals[coordIdx],
                            meshData.verticesNormals[coordIdx + 1],
                            meshData.verticesNormals[coordIdx + 2]
                            );
                    }
                    else
                    {
                        v.Normal = new Vector3(0, 0, 0);
                    }

                    //tangent
                    if (meshData.verticesTangents != null)
                    {
                        v.Tangent = new Vector3(
                            meshData.verticesTangents[coordIdx],
                            meshData.verticesTangents[coordIdx + 1],
                            meshData.verticesTangents[coordIdx + 2]
                            );
                    }
                    else
                    {
                        v.Tangent = new Vector3(0, 0, 0);
                    }

                    //binormal
                    if (meshData.verticesBinormals != null)
                    {
                        v.Binormal = new Vector3(
                            meshData.verticesBinormals[coordIdx],
                            meshData.verticesBinormals[coordIdx + 1],
                            meshData.verticesBinormals[coordIdx + 2]
                            );
                    }
                    else
                    {
                        v.Binormal = new Vector3(0, 0, 0);
                    }



                    //BlendWeights y BlendIndices
                    TgcSkeletalVertexWeight vWeight = verticesWeights[meshData.coordinatesIndices[j]];
                    vWeight.createVector4WeightsAndIndices(out v.BlendWeights, out v.BlendIndices);


                    data.Write(v);
                }
                vb.Unlock();
            }

            //Cargar indexBuffer en forma plana
            using (IndexBuffer ib = mesh.IndexBuffer)
            {
                short[] indices = new short[meshData.coordinatesIndices.Length];
                for (int i = 0; i < indices.Length; i++)
                {
                    indices[i] = (short)i;
                }
                ib.SetData(indices, 0, LockFlags.None);
            }

            //Crear mesh de TGC
            TgcSkeletalMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcSkeletalMesh.MeshRenderType.VERTEX_COLOR, bones);

            return(tgcMesh);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Crea un mesh con uno o varios DiffuseMap
        /// </summary>
        /// <returns></returns>
        private TgcSkeletalMesh crearMeshDiffuseMap(TgcSkeletalLoaderMaterialAux[] materialsArray, TgcSkeletalMeshData meshData)
        {
            //Crear Mesh
            Mesh mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, DiffuseMapVertexElements, device);

            //Cargar VertexBuffer
            using (VertexBuffer vb = mesh.VertexBuffer)
            {
                GraphicsStream data = vb.Lock(0, 0, LockFlags.None);
                for (int j = 0; j < meshData.coordinatesIndices.Length; j++)
                {
                    DiffuseMapVertex v = new DiffuseMapVertex();

                    //vertices
                    int coordIdx = meshData.coordinatesIndices[j] * 3;
                    v.Position = new Vector3(
                        meshData.verticesCoordinates[coordIdx],
                        meshData.verticesCoordinates[coordIdx + 1],
                        meshData.verticesCoordinates[coordIdx + 2]
                        );

                    //texture coordinates diffuseMap
                    int texCoordIdx = meshData.texCoordinatesIndices[j] * 2;
                    v.Tu = meshData.textureCoordinates[texCoordIdx];
                    v.Tv = meshData.textureCoordinates[texCoordIdx + 1];

                    //color
                    int colorIdx = meshData.colorIndices[j];
                    v.Color = meshData.verticesColors[colorIdx];

                    data.Write(v);
                }
                vb.Unlock();
            }

            //Cargar IndexBuffer en forma plana
            using (IndexBuffer ib = mesh.IndexBuffer)
            {
                short[] indices = new short[meshData.coordinatesIndices.Length];
                for (int j = 0; j < indices.Length; j++)
                {
                    indices[j] = (short)j;
                }
                ib.SetData(indices, 0, LockFlags.None);
            }

            //Configurar Material y Textura para un solo SubSet
            TgcSkeletalLoaderMaterialAux matAux = materialsArray[meshData.materialId];

            Material[]   meshMaterials;
            TgcTexture[] meshTextures;
            if (matAux.subMaterials == null)
            {
                meshMaterials = new Material[] { matAux.materialId };
                meshTextures  = new TgcTexture[] { matAux.texture };
            }

            //Configurar Material y Textura para varios SubSet
            else
            {
                //Cargar attributeBuffer con los id de las texturas de cada triángulo
                int[] attributeBuffer = mesh.LockAttributeBufferArray(LockFlags.None);
                Array.Copy(meshData.materialsIds, attributeBuffer, attributeBuffer.Length);
                mesh.UnlockAttributeBuffer(attributeBuffer);

                //Cargar array de Materials y Texturas
                meshMaterials = new Material[matAux.subMaterials.Length];
                meshTextures  = new TgcTexture[matAux.subMaterials.Length];
                for (int m = 0; m < matAux.subMaterials.Length; m++)
                {
                    meshMaterials[m] = matAux.subMaterials[m].materialId;
                    meshTextures[m]  = matAux.subMaterials[m].texture;
                }
            }

            //Cargar esqueleto
            TgcSkeletalBone[]         bones           = loadSkeleton(meshData);
            TgcSkeletalVertexWeight[] verticesWeights = loadVerticesWeights(meshData, bones);

            //Cargar datos de meshData que interesan mantener como originales
            TgcSkeletalMesh.OriginalData origData = new TgcSkeletalMesh.OriginalData();
            origData.coordinatesIndices    = meshData.coordinatesIndices;
            origData.verticesCoordinates   = meshData.verticesCoordinates;
            origData.colorIndices          = meshData.colorIndices;
            origData.verticesColors        = meshData.verticesColors;
            origData.texCoordinatesIndices = meshData.texCoordinatesIndices;
            origData.textureCoordinates    = meshData.textureCoordinates;

            //Crear mesh de TGC
            TgcSkeletalMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcSkeletalMesh.MeshRenderType.DIFFUSE_MAP, origData, bones, verticesWeights);

            tgcMesh.Materials   = meshMaterials;
            tgcMesh.DiffuseMaps = meshTextures;
            return(tgcMesh);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Carga un Modelo a partir de un objeto TgcSkeletalMeshData ya parseado
        /// </summary>
        /// <param name="meshData">Objeto con datos ya parseados</param>
        /// <param name="mediaPath">Path a partir del cual hay que buscar las Texturas</param>
        /// <returns>Modelo cargado</returns>
        public TgcSkeletalMesh loadMesh(TgcSkeletalMeshData meshData, string mediaPath)
        {
            //Cargar Texturas
            TgcSkeletalLoaderMaterialAux[] materialsArray = new TgcSkeletalLoaderMaterialAux[meshData.materialsData.Length];
            for (int i = 0; i < meshData.materialsData.Length; i++)
            {
                TgcMaterialData materialData = meshData.materialsData[i];
                string          texturesPath = mediaPath + meshData.texturesDir + "\\";

                //Crear StandardMaterial
                if (materialData.type.Equals(TgcMaterialData.StandardMaterial))
                {
                    materialsArray[i] = createTextureAndMaterial(materialData, texturesPath);
                }

                //Crear MultiMaterial
                else if (materialData.type.Equals(TgcMaterialData.MultiMaterial))
                {
                    TgcSkeletalLoaderMaterialAux matAux = new TgcSkeletalLoaderMaterialAux();
                    materialsArray[i]   = matAux;
                    matAux.subMaterials = new TgcSkeletalLoaderMaterialAux[materialData.subMaterials.Length];
                    for (int j = 0; j < materialData.subMaterials.Length; j++)
                    {
                        matAux.subMaterials[j] = createTextureAndMaterial(materialData.subMaterials[j], texturesPath);
                    }
                }
            }


            //Crear Mesh
            TgcSkeletalMesh tgcMesh = null;

            //Crear mesh que no tiene Material, con un color simple
            if (meshData.materialId == -1)
            {
                tgcMesh = crearMeshSoloColor(meshData);
            }


            //Crear mesh con DiffuseMap
            else
            {
                tgcMesh = crearMeshDiffuseMap(materialsArray, meshData);
            }


            //Crear BoundingBox, aprovechar lo que viene del XML o crear uno por nuestra cuenta
            if (meshData.pMin != null && meshData.pMax != null)
            {
                tgcMesh.BoundingBox = new TgcBoundingBox(
                    TgcParserUtils.float3ArrayToVector3(meshData.pMin),
                    TgcParserUtils.float3ArrayToVector3(meshData.pMax)
                    );
            }
            else
            {
                tgcMesh.createBoundingBox();
            }


            tgcMesh.Enabled = true;
            return(tgcMesh);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Crea un mesh sin texturas, solo con VertexColors
        /// </summary>
        /// <param name="meshData"></param>
        private TgcSkeletalMesh crearMeshSoloColor(TgcSkeletalMeshData meshData)
        {
            //Crear Mesh
            Mesh mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, VertexColorVertexElements, device);

            //Cargar esqueleto
            TgcSkeletalBone[] bones = loadSkeleton(meshData);
            TgcSkeletalVertexWeight[] verticesWeights = loadVerticesWeights(meshData, bones);

            //Cargar VertexBuffer
            using (VertexBuffer vb = mesh.VertexBuffer)
            {
                GraphicsStream data = vb.Lock(0, 0, LockFlags.None);
                for (int j = 0; j < meshData.coordinatesIndices.Length; j++)
                {
                    VertexColorVertex v = new VertexColorVertex();

                    //vertices
                    int coordIdx = meshData.coordinatesIndices[j] * 3;
                    v.Position = new Vector3(
                        meshData.verticesCoordinates[coordIdx],
                        meshData.verticesCoordinates[coordIdx + 1],
                        meshData.verticesCoordinates[coordIdx + 2]
                        );

                    //color
                    int colorIdx = meshData.colorIndices[j];
                    v.Color = meshData.verticesColors[colorIdx];

                    //normal
                    if (meshData.verticesNormals != null)
                    {
                        v.Normal = new Vector3(
                            meshData.verticesNormals[coordIdx],
                            meshData.verticesNormals[coordIdx + 1],
                            meshData.verticesNormals[coordIdx + 2]
                            );
                    }
                    else
                    {
                        v.Normal = new Vector3(0, 0, 0);
                    }

                    //tangent
                    if (meshData.verticesTangents != null)
                    {
                        v.Tangent = new Vector3(
                            meshData.verticesTangents[coordIdx],
                            meshData.verticesTangents[coordIdx + 1],
                            meshData.verticesTangents[coordIdx + 2]
                            );
                    }
                    else
                    {
                        v.Tangent = new Vector3(0, 0, 0);
                    }

                    //binormal
                    if (meshData.verticesBinormals != null)
                    {
                        v.Binormal = new Vector3(
                            meshData.verticesBinormals[coordIdx],
                            meshData.verticesBinormals[coordIdx + 1],
                            meshData.verticesBinormals[coordIdx + 2]
                            );
                    }
                    else
                    {
                        v.Binormal = new Vector3(0, 0, 0);
                    }



                    //BlendWeights y BlendIndices
                    TgcSkeletalVertexWeight vWeight = verticesWeights[meshData.coordinatesIndices[j]];
                    vWeight.createVector4WeightsAndIndices(out v.BlendWeights, out v.BlendIndices);


                    data.Write(v);
                }
                vb.Unlock();
            }

            //Cargar indexBuffer en forma plana
            using (IndexBuffer ib = mesh.IndexBuffer)
            {
                short[] indices = new short[meshData.coordinatesIndices.Length];
                for (int i = 0; i < indices.Length; i++)
                {
                    indices[i] = (short)i;
                }
                ib.SetData(indices, 0, LockFlags.None);
            }

            //Crear mesh de TGC
            TgcSkeletalMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcSkeletalMesh.MeshRenderType.VERTEX_COLOR, bones);
            return tgcMesh;
        }
Exemplo n.º 15
0
        /// <summary>
        /// Crea un mesh sin texturas, solo con VertexColors
        /// </summary>
        /// <param name="meshData"></param>
        private TgcSkeletalMesh crearMeshSoloColor(TgcSkeletalMeshData meshData)
        {
            //Crear Mesh
            Mesh mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, VertexColorVertexElements, device);

            //Cargar VertexBuffer
            using (VertexBuffer vb = mesh.VertexBuffer)
            {
                GraphicsStream data = vb.Lock(0, 0, LockFlags.None);
                for (int j = 0; j < meshData.coordinatesIndices.Length; j++)
                {
                    VertexColorVertex v = new VertexColorVertex();

                    //vertices
                    int coordIdx = meshData.coordinatesIndices[j] * 3;
                    v.Position = new Vector3(
                        meshData.verticesCoordinates[coordIdx],
                        meshData.verticesCoordinates[coordIdx + 1],
                        meshData.verticesCoordinates[coordIdx + 2]
                        );

                    //color
                    int colorIdx = meshData.colorIndices[j];
                    v.Color = meshData.verticesColors[colorIdx];

                    data.Write(v);
                }
                vb.Unlock();
            }

            //Cargar indexBuffer en forma plana
            using (IndexBuffer ib = mesh.IndexBuffer)
            {
                short[] indices = new short[meshData.coordinatesIndices.Length];
                for (int i = 0; i < indices.Length; i++)
                {
                    indices[i] = (short)i;
                }
                ib.SetData(indices, 0, LockFlags.None);
            }

            //Cargar esqueleto
            TgcSkeletalBone[] bones = loadSkeleton(meshData);
            TgcSkeletalVertexWeight[] verticesWeights = loadVerticesWeights(meshData, bones);

            //Cargar datos de meshData que interesan mantener como originales
            TgcSkeletalMesh.OriginalData origData = new TgcSkeletalMesh.OriginalData();
            origData.coordinatesIndices = meshData.coordinatesIndices;
            origData.verticesCoordinates = meshData.verticesCoordinates;
            origData.colorIndices = meshData.colorIndices;
            origData.verticesColors = meshData.verticesColors;
            origData.texCoordinatesIndices = null;
            origData.textureCoordinates = null;

            //Crear mesh de TGC
            TgcSkeletalMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcSkeletalMesh.MeshRenderType.VERTEX_COLOR, origData, bones, verticesWeights);
            return tgcMesh;
        }
Exemplo n.º 16
0
        /// <summary>
        /// Levanta la informacion del mesh a partir de un XML
        /// </summary>
        /// <param name="xmlString">contenido del XML</param>
        /// <returns></returns>
        public TgcSkeletalMeshData parseMeshFromString(string xmlString)
        {
            XmlDocument dom = new XmlDocument();
            dom.LoadXml(xmlString);
            XmlElement root = dom.DocumentElement;

            TgcSkeletalMeshData meshData = new TgcSkeletalMeshData();

            //Ver si tiene exportacion de texturas
            XmlNode texturesExportNode = root.GetElementsByTagName("texturesExport")[0];
            bool texturesExportEnabled = bool.Parse(texturesExportNode.Attributes["enabled"].InnerText);
            if (texturesExportEnabled)
            {
                meshData.texturesDir = texturesExportNode.Attributes["dir"].InnerText;
            }

            //Parsear Texturas
            XmlNodeList materialNodes = root.GetElementsByTagName("materials")[0].ChildNodes;
            meshData.materialsData = new TgcMaterialData[materialNodes.Count];
            int i = 0;
            foreach (XmlElement matNode in materialNodes)
            {
                //determinar tipo de Material
                TgcMaterialData material = new TgcMaterialData();
                material.type = matNode.Attributes["type"].InnerText;

                //Standard Material
                if (material.type.Equals(TgcMaterialData.StandardMaterial))
                {
                    parseStandardMaterial(material, matNode);

                }

                //Multi Material
                else if (material.type.Equals(TgcMaterialData.MultiMaterial))
                {
                    material.name = matNode.Attributes["name"].InnerText;
                    XmlNodeList subMaterialsNodes = matNode.GetElementsByTagName("subM");
                    material.subMaterials = new TgcMaterialData[subMaterialsNodes.Count];
                    for (int j = 0; j < subMaterialsNodes.Count; j++)
                    {
                        TgcMaterialData subMaterial = new TgcMaterialData();
                        parseStandardMaterial(subMaterial, (XmlElement)subMaterialsNodes[j]);
                        material.subMaterials[j] = subMaterial;
                    }
                }

                meshData.materialsData[i++] = material;
            }

            //Parsear Mesh
            XmlElement meshNode = (XmlElement)root.GetElementsByTagName("mesh")[0];

            //parser y convertir valores
            meshData.name = meshNode.Attributes["name"].InnerText;
            meshData.materialId = int.Parse(meshNode.Attributes["matId"].InnerText);
            meshData.color = TgcParserUtils.parseFloat3Array(meshNode.Attributes["color"].InnerText);

            //TODO: formatear bien visibility
            string visibilityStr = meshNode.Attributes["visibility"].InnerText;

            //boundingBox, si esta
            XmlNodeList boundingBoxNodes = root.GetElementsByTagName("boundingBox");
            if (boundingBoxNodes != null && boundingBoxNodes.Count == 1)
            {
                XmlNode boundingBoxNode = boundingBoxNodes[0];
                meshData.pMin = TgcParserUtils.parseFloat3Array(boundingBoxNode.Attributes["min"].InnerText);
                meshData.pMax = TgcParserUtils.parseFloat3Array(boundingBoxNode.Attributes["max"].InnerText);
            }

            int count;

            //parsear coordinatesIdx
            XmlNode coordinatesIdxNode = meshNode.GetElementsByTagName("coordinatesIdx")[0];
            count = int.Parse(coordinatesIdxNode.Attributes["count"].InnerText);
            meshData.coordinatesIndices = TgcParserUtils.parseIntStream(coordinatesIdxNode.InnerText, count);

            //parsear textCoordsIdx
            XmlNode textCoordsIdxNode = meshNode.GetElementsByTagName("textCoordsIdx")[0];
            count = int.Parse(textCoordsIdxNode.Attributes["count"].InnerText);
            meshData.texCoordinatesIndices = TgcParserUtils.parseIntStream(textCoordsIdxNode.InnerText, count);

            //parsear colorsIdx
            XmlNode colorsIdxNode = meshNode.GetElementsByTagName("colorsIdx")[0];
            count = int.Parse(colorsIdxNode.Attributes["count"].InnerText);
            meshData.colorIndices = TgcParserUtils.parseIntStream(colorsIdxNode.InnerText, count);

            //parsear matIds
            if (meshData.materialsData.Length > 0)
            {
                XmlNode matIdsNode = meshNode.GetElementsByTagName("matIds")[0];
                count = int.Parse(matIdsNode.Attributes["count"].InnerText);
                meshData.materialsIds = TgcParserUtils.parseIntStream(matIdsNode.InnerText, count);
            }

            //parsear vertices
            XmlNode verticesNode = meshNode.GetElementsByTagName("vertices")[0];
            count = int.Parse(verticesNode.Attributes["count"].InnerText);
            meshData.verticesCoordinates = TgcParserUtils.parseFloatStream(verticesNode.InnerText, count);

            //parsear texCoords
            XmlNode texCoordsNode = meshNode.GetElementsByTagName("texCoords")[0];
            count = int.Parse(texCoordsNode.Attributes["count"].InnerText);
            meshData.textureCoordinates = TgcParserUtils.parseFloatStream(texCoordsNode.InnerText, count);

            //parsear colors
            XmlNode colorsNode = meshNode.GetElementsByTagName("colors")[0];
            count = int.Parse(colorsNode.Attributes["count"].InnerText);
            float[] colorsArray = TgcParserUtils.parseFloatStream(colorsNode.InnerText, count);
            //convertir a format TV
            meshData.verticesColors = new int[count / 3];
            for (int j = 0; j < meshData.verticesColors.Length; j++)
            {
                meshData.verticesColors[j] = Color.FromArgb(
                    (int)colorsArray[j * 3],
                    (int)colorsArray[j * 3 + 1],
                    (int)colorsArray[j * 3 + 2]).ToArgb();
            }

            //parsear normals, si hay
            XmlNodeList normalsNodes = meshNode.GetElementsByTagName("normals");
            if (normalsNodes != null && normalsNodes.Count == 1)
            {
                XmlNode normalsNode = normalsNodes[0];
                count = int.Parse(normalsNode.Attributes["count"].InnerText);
                meshData.verticesNormals = TgcParserUtils.parseFloatStream(normalsNode.InnerText, count);
            }

            //parsear tangents, si hay
            XmlNodeList tangentsNodes = meshNode.GetElementsByTagName("tangents");
            if (tangentsNodes != null && tangentsNodes.Count == 1)
            {
                XmlNode tangentsNode = tangentsNodes[0];
                count = int.Parse(tangentsNode.Attributes["count"].InnerText);
                meshData.verticesTangents = TgcParserUtils.parseFloatStream(tangentsNode.InnerText, count);
            }

            //parsear binormals, si hay
            XmlNodeList binormalsNodes = meshNode.GetElementsByTagName("binormals");
            if (binormalsNodes != null && binormalsNodes.Count == 1)
            {
                XmlNode binormalsNode = binormalsNodes[0];
                count = int.Parse(binormalsNode.Attributes["count"].InnerText);
                meshData.verticesBinormals = TgcParserUtils.parseFloatStream(binormalsNode.InnerText, count);
            }

            //parsear esqueleto
            XmlNode skeletonNode = meshNode.GetElementsByTagName("skeleton")[0];
            TgcSkeletalBoneData[] bonesData = new TgcSkeletalBoneData[skeletonNode.ChildNodes.Count];
            int boneCount = 0;
            foreach (XmlElement boneNode in skeletonNode.ChildNodes)
            {
                TgcSkeletalBoneData boneData = new TgcSkeletalBoneData();
                boneData.id = int.Parse(boneNode.Attributes["id"].InnerText);
                boneData.name = boneNode.Attributes["name"].InnerText;
                boneData.parentId = int.Parse(boneNode.Attributes["parentId"].InnerText);
                boneData.startPosition = TgcParserUtils.parseFloat3Array(boneNode.Attributes["pos"].InnerText);
                boneData.startRotation = TgcParserUtils.parseFloat4Array(boneNode.Attributes["rotQuat"].InnerText);

                bonesData[boneCount++] = boneData;
            }
            meshData.bones = bonesData;

            //parsear Weights
            XmlNode weightsNode = meshNode.GetElementsByTagName("weights")[0];
            count = int.Parse(weightsNode.Attributes["count"].InnerText);
            meshData.verticesWeights = TgcParserUtils.parseFloatStream(weightsNode.InnerText, count);

            return meshData;
        }
Exemplo n.º 17
0
        /// <summary>
        /// Cargar Weights de vertices
        /// </summary>
        /// <param name="meshData"></param>
        /// <returns></returns>
        private TgcSkeletalVertexWeight[] loadVerticesWeights(TgcSkeletalMeshData meshData, TgcSkeletalBone[] bones)
        {
            int maxWeights = 4;

            TgcSkeletalVertexWeight.BoneWeight.GreaterComparer weightComparer = new TgcSkeletalVertexWeight.BoneWeight.GreaterComparer();

            //Crear un array de Weights para cada uno de los vertices de la malla
            TgcSkeletalVertexWeight[] weights = new TgcSkeletalVertexWeight[meshData.verticesCoordinates.Length / 3];
            for (int i = 0; i < weights.Length; i++)
            {
                weights[i] = new TgcSkeletalVertexWeight();
            }

            //Cargar los weights de cada vertice
            int weightsCount = meshData.verticesWeights.Length / 3;

            for (int i = 0; i < weightsCount; i++)
            {
                int   vertexIdx = (int)meshData.verticesWeights[i * 3];
                int   boneIdx   = (int)meshData.verticesWeights[i * 3 + 1];
                float weightVal = meshData.verticesWeights[i * 3 + 2];

                TgcSkeletalBone bone = bones[boneIdx];
                TgcSkeletalVertexWeight.BoneWeight weight = new TgcSkeletalVertexWeight.BoneWeight(bone, weightVal);

                weights[vertexIdx].Weights.Add(weight);
            }

            //Normalizar weights de cada vertice
            for (int i = 0; i < weights.Length; i++)
            {
                TgcSkeletalVertexWeight vertexWeight = weights[i];

                //Se soportan hasta 4 weights por vertice. Si hay mas se quitan y se reparten las influencias entre el resto de los huesos
                if (vertexWeight.Weights.Count > maxWeights)
                {
                    //Ordenar por weight de menor a mayor y luego revertir, para que quede de mayor a menor peso
                    vertexWeight.Weights.Sort(weightComparer);
                    vertexWeight.Weights.Reverse();

                    //Quitar los ultimos los weight que superan 4
                    while (vertexWeight.Weights.Count > maxWeights)
                    {
                        vertexWeight.Weights.RemoveAt(vertexWeight.Weights.Count - 1);
                    }
                }

                //Sumar el total de todos los weights de este vertice
                float weightTotal = 0;
                foreach (TgcSkeletalVertexWeight.BoneWeight w in vertexWeight.Weights)
                {
                    weightTotal += w.Weight;
                }

                //Normalizar cada valor segun el total acumulado en el vertice
                foreach (TgcSkeletalVertexWeight.BoneWeight w in vertexWeight.Weights)
                {
                    w.Weight = w.Weight / weightTotal;
                }
            }

            return(weights);
        }