/// <summary> /// Crea Material y Textura /// </summary> private TgcSceneLoaderMaterialAux createTextureAndMaterial(TgcMaterialData materialData, string texturesPath) { TgcSceneLoaderMaterialAux matAux = new TgcSceneLoaderMaterialAux(); //Crear material Material material = new Material(); matAux.materialId = material; material.AmbientColor = new ColorValue( materialData.ambientColor[0], materialData.ambientColor[1], materialData.ambientColor[2], materialData.ambientColor[3]); material.DiffuseColor = new ColorValue( materialData.diffuseColor[0], materialData.diffuseColor[1], materialData.diffuseColor[2], materialData.diffuseColor[3]); material.SpecularColor = new ColorValue( materialData.specularColor[0], materialData.specularColor[1], materialData.specularColor[2], materialData.specularColor[3]); //TODO ver que hacer con la opacity //crear textura texturesDict.Clear(); if (materialData.fileName != null) { //revisar que esa imagen no se haya cargado previamente TgcTexture texture; if (texturesDict.ContainsKey(materialData.fileName)) { texture = texturesDict[materialData.fileName]; } else { texture = TgcTexture.createTexture(device, materialData.fileName, texturesPath + "\\" + materialData.fileName); texturesDict[materialData.fileName] = texture; //TODO usar para algo el OFFSET y el TILING } matAux.texture = texture; } else { matAux.texture = null; } return(matAux); }
/// <summary> /// Crea Material y Textura /// </summary> private TgcSceneLoaderMaterialAux createTextureAndMaterial(TgcMaterialData materialData, string texturesPath) { TgcSceneLoaderMaterialAux matAux = new TgcSceneLoaderMaterialAux(); //Crear material Material material = new Material(); matAux.materialId = material; material.AmbientColor = new ColorValue( materialData.ambientColor[0], materialData.ambientColor[1], materialData.ambientColor[2], materialData.ambientColor[3]); material.DiffuseColor = new ColorValue( materialData.diffuseColor[0], materialData.diffuseColor[1], materialData.diffuseColor[2], materialData.diffuseColor[3]); material.SpecularColor = new ColorValue( materialData.specularColor[0], materialData.specularColor[1], materialData.specularColor[2], materialData.specularColor[3]); //TODO ver que hacer con la opacity //guardar datos de textura if (materialData.fileName != null) { matAux.texturePath = texturesPath + materialData.fileName; matAux.textureFileName = materialData.fileName; } else { matAux.texturePath = null; matAux.textureFileName = null; } return(matAux); }
/// <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) { var tgcScene = new TgcScene(sceneData.name, null); //Cargar Texturas var materialsArray = new TgcSceneLoaderMaterialAux[sceneData.materialsData.Length]; for (var i = 0; i < sceneData.materialsData.Length; i++) { var materialData = sceneData.materialsData[i]; var 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)) { var matAux = new TgcSceneLoaderMaterialAux(); materialsArray[i] = matAux; matAux.subMaterials = new TgcSceneLoaderMaterialAux[materialData.subMaterials.Length]; for (var j = 0; j < materialData.subMaterials.Length; j++) { matAux.subMaterials[j] = createTextureAndMaterial(materialData.subMaterials[j], texturesPath); } } } //Cargar Meshes for (var i = 0; i < sceneData.meshesData.Length; i++) { var 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 { var boundingBoxes = new List <TgcBoundingBox>(); foreach (var 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) { var portalLoader = new TgcPortalRenderingLoader(); tgcScene.PortalRendering = portalLoader.loadFromData(tgcScene, sceneData.portalData); } return(tgcScene); }
/// <summary> /// Crea Material y Textura /// </summary> private TgcSceneLoaderMaterialAux createTextureAndMaterial(TgcMaterialData materialData, string texturesPath) { TgcSceneLoaderMaterialAux matAux = new TgcSceneLoaderMaterialAux(); //Crear material Material material = new Material(); matAux.materialId = material; material.AmbientColor = new ColorValue( materialData.ambientColor[0], materialData.ambientColor[1], materialData.ambientColor[2], materialData.ambientColor[3]); material.DiffuseColor = new ColorValue( materialData.diffuseColor[0], materialData.diffuseColor[1], materialData.diffuseColor[2], materialData.diffuseColor[3]); material.SpecularColor = new ColorValue( materialData.specularColor[0], materialData.specularColor[1], materialData.specularColor[2], materialData.specularColor[3]); //TODO ver que hacer con la opacity //crear textura texturesDict.Clear(); if (materialData.fileName != null) { //revisar que esa imagen no se haya cargado previamente TgcTexture texture; if (texturesDict.ContainsKey(materialData.fileName)) { texture = texturesDict[materialData.fileName]; } else { texture = TgcTexture.createTexture(device, materialData.fileName, texturesPath + "\\" + materialData.fileName); texturesDict[materialData.fileName] = texture; //TODO usar para algo el OFFSET y el TILING } matAux.texture = texture; } else { matAux.texture = null; } return matAux; }
/// <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; }
/// <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) ); } 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; }
/// <summary> /// Crea Material y Textura /// </summary> private TgcSceneLoaderMaterialAux createTextureAndMaterial(TgcMaterialData materialData, string texturesPath) { TgcSceneLoaderMaterialAux matAux = new TgcSceneLoaderMaterialAux(); //Crear material Material material = new Material(); matAux.materialId = material; material.AmbientColor = new ColorValue( materialData.ambientColor[0], materialData.ambientColor[1], materialData.ambientColor[2], materialData.ambientColor[3]); material.DiffuseColor = new ColorValue( materialData.diffuseColor[0], materialData.diffuseColor[1], materialData.diffuseColor[2], materialData.diffuseColor[3]); material.SpecularColor = new ColorValue( materialData.specularColor[0], materialData.specularColor[1], materialData.specularColor[2], materialData.specularColor[3]); //TODO ver que hacer con la opacity //guardar datos de textura if (materialData.fileName != null) { matAux.texturePath = texturesPath + materialData.fileName; matAux.textureFileName = materialData.fileName; } else { matAux.texturePath = null; matAux.textureFileName = null; } return matAux; }
/// <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); }