/// <summary> /// Convierte el terreno en un TgcMesh /// </summary> /// <param name="meshName">Nombre de la malla que se va a crear</param> public TgcMesh toMesh(string meshName) { //Obtener matriz para transformar vertices if (AutoTransformEnable) { Transform = Matrix.Scaling(scale) * Matrix.RotationYawPitchRoll(rotation.Y, rotation.X, rotation.Z) * Matrix.Translation(translation); } //Crear Mesh con DiffuseMap var d3dMesh = new Mesh(vertices.Length / 3, vertices.Length, MeshFlags.Managed, TgcSceneLoader.DiffuseMapVertexElements, D3DDevice.Instance.Device); //Cargar VertexBuffer using (var vb = d3dMesh.VertexBuffer) { var data = vb.Lock(0, 0, LockFlags.None); for (var j = 0; j < vertices.Length; j++) { var v = new TgcSceneLoader.DiffuseMapVertex(); var vLand = vertices[j]; //vertices v.Position = Vector3.TransformCoordinate(vLand.Position, Transform); //normals v.Normal = Vector3.Empty; //texture coordinates diffuseMap v.Tu = vLand.Tu; v.Tv = vLand.Tv; data.Write(v); } vb.Unlock(); } //Cargar IndexBuffer en forma plana using (var ib = d3dMesh.IndexBuffer) { var indices = new short[vertices.Length]; for (var j = 0; j < indices.Length; j++) { indices[j] = (short)j; } ib.SetData(indices, 0, LockFlags.None); } //Calcular normales d3dMesh.ComputeNormals(); //Malla de TGC var tgcMesh = new TgcMesh(d3dMesh, meshName, TgcMesh.MeshRenderType.DIFFUSE_MAP); tgcMesh.DiffuseMaps = new[] { Texture }; tgcMesh.Materials = new[] { D3DDevice.DEFAULT_MATERIAL }; tgcMesh.createBoundingBox(); tgcMesh.Enabled = true; return(tgcMesh); }
private void ParseVertices() { //numero de faces _cantFaces = _byteData.ReadInt32(); //vertices _cantVertices = _byteData.ReadInt32(); _vertices = new TgcSceneLoader.DiffuseMapVertex[_cantVertices]; //bytes por vertice _sizeofVertex = _byteData.ReadInt32(); if (progress_bar != null) { progress_bar.SetRange(0, _cantVertices - 1, fname); } for (int i = 0; i < _cantVertices; i++) { if (i % 200 == 0) { // Cada 200 vertices llamo al loop if (progress_bar != null) { progress_bar.SetPos(i); } GuiController.Instance.MessageLoop(); } var p = new TgcSceneLoader.DiffuseMapVertex(); float x = _byteData.ReadSingle(); float z = _byteData.ReadSingle(); float y = _byteData.ReadSingle(); //_vertices.push(new Vertex(x, y, z)); p.Position = new Vector3(x, y, -z); minVert = Vector3.Minimize(minVert, p.Position); maxVert = Vector3.Maximize(maxVert, p.Position); x = _byteData.ReadSingle(); z = _byteData.ReadSingle(); y = _byteData.ReadSingle(); p.Normal = new Vector3(x, y, -z); p.Color = 0xFFFFFF; if (_sizeofVertex >= 32) { p.Tu = _byteData.ReadSingle(); p.Tv = _byteData.ReadSingle(); } if (_sizeofVertex > 32) { _byteData.ReadBytes(_sizeofVertex - 32); } _vertices[i] = p; } }
/// <summary> /// Convierte la pared en un TgcMesh /// </summary> /// <param name="meshName">Nombre de la malla que se va a crear</param> public TgcMesh toMesh(string meshName) { //Crear Mesh var d3dMesh = new Mesh(vertices.Length / 3, vertices.Length, MeshFlags.Managed, TgcSceneLoader.DiffuseMapVertexElements, D3DDevice.Instance.Device); //Cargar VertexBuffer using (var vb = d3dMesh.VertexBuffer) { var data = vb.Lock(0, 0, LockFlags.None); var ceroNormal = new Vector3(0, 0, 0); var whiteColor = Color.White.ToArgb(); for (var j = 0; j < vertices.Length; j++) { var v = new TgcSceneLoader.DiffuseMapVertex(); var vPlane = vertices[j]; //vertices v.Position = vPlane.Position; //normals v.Normal = ceroNormal; //texture coordinates diffuseMap v.Tu = vPlane.Tu; v.Tv = vPlane.Tv; //color v.Color = whiteColor; data.Write(v); } vb.Unlock(); } //Cargar IndexBuffer en forma plana using (var ib = d3dMesh.IndexBuffer) { var indices = new short[vertices.Length]; for (var j = 0; j < indices.Length; j++) { indices[j] = (short)j; } ib.SetData(indices, 0, LockFlags.None); } //Calcular normales d3dMesh.ComputeNormals(); //Malla de TGC var tgcMesh = new TgcMesh(d3dMesh, meshName, TgcMesh.MeshRenderType.DIFFUSE_MAP); tgcMesh.DiffuseMaps = new[] { Texture.Clone() }; tgcMesh.Materials = new[] { D3DDevice.DEFAULT_MATERIAL }; tgcMesh.createBoundingBox(); tgcMesh.Enabled = true; return(tgcMesh); }
/// <summary> /// Crear vertices para la cara Left /// </summary> private void cargarVerticesLeft(GraphicsStream data, int color) { TgcSceneLoader.DiffuseMapVertex v; Vector3 n = new Vector3(0, -1, 0); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( center.X - size.X / 2, center.Y + size.Y / 2 + skyEpsilon, center.Z - size.Z / 2 - skyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 0; v.Tv = 0; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( center.X - size.X / 2, center.Y - size.Y / 2 - skyEpsilon, center.Z - size.Z / 2 - skyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 0; v.Tv = 1; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( center.X - size.X / 2, center.Y - size.Y / 2 - skyEpsilon, center.Z + size.Z / 2 + skyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 1; v.Tv = 1; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( center.X - size.X / 2, center.Y + size.Y / 2 + skyEpsilon, center.Z + size.Z / 2 + skyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 1; v.Tv = 0; data.Write(v); }
/// <summary> /// Crear vertices para la cara Right /// </summary> private void cargarVerticesRight(GraphicsStream data, int color) { TgcSceneLoader.DiffuseMapVertex v; var n = new Vector3(0, -1, 0); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( Center.X + Size.X / 2, Center.Y + Size.Y / 2 + SkyEpsilon, Center.Z + Size.Z / 2 + SkyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 0; v.Tv = 0; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( Center.X + Size.X / 2, Center.Y - Size.Y / 2 - SkyEpsilon, Center.Z + Size.Z / 2 + SkyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 0; v.Tv = 1; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( Center.X + Size.X / 2, Center.Y - Size.Y / 2 - SkyEpsilon, Center.Z - Size.Z / 2 - SkyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 1; v.Tv = 1; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( Center.X + Size.X / 2, Center.Y + Size.Y / 2 + SkyEpsilon, Center.Z - Size.Z / 2 - SkyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 1; v.Tv = 0; data.Write(v); }
/// <summary> /// Crear vertices para la cara Back /// </summary> private void cargarVerticesBack(GraphicsStream data, int color) { TgcSceneLoader.DiffuseMapVertex v; var n = TGCVector3.Down; v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new TGCVector3( Center.X + Size.X / 2 + SkyEpsilon, Center.Y + Size.Y / 2 + SkyEpsilon, Center.Z - Size.Z / 2 ); v.Normal = new TGCVector3(-1, -1, 1); v.Color = color; v.Tu = 0; v.Tv = 0; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new TGCVector3( Center.X + Size.X / 2 + SkyEpsilon, Center.Y - Size.Y / 2 - SkyEpsilon, Center.Z - Size.Z / 2 ); v.Normal = new TGCVector3(-1, 1, 1); v.Color = color; v.Tu = 0; v.Tv = 1; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new TGCVector3( Center.X - Size.X / 2 - SkyEpsilon, Center.Y - Size.Y / 2 - SkyEpsilon, Center.Z - Size.Z / 2 ); v.Normal = new TGCVector3(1, 1, 1); v.Color = color; v.Tu = 1; v.Tv = 1; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new TGCVector3( Center.X - Size.X / 2 - SkyEpsilon, Center.Y + Size.Y / 2 + SkyEpsilon, Center.Z - Size.Z / 2 ); v.Normal = new TGCVector3(1, -1, 1); v.Color = color; v.Tu = 1; v.Tv = 0; data.Write(v); }
/// <summary> /// Crear un TgcMeshBumpMapping en base a un TgcMesh y su normalMap. /// Solo esta soportado un TgcMehs MeshRenderType = DiffuseMap /// </summary> public static TgcMeshBumpMapping fromTgcMesh(TgcMesh mesh, TgcTexture[] normalMaps) { if (mesh.RenderType != MeshRenderType.DIFFUSE_MAP) { throw new Exception("Solo esta soportado MeshRenderType = DiffuseMap"); } //Obtener vertexBuffer original TgcSceneLoader.DiffuseMapVertex[] origVertexBuffer = (TgcSceneLoader.DiffuseMapVertex[])mesh.D3dMesh.LockVertexBuffer( typeof(TgcSceneLoader.DiffuseMapVertex), LockFlags.ReadOnly, mesh.D3dMesh.NumberVertices); mesh.D3dMesh.UnlockVertexBuffer(); //Crear nuevo Mesh de DirectX int triCount = origVertexBuffer.Length / 3; Mesh d3dMesh = new Mesh(triCount, origVertexBuffer.Length, MeshFlags.Managed, BumpMappingVertexElements, GuiController.Instance.D3dDevice); //Calcular normales recorriendo los triangulos Vector3[] normals = new Vector3[origVertexBuffer.Length]; for (int i = 0; i < normals.Length; i++) { normals[i] = new Vector3(0, 0, 0); } for (int i = 0; i < triCount; i++) { //Los 3 vertices del triangulo TgcSceneLoader.DiffuseMapVertex v1 = origVertexBuffer[i * 3]; TgcSceneLoader.DiffuseMapVertex v2 = origVertexBuffer[i * 3 + 1]; TgcSceneLoader.DiffuseMapVertex v3 = origVertexBuffer[i * 3 + 2]; //Face-normal (left-handend) Vector3 a = v2.Position - v1.Position; Vector3 b = v3.Position - v1.Position; Vector3 n = Vector3.Cross(a, b); //Acumular normal del vertice segun todas sus Face-normal normals[i * 3] += n; normals[i * 3 + 1] += n; normals[i * 3 + 2] += n; } //Normalizar normales for (int i = 0; i < normals.Length; i++) { normals[i] = Vector3.Normalize(normals[i]); } //Crear nuevo VertexBuffer using (VertexBuffer vb = d3dMesh.VertexBuffer) { //Iterar sobre triangulos GraphicsStream data = vb.Lock(0, 0, LockFlags.None); for (int i = 0; i < triCount; i++) { //Vertices originales TgcSceneLoader.DiffuseMapVertex vOrig1 = origVertexBuffer[i * 3]; TgcSceneLoader.DiffuseMapVertex vOrig2 = origVertexBuffer[i * 3 + 1]; TgcSceneLoader.DiffuseMapVertex vOrig3 = origVertexBuffer[i * 3 + 2]; //Nuevo vertice 1 BumpMappingVertex v1 = new BumpMappingVertex(); v1.Position = vOrig1.Position; v1.Color = vOrig1.Color; v1.Tu = vOrig1.Tu; v1.Tv = vOrig1.Tv; v1.Normal = normals[i * 3]; //Nuevo vertice 2 BumpMappingVertex v2 = new BumpMappingVertex(); v2.Position = vOrig2.Position; v2.Color = vOrig2.Color; v2.Tu = vOrig2.Tu; v2.Tv = vOrig2.Tv; v2.Normal = normals[i * 3 + 1]; //Nuevo vertice 3 BumpMappingVertex v3 = new BumpMappingVertex(); v3.Position = vOrig3.Position; v3.Color = vOrig3.Color; v3.Tu = vOrig3.Tu; v3.Tv = vOrig3.Tv; v3.Normal = normals[i * 3 + 2]; //Calcular tangente y binormal para todo el triangulo y cargarlas en cada vertice Vector3 tangent; Vector3 binormal; TgcMeshBumpMapping.computeTangentBinormal(v1, v2, v3, out tangent, out binormal); v1.Tangent = tangent; v1.Binormal = binormal; v2.Tangent = tangent; v2.Binormal = binormal; v3.Tangent = tangent; v3.Binormal = binormal; //Cargar VertexBuffer data.Write(v1); data.Write(v2); data.Write(v3); } vb.Unlock(); } //Cargar IndexBuffer en forma plana using (IndexBuffer ib = d3dMesh.IndexBuffer) { short[] indices = new short[origVertexBuffer.Length]; for (int i = 0; i < indices.Length; i++) { indices[i] = (short)i; } ib.SetData(indices, 0, LockFlags.None); } //Clonar texturas y materials TgcTexture[] diffuseMaps = new TgcTexture[mesh.DiffuseMaps.Length]; Material[] materials = new Material[mesh.Materials.Length]; for (int i = 0; i < mesh.DiffuseMaps.Length; i++) { diffuseMaps[i] = mesh.DiffuseMaps[i].clone(); materials[i] = TgcD3dDevice.DEFAULT_MATERIAL; } //Cargar attributeBuffer if (diffuseMaps.Length > 1) { int[] origAttributeBuffer = mesh.D3dMesh.LockAttributeBufferArray(LockFlags.None); int[] newAttributeBuffer = d3dMesh.LockAttributeBufferArray(LockFlags.None); Array.Copy(origAttributeBuffer, newAttributeBuffer, origAttributeBuffer.Length); mesh.D3dMesh.UnlockAttributeBuffer(); d3dMesh.UnlockAttributeBuffer(newAttributeBuffer); } //Crear mesh de BumpMapping Mesh TgcMeshBumpMapping bumpMesh = new TgcMeshBumpMapping(d3dMesh, mesh.Name, mesh.RenderType); bumpMesh.diffuseMaps = diffuseMaps; bumpMesh.materials = materials; bumpMesh.normalMaps = normalMaps; bumpMesh.layer = mesh.Layer; bumpMesh.alphaBlendEnable = mesh.AlphaBlendEnable; bumpMesh.UserProperties = mesh.UserProperties; bumpMesh.boundingBox = mesh.BoundingBox.clone(); bumpMesh.enabled = true; return(bumpMesh); }
/// <summary> /// Convierte el TgcSphere en un TgcMesh /// </summary> /// <param name="meshName">Nombre de la malla que se va a crear</param> public TgcMesh toMesh(string meshName) { //Obtener matriz para transformar vertices if (AutoTransformEnable) { Transform = Matrix.Scaling(radius, radius, radius) * Matrix.Scaling(Scale) * Matrix.RotationYawPitchRoll(rotation.Y, rotation.X, rotation.Z) * Matrix.Translation(translation); } //Crear mesh con DiffuseMap if (Texture != null) { //Crear Mesh var d3dMesh = new Mesh(indices.Count / 3, indices.Count, MeshFlags.Managed, TgcSceneLoader.DiffuseMapVertexElements, D3DDevice.Instance.Device); //Cargar VertexBuffer using (var vb = d3dMesh.VertexBuffer) { var data = vb.Lock(0, 0, LockFlags.None); for (var j = 0; j < indices.Count; j++) { var v = new TgcSceneLoader.DiffuseMapVertex(); var vSphere = vertices[indices[j]]; //vertices v.Position = Vector3.TransformCoordinate(vSphere.getPosition(), Transform); //normals v.Normal = vSphere.getNormal(); //texture coordinates diffuseMap v.Tu = vSphere.Tu; v.Tv = vSphere.Tv; //color v.Color = vSphere.Color; data.Write(v); } vb.Unlock(); } //Cargar IndexBuffer en forma plana using (var ib = d3dMesh.IndexBuffer) { var vIndices = new short[indices.Count]; for (var j = 0; j < vIndices.Length; j++) { vIndices[j] = (short)j; } ib.SetData(vIndices, 0, LockFlags.None); } //Calcular normales //d3dMesh.ComputeNormals(); //Malla de TGC var tgcMesh = new TgcMesh(d3dMesh, meshName, TgcMesh.MeshRenderType.DIFFUSE_MAP); tgcMesh.DiffuseMaps = new[] { Texture.Clone() }; tgcMesh.Materials = new[] { D3DDevice.DEFAULT_MATERIAL }; tgcMesh.createBoundingBox(); tgcMesh.Enabled = true; return(tgcMesh); } //Crear mesh con solo color else { //Crear Mesh var d3dMesh = new Mesh(indices.Count / 3, indices.Count, MeshFlags.Managed, TgcSceneLoader.VertexColorVertexElements, D3DDevice.Instance.Device); //Cargar VertexBuffer using (var vb = d3dMesh.VertexBuffer) { var data = vb.Lock(0, 0, LockFlags.None); for (var j = 0; j < indices.Count; j++) { var v = new TgcSceneLoader.VertexColorVertex(); var vSphere = vertices[indices[j]]; //vertices v.Position = Vector3.TransformCoordinate(vSphere.getPosition(), Transform); //normals v.Normal = vSphere.getNormal(); //color v.Color = vSphere.Color; data.Write(v); } vb.Unlock(); } //Cargar IndexBuffer en forma plana using (var ib = d3dMesh.IndexBuffer) { var vIndices = new short[indices.Count]; for (var j = 0; j < vIndices.Length; j++) { vIndices[j] = (short)j; } ib.SetData(vIndices, 0, LockFlags.None); } //Malla de TGC var tgcMesh = new TgcMesh(d3dMesh, meshName, TgcMesh.MeshRenderType.VERTEX_COLOR); tgcMesh.Materials = new[] { D3DDevice.DEFAULT_MATERIAL }; tgcMesh.createBoundingBox(); tgcMesh.Enabled = true; return(tgcMesh); } }
protected void ParseFaces() { //Faces // Cantidad de Faces _cantFaces = _byteData.ReadInt32(); _faces = new Face[_cantFaces]; _vertices = new TgcSceneLoader.DiffuseMapVertex[_cantFaces * 4]; for (int i = 0; i < _cantFaces; i++) { var face = new Face(); //tipo Face, Triangulo(3) o Rectangulo(1) face.Tipo = _byteData.ReadByte(); //3 byte de relleno (alineacion) _byteData.ReadBytes(3); for (int j = 0; j < 4; j++) { //Vertices var v = new TgcSceneLoader.DiffuseMapVertex(); //Posicion v.Position = ParseVector3(); //Normal v.Normal = ParseVector3(); //color _color = _byteData.ReadUInt32(); v.Color = (int)0xFFFFFF; //UV v.Tu = _byteData.ReadSingle(); v.Tv = _byteData.ReadSingle(); _vertices[i * 4 + j] = v; } //id face.Id = _byteData.ReadInt32(); // Borde face.Borde = _byteData.ReadByte(); //3 byte de relleno (alineacion) _byteData.ReadBytes(3); //nro_mesh, -1 si no es mesh face.NroMesh = _byteData.ReadInt32(); //nro de textura int nroTextura = _byteData.ReadByte(); //3 byte de relleno (alineacion) _byteData.ReadBytes(3); // parametros de iluminacion face.kd = _byteData.ReadSingle(); face.ks = _byteData.ReadSingle(); face.kr = _byteData.ReadSingle(); face.kt = _byteData.ReadSingle(); int nroConjunto = _byteData.ReadInt32(); if (nroConjunto == 65535) { nroConjunto = -1; } face.NroConjunto = nroConjunto; if (face.NroMesh != -1) { //es un mesh //Cant Layers face.CantLayers = _byteData.ReadByte(); //3 byte de relleno (alineacion) _byteData.ReadBytes(3); //WordMatrix face.MatWorld = ParseMatrix(); face.BmpK = _byteData.ReadSingle(); face.TexturaRotada = _byteData.ReadByte(); face.FlagEspejar = _byteData.ReadByte(); //2 byte de relleno (alineacion) _byteData.ReadBytes(2); face.FlagMaterial = _byteData.ReadInt32(); //layers face.Layers = new Layer[face.CantLayers]; for (int j = 0; j < face.CantLayers; j++) { var layer = new Layer(); //nro layer layer.NroLayer = _byteData.ReadByte(); //3 byte de relleno (alineacion) _byteData.ReadBytes(3); //material Material mat = layer.Material; mat.DiffuseColor = new ColorValue(_byteData.ReadSingle(), _byteData.ReadSingle(), _byteData.ReadSingle(), _byteData.ReadSingle()); mat.AmbientColor = new ColorValue(_byteData.ReadSingle(), _byteData.ReadSingle(), _byteData.ReadSingle(), _byteData.ReadSingle()); mat.SpecularColor = new ColorValue(_byteData.ReadSingle(), _byteData.ReadSingle(), _byteData.ReadSingle(), _byteData.ReadSingle()); mat.EmissiveColor = new ColorValue(_byteData.ReadSingle(), _byteData.ReadSingle(), _byteData.ReadSingle(), _byteData.ReadSingle()); mat.SpecularSharpness = _byteData.ReadSingle(); //Coefcientes luz float transparencyLevel = _byteData.ReadSingle(); float SpecularLevel = _byteData.ReadSingle(); //textura Propia int textura_propia = _byteData.ReadByte(); //Nro Textura int lNroTextura = _byteData.ReadByte(); //2 byte de relleno (alineacion) _byteData.ReadBytes(2); //if(textura_propia == 0) //TODO revisar // mat = null; layer.NroTextura = textura_propia > 0 && lNroTextura != 255 ? lNroTextura : -1; layer.Material = mat; if (layer.NroLayer >= face.Layers.Length) { throw new Exception("Nro de layer mayor a la cantidad de layers."); } //face.Layers[layer.NroLayer] = layer; face.Layers[layer.NroLayer] = layer; } //Fin mesh } //Fin Face face.NroTextura = nroTextura; _faces[i] = face; } }