public MaterialInfoWithFaces(SSWavefrontMTLInfo sourceMtl) { mtl = sourceMtl; }
/// <summary> /// This method is used to load information stored in .mtl files referenced by the .obj file. /// </summary> /// <param name="d3ddevice"></param> /// <param name="file"></param> private void parseOBJ(SSAssetManager.Context ctx, string filename) { MaterialInfoWithFaces currentMaterial = null; StreamReader sr = ctx.OpenText(filename); //Read the first line of text string line = sr.ReadLine(); //Continue to read until you reach end of file while (line != null) { string[] tokens = line.Split(" ".ToArray(), 2); if (tokens.Length < 2) { goto next_line; } string firstToken = tokens[0]; string lineContent = tokens[1]; switch (firstToken) { case "#": // Nothing to read, these are comments. break; case "v": // Vertex position positions.Add(WavefrontParser.readVector4(lineContent, null)); break; case "vn": // vertex normal direction vector normals.Add(WavefrontParser.readVector3(lineContent, null)); break; case "vt": // Vertex texcoordinate texCoords.Add(WavefrontParser.readVector2(lineContent, null)); break; case "f": // Face string[] values = WavefrontParser.FilteredSplit(lineContent, null); int numPoints = values.Length; Face face = new Face(); face.v_idx = new Int16[numPoints]; face.n_idx = new Int16[numPoints]; face.tex_idx = new Int16[numPoints]; // todo: how do outside clients know if there were texcoords or not?!?! for (int i = 0; i < numPoints; i++) { // format is "loc_index[/tex_index[/normal_index]]" e.g. 3 ; 3/2 ; 3/2/5 // but middle part can me empty, e.g. 3//5 string[] indexes = values[i].Split('/'); int iPosition = (int.Parse(indexes[0]) - 1); // adjust 1-based index if (iPosition < 0) { iPosition += positions.Count + 1; } // adjust negative indicies face.v_idx[i] = (Int16)iPosition; numIndices++; // initialize other indicies to not provided, in case they are missing face.n_idx[i] = -1; face.tex_idx[i] = -1; if (indexes.Length > 1) { string tex_index = indexes[1]; if (tex_index != "") { int iTexCoord = int.Parse(tex_index) - 1; // adjust 1-based index if (iTexCoord < 0) { iTexCoord += texCoords.Count + 1; } // adjust negative indicies face.tex_idx[i] = (Int16)iTexCoord; } if (indexes.Length > 2) { hasNormals = true; int iNormal = int.Parse(indexes[2]) - 1; // adjust 1 based index if (iNormal < 0) { iNormal += normals.Count + 1; } // adjust negative indicies face.n_idx[i] = (Int16)iNormal; } } } if (currentMaterial == null) { // no material in file, so create one currentMaterial = createImplicitMaterial(); } currentMaterial.faces.Add(face); currentMaterial.nbrIndices += face.v_idx.Length; numFaces++; break; case "mtllib": // load named material file string mtlFile = lineContent; { var mtls = SSWavefrontMTLInfo.ReadMTLs(ctx, mtlFile); foreach (var mtl in mtls) { materials.Add(new MaterialInfoWithFaces(mtl)); } } break; case "usemtl": // use named material (from material file previously loaded) bool found = false; string matName = lineContent; for (int i = 0; i < materials.Count; i++) { if (matName.Equals(materials[i].mtl.name)) { found = true; currentMaterial = materials[i]; } } if (!found) { throw new WavefrontObjParseException("Materials are already loaded so we should have it!"); } break; } next_line: //Read the next line line = sr.ReadLine(); } //close the file sr.Close(); }