/// <summary>
        /// Crear una malla instancia de una original
        /// </summary>
        private TgcMesh crearMeshInstance(TgcMeshData meshData, List <TgcMesh> meshes)
        {
            TgcMesh    originalMesh = meshes[meshData.originalMesh];
            Vector3    translation  = new Vector3(meshData.position[0], meshData.position[1], meshData.position[2]);
            Quaternion rotationQuat = new Quaternion(meshData.rotation[0], meshData.rotation[1], meshData.rotation[2], meshData.rotation[3]);
            Vector3    rotation     = quaternionToEuler(rotationQuat);
            Vector3    scale        = new Vector3(meshData.scale[0], meshData.scale[1], meshData.scale[2]);

            TgcMesh tgcMesh = new TgcMesh(meshData.name, originalMesh, translation, rotation, scale);

            return(tgcMesh);
        }
Exemple #2
0
 public LightData(TgcMeshData meshData)
 {
     this.color = parserColor(meshData.userProperties["color"]);
             this.aabb = new TgcBoundingBox(TgcParserUtils.float3ArrayToVector3(meshData.pMin), TgcParserUtils.float3ArrayToVector3(meshData.pMax));
             this.pos = this.aabb.calculateBoxCenter();
             this.spot = meshData.userProperties["esSpot"].Equals("SI");
             this.direccion = convertirDireccion(meshData.userProperties["dir"]);
             this.intencidad = float.Parse(meshData.userProperties["inten"]);
             this.atenuacion = float.Parse(meshData.userProperties["atenua"])/10;
             this.angleCos = float.Parse(meshData.userProperties["angleCos"]);
             this.exp = float.Parse(meshData.userProperties["exp"]);
 }
        /// <summary>
        /// Levanta la informacion del XML
        /// </summary>
        /// <param name="xmlString">contenido del XML</param>
        /// <returns></returns>
        public TgcSceneData parseSceneFromString(string xmlString)
        {
            XmlDocument dom = new XmlDocument();

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

            string       sceneName    = root.GetElementsByTagName("name")[0].InnerText;
            TgcSceneData tgcSceneData = new TgcSceneData();

            tgcSceneData.name = sceneName;

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

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

            //Ver si tiene LightMaps
            XmlNode lightmapsExportNode = root.GetElementsByTagName("lightmapExport")[0];

            tgcSceneData.lightmapsEnabled = bool.Parse(lightmapsExportNode.Attributes["enabled"].InnerText);
            if (tgcSceneData.lightmapsEnabled)
            {
                tgcSceneData.lightmapsDir = lightmapsExportNode.Attributes["dir"].InnerText;
            }

            //sceneBoundingBox, si está
            XmlNodeList sceneBoundingBoxNodes = root.GetElementsByTagName("sceneBoundingBox");

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


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

            tgcSceneData.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;
                    }
                }

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



            //Parsear Meshes
            XmlNodeList meshesNodes = root.GetElementsByTagName("meshes")[0].ChildNodes;

            tgcSceneData.meshesData = new TgcMeshData[meshesNodes.Count];
            i = 0;
            int count;

            foreach (XmlElement meshNode in meshesNodes)
            {
                TgcMeshData meshData = new TgcMeshData();
                tgcSceneData.meshesData[i++] = meshData;

                //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);
                meshData.lightmap   = meshNode.Attributes["lightmap"].InnerText;

                //type
                XmlAttribute typeAttr = meshNode.Attributes["type"];
                meshData.instanceType = TgcMeshData.ORIGINAL;
                if (typeAttr != null)
                {
                    meshData.instanceType = typeAttr.InnerText;
                }

                //type
                XmlAttribute layerAttr = meshNode.Attributes["layer"];
                if (layerAttr != null)
                {
                    meshData.layerName = layerAttr.InnerText;
                }

                //visibility
                float visibility = TgcParserUtils.parseFloat(meshNode.Attributes["visibility"].InnerText);
                meshData.alphaBlending = visibility != 1.0f ? true : false;

                //parsear boundingBox
                XmlNodeList boundingBoxNodes = meshNode.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);
                }

                //parsear datos de mesh Original
                if (meshData.instanceType.Equals(TgcMeshData.ORIGINAL))
                {
                    //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
                    //TODO: ver bien como calcula esto el SCRIPT de Exportacion
                    if (meshData.materialId != -1)
                    {
                        XmlNode matIdsNode = meshNode.GetElementsByTagName("matIds")[0];
                        count = int.Parse(matIdsNode.Attributes["count"].InnerText);
                        meshData.materialsIds = TgcParserUtils.parseIntStream(matIdsNode.InnerText, count);
                    }

                    //parsear textCoordsLightMapIdx
                    meshData.lightmapEnabled = tgcSceneData.lightmapsEnabled && (meshData.lightmap.Trim()).Length > 0;
                    if (meshData.lightmapEnabled)
                    {
                        XmlNode textCoordsLightMapIdxNode = meshNode.GetElementsByTagName("textCoordsLightMapIdx")[0];
                        count = int.Parse(textCoordsLightMapIdxNode.Attributes["count"].InnerText);
                        meshData.texCoordinatesIndicesLightMap = TgcParserUtils.parseIntStream(textCoordsLightMapIdxNode.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 normals
                    XmlNode normalsNode = meshNode.GetElementsByTagName("normals")[0];
                    count = int.Parse(normalsNode.Attributes["count"].InnerText);
                    meshData.verticesNormals = TgcParserUtils.parseFloatStream(normalsNode.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 formato DirectX
                    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 texCoordsLightMap
                    if (meshData.lightmapEnabled)
                    {
                        XmlNode texCoordsLightMapNode = meshNode.GetElementsByTagName("texCoordsLightMap")[0];
                        count = int.Parse(texCoordsLightMapNode.Attributes["count"].InnerText);
                        meshData.textureCoordinatesLightMap = TgcParserUtils.parseFloatStream(texCoordsLightMapNode.InnerText, count);
                    }
                }

                //parsear datos de mesh Instancia
                else if (meshData.instanceType.Equals(TgcMeshData.INSTANCE))
                {
                    //originalMesh
                    XmlNode originalMeshNode = meshNode.GetElementsByTagName("originalMesh")[0];
                    meshData.originalMesh = TgcParserUtils.parseInt(originalMeshNode.InnerText);

                    //transform
                    XmlNode transformNode = meshNode.GetElementsByTagName("transform")[0];
                    meshData.position = TgcParserUtils.parseFloat3Array(transformNode.Attributes["pos"].InnerText);
                    meshData.rotation = TgcParserUtils.parseFloat4Array(transformNode.Attributes["rotQuat"].InnerText);
                    meshData.scale    = TgcParserUtils.parseFloat3Array(transformNode.Attributes["scale"].InnerText);
                }

                //Parsear userProperties, si hay
                XmlNodeList userPropsNodes = meshNode.GetElementsByTagName("userProps");
                if (userPropsNodes != null && userPropsNodes.Count == 1)
                {
                    meshData.userProperties = new Dictionary <string, string>();
                    XmlElement userPropsNode = (XmlElement)userPropsNodes[0];
                    foreach (XmlElement prop in userPropsNode.ChildNodes)
                    {
                        meshData.userProperties.Add(prop.Name, prop.InnerText);
                    }
                }
            }


            //Parsear PortalRendering, si hay información
            XmlNodeList portalRenderingNodes = root.GetElementsByTagName("portalRendering");

            if (portalRenderingNodes != null && portalRenderingNodes.Count == 1)
            {
                XmlElement portalRenderingNode        = (XmlElement)portalRenderingNodes[0];
                TgcPortalRenderingParser portalParser = new TgcPortalRenderingParser();
                tgcSceneData.portalData = portalParser.parseFromXmlNode(portalRenderingNode);
            }



            return(tgcSceneData);
        }
 public static RTLLight loadLight(TgcMeshData data)
 {
     return new RTLLight();
 }
 public static bool isLight(TgcMeshData data)
 {
     return loaders.ContainsKey(data.layerName);
 }
        /// <summary>
        /// Toma los datos de un TgcMesh y los exporta a un formato de objetos plano
        /// </summary>
        /// <param name="tgcMesh">Malla a exportar</param>
        /// <returns>Datos de la malla en objetos</returns>
        public MeshExport exportMeshData(TgcMesh tgcMesh, List<TgcMesh> sceneMeshes)
        {
            try
            {
                MeshExport meshExport = new MeshExport();
                TgcMeshData meshData = new TgcMeshData();
                meshExport.MeshData = meshData;
                meshExport.MaterialsData = null;
                meshExport.diffuseMapsAbsolutePath = null;

                //General
                meshExport.MeshData.name = tgcMesh.Name;
                meshExport.MeshData.layerName = tgcMesh.Layer;
                meshExport.MeshRenderType = tgcMesh.RenderType;
                meshExport.MeshData.pMin = TgcParserUtils.vector3ToFloat3Array(tgcMesh.BoundingBox.PMin);
                meshExport.MeshData.pMax = TgcParserUtils.vector3ToFloat3Array(tgcMesh.BoundingBox.PMax);
                meshExport.MeshData.userProperties = tgcMesh.UserProperties;
                meshExport.MeshData.alphaBlending = tgcMesh.AlphaBlendEnable;

                //Exportar malla original
                if (tgcMesh.ParentInstance == null)
                {
                    meshExport.MeshData.instanceType = TgcMeshData.ORIGINAL;

                    //Exportar segun el tipo de Mesh
                    switch (tgcMesh.RenderType)
                    {
                        case TgcMesh.MeshRenderType.VERTEX_COLOR:
                            exportMeshVertexColor(tgcMesh, meshExport, meshData);
                            break;

                        case TgcMesh.MeshRenderType.DIFFUSE_MAP:
                            exportMeshDiffuseMap(tgcMesh, meshExport, meshData);
                            break;

                        case TgcMesh.MeshRenderType.DIFFUSE_MAP_AND_LIGHTMAP:
                            exportMeshDiffuseMapAndLightmap(tgcMesh, meshExport, meshData);
                            break;
                    }
                }

                //Exportar malla instancia
                else
                {
                    meshExport.MeshData.instanceType = TgcMeshData.INSTANCE;

                    //Buscar indice de original
                    TgcMesh parentInstance = tgcMesh.ParentInstance;
                    int parentIdx = -1;
                    for (int i = 0; i < sceneMeshes.Count; i++)
                    {
                         if(parentInstance.Equals(sceneMeshes[i]))
                         {
                             parentIdx = i;
                             break;
                         }
                    }
                    meshExport.MeshData.originalMesh = parentIdx;

                    //TODO: la rotación no se exporta correctamente cuando la malla original esta rotada

                    //Posicion, rotacion y escala con diferencia de la malla original
                    meshExport.MeshData.position = TgcParserUtils.vector3ToFloat3Array(tgcMesh.Position - parentInstance.Position);
                    Quaternion rotQuat = Quaternion.RotationYawPitchRoll(tgcMesh.Rotation.Y, tgcMesh.Rotation.X, tgcMesh.Rotation.Z);
                    Quaternion parentRotQuat = Quaternion.RotationYawPitchRoll(parentInstance.Rotation.Y, parentInstance.Rotation.X, parentInstance.Rotation.Z);
                    meshExport.MeshData.rotation = TgcParserUtils.quaternionToFloat4Array(rotQuat - parentRotQuat);
                    Vector3 scale = new Vector3(
                        tgcMesh.Scale.X / parentInstance.Scale.X,
                        tgcMesh.Scale.Y / parentInstance.Scale.Y,
                        tgcMesh.Scale.Z / parentInstance.Scale.Z
                        );
                    meshExport.MeshData.scale = TgcParserUtils.vector3ToFloat3Array(scale);
                }

                return meshExport;
            }
            catch (Exception ex)
            {
                throw new Exception("Error al intentar obtener datos de Mesh para exportar. MeshName: " + tgcMesh.Name, ex);
            }
        }
        /// <summary>
        /// Exportar datos de Mesh de tipo TgcMesh.MeshRenderType.VERTEX_COLOR
        /// </summary>
        private void exportMeshVertexColor(TgcMesh tgcMesh, MeshExport meshExport, TgcMeshData meshData)
        {
            //Marcar todo lo que no tiene
            meshData.lightmap = null;
            meshData.texCoordinatesIndices = new int[0];
            meshData.textureCoordinates = new float[0];
            meshData.texCoordinatesIndicesLightMap = new int[0];
            meshData.textureCoordinatesLightMap = new float[0];
            meshExport.MaterialsData = null;
            meshExport.diffuseMapsAbsolutePath = null;
            meshExport.lightmapAbsolutePath = null;
            meshData.materialId = -1;
            meshData.materialsIds = new int[0];

            //Color general
            Color defaultColor = Color.White;
            ColorValue defaultColorValue = ColorValue.FromColor(defaultColor);
            meshData.color = new float[] { defaultColorValue.Red, defaultColorValue.Green, defaultColorValue.Blue };

            //Obtener datos del VertexBuffer
            TgcSceneLoader.VertexColorVertex[] vbData = (TgcSceneLoader.VertexColorVertex[])tgcMesh.D3dMesh.LockVertexBuffer(
                typeof(TgcSceneLoader.VertexColorVertex),
                LockFlags.ReadOnly,
                tgcMesh.D3dMesh.NumberVertices);
            tgcMesh.D3dMesh.UnlockVertexBuffer();

            short[] indices = (short[])tgcMesh.D3dMesh.LockIndexBuffer(typeof(short), LockFlags.ReadOnly, tgcMesh.D3dMesh.NumberFaces * 3);
            tgcMesh.D3dMesh.UnlockIndexBuffer();

            //Armar buffer de vertices, normales y coordenadas de textura, buscando similitudes de valores
            List<int> coordinatesIndices = new List<int>();
            List<int> colorIndices = new List<int>();
            List<Vector3> verticesCoordinates = new List<Vector3>();
            List<int> verticesColors = new List<int>();
            List<Vector3> verticesNormals = new List<Vector3>();
            for (int i = 0; i < indices.Length; i++)
            {
                TgcSceneLoader.VertexColorVertex vertexData = vbData[indices[i]];
                Vector3 position = Vector3.TransformCoordinate(vertexData.Position, tgcMesh.Transform);

                int coordIdx = addVertex(coordinatesIndices, verticesCoordinates, position);
                addNormal(verticesNormals, coordIdx, vertexData.Normal);
                addColor(colorIndices, verticesColors, vertexData.Color);

            }

            //Cargar array de vertices
            meshData.coordinatesIndices = coordinatesIndices.ToArray();
            meshData.verticesCoordinates = new float[verticesCoordinates.Count * 3];
            for (int i = 0; i < verticesCoordinates.Count; i++)
            {
                Vector3 v = verticesCoordinates[i];
                meshData.verticesCoordinates[i * 3] = v.X;
                meshData.verticesCoordinates[i * 3 + 1] = v.Y;
                meshData.verticesCoordinates[i * 3 + 2] = v.Z;
            }

            //Cargar array de normales
            meshData.verticesNormals = new float[verticesNormals.Count * 3];
            for (int i = 0; i < verticesNormals.Count; i++)
            {
                Vector3 n = verticesNormals[i];
                meshData.verticesNormals[i * 3] = n.X;
                meshData.verticesNormals[i * 3 + 1] = n.Y;
                meshData.verticesNormals[i * 3 + 2] = n.Z;
            }

            //Cargar array de colores
            meshData.colorIndices = colorIndices.ToArray();
            meshData.verticesColors = new int[verticesColors.Count * 3];
            for (int i = 0; i < verticesColors.Count; i++)
            {
                Color c = Color.FromArgb(verticesColors[i]);
                meshData.verticesColors[i * 3] = c.R;
                meshData.verticesColors[i * 3 + 1] = c.G;
                meshData.verticesColors[i * 3 + 2] = c.B;
            }
        }
        /// <summary>
        /// Exportar datos de Mesh de formato TgcMesh.MeshRenderType.DIFFUSE_MAP_AND_LIGHTMAP
        /// </summary>
        private void exportMeshDiffuseMapAndLightmap(TgcMesh tgcMesh, MeshExport meshExport, TgcMeshData meshData)
        {
            //Obtener datos del VertexBuffer
            TgcSceneLoader.DiffuseMapAndLightmapVertex[] vbData = (TgcSceneLoader.DiffuseMapAndLightmapVertex[])tgcMesh.D3dMesh.LockVertexBuffer(
                typeof(TgcSceneLoader.DiffuseMapAndLightmapVertex),
                LockFlags.ReadOnly,
                tgcMesh.D3dMesh.NumberVertices);
            tgcMesh.D3dMesh.UnlockVertexBuffer();

            short[] indices = (short[])tgcMesh.D3dMesh.LockIndexBuffer(typeof(short), LockFlags.ReadOnly, tgcMesh.D3dMesh.NumberFaces * 3);
            tgcMesh.D3dMesh.UnlockIndexBuffer();

            //Color general
            Color defaultColor = Color.White;
            ColorValue defaultColorValue = ColorValue.FromColor(defaultColor);
            meshData.color = new float[] { defaultColorValue.Red, defaultColorValue.Green, defaultColorValue.Blue };

            //Armar buffer de vertices, normales y coordenadas de textura, buscando similitudes de valores
            List<int> coordinatesIndices = new List<int>();
            List<int> texCoordinatesIndices = new List<int>();
            List<int> texCoordinatesIndicesLightMap = new List<int>();
            List<Vector3> verticesCoordinates = new List<Vector3>();
            List<Vector2> textureCoordinates = new List<Vector2>();
            List<Vector2> textureCoordinatesLightMap = new List<Vector2>();
            List<Vector3> verticesNormals = new List<Vector3>();
            List<int> colorIndices = new List<int>();
            List<int> verticesColors = new List<int>();

            for (int i = 0; i < indices.Length; i++)
            {
                TgcSceneLoader.DiffuseMapAndLightmapVertex vertexData = vbData[indices[i]];
                Vector3 position = Vector3.TransformCoordinate(vertexData.Position, tgcMesh.Transform);

                int coordIdx = addVertex(coordinatesIndices, verticesCoordinates, position);
                addNormal(verticesNormals, coordIdx, vertexData.Normal);
                addTextureCoordinates(texCoordinatesIndices, textureCoordinates, new Vector2(vertexData.Tu0, vertexData.Tv0));
                addTextureCoordinates(texCoordinatesIndicesLightMap, textureCoordinatesLightMap, new Vector2(vertexData.Tu1, vertexData.Tv1));
                addColor(colorIndices, verticesColors, vertexData.Color);
            }

            //Cargar array de vertices
            meshData.coordinatesIndices = coordinatesIndices.ToArray();
            meshData.verticesCoordinates = new float[verticesCoordinates.Count * 3];
            for (int i = 0; i < verticesCoordinates.Count; i++)
            {
                Vector3 v = verticesCoordinates[i];
                meshData.verticesCoordinates[i * 3] = v.X;
                meshData.verticesCoordinates[i * 3 + 1] = v.Y;
                meshData.verticesCoordinates[i * 3 + 2] = v.Z;
            }

            //Cargar array de normales
            meshData.verticesNormals = new float[verticesNormals.Count * 3];
            for (int i = 0; i < verticesNormals.Count; i++)
            {
                Vector3 n = verticesNormals[i];
                meshData.verticesNormals[i * 3] = n.X;
                meshData.verticesNormals[i * 3 + 1] = n.Y;
                meshData.verticesNormals[i * 3 + 2] = n.Z;
            }

            //Cargar array de coordenadas de textura
            meshData.texCoordinatesIndices = texCoordinatesIndices.ToArray();
            meshData.textureCoordinates = new float[textureCoordinates.Count * 2];
            for (int i = 0; i < textureCoordinates.Count; i++)
            {
                Vector2 t = textureCoordinates[i];
                meshData.textureCoordinates[i * 2] = t.X;
                meshData.textureCoordinates[i * 2 + 1] = t.Y;
            }

            //Cargar array de coordenadas de textura de Lightmap
            meshData.texCoordinatesIndicesLightMap = texCoordinatesIndicesLightMap.ToArray();
            meshData.textureCoordinatesLightMap = new float[textureCoordinatesLightMap.Count * 2];
            for (int i = 0; i < textureCoordinatesLightMap.Count; i++)
            {
                Vector2 t = textureCoordinatesLightMap[i];
                meshData.textureCoordinatesLightMap[i * 2] = t.X;
                meshData.textureCoordinatesLightMap[i * 2 + 1] = t.Y;
            }

            //Cargar array de colores
            meshData.colorIndices = colorIndices.ToArray();
            meshData.verticesColors = new int[verticesColors.Count * 3];
            for (int i = 0; i < verticesColors.Count; i++)
            {
                Color c = Color.FromArgb(verticesColors[i]);
                meshData.verticesColors[i * 3] = c.R;
                meshData.verticesColors[i * 3 + 1] = c.G;
                meshData.verticesColors[i * 3 + 2] = c.B;
            }

            //Exportar Materials y DiffuseMaps
            exportMaterialData(tgcMesh, meshExport, meshData);

            //Exportar Lightmap
            TgcTexture tgcLightmap = tgcMesh.LightMap;
            meshData.lightmap = tgcLightmap.FileName;
            meshExport.lightmapAbsolutePath = tgcLightmap.FilePath;
        }
        /// <summary>
        /// Exportar datos de Material
        /// </summary>
        private void exportMaterialData(TgcMesh tgcMesh, MeshExport meshExport, TgcMeshData meshData)
        {
            //Exportar diffuseMap y material simple
            bool alphaBlendEnabled = false;
            if (tgcMesh.Materials.Length == 1)
            {
                TgcMaterialData materialData = new TgcMaterialData();
                meshExport.MaterialsData = new TgcMaterialData[] { materialData };

                //Material
                Material tgcMaterial = tgcMesh.Materials[0];
                materialData.type = TgcMaterialData.StandardMaterial;
                materialData.name = TgcMaterialData.StandardMaterial;
                materialData.subMaterials = null;

                materialData.ambientColor = new float[]{
                            tgcMaterial.AmbientColor.Red,
                            tgcMaterial.AmbientColor.Green,
                            tgcMaterial.AmbientColor.Blue,
                            tgcMaterial.AmbientColor.Alpha,
                        };
                materialData.diffuseColor = new float[]{
                            tgcMaterial.DiffuseColor.Red,
                            tgcMaterial.DiffuseColor.Green,
                            tgcMaterial.DiffuseColor.Blue,
                            tgcMaterial.DiffuseColor.Alpha,
                        };
                materialData.specularColor = new float[]{
                            tgcMaterial.SpecularColor.Red,
                            tgcMaterial.SpecularColor.Green,
                            tgcMaterial.SpecularColor.Blue,
                            tgcMaterial.SpecularColor.Alpha,
                        };
                materialData.opacity = 1f;
                materialData.alphaBlendEnable = tgcMesh.AlphaBlendEnable;

                //Texture
                TgcTexture tgcTexture = tgcMesh.DiffuseMaps[0];
                materialData.fileName = tgcTexture.FileName;
                materialData.uvOffset = new float[] { 1f, 1f };
                materialData.uvTiling = new float[] { 1f, 1f };
                meshExport.diffuseMapsAbsolutePath = new string[] { tgcTexture.FilePath };

                //Configurar mesh
                meshData.materialId = 0;
                meshData.materialsIds = new int[] { meshData.materialId };

            }
            //Exportar varios diffuseMaps y materials
            else
            {
                meshExport.MaterialsData = new TgcMaterialData[tgcMesh.Materials.Length];
                meshExport.diffuseMapsAbsolutePath = new string[tgcMesh.Materials.Length];
                for (int i = 0; i < tgcMesh.Materials.Length; i++)
                {
                    //Material
                    Material tgcMaterial = tgcMesh.Materials[i];
                    TgcMaterialData materialData = new TgcMaterialData();
                    meshExport.MaterialsData[i] = materialData;
                    materialData.type = TgcMaterialData.StandardMaterial;
                    materialData.name = TgcMaterialData.StandardMaterial;
                    materialData.subMaterials = null;

                    materialData.ambientColor = new float[]{
                                tgcMaterial.AmbientColor.Red,
                                tgcMaterial.AmbientColor.Green,
                                tgcMaterial.AmbientColor.Blue,
                                tgcMaterial.AmbientColor.Alpha,
                            };
                    materialData.diffuseColor = new float[]{
                                tgcMaterial.DiffuseColor.Red,
                                tgcMaterial.DiffuseColor.Green,
                                tgcMaterial.DiffuseColor.Blue,
                                tgcMaterial.DiffuseColor.Alpha,
                            };
                    materialData.specularColor = new float[]{
                                tgcMaterial.SpecularColor.Red,
                                tgcMaterial.SpecularColor.Green,
                                tgcMaterial.SpecularColor.Blue,
                                tgcMaterial.SpecularColor.Alpha,
                            };
                    materialData.opacity = 1f;
                    materialData.alphaBlendEnable = tgcMesh.AlphaBlendEnable;

                    //Texture
                    TgcTexture tgcTexture = tgcMesh.DiffuseMaps[i];
                    materialData.fileName = tgcTexture.FileName;
                    materialData.uvOffset = new float[] { 1f, 1f };
                    materialData.uvTiling = new float[] { 1f, 1f };
                    meshExport.diffuseMapsAbsolutePath[i] = tgcTexture.FilePath;
                }

                //Configurar Mesh
                meshData.materialId = 0;
                meshData.materialsIds = tgcMesh.D3dMesh.LockAttributeBufferArray(LockFlags.ReadOnly);
                tgcMesh.D3dMesh.UnlockAttributeBuffer();
            }
        }
Exemple #10
0
        /// <summary>
        /// Crea un mesh sin texturas, solo con VertexColors
        /// </summary>
        /// <param name="meshData"></param>
        private TgcMesh crearMeshSoloColor(TgcMeshData 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]
                        );

                    //normals
                    //puede haber una normal compartida para cada vertice del mesh
                    if (meshData.verticesNormals.Length == meshData.verticesCoordinates.Length)
                    {
                        v.Normal = new Vector3(
                            meshData.verticesNormals[coordIdx],
                            meshData.verticesNormals[coordIdx + 1],
                            meshData.verticesNormals[coordIdx + 2]
                            );
                    }
                    //o una normal propia por cada vertice de cada triangulo (version mejorada del exporter)
                    else
                    {
                        int normalIdx = j * 3;
                        v.Normal = new Vector3(
                            meshData.verticesNormals[normalIdx],
                            meshData.verticesNormals[normalIdx + 1],
                            meshData.verticesNormals[normalIdx + 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);
            }

            //Crear mesh de TGC
            TgcMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcMesh.MeshRenderType.VERTEX_COLOR);
            return tgcMesh;
        }
Exemple #11
0
        /// <summary>
        /// Crear una malla instancia de una original
        /// </summary>
        private TgcMesh crearMeshInstance(TgcMeshData meshData, List<TgcMesh> meshes)
        {
            TgcMesh originalMesh = meshes[meshData.originalMesh];
            Vector3 translation = new Vector3(meshData.position[0], meshData.position[1], meshData.position[2]);
            Quaternion rotationQuat = new Quaternion(meshData.rotation[0], meshData.rotation[1], meshData.rotation[2], meshData.rotation[3]);
            Vector3 rotation = quaternionToEuler(rotationQuat);
            Vector3 scale = new Vector3(meshData.scale[0], meshData.scale[1], meshData.scale[2]);

            TgcMesh tgcMesh = new TgcMesh(meshData.name, originalMesh, translation, rotation, scale);
            return tgcMesh;
        }
Exemple #12
0
        /// <summary>
        /// Crea un mesh con uno o varios DiffuseMap y un Lightmap
        /// </summary>
        /// <returns></returns>
        private TgcMesh crearMeshDiffuseMapLightmap(TgcSceneData sceneData, string mediaPath, TgcSceneLoaderMaterialAux[] materialsArray, TgcMeshData meshData)
        {
            //Crear Mesh
            Mesh mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, DiffuseMapAndLightmapVertexElements, 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++)
                {
                    DiffuseMapAndLightmapVertex v = new DiffuseMapAndLightmapVertex();

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

                    //normals
                    //puede haber una normal compartida para cada vertice del mesh
                    if (meshData.verticesNormals.Length == meshData.verticesCoordinates.Length)
                    {
                        v.Normal = new Vector3(
                            meshData.verticesNormals[coordIdx],
                            meshData.verticesNormals[coordIdx + 1],
                            meshData.verticesNormals[coordIdx + 2]
                            );
                    }
                    //o una normal propia por cada vertice de cada triangulo (version mejorada del exporter)
                    else
                    {
                        int normalIdx = j * 3;
                        v.Normal = new Vector3(
                            meshData.verticesNormals[normalIdx],
                            meshData.verticesNormals[normalIdx + 1],
                            meshData.verticesNormals[normalIdx + 2]
                            );
                    }

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

                    //texture coordinates LightMap
                    int texCoordIdxLM = meshData.texCoordinatesIndicesLightMap[j] * 2;
                    v.Tu1 = meshData.textureCoordinatesLightMap[texCoordIdxLM];
                    v.Tv1 = meshData.textureCoordinatesLightMap[texCoordIdxLM + 1];

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

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

            }

            //Cargar IndexBuffer
            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
            TgcSceneLoaderMaterialAux 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 lightMap
            TgcTexture lightMap = TgcTexture.createTexture(device, meshData.lightmap, mediaPath + sceneData.lightmapsDir + "\\" + meshData.lightmap);

            //Crear mesh de TGC
            TgcMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcMesh.MeshRenderType.DIFFUSE_MAP_AND_LIGHTMAP);
            tgcMesh.Materials = meshMaterials;
            tgcMesh.DiffuseMaps = meshTextures;
            tgcMesh.LightMap = lightMap;
            return tgcMesh;
        }
Exemple #13
0
        /// <summary>
        /// Levanta la informacion del XML
        /// </summary>
        /// <param name="xmlString">contenido del XML</param>
        /// <returns></returns>
        public TgcSceneData parseSceneFromString(string xmlString)
        {
            XmlDocument dom = new XmlDocument();
            dom.LoadXml(xmlString);
            XmlElement root = dom.DocumentElement;

            string sceneName = root.GetElementsByTagName("name")[0].InnerText;
            TgcSceneData tgcSceneData = new TgcSceneData();
            tgcSceneData.name = sceneName;

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

            //Ver si tiene LightMaps
            XmlNode lightmapsExportNode = root.GetElementsByTagName("lightmapExport")[0];
            tgcSceneData.lightmapsEnabled = bool.Parse(lightmapsExportNode.Attributes["enabled"].InnerText);
            if (tgcSceneData.lightmapsEnabled)
            {
                tgcSceneData.lightmapsDir = lightmapsExportNode.Attributes["dir"].InnerText;
            }

            //sceneBoundingBox, si está
            XmlNodeList sceneBoundingBoxNodes = root.GetElementsByTagName("sceneBoundingBox");
            if (sceneBoundingBoxNodes != null && sceneBoundingBoxNodes.Count == 1)
            {
                XmlNode sceneBoundingBoxNode = sceneBoundingBoxNodes[0];
                tgcSceneData.pMin = TgcParserUtils.parseFloat3Array(sceneBoundingBoxNode.Attributes["min"].InnerText);
                tgcSceneData.pMax = TgcParserUtils.parseFloat3Array(sceneBoundingBoxNode.Attributes["max"].InnerText);
            }


            //Parsear Texturas
            XmlNodeList materialNodes = root.GetElementsByTagName("materials")[0].ChildNodes;
            tgcSceneData.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;
                    }
                }

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



            //Parsear Meshes
            XmlNodeList meshesNodes = root.GetElementsByTagName("meshes")[0].ChildNodes;
            tgcSceneData.meshesData = new TgcMeshData[meshesNodes.Count];
            i = 0;
            int count;
            foreach (XmlElement meshNode in meshesNodes)
            {
                TgcMeshData meshData = new TgcMeshData();
                tgcSceneData.meshesData[i++] = meshData;

                //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);
                meshData.lightmap = meshNode.Attributes["lightmap"].InnerText;

                //type
                XmlAttribute typeAttr = meshNode.Attributes["type"];
                meshData.instanceType = TgcMeshData.ORIGINAL;
                if (typeAttr != null)
                {
                    meshData.instanceType = typeAttr.InnerText;
                }

                //layer
                XmlAttribute layerAttr = meshNode.Attributes["layer"];
                if (layerAttr != null)
                {
                    meshData.layerName = layerAttr.InnerText;
                }

                //visibility
                float visibility = TgcParserUtils.parseFloat(meshNode.Attributes["visibility"].InnerText);
                meshData.alphaBlending = visibility != 1.0f ? true : false;

                //parsear boundingBox
                XmlNodeList boundingBoxNodes = meshNode.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);
                }

                //parsear datos de mesh Original
                if (meshData.instanceType.Equals(TgcMeshData.ORIGINAL))
                {
                    //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
                    //TODO: ver bien como calcula esto el SCRIPT de Exportacion
                    if (meshData.materialId != -1)
                    {
                        XmlNode matIdsNode = meshNode.GetElementsByTagName("matIds")[0];
                        count = int.Parse(matIdsNode.Attributes["count"].InnerText);
                        meshData.materialsIds = TgcParserUtils.parseIntStream(matIdsNode.InnerText, count);
                    }

                    //parsear textCoordsLightMapIdx
                    meshData.lightmapEnabled = tgcSceneData.lightmapsEnabled && (meshData.lightmap.Trim()).Length > 0;
                    if (meshData.lightmapEnabled)
                    {
                        XmlNode textCoordsLightMapIdxNode = meshNode.GetElementsByTagName("textCoordsLightMapIdx")[0];
                        count = int.Parse(textCoordsLightMapIdxNode.Attributes["count"].InnerText);
                        meshData.texCoordinatesIndicesLightMap = TgcParserUtils.parseIntStream(textCoordsLightMapIdxNode.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 normals
                    XmlNode normalsNode = meshNode.GetElementsByTagName("normals")[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 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 formato DirectX
                    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 texCoordsLightMap
                    if (meshData.lightmapEnabled)
                    {
                        XmlNode texCoordsLightMapNode = meshNode.GetElementsByTagName("texCoordsLightMap")[0];
                        count = int.Parse(texCoordsLightMapNode.Attributes["count"].InnerText);
                        meshData.textureCoordinatesLightMap = TgcParserUtils.parseFloatStream(texCoordsLightMapNode.InnerText, count);
                    }
                }

                //parsear datos de mesh Instancia
                else if(meshData.instanceType.Equals(TgcMeshData.INSTANCE))
                {
                    //originalMesh
                    XmlNode originalMeshNode = meshNode.GetElementsByTagName("originalMesh")[0];
                    meshData.originalMesh = TgcParserUtils.parseInt(originalMeshNode.InnerText);

                    //transform
                    XmlNode transformNode = meshNode.GetElementsByTagName("transform")[0];
                    meshData.position = TgcParserUtils.parseFloat3Array(transformNode.Attributes["pos"].InnerText);
                    meshData.rotation = TgcParserUtils.parseFloat4Array(transformNode.Attributes["rotQuat"].InnerText);
                    meshData.scale = TgcParserUtils.parseFloat3Array(transformNode.Attributes["scale"].InnerText);
                }

                //Parsear userProperties, si hay
                XmlNodeList userPropsNodes = meshNode.GetElementsByTagName("userProps");
                if (userPropsNodes != null && userPropsNodes.Count == 1)
                {
                    meshData.userProperties = new Dictionary<string, string>();
                    XmlElement userPropsNode = (XmlElement)userPropsNodes[0];
                    foreach (XmlElement prop in userPropsNode.ChildNodes)
                    {
                        meshData.userProperties.Add(prop.Name, prop.InnerText);
                    }
                }
            }


            //Parsear PortalRendering, si hay información
            XmlNodeList portalRenderingNodes = root.GetElementsByTagName("portalRendering");
            if (portalRenderingNodes != null && portalRenderingNodes.Count == 1)
            {
                XmlElement portalRenderingNode = (XmlElement)portalRenderingNodes[0];
                TgcPortalRenderingParser portalParser = new TgcPortalRenderingParser();
                tgcSceneData.portalData = portalParser.parseFromXmlNode(portalRenderingNode);
            }

            

            return tgcSceneData;
        }
        /// <summary>
        /// Crea un mesh sin texturas, solo con VertexColors
        /// </summary>
        /// <param name="meshData"></param>
        private TgcMesh crearMeshSoloColor(TgcMeshData 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]
                        );

                    //normals
                    //puede haber una normal compartida para cada vertice del mesh
                    if (meshData.verticesNormals.Length == meshData.verticesCoordinates.Length)
                    {
                        v.Normal = new Vector3(
                            meshData.verticesNormals[coordIdx],
                            meshData.verticesNormals[coordIdx + 1],
                            meshData.verticesNormals[coordIdx + 2]
                            );
                    }
                    //o una normal propia por cada vertice de cada triangulo (version mejorada del exporter)
                    else
                    {
                        int normalIdx = j * 3;
                        v.Normal = new Vector3(
                            meshData.verticesNormals[normalIdx],
                            meshData.verticesNormals[normalIdx + 1],
                            meshData.verticesNormals[normalIdx + 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);
            }


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

            return(tgcMesh);
        }
        /// <summary>
        /// Crea un mesh con uno o varios DiffuseMap
        /// </summary>
        /// <returns></returns>
        private TgcMesh crearMeshDiffuseMap(TgcSceneLoaderMaterialAux[] materialsArray, TgcMeshData 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]
                        );

                    //normals
                    //puede haber una normal compartida para cada vertice del mesh
                    if (meshData.verticesNormals.Length == meshData.verticesCoordinates.Length)
                    {
                        v.Normal = new Vector3(
                            meshData.verticesNormals[coordIdx],
                            meshData.verticesNormals[coordIdx + 1],
                            meshData.verticesNormals[coordIdx + 2]
                            );
                    }
                    //o una normal propia por cada vertice de cada triangulo (version mejorada del exporter)
                    else
                    {
                        int normalIdx = j * 3;
                        v.Normal = new Vector3(
                            meshData.verticesNormals[normalIdx],
                            meshData.verticesNormals[normalIdx + 1],
                            meshData.verticesNormals[normalIdx + 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
            TgcSceneLoaderMaterialAux matAux = materialsArray[meshData.materialId];

            Material[]   meshMaterials;
            TgcTexture[] meshTextures;
            if (matAux.subMaterials == null)
            {
                meshMaterials = new Material[] { matAux.materialId };
                meshTextures  = new TgcTexture[] { TgcTexture.createTexture(device, matAux.textureFileName, matAux.texturePath) };
            }

            //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]  = TgcTexture.createTexture(device, matAux.subMaterials[m].textureFileName, matAux.subMaterials[m].texturePath);
                }
            }

            //Crear mesh de TGC
            TgcMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcMesh.MeshRenderType.DIFFUSE_MAP);

            tgcMesh.Materials   = meshMaterials;
            tgcMesh.DiffuseMaps = meshTextures;
            return(tgcMesh);
        }
        /// <summary>
        /// Carga la escena a partir de un objeto TgcSceneData ya parseado
        /// </summary>
        /// <param name="sceneData">Objeto con datos de la escena ya parseados</param>
        /// <param name="mediaPath">Path a partir del cual hay que buscar los recursos de escena (Texturas, LightMaps, etc.)</param>
        /// <returns></returns>
        public TgcScene loadScene(TgcSceneData sceneData, string mediaPath)
        {
            TgcScene tgcScene = new TgcScene(sceneData.name, null);

            //Cargar Texturas
            TgcSceneLoaderMaterialAux[] materialsArray = new TgcSceneLoaderMaterialAux[sceneData.materialsData.Length];
            for (int i = 0; i < sceneData.materialsData.Length; i++)
            {
                TgcMaterialData materialData = sceneData.materialsData[i];
                string          texturesPath = mediaPath + sceneData.texturesDir + "\\";

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

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


            //Cargar Meshes
            for (int i = 0; i < sceneData.meshesData.Length; i++)
            {
                TgcMeshData meshData = sceneData.meshesData[i];
                TgcMesh     tgcMesh  = null;

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

                    //Para los que si tienen Material
                    else
                    {
                        //Crear MeshFormat que soporte LightMaps
                        if (meshData.lightmapEnabled)
                        {
                            tgcMesh = crearMeshDiffuseMapLightmap(sceneData, mediaPath, materialsArray, meshData);
                        }

                        //Formato de Mesh con Textura pero sin Lightmap
                        else
                        {
                            tgcMesh = crearMeshDiffuseMap(materialsArray, meshData);
                        }
                    }
                }

                //Crear malla instancia
                else if (meshData.instanceType.Equals(TgcMeshData.INSTANCE))
                {
                    tgcMesh = crearMeshInstance(meshData, tgcScene.Meshes);
                }



                //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),
                        tgcMesh.Position,
                        tgcMesh.Scale
                        );
                }
                else
                {
                    tgcMesh.createBoundingBox();
                }

                //Cargar layer
                tgcMesh.Layer = meshData.layerName;

                //Cargar AlphaBlending
                tgcMesh.AlphaBlendEnable = meshData.alphaBlending;

                //agregar mesh a escena
                tgcMesh.Enabled = true;
                tgcScene.Meshes.Add(tgcMesh);

                //Cargar userProperties, si hay
                tgcMesh.UserProperties = meshData.userProperties;
            }


            //BoundingBox del escenario, utilizar el que viene del XML o crearlo nosotros
            if (sceneData.pMin != null && sceneData.pMax != null)
            {
                tgcScene.BoundingBox = new TgcBoundingBox(
                    new Vector3(sceneData.pMin[0], sceneData.pMin[1], sceneData.pMin[2]),
                    new Vector3(sceneData.pMax[0], sceneData.pMax[1], sceneData.pMax[2])
                    );
            }
            else
            {
                List <TgcBoundingBox> boundingBoxes = new List <TgcBoundingBox>();
                foreach (TgcMesh mesh in tgcScene.Meshes)
                {
                    boundingBoxes.Add(mesh.BoundingBox);
                }
                tgcScene.BoundingBox = TgcBoundingBox.computeFromBoundingBoxes(boundingBoxes);
            }


            //Cargar parte de PortalRendering, solo hay información
            if (sceneData.portalData != null)
            {
                TgcPortalRenderingLoader portalLoader = new TgcPortalRenderingLoader();
                tgcScene.PortalRendering = portalLoader.loadFromData(tgcScene, sceneData.portalData);
            }


            return(tgcScene);
        }