/* * ms3dascii2wld conversion program * * This program pulls out vertex, triangle, and color information from a * MilkShape3D ascii file and outputs it in .wld format, an augmented form * of the .ply format for use in Team6's golf game. * * This code includes some code from Team1's conversion code and Team6's * .wld parser. */ #include #include #include #include #include using namespace std; const int COLOR_STYLES = 4; struct MaterialData { string _materialName; // colorData stores the different color styles. // There are 4 by default: ambient, diffuse, specular, and emissive. float colorData[COLOR_STYLES][3]; }; /* * outputMaterialData */ void outputMaterialData(ostream &out, struct MaterialData *mDataArray, int material) { for (int colorStyle = 0; colorStyle < COLOR_STYLES; colorStyle++) { for (int rgbIndex = 0; rgbIndex < 3; rgbIndex++) { if (rgbIndex > 0) out << " "; out << mDataArray[material].colorData[colorStyle][rgbIndex]; } out << endl; } } /* * ignoreTokens strips away and ignores the next number tokens. */ void ignoreTokens(istream &in, int number) { string ignored; for (int counter = 0; counter < number; counter++) { in >> ignored; } return; } /* * outputTokens sends the first number tokens from the input stream to the * output stream with spaces between tokens (but not before first token * or after last token). */ void outputTokens(istream &in, ostream &out, int number) { string outputToken; for (int counter = 0; counter < number; counter++) { in >> outputToken; if (counter > 0) out << " "; out << outputToken; } return; } int parse(string sourceFile, string targetFile) { int numMaterials = 0; int numMeshes = 0; MaterialData* materialsArray = NULL; // Open the source and target files. fstream source(sourceFile.c_str(), ios_base::in); fstream target(targetFile.c_str(), ios_base::out); string nextToken; // // In order to output material data with each mesh as it is parsed, // parse and store material data ahead of time. // // Ignore all tokens before reaching materials section. do { source >> nextToken; } while (nextToken != "Materials:"); source >> numMaterials; if (numMaterials) { materialsArray = new MaterialData[numMaterials]; } for (int counter = 0; counter < numMaterials; counter++) { source >> materialsArray[counter]._materialName; for (int colorStyle = 0; colorStyle < COLOR_STYLES; colorStyle++) { for (int rgbIndex = 0; rgbIndex < 3; rgbIndex++) { source >> materialsArray[counter].colorData[colorStyle][rgbIndex]; } // Ignore extra flag at the end of each color line. ignoreTokens(source, 1); } // Ignore extra material information. ignoreTokens(source, 4); } // // Parse each triangle mesh and output desired information to target // file, including appropriate material data gathered in first pass. // // Close and reopen source file so we can start to parse meshes. source.close(); source.open(sourceFile.c_str(), ios_base::in); // Ignore all tokens before reaching meshes section. do { source >> nextToken; } while (nextToken != "Meshes:"); source >> numMeshes; // Parse each mesh. for (int counter = 0; counter < numMeshes; counter++) { // Output: Before every mesh aside from the first, add "newmesh" // command to signal another mesh to be input. if (counter > 0) { target << "newmesh" << endl; } // Decide if mesh counts as hole. bool meshIsHole = false; string meshName; source >> meshName; if (meshName == "\"Hole\"" || meshName == "\"hole\"") { meshIsHole = true; } // Ignore first flag. ignoreTokens(source, 1); int meshMaterial; source >> meshMaterial; // // Parse the mesh vertex information. // int meshVertices; source >> meshVertices; // Output: Number of vertices in mesh. target << meshVertices << endl; for (int counter = 0; counter < meshVertices; counter++) { // Ignore first flag. ignoreTokens(source, 1); // Output: Three coordinates of the vertex. outputTokens(source, target, 3); // Ignore next three values. ignoreTokens(source, 3); // Output: Dummy RGB color values for vertex. target << " 1 1 1"; target << endl; } // // Ignore normals information. // int meshNormals; source >> meshNormals; for (int counter = 0; counter < meshNormals; counter++) { ignoreTokens(source, 3); } // // Parse the mesh triangle information. // int meshTriangles; source >> meshTriangles; // Output: Number of triangles in mesh. target << meshTriangles << endl; for (int counter = 0; counter < meshTriangles; counter++) { // Ignore first flag. ignoreTokens(source, 1); // Output: Three vertices of triangle. outputTokens(source, target, 3); // Ignore next four values. ignoreTokens(source, 4); target << endl; } // // Output mesh material information if a material was specified. // if (meshMaterial >= 0) { // Output: command "hole" signals this mesh counts as the hole. if (meshIsHole) target << "hole" << endl; // Output: command "meshcolor" signals color information input. target << "meshcolor" << endl; outputMaterialData(target, materialsArray, meshMaterial); } } // End of mesh parsing loop. if (numMaterials) { assert(materialsArray != NULL); delete[] materialsArray; } return 0; } int main(int argc, char **argv) { string sourceFile; string targetFile; // Get name of milkshape file to be read. cout << "Please input the name of the MilkShape3D ascii input file: " << endl; cin >> sourceFile; // Get name of file to output .wld data. cout << "Please input the name of the destination file: " << endl; cin >> targetFile; parse(sourceFile, targetFile); return 0; }