/// <summary> /// Carga una animación a un modelo ya cargado, a partir del string del XML. /// La animación se agrega al modelo. /// </summary> /// <param name="mesh">Modelo ya cargado</param> /// <param name="xmlString">contenido del XML</param> public TgcKeyFrameAnimation loadAnimationFromString(TgcKeyFrameMesh mesh, string xmlString) { var parser = new TgcKeyFrameParser(); var animationData = parser.parseAnimationFromString(xmlString); return(loadAnimation(mesh, animationData)); }
/// <summary> /// Carga un Modelo a partir de un objeto TgcKeyFrameMeshData 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 TgcKeyFrameMesh loadMesh(TgcKeyFrameMeshData meshData, string mediaPath) { //Cargar Texturas var materialsArray = new TgcKeyFrameLoaderMaterialAux[meshData.materialsData.Length]; for (var i = 0; i < meshData.materialsData.Length; i++) { var materialData = meshData.materialsData[i]; var 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)) { var matAux = new TgcKeyFrameLoaderMaterialAux(); materialsArray[i] = matAux; matAux.subMaterials = new TgcKeyFrameLoaderMaterialAux[materialData.subMaterials.Length]; for (var j = 0; j < materialData.subMaterials.Length; j++) { matAux.subMaterials[j] = createTextureAndMaterial(materialData.subMaterials[j], texturesPath); } } } //Crear Mesh TgcKeyFrameMesh 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 TgcBoundingAxisAlignBox( TgcParserUtils.float3ArrayToVector3(meshData.pMin), TgcParserUtils.float3ArrayToVector3(meshData.pMax) ); } else { tgcMesh.createBoundingBox(); } tgcMesh.Enabled = true; return(tgcMesh); }
/// <summary> /// Crea un mesh sin texturas, solo con VertexColors /// </summary> /// <param name="meshData"></param> private TgcKeyFrameMesh crearMeshSoloColor(TgcKeyFrameMeshData meshData) { //Crear Mesh var mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, VertexColorVertexElements, D3DDevice.Instance.Device); //Cargar VertexBuffer using (var vb = mesh.VertexBuffer) { var data = vb.Lock(0, 0, LockFlags.None); for (var j = 0; j < meshData.coordinatesIndices.Length; j++) { var v = new VertexColorVertex(); //vertices var coordIdx = meshData.coordinatesIndices[j] * 3; v.Position = new TGCVector3( meshData.verticesCoordinates[coordIdx], meshData.verticesCoordinates[coordIdx + 1], meshData.verticesCoordinates[coordIdx + 2] ); //color var colorIdx = meshData.colorIndices[j]; v.Color = meshData.verticesColors[colorIdx]; data.Write(v); } vb.Unlock(); } //Cargar indexBuffer en forma plana using (var ib = mesh.IndexBuffer) { var indices = new short[meshData.coordinatesIndices.Length]; for (var i = 0; i < indices.Length; i++) { indices[i] = (short)i; } ib.SetData(indices, 0, LockFlags.None); } //Cargar datos que originales que tienen que mantenerse var originalData = new OriginalData(); originalData.coordinatesIndices = meshData.coordinatesIndices; originalData.colorIndices = meshData.colorIndices; originalData.verticesColors = meshData.verticesColors; originalData.texCoordinatesIndices = null; originalData.textureCoordinates = null; //Crear mesh de TGC var tgcMesh = new TgcKeyFrameMesh(mesh, meshData.name, TgcKeyFrameMesh.MeshRenderType.VERTEX_COLOR, originalData); return(tgcMesh); }
/// <summary> /// Carga una animación a un modelo ya cargado, en base a un archivo /// La animación se agrega al modelo. /// </summary> /// <param name="mesh">Modelo ya cargado</param> /// <param name="filePath">Ubicacion del archivo XML de la animación</param> public TgcKeyFrameAnimation loadAnimationFromFile(TgcKeyFrameMesh mesh, string filePath) { try { var xmlString = File.ReadAllText(filePath); return(loadAnimationFromString(mesh, xmlString)); } catch (Exception ex) { throw new Exception("Error al cargar animacion desde archivo: " + filePath, ex); } }
/// <summary> /// Crea una nueva malla que es una instancia de esta malla original /// Reutiliza toda la geometría de la malla original sin duplicarla. /// Solo se puede crear instancias a partir de originales. /// Se debe crear después de haber agregado todas las animaciones al original. /// </summary> /// <param name="name">Nombre de la malla</param> /// <param name="translation">Traslación respecto de la malla original</param> /// <param name="rotation">Rotación respecto de la malla original</param> /// <param name="scale">Escala respecto de la malla original</param> public TgcKeyFrameMesh createMeshInstance(string name, TGCVector3 translation, TGCVector3 rotation, TGCVector3 scale) { if (ParentInstance != null) { throw new Exception( "No se puede crear una instancia de otra malla instancia. Hay que partir del original."); } //Crear instancia var instance = new TgcKeyFrameMesh(name, this, translation, rotation, scale); //BoundingBox instance.boundingBox = new TgcBoundingAxisAlignBox(boundingBox.PMin, boundingBox.PMax); instance.updateBoundingBox(); instance.Enabled = true; return(instance); }
/// <summary> /// Carga una animación a un modelo ya cargado, a partir de un objeto TgcKeyFrameAnimationData ya parseado /// La animación se agrega al modelo. /// </summary> /// <param name="mesh">Modelo ya cargado</param> /// <param name="animationData">Objeto de animacion con datos ya cargados</param> public TgcKeyFrameAnimation loadAnimation(TgcKeyFrameMesh mesh, TgcKeyFrameAnimationData animationData) { //BoundingBox de la animación, aprovechar lo que viene en el XML o utilizar el de la malla estática TgcBoundingAxisAlignBox boundingBox = null; if (animationData.pMin != null && animationData.pMax != null) { boundingBox = new TgcBoundingAxisAlignBox( TGCVector3.Float3ArrayToVector3(animationData.pMin), TGCVector3.Float3ArrayToVector3(animationData.pMax)); } else { boundingBox = mesh.BoundingBox; } var animation = new TgcKeyFrameAnimation(animationData, boundingBox); mesh.Animations.Add(animationData.name, animation); return(animation); }
/// <summary> /// Crea una nueva malla que es una instancia de otra malla original. /// Reutiliza toda la geometría de la malla original sin duplicarla. /// Debe crearse luego de haber cargado todas las animaciones en la malla original /// </summary> /// <param name="name">Nombre de la malla</param> /// <param name="parentInstance">Malla original desde la cual basarse</param> /// <param name="translation">Traslación respecto de la malla original</param> /// <param name="rotation">Rotación respecto de la malla original</param> /// <param name="scale">Escala respecto de la malla original</param> public TgcKeyFrameMesh(string name, TgcKeyFrameMesh parentInstance, TGCVector3 translation, TGCVector3 rotation, TGCVector3 scale) { //Cargar iniciales datos en base al original initData(parentInstance.d3dMesh, name, parentInstance.RenderType, parentInstance.originalData); DiffuseMaps = parentInstance.DiffuseMaps; Materials = parentInstance.Materials; //Almacenar transformación inicial this.translation = translation; this.rotation = rotation; this.scale = scale; //Agregar animaciones del original foreach (var entry in parentInstance.Animations) { Animations.Add(entry.Key, entry.Value); } //almacenar instancia en el padre ParentInstance = parentInstance; parentInstance.MeshInstances.Add(this); }
/// <summary> /// Crea un mesh con uno o varios DiffuseMap /// </summary> /// <returns></returns> private TgcKeyFrameMesh crearMeshDiffuseMap(TgcKeyFrameLoaderMaterialAux[] materialsArray, TgcKeyFrameMeshData meshData) { //Crear Mesh var mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, DiffuseMapVertexElements, D3DDevice.Instance.Device); //Cargar VertexBuffer using (var vb = mesh.VertexBuffer) { var data = vb.Lock(0, 0, LockFlags.None); for (var j = 0; j < meshData.coordinatesIndices.Length; j++) { var v = new DiffuseMapVertex(); //vertices var coordIdx = meshData.coordinatesIndices[j] * 3; v.Position = new TGCVector3( meshData.verticesCoordinates[coordIdx], meshData.verticesCoordinates[coordIdx + 1], meshData.verticesCoordinates[coordIdx + 2] ); //texture coordinates diffuseMap var texCoordIdx = meshData.texCoordinatesIndices[j] * 2; v.Tu = meshData.textureCoordinates[texCoordIdx]; v.Tv = meshData.textureCoordinates[texCoordIdx + 1]; //color var colorIdx = meshData.colorIndices[j]; v.Color = meshData.verticesColors[colorIdx]; data.Write(v); } vb.Unlock(); } //Cargar IndexBuffer using (var ib = mesh.IndexBuffer) { var indices = new short[meshData.coordinatesIndices.Length]; for (var j = 0; j < indices.Length; j++) { indices[j] = (short)j; } ib.SetData(indices, 0, LockFlags.None); } //Configurar Material y Textura para un solo SubSet var matAux = materialsArray[meshData.materialId]; Material[] meshMaterials; TgcTexture[] meshTextures; if (matAux.subMaterials == null) { meshMaterials = new[] { matAux.materialId }; meshTextures = new[] { matAux.texture }; } //Configurar Material y Textura para varios SubSet else { //Cargar attributeBuffer con los id de las texturas de cada triángulo var 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 (var m = 0; m < matAux.subMaterials.Length; m++) { meshMaterials[m] = matAux.subMaterials[m].materialId; meshTextures[m] = matAux.subMaterials[m].texture; } } //Cargar datos que originales que tienen que mantenerse var originalData = new OriginalData(); originalData.coordinatesIndices = meshData.coordinatesIndices; originalData.colorIndices = meshData.colorIndices; originalData.verticesColors = meshData.verticesColors; originalData.texCoordinatesIndices = meshData.texCoordinatesIndices; originalData.textureCoordinates = meshData.textureCoordinates; //Crear mesh de TGC var tgcMesh = new TgcKeyFrameMesh(mesh, meshData.name, TgcKeyFrameMesh.MeshRenderType.DIFFUSE_MAP, originalData); tgcMesh.Materials = meshMaterials; tgcMesh.DiffuseMaps = meshTextures; return(tgcMesh); }