Mesh LoadMesh() { MeshIndexed meshIndexed = new MeshIndexed(); int vertexStart = GetIndex("vertices"); int vertexCount = (int)GetNumber(file[vertexStart], "#", 5); int textureStart = GetIndex("texture"); int textureCount = (int)GetNumber(file[textureStart], "#", 4); meshIndexed.vertexList = new Vertex[vertexCount]; meshIndexed.textures = new TextureCoord[textureCount]; int count = GetIndex("object") + 2; //obtengo la lista de puntos for (int i = 0; i < vertexCount; i++) { meshIndexed.vertexList[i] = GetVertexPoint(file[i + count]); } count = GetIndex("vt"); //obtengo la lista de coordenadas de textura for (int i = 0; i < textureCount; i++) { meshIndexed.textures[i] = GetTexturePoint(file[i + count], 3); } int facesStart = GetIndex("faces"); int facesCount = (int)GetNumber(file[facesStart], "#", 5); meshIndexed.faceList = new FaceIndexed[facesCount]; count = GetIndex("f "); int index = 0; int s = 0; // para obtener los indices de puntos y de texturas for (int i = 0; i < facesCount + s; i++) { if (file[count + i].IndexOf('s') == -1) { meshIndexed.faceList[index].vertexIndexes = new int[3]; meshIndexed.faceList[index].textureIndexes = new int[3]; for (int j = 0; j < 3; j++) { indexes = GetIndexes(file[count + i], j); meshIndexed.faceList[index].vertexIndexes[j] = indexes.faceIndex - prevVertex; meshIndexed.faceList[index].textureIndexes[j] = indexes.textureIndex - prevTexture; } index++; } else { // s significa el material de las caras (no implementado) s++; } } prevVertex += vertexCount; prevTexture += textureCount; CalcularNormales(meshIndexed); return(CopyMesh(meshIndexed)); }
public void LoadAllMeshes(List <MeshIndexed> outMeshes, float scale) { uint i; for (i = 0; i < _meshes.Count; ++i) { MeshIndexed mesh = new MeshIndexed(); mesh = LoadMesh(i, mesh, scale, false); outMeshes.Add(mesh); } }
public void LoadMesh(string name, MeshIndexed mesh, float scale) { MeshObject meshobj = null; for (int i = 0; i < _meshes.Count; ++i) { meshobj = _meshes[i]; if (meshobj.name == name) { LoadMesh((uint)i, mesh, scale, false); } } if (null == meshobj) { throw new Exception("No such named mesh object: " + name); } }
Mesh CopyMesh(MeshIndexed meshIndexed) { Mesh mesh = new Mesh(); mesh.Faces = new Face[meshIndexed.faceList.Length]; for (int i = 0; i < mesh.Faces.Length; i++) { Vertex[] vertex = new Vertex[3]; Vector3[] normal = new Vector3[3]; for (int j = 0; j < 3; j++) { vertex[j] = meshIndexed.vertexList[meshIndexed.faceList[i].vertexIndexes[j]]; vertex[j].u = meshIndexed.textures[meshIndexed.faceList[i].textureIndexes[j]].x; vertex[j].v = meshIndexed.textures[meshIndexed.faceList[i].textureIndexes[j]].y; normal[j] = meshIndexed.faceList[i].normal[j]; } mesh.Faces[i].vertex = vertex; mesh.Faces[i].normal = normal; } return(mesh); }
public MeshIndexed LoadMesh(uint i, MeshIndexed meshIndexed, float scale, bool applySmoothingGroups) { Debug.Assert(i < _meshes.Count); MeshObject meshobj = _meshes[(int)i]; meshIndexed.meshName = meshobj.name; meshIndexed.matrix = meshobj.lmat; meshIndexed.Allocate(meshobj.nVerts, meshobj.nFaces); if (meshobj.mc != null) { // scale and transform the mesh object for (i = 0; i < meshobj.nVerts; ++i) { Vector3 v = new Vector3(meshobj.verts[i].x * -1, meshobj.verts[i].y, meshobj.verts[i].z); meshIndexed.SetVertexPosition(i, v); meshIndexed.textures[i].y = meshobj.mc[i * 2]; meshIndexed.textures[i].x = meshobj.mc[(i * 2) + 1]; } } else { // scale and transform the mesh object for (i = 0; i < meshobj.nVerts; ++i) { Vector3 v = new Vector3(meshobj.verts[i].x * -1, meshobj.verts[i].y, meshobj.verts[i].z); meshIndexed.SetVertexPosition(i, v); } } // Buffers for calculating smoothing groups ushort[] sharedFaces = new ushort[meshIndexed.vertexList.Length]; Vector3[] summedNormals = new Vector3[meshIndexed.vertexList.Length]; Vector3 v1, v2, normal; for (i = 0; i < meshobj.nFaces; ++i) { Face3S f = meshobj.faces[i]; // copy face information meshIndexed.SetFaceIndicies(i, meshobj.faces[i].a, meshobj.faces[i].b, meshobj.faces[i].c); // get the normal with the cross product of two verts // on the same face Vector3 a = new Vector3(meshobj.verts[f.a].x, meshobj.verts[f.a].y, meshobj.verts[f.a].z); Vector3 b = new Vector3(meshobj.verts[f.b].x, meshobj.verts[f.b].y, meshobj.verts[f.b].z); Vector3 c = new Vector3(meshobj.verts[f.c].x, meshobj.verts[f.c].y, meshobj.verts[f.c].z); v1 = b - c; v2 = a - b; // calculate the normal, sum it in the normal // array and normal = Vector3.Cross(v1, v2) * -1; normal.Normalize(); meshIndexed.SetVertexNormal(f.a, normal); meshIndexed.SetVertexNormal(f.b, normal); meshIndexed.SetVertexNormal(f.c, normal); sharedFaces[f.a]++; sharedFaces[f.b]++; sharedFaces[f.c]++; summedNormals[f.a] += normal; summedNormals[f.b] += normal; summedNormals[f.c] += normal; } if (applySmoothingGroups) { // apply the smoothing groups for (int iv = 0; iv < meshIndexed.vertexList.Length; ++iv) { // get the weighted normal Vector3 n = summedNormals[iv]; n = n / sharedFaces[iv]; // renorm n.Normalize(); meshIndexed.SetVertexNormal(i, n); } } // Lookup and assign materials groups, this will convert the material // group to something that can be rendered quickly and has to happen // after we have already loaded all the face->vert indexes foreach (FaceMaterial material in meshobj.faceMaterials) { Material mat; if (LookupMaterialByName(material.name, out mat)) { if (mat.textures.Count > 0) { meshIndexed.textureName = mat.name; } meshIndexed.AddMaterialAmbient(mat.ambient.r, mat.ambient.g, mat.ambient.b); meshIndexed.AddMaterialDifusse(mat.diffuse.r, mat.diffuse.g, mat.diffuse.b); meshIndexed.AddMaterialSpecular(mat.specular.r, mat.specular.g, mat.specular.b); // mesh.AddMaterialGroup( // material.faces, // new Color(mat.ambient.r, mat.ambient.g, mat.ambient.b), // new Color(mat.diffuse.r, mat.diffuse.g, mat.diffuse.b), // new Color(mat.specular.r, mat.diffuse.g, mat.diffuse.b)); } } return(meshIndexed); }
void CalcularNormales(MeshIndexed objeto) { float NormalX = 0, NormalY = 0, NormalZ = 0; float sumx = 0.0f, sumy = 0.0f, sumz = 0.0f; int shared = 0; int i, j; int policount = objeto.faceList.Length; int vertexcount = objeto.vertexList.Length; Faces[] Tri = new Faces[policount]; for (i = 0; i < policount; i++) { objeto.faceList[i].normal = new Vector3[3]; } for (i = 0; i < Tri.Length; i++) { Tri[i].V1 = new float[3]; Tri[i].V2 = new float[3]; Tri[i].V3 = new float[3]; Tri[i].N = new float[3]; } float[,] vnormales = new float[vertexcount, 3]; for (i = 0; i < policount; i++) { //Vertice 1 j = objeto.faceList[i].vertexIndexes[0]; Tri[i].V1[0] = objeto.vertexList[j].x; Tri[i].V1[1] = objeto.vertexList[j].y; Tri[i].V1[2] = objeto.vertexList[j].z; //Vertice 2 j = objeto.faceList[i].vertexIndexes[1]; Tri[i].V2[0] = objeto.vertexList[j].x; Tri[i].V2[1] = objeto.vertexList[j].y; Tri[i].V2[2] = objeto.vertexList[j].z; //Vertice 3 j = objeto.faceList[i].vertexIndexes[2]; Tri[i].V3[0] = objeto.vertexList[j].x; Tri[i].V3[1] = objeto.vertexList[j].y; Tri[i].V3[2] = objeto.vertexList[j].z; //Calcula el vector Normal VectorNormal(Tri[i].V1, Tri[i].V2, Tri[i].V3, out NormalX, out NormalY, out NormalZ); //nos retorna un vector unitario, es decir de modulo 1 Normalizar(ref NormalX, ref NormalY, ref NormalZ); //almacena los vectores normales, para cada poligono Tri[i].N[0] = NormalX; Tri[i].N[1] = NormalY; Tri[i].N[2] = NormalZ; } for (i = 0; i < vertexcount; i++) { for (j = 0; j < policount; j++) { if (objeto.faceList[j].vertexIndexes[0] == i || objeto.faceList[j].vertexIndexes[1] == i || objeto.faceList[j].vertexIndexes[2] == i) { sumx = sumx + Tri[j].N[0]; sumy = sumy + Tri[j].N[1]; sumz = sumz + Tri[j].N[2]; shared++; } } vnormales[i, 0] = sumx / (float)shared; vnormales[i, 1] = sumy / (float)shared; vnormales[i, 2] = sumz / (float)shared; Normalizar(ref vnormales[i, 0], ref vnormales[i, 1], ref vnormales[i, 2]); sumx = 0.0f; sumy = 0.0f; sumz = 0.0f; shared = 0; } //guardo las normales calculadas en el objeto for (i = 0; i < policount; i++) { for (j = 0; j < 3; j++) { objeto.faceList[i].normal[j].X = vnormales[objeto.faceList[i].vertexIndexes[j], 0]; objeto.faceList[i].normal[j].Y = vnormales[objeto.faceList[i].vertexIndexes[j], 1]; objeto.faceList[i].normal[j].Z = vnormales[objeto.faceList[i].vertexIndexes[j], 2]; } } }