home *** CD-ROM | disk | FTP | other *** search
- #include "stdafx.h"
-
- bool extract_TGP(const char* filename);
- bool process_MDL(const char* filename);
- bool parse(const char* data, deque<string>& list);
- string strip(const string& data, char c);
- string strip_trailing_spaces(const string& data);
-
- class Exporter {
- private :
- struct Material {
- string name;
- string type;
- deque<unsigned int> diffuse_texture_index;
- float ambient[3];
- float diffuse[3];
- float specular[3];
- float emissive[3];
- float bump[3];
- float opacity;
- float shininess;
- float reflectivity;
- };
- struct Texture {
- string name;
- string type;
- string filename;
- };
- struct Skeleton {
- string parent;
- string type;
- string order;
- float translation[3];
- float rotation[3];
- float scale[3];
- };
- struct Polygon {
- deque<unsigned int> material_index;
- unsigned int face_index[3];
- unsigned int uv_index[3];
- unsigned int color[3];
- };
- struct Weight {
- size_t index;
- float value;
- };
- struct WeightMap {
- size_t size;
- string name;
- deque<Weight> data;
- };
- struct Mesh {
- string name;
- deque<Polygon> polygon_list;
- deque<vector3D<float>> vertex_list;
- deque<WeightMap> weight_list;
- deque<vector3D<float>> normal_list;
- deque<vector2D<float>> uv_list;
- deque<unsigned int> material_index_list;
- };
- private :
- deque<string> line_list;
- size_t curr_line;
- private :
- deque<Material> material_list;
- deque<Texture> texture_list;
- map<string, Skeleton> skeleton_list;
- deque<Mesh> mesh_list;
- private :
- void clear(void);
- public :
- bool ProcessMaterialList(size_t n_materials);
- bool ProcessMaterial(void);
- public :
- bool ProcessSkeletonList(size_t n_nodes);
- bool ProcessSkeleton(void);
- public :
- bool ProcessMeshList(size_t n_meshes);
- bool ProcessMesh(void);
- bool ProcessPolygonList(size_t n_polygons, Mesh& mesh);
- bool ProcessPolygon(Mesh& mesh);
- bool ProcessVertexList(size_t n_points, Mesh& mesh);
- bool ProcessWeightList(size_t n_weights, Mesh& mesh);
- bool ProcessWeight(Mesh& mesh);
- bool ProcessNormalList(size_t n_normals, Mesh& mesh);
- bool ProcessUVList(size_t n_points, Mesh& mesh);
- bool ProcessMaterialIndexList(size_t n_items, Mesh& mesh);
- public :
- bool ProcessTextureList(size_t n_textures);
- bool ProcessTexture(void);
- public :
- bool process(const char* filename, const char* savename, const char* editname, const char* wavename, const char* wmtlname);
- public :
- Exporter();
- ~Exporter();
- private :
- Exporter(const Exporter&);
- void operator =(const Exporter&);
- };
-
- int main()
- {
- // create namelist
- deque<string> namelist;
- if(get_filename_list(namelist, "tgp")) {
- for(size_t i = 0; i < namelist.size(); i++)
- extract_TGP(namelist[i].c_str());
- }
-
- // create model namelist
- deque<string> filelist;
- deque<string> savelist;
- deque<string> editlist;
- deque<string> wavelist;
- deque<string> wmtllist;
-
- if(!get_filename_list(filelist, "mdl"))
- return -1;
-
- for(size_t i = 0; i < filelist.size(); i++)
- {
- // extract filename parameters
- char param1[MAX_PATH];
- char param2[MAX_PATH];
- char param3[MAX_PATH];
- char param4[MAX_PATH];
- _splitpath(filelist[i].c_str(), param1, param2, param3, param4);
-
- // change extension
- string savename(param1);
- savename += param2;
- savename += param3;
- savename += ".ls";
- savelist.push_back(savename);
-
- // change extension
- string wavename(param1);
- wavename += param2;
- wavename += param3;
- wavename += ".obj";
- wavelist.push_back(wavename);
-
- // change extension
- string wmtlname(param1);
- wmtlname += param2;
- wmtlname += param3;
- wmtlname += ".mtl";
- wmtllist.push_back(wmtlname);
-
- // change extension
- string editname(param1);
- editname += param2;
- editname += param3;
- editname += ".txt";
- editlist.push_back(editname);
- }
-
- // process model files
- for(size_t i = 0; i < filelist.size(); i++) {
- cout << "Processing " << filelist[i].c_str() << "..." << endl;
- Exporter e;
- e.process(filelist[i].c_str(), savelist[i].c_str(), editlist[i].c_str(), wavelist[i].c_str(), wmtllist[i].c_str());
- }
-
- return -1;
- }
-
- Exporter::Exporter()
- {
- }
-
- Exporter::~Exporter()
- {
- }
-
- void Exporter::clear(void)
- {
- // clear data
- material_list.clear();
- texture_list.clear();
- skeleton_list.clear();
- mesh_list.clear();
-
- // clear file data
- line_list.clear();
- curr_line = 0;
- }
-
- bool Exporter::process(const char* filename, const char* savename, const char* editname, const char* wavename, const char* wmtlname)
- {
- // clear data
- clear();
-
- // open file
- ifstream ifile(filename, ios::binary);
- if(!ifile) return error("Cannot open file.");
-
- // edit file
- ofstream efile(editname);
- if(!ifile) return error("Cannot open file.");
-
- // load data line-by-line
- for(;;)
- {
- // read line
- char buffer[2048];
- ifile.getline(buffer, 2048);
- if(ifile.fail()) break;
-
- // must have data
- string data(buffer);
- if(data.length() == 0) continue;
- if(data.length() == 1 && data[0] == 0x0A) continue;
- if(data.length() == 1 && data[0] == 0x0D) continue;
-
- // remove comments
- size_t position = data.find('#');
- if(position == 0) continue;
- if(position != string::npos) data = data.substr(0, position);
- if(!data.length()) continue;
-
- // remove beginning spaces
- size_t j = 0;
- for(size_t i = 0; i < data.length(); i++) {
- if(data[i] != 0x09) break;
- else j++;
- }
- data = data.substr(j);
- if(data.length() == 0) continue;
- if(data.length() == 1 && data[0] == 0x0A) continue;
- if(data.length() == 1 && data[0] == 0x0D) continue;
-
- // remove trailing spaces
- data = strip_trailing_spaces(data);
-
- // insert line
- line_list.push_back(data);
- efile << data.c_str() << endl;
- }
-
- // process data line-by-line
- curr_line = 0;
- do {
- // parse line
- deque<string> list;
- if(parse(line_list[curr_line].c_str(), list) == false) break;
-
- // process root nodes
- if(list[0] == "TGL Model Format Text Ver 0.8") curr_line++;
- else if(list[0] == "MaterialList") {
- if(list.size() < 2) return error("<MaterialList>: Expecting at least two arguments.");
- cout << " <MaterialList>" << endl;
- ProcessMaterialList(stoi(list[1].c_str()));
- }
- else if(list[0] == "MeshList") {
- cout << " <MeshList>" << endl;
- if(list.size() < 2) return error("<MeshList>: Expecting at least two arguments.");
- ProcessMeshList(stoi(list[1].c_str()));
- }
- else if(list[0] == "SkeltonList") {
- cout << " <SkeltonList>" << endl;
- if(list.size() < 2) return error("<SkeletonList>: Expecting at least two arguments.");
- ProcessSkeletonList(stoi(list[1].c_str()));
- }
- else if(list[0] == "TextureList") {
- cout << " <TextureList>" << endl;
- if(list.size() < 2) return error("<TextureList>: Expecting at least two arguments.");
- ProcessTextureList(stoi(list[1].c_str()));
- }
- else curr_line++;
- }
- while(curr_line < line_list.size());
-
- // create lscript file
- ofstream ofile(savename);
- ofile << "main" << endl;
- ofile << "{" << endl;
- ofile << " editbegin();" << endl;
-
- // for each mesh
- for(size_t i = 0; i < mesh_list.size(); i++)
- {
- // store texture
- ofile << " editbegin();" << endl;
- ofile << " uvmap = VMap(\"texture\", " << mesh_list[i].name << ", 2);" << endl;
- ofile << " editend();" << endl;
-
- // set layer and surface
- ofile << " lyrsetfg(" << (i + 1) << ");" << endl;
- ofile << " setsurface(" << mesh_list[i].name << ");" << endl;
-
- // save triangles
- ofile << " editbegin();" << endl;
- size_t point_index = 1;
- for(size_t j = 0; j < mesh_list[i].polygon_list.size(); j++)
- {
- // point indeces
- size_t a_index = point_index++;
- size_t b_index = point_index++;
- size_t c_index = point_index++;
-
- // get vertex index
- unsigned short a_vertex_index = mesh_list[i].polygon_list[j].face_index[0];
- unsigned short b_vertex_index = mesh_list[i].polygon_list[j].face_index[1];
- unsigned short c_vertex_index = mesh_list[i].polygon_list[j].face_index[2];
-
- // get vertex value
- vector3D<float> a_vertex = mesh_list[i].vertex_list[a_vertex_index];
- vector3D<float> b_vertex = mesh_list[i].vertex_list[b_vertex_index];
- vector3D<float> c_vertex = mesh_list[i].vertex_list[c_vertex_index];
-
- // get uv index
- unsigned short a_uv_index = mesh_list[i].polygon_list[j].uv_index[0];
- unsigned short b_uv_index = mesh_list[i].polygon_list[j].uv_index[1];
- unsigned short c_uv_index = mesh_list[i].polygon_list[j].uv_index[2];
-
- // get uv value
- vector2D<float> a_uv_value = mesh_list[i].uv_list[a_uv_index];
- vector2D<float> b_uv_value = mesh_list[i].uv_list[b_uv_index];
- vector2D<float> c_uv_value = mesh_list[i].uv_list[c_uv_index];
-
- // save points
- ofile << " pointlist[" << a_index << "]" << " = " << "addpoint(" << a_vertex[0] << "," << a_vertex[1] << "," << a_vertex[2] << ");" << endl;
- ofile << " pointlist[" << b_index << "]" << " = " << "addpoint(" << b_vertex[0] << "," << b_vertex[1] << "," << b_vertex[2] << ");" << endl;
- ofile << " pointlist[" << c_index << "]" << " = " << "addpoint(" << c_vertex[0] << "," << c_vertex[1] << "," << c_vertex[2] << ");" << endl;
-
- // save uv map
- ofile << " uvmap.setValue(pointlist[" << a_index << "]," << "@" << a_uv_value[0] << "," << -a_uv_value[1] << "@);" << endl;
- ofile << " uvmap.setValue(pointlist[" << b_index << "]," << "@" << b_uv_value[0] << "," << -b_uv_value[1] << "@);" << endl;
- ofile << " uvmap.setValue(pointlist[" << c_index << "]," << "@" << c_uv_value[0] << "," << -c_uv_value[1] << "@);" << endl;
-
- // save triangle
- ofile << " addtriangle(pointlist[" << a_index << "], pointlist[" << b_index << "], pointlist[" << c_index << "]);" << endl;
- }
- ofile << " editend();" << endl;
- }
-
- // finish lscript file
- ofile << " editend();" << endl;
- ofile << "}" << endl;
-
- // extract filename parameters
- char param1[MAX_PATH];
- char param2[MAX_PATH];
- char param3[MAX_PATH];
- char param4[MAX_PATH];
- _splitpath(filename, param1, param2, param3, param4);
-
- // create obj file
- ofstream objfile(wavename);
- objfile << "o " << param3 << ".obj" << endl;
- objfile << "mtllib " << param3 << ".mtl" << endl;
-
- // for each mesh
- size_t v_offset = 0;
- size_t t_offset = 0;
- for(size_t i = 0; i < mesh_list.size(); i++)
- {
- objfile << "g " << strip(mesh_list[i].name, '\"').c_str() << endl;
- objfile << "usemtl " << strip(mesh_list[i].name, '\"').c_str() << endl;
-
- // vertices
- for(size_t j = 0; j < mesh_list[i].vertex_list.size(); j++) {
- float x = mesh_list[i].vertex_list[j][0];
- float y = mesh_list[i].vertex_list[j][1];
- float z = mesh_list[i].vertex_list[j][2];
- objfile << "v " << x << " " << y << " " << z << endl;
- }
-
- // texture coordinates
- for(size_t j = 0; j < mesh_list[i].uv_list.size(); j++) {
- float u = mesh_list[i].uv_list[j][0];
- float v = mesh_list[i].uv_list[j][1];
- objfile << "vt " << u << " " << -v << endl;
- }
-
- // normals
- for(size_t j = 0; j < mesh_list[i].normal_list.size(); j++) {
- float x = mesh_list[i].normal_list[j][0];
- float y = mesh_list[i].normal_list[j][1];
- float z = mesh_list[i].normal_list[j][2];
- objfile << "vn " << x << " " << y << " " << z << endl;
- }
-
- // triangles
- for(size_t j = 0; j < mesh_list[i].polygon_list.size(); j++)
- {
- unsigned short v1 = v_offset + mesh_list[i].polygon_list[j].face_index[0] + 1;
- unsigned short v2 = v_offset + mesh_list[i].polygon_list[j].face_index[1] + 1;
- unsigned short v3 = v_offset + mesh_list[i].polygon_list[j].face_index[2] + 1;
-
- unsigned short t1 = t_offset + mesh_list[i].polygon_list[j].uv_index[0] + 1;
- unsigned short t2 = t_offset + mesh_list[i].polygon_list[j].uv_index[1] + 1;
- unsigned short t3 = t_offset + mesh_list[i].polygon_list[j].uv_index[2] + 1;
-
- objfile << "f " <<
- v1 << "/" << t1 << " " <<
- v2 << "/" << t2 << " " <<
- v3 << "/" << t3 << endl;
- }
-
- v_offset += mesh_list[i].vertex_list.size();
- t_offset += mesh_list[i].uv_list.size();
- objfile << endl;
- }
-
- // create material file
- ofstream mtlfile(wmtlname);
-
- for(size_t i = 0; i < mesh_list.size(); i++)
- {
- unsigned int material_index = mesh_list[i].material_index_list[0];
- unsigned int texture_index = 0;
- if(material_list[material_index].diffuse_texture_index.size()) texture_index = material_list[material_index].diffuse_texture_index[0];
-
- mtlfile << "newmtl " << strip(mesh_list[i].name, '\"').c_str() << endl;
- mtlfile << "Ka " << 0 << " " << 0 << " " << 0 << endl;
- mtlfile << "Kd " << 0.784314 << " " << 0.784314 << " " << 0.784314 << endl;
- mtlfile << "Ks " << 0 << " " << 0 << " " << 0 << endl;
- mtlfile << "Ni " << 1 << endl;
- mtlfile << "Ns " << 400 << endl;
- mtlfile << "Tf " << 1 << " " << 1 << " " << 1 << endl;
- mtlfile << "d " << 1 << endl;
- mtlfile << "map_Kd " << strip(texture_list[texture_index].filename, '\"').c_str() << endl;
- mtlfile << endl;
- }
-
- return true;
- }
-
- bool Exporter::ProcessMaterialList(size_t n_materials)
- {
- // parse line
- deque<string> parse_list;
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<MaterialList>: Empty token list.");
- if(parse_list[0] != "{") return error("<MaterialList>: Expecting '{' token.");
-
- // process textures
- for(size_t i = 0; i < n_materials; i++)
- if(!ProcessMaterial()) return false;
-
- // line should be ''
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<MaterialList>: Empty token list.");
- if(parse_list[0] != "}") return error("<MaterialList>: Expecting '}' token.");
-
- // success
- return true;
- }
-
- bool Exporter::ProcessMaterial(void)
- {
- // variables
- deque<string> parse_list;
- Material material;
-
- // line should be 'Material "name"'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Material>: Empty token list.");
- if(parse_list.size() < 2) return error("<Material>: Expecting <Material> <name>.");
- material.name = parse_list[1];
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Material>: Empty token list.");
- if(parse_list[0] != "{") return error("<Material>: Expecting '{' token.");
-
- // process lines
- for(;;)
- {
- // parse line
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Material>: Empty token list.");
-
- // process tokens
- if(parse_list.size() == 1) {
- if(parse_list[0] == "}") break;
- else return error("<Material>: Unexpected token.");
- }
- else if(parse_list.size() == 2) {
- if(parse_list[0] == "type") material.type = parse_list[1];
- else if(parse_list[0] == "Opacity") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[1] = strip(parse_list[1], ')');
- material.opacity = stof(parse_list[1]);
- }
- else if(parse_list[0] == "Shininess") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[1] = strip(parse_list[1], ')');
- material.shininess = stof(parse_list[1]);
- }
- else if(parse_list[0] == "Reflectivity") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[1] = strip(parse_list[1], ')');
- material.reflectivity = stof(parse_list[1]);
- }
- else if(parse_list[0] == "DiffuseTextureIndex")
- {
- // number of indices
- size_t n_indices = stoi(parse_list[1].c_str());
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<DiffuseTextureIndex>: Empty token list.");
- if(parse_list[0] != "{") return error("<DiffuseTextureIndex>: Expecting '{' token.");
-
- // process indicies
- for(size_t i = 0; i < n_indices; i++) {
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<DiffuseTextureIndex>: Empty token list.");
- material.diffuse_texture_index.push_back(stoi(parse_list[0].c_str()));
- }
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<DiffuseTextureIndex>: Empty token list.");
- if(parse_list[0] != "}") return error("<DiffuseTextureIndex>: Expecting '}' token.");
- }
- else return error("<Material>: Unexpected token.");
- }
- else if(parse_list.size() == 4) {
- if(parse_list[0] == "Ambient") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[3] = strip(parse_list[3], ')');
- material.ambient[0] = stof(parse_list[1]);
- material.ambient[1] = stof(parse_list[2]);
- material.ambient[2] = stof(parse_list[3]);
- }
- else if(parse_list[0] == "Diffuse") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[3] = strip(parse_list[3], ')');
- material.diffuse[0] = stof(parse_list[1]);
- material.diffuse[1] = stof(parse_list[2]);
- material.diffuse[2] = stof(parse_list[3]);
- }
- else if(parse_list[0] == "Specular") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[3] = strip(parse_list[3], ')');
- material.specular[0] = stof(parse_list[1]);
- material.specular[1] = stof(parse_list[2]);
- material.specular[2] = stof(parse_list[3]);
- }
- else if(parse_list[0] == "Emissive") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[3] = strip(parse_list[3], ')');
- material.emissive[0] = stof(parse_list[1]);
- material.emissive[1] = stof(parse_list[2]);
- material.emissive[2] = stof(parse_list[3]);
- }
- else if(parse_list[0] == "Bump") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[3] = strip(parse_list[3], ')');
- material.bump[0] = stof(parse_list[1]);
- material.bump[1] = stof(parse_list[2]);
- material.bump[2] = stof(parse_list[3]);
- }
- else return error("<Material>: Unexpected token.");
- }
- }
-
- // debug
- //cout << "MATERIAL" << endl;
- //cout << " name = " << material.name << endl;
- //cout << " type = " << material.type << endl;
- //cout << " ambient = " << material.ambient[0] << "," << material.ambient[1] << "," << material.ambient[2] << endl;
- //cout << " diffuse = " << material.diffuse[0] << "," << material.diffuse[1] << "," << material.diffuse[2] << endl;
- //cout << " specular = " << material.specular[0] << "," << material.specular[1] << "," << material.specular[2] << endl;
- //cout << " emissive = " << material.emissive[0] << "," << material.emissive[1] << "," << material.emissive[2] << endl;
- //cout << " bump = " << material.bump[0] << "," << material.bump[1] << "," << material.bump[2] << endl;
- //cout << " opacity = " << material.opacity << endl;
- //cout << " shininess = " << material.shininess << endl;
- //cout << " reflectivity = " << material.reflectivity << endl;
-
- // insert texture
- material_list.push_back(material);
- return true;
- }
-
- bool Exporter::ProcessSkeletonList(size_t n_nodes)
- {
- // parse line
- deque<string> parse_list;
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<SkeletonList>: Empty token list.");
- if(parse_list[0] != "{") return error("<SkeletonList>: Expecting '{' token.");
-
- // process textures
- for(size_t i = 0; i < n_nodes; i++)
- if(!ProcessSkeleton()) return false;
-
- // line should be ''
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<SkeletonList>: Empty token list.");
- if(parse_list[0] != "}") return error("<SkeletonList>: Expecting '}' token.");
-
- // success
- return true;
- }
-
- bool Exporter::ProcessSkeleton(void)
- {
- // variables
- deque<string> parse_list;
- Skeleton skeleton;
-
- // line should be 'Texture "name"'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Skeleton>: Empty token list.");
- if(parse_list.size() < 2) return error("<Skeleton>: Expecting <Skeleton> <name>.");
- string skeleton_name = parse_list[1];
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Skeleton>: Empty token list.");
- if(parse_list[0] != "{") return error("<Skeleton>: Expecting '{' token.");
-
- // process lines
- for(;;)
- {
- // parse line
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Skeleton>: Empty token list.");
-
- // process tokens
- if(parse_list.size() == 1) {
- if(parse_list[0] == "}") break;
- else return error("<Skeleton>: Unexpected token.");
- }
- else if(parse_list.size() == 2) {
- if(parse_list[0] == "Parent") skeleton.parent = parse_list[1];
- else if(parse_list[0] == "Type") skeleton.type = parse_list[1];
- else if(parse_list[0] == "RotationOrder") skeleton.order = parse_list[1];
- else return error("<Skeleton>: Unexpected token.");
- }
- else if(parse_list.size() == 4) {
- if(parse_list[0] == "Trans") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[3] = strip(parse_list[3], ')');
- skeleton.translation[0] = stof(parse_list[1]);
- skeleton.translation[1] = stof(parse_list[2]);
- skeleton.translation[2] = stof(parse_list[3]);
- }
- else if(parse_list[0] == "Rotate") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[3] = strip(parse_list[3], ')');
- skeleton.rotation[0] = stof(parse_list[1]);
- skeleton.rotation[1] = stof(parse_list[2]);
- skeleton.rotation[2] = stof(parse_list[3]);
- }
- else if(parse_list[0] == "Scale") {
- parse_list[1] = strip(parse_list[1], '(');
- parse_list[3] = strip(parse_list[3], ')');
- skeleton.scale[0] = stof(parse_list[1]);
- skeleton.scale[1] = stof(parse_list[2]);
- skeleton.scale[2] = stof(parse_list[3]);
- }
- else return error("<Skeleton>: Unexpected token.");
- }
- else return error("<Skeleton>: Unexpected number of tokens.");
- }
-
- // insert texture
- typedef map<string, Skeleton>::value_type value_type;
- skeleton_list.insert(value_type(skeleton_name, skeleton));
-
- // debug
- //cout << "SKELETON" << endl;
- //cout << " parent = " << skeleton.parent << endl;
- //cout << " type = " << skeleton.type << endl;
- //cout << " order = " << skeleton.order << endl;
- //cout << " translation = " << skeleton.translation[0] << "," << skeleton.translation[1] << "," << skeleton.translation[2] << endl;
- //cout << " rotation = " << skeleton.rotation[0] << "," << skeleton.rotation[1] << "," << skeleton.rotation[2] << endl;
- //cout << " scale = " << skeleton.scale[0] << "," << skeleton.scale[1] << "," << skeleton.scale[2] << endl;
- //cout << endl;
-
- return true;
- }
-
- bool Exporter::ProcessMeshList(size_t n_meshes)
- {
- // parse line
- deque<string> parse_list;
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<MeshList>: Empty token list.");
- if(parse_list[0] != "{") return error("<MeshList>: Expecting '{' token.");
-
- // process textures
- for(size_t i = 0; i < n_meshes; i++)
- if(!ProcessMesh()) return false;
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<MeshList>: Empty token list.");
- if(parse_list[0] != "}") return error("<MeshList>: Expecting '}' token.");
-
- // success
- return true;
- }
-
- bool Exporter::ProcessMesh(void)
- {
- // variables
- deque<string> parse_list;
- Mesh mesh;
-
- // line should be 'Mesh "name"'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Mesh>: Empty token list.");
- if(parse_list.size() < 2) return error("<Mesh>: Expecting <Mesh> <name>.");
- mesh.name = parse_list[1];
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Mesh>: Empty token list.");
- if(parse_list[0] != "{") return error("<Mesh>: Expecting '{' token.");
-
- // process lines
- for(;;)
- {
- // parse line
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Mesh>: Empty token list.");
-
- // process tokens
- if(parse_list.size() == 1) {
- if(parse_list[0] == "}") break;
- else return error("<Mesh>: Unexpected token.");
- }
- else if(parse_list.size() == 2) {
- if(parse_list[0] == "PolygonList") {
- if(!ProcessPolygonList(stoi(parse_list[1]), mesh))
- return false;
- }
- else if(parse_list[0] == "VertexList") {
- if(!ProcessVertexList(stoi(parse_list[1]), mesh))
- return false;
- }
- else if(parse_list[0] == "WeightList") {
- if(!ProcessWeightList(stoi(parse_list[1]), mesh))
- return false;
- }
- else if(parse_list[0] == "NormalList") {
- if(!ProcessNormalList(stoi(parse_list[1]), mesh))
- return false;
- }
- else if(parse_list[0] == "UVList") {
- if(!ProcessUVList(stoi(parse_list[1]), mesh))
- return false;
- }
- else if(parse_list[0] == "MaterialIndexList") {
- if(!ProcessMaterialIndexList(stoi(parse_list[1]), mesh))
- return false;
- }
- else return error("<Mesh>: Unexpected token.");
- }
- }
-
- // debug
- //cout << "Mesh" << endl;
-
- // insert texture
- mesh_list.push_back(mesh);
- return true;
- }
-
- bool Exporter::ProcessPolygonList(size_t n_polygons, Mesh& mesh)
- {
- // parse line
- deque<string> parse_list;
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<PolygonList>: Empty token list.");
- if(parse_list[0] != "{") return error("<PolygonList>: Expecting '{' token.");
-
- // process textures
- for(size_t i = 0; i < n_polygons; i++)
- if(!ProcessPolygon(mesh)) return false;
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<PolygonList>: Empty token list.");
- if(parse_list[0] != "}") return error("<PolygonList>: Expecting '}' token.");
-
- // success
- return true;
- }
-
- bool Exporter::ProcessPolygon(Mesh& mesh)
- {
- // variables
- deque<string> parse_list;
- Polygon polygon;
-
- // line should be <Polygon> <n>
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Polygon>: Empty token list.");
- if(parse_list.size() < 2) return error("<Polygon>: Expecting <Polygon> <n>.");
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Polygon>: Empty token list.");
- if(parse_list[0] != "{") return error("<Polygon>: Expecting '{' token.");
-
- // process lines
- for(;;)
- {
- // parse line
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Polygon>: Empty token list.");
-
- // process tokens
- if(parse_list[0] == "}") break;
- else if(parse_list[0] == "Material")
- {
- size_t n_indices = stoi(parse_list[1]);
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Polygon>: Empty token list.");
- if(parse_list[0] != "{") return error("<Polygon>: Expecting '{' token.");
-
- // read indices
- for(size_t i = 0; i < n_indices; i++) {
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Polygon>: Empty token list.");
- polygon.material_index.push_back(stoi(parse_list[0].c_str()));
- }
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Polygon>: Empty token list.");
- if(parse_list[0] != "}") return error("<Polygon>: Expecting '}' token.");
- }
- else if(parse_list[0] == "Face")
- {
- parse_list[2] = strip(parse_list[2], '(');
- parse_list[4] = strip(parse_list[4], ')');
- polygon.face_index[0] = stoi(parse_list[2]);
- polygon.face_index[1] = stoi(parse_list[3]);
- polygon.face_index[2] = stoi(parse_list[4]);
- }
- else if(parse_list[0] == "UV")
- {
- parse_list[2] = strip(parse_list[2], '(');
- parse_list[4] = strip(parse_list[4], ')');
- polygon.uv_index[0] = stoi(parse_list[2]);
- polygon.uv_index[1] = stoi(parse_list[3]);
- polygon.uv_index[2] = stoi(parse_list[4]);
- }
- else if(parse_list[0] == "Color")
- {
- parse_list[2] = strip(parse_list[2], '(');
- parse_list[4] = strip(parse_list[4], ')');
- polygon.color[0] = stoul(parse_list[2]); // careful here! crashes for stoi
- polygon.color[1] = stoul(parse_list[3]); // careful here! crashes for stoi
- polygon.color[2] = stoul(parse_list[4]); // careful here! crashes for stoi
- }
- else
- return error("<Polygon>: Unexpected token.");
- }
-
- // insert texture
- mesh.polygon_list.push_back(polygon);
- return true;
- }
-
- bool Exporter::ProcessVertexList(size_t n_points, Mesh& mesh)
- {
- // parse line
- deque<string> parse_list;
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<VertexList>: Empty token list.");
- if(parse_list[0] != "{") return error("<VertexList>: Expecting '{' token.");
-
- // process points
- for(size_t i = 0; i < n_points; i++)
- {
- // parse line
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<VertexList>: Empty token list.");
- if(parse_list.size() != 3) return error("<VertexList>: Invalid vertex.");
-
- // add vertex
- vector3D<float> v;
- v[0] = stof(parse_list[0]);
- v[1] = stof(parse_list[1]);
- v[2] = stof(parse_list[2]);
- mesh.vertex_list.push_back(v);
- }
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<VertexList>: Empty token list.");
- if(parse_list[0] != "}") return error("<VertexList>: Expecting '}' token.");
-
- // success
- return true;
- }
-
- bool Exporter::ProcessWeightList(size_t n_weights, Mesh& mesh)
- {
- // parse line
- deque<string> parse_list;
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<WeightList>: Empty token list.");
- if(parse_list[0] != "{") return error("<WeightList>: Expecting '{' token.");
-
- // process points
- for(size_t i = 0; i < n_weights; i++)
- ProcessWeight(mesh);
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<WeightList>: Empty token list.");
- if(parse_list[0] != "}") return error("<WeightList>: Expecting '}' token.");
-
- // success
- return true;
- }
-
- bool Exporter::ProcessWeight(Mesh& mesh)
- {
- // variables
- deque<string> parse_list;
- WeightMap wmap;
-
- // line should be <Weight> <n> <name>
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Weight>: Empty token list.");
- if(parse_list.size() != 3) return error("<Weight>: Expecting <Weight> <n> <name>.");
-
- wmap.size = stoi(parse_list[1]);
- wmap.name = parse_list[2];
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Weight>: Empty token list.");
- if(parse_list[0] != "{") return error("<Weight>: Expecting '{' token.");
-
- // process weights
- for(size_t i = 0; i < wmap.size; i++)
- {
- // parse line
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Weight>: Empty token list.");
-
- // insert weight
- Weight w;
- w.index = stoi(parse_list[0].c_str());
- w.value = stof(parse_list[0].c_str());
- wmap.data.push_back(w);
- }
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Weight>: Empty token list.");
- if(parse_list[0] != "}") return error("<Weight>: Expecting '}' token.");
-
- // insert texture
- mesh.weight_list.push_back(wmap);
- return true;
- }
-
- bool Exporter::ProcessNormalList(size_t n_normals, Mesh& mesh)
- {
- // parse line
- deque<string> parse_list;
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<NormalList>: Empty token list.");
- if(parse_list[0] != "{") return error("<NormalList>: Expecting '{' token.");
-
- // process points
- for(size_t i = 0; i < n_normals; i++)
- {
- // parse line
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<NormalList>: Empty token list.");
- if(parse_list.size() != 3) return error("<NormalList>: Invalid vertex.");
-
- // add vertex
- vector3D<float> v;
- v[0] = stof(parse_list[0]);
- v[1] = stof(parse_list[1]);
- v[2] = stof(parse_list[2]);
- mesh.normal_list.push_back(v);
- }
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<NormalList>: Empty token list.");
- if(parse_list[0] != "}") return error("<NormalList>: Expecting '}' token.");
-
- // success
- return true;
- }
-
- bool Exporter::ProcessUVList(size_t n_points, Mesh& mesh)
- {
- // parse line
- deque<string> parse_list;
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<UVList>: Empty token list.");
- if(parse_list[0] != "{") return error("<UVList>: Expecting '{' token.");
-
- // process points
- for(size_t i = 0; i < n_points; i++)
- {
- // parse line
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<UVList>: Empty token list.");
- if(parse_list.size() != 2) return error("<UVList>: Invalid vertex.");
-
- // add vertex
- vector2D<float> v;
- v[0] = stof(parse_list[0]);
- v[1] = stof(parse_list[1]);
- mesh.uv_list.push_back(v);
- }
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<UVList>: Empty token list.");
- if(parse_list[0] != "}") return error("<UVList>: Expecting '}' token.");
-
- // success
- return true;
- }
-
- bool Exporter::ProcessMaterialIndexList(size_t n_items, Mesh& mesh)
- {
- // parse line
- deque<string> parse_list;
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<MaterialIndexList>: Empty token list.");
- if(parse_list[0] != "{") return error("<MaterialIndexList>: Expecting '{' token.");
-
- // process material indices
- for(size_t i = 0; i < n_items; i++)
- {
- // parse line
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<MaterialIndexList>: Empty token list.");
- if(parse_list.size() != 1) return error("<MaterialIndexList>: Invalid index.");
-
- // add material index
- mesh.material_index_list.push_back(stoi(parse_list[0].c_str()));
- }
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<MaterialIndexList>: Empty token list.");
- if(parse_list[0] != "}") return error("<MaterialIndexList>: Expecting '}' token.");
-
- // success
- return true;
- }
-
- bool Exporter::ProcessTextureList(size_t n_textures)
- {
- // parse line
- deque<string> parse_list;
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<TextureList>: Empty token list.");
- if(parse_list[0] != "{") return error("<TextureList>: Expecting '{' token.");
-
- // process textures
- for(size_t i = 0; i < n_textures; i++)
- if(!ProcessTexture()) return false;
-
- // line should be '}'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<TextureList>: Empty token list.");
- if(parse_list[0] != "}") return error("<TextureList>: Expecting '}' token.");
-
- // success
- return true;
- }
-
- bool Exporter::ProcessTexture(void)
- {
- // variables
- deque<string> parse_list;
- Texture texture;
-
- // line should be 'Texture "name"'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Texture>: Empty token list.");
- if(parse_list.size() < 2) return error("<Texture>: Expecting <Texture> <name>.");
- texture.name = parse_list[1];
-
- // line should be '{'
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Texture>: Empty token list.");
- if(parse_list[0] != "{") return error("<Texture>: Expecting '{' token.");
-
- // process lines
- for(;;)
- {
- // parse line
- curr_line++;
- parse_list.clear();
- if(parse(line_list[curr_line].c_str(), parse_list) == false) return error("<Texture>: Empty token list.");
-
- // process tokens
- if(parse_list.size() == 1) {
- if(parse_list[0] == "}") break;
- else return error("<Texture>: Unexpected token.");
- }
- else if(parse_list.size() == 2) {
- if(parse_list[0] == "type") texture.type = parse_list[1];
- else if(parse_list[0] == "file") texture.filename = parse_list[1];
- else return error("<Texture>: Unexpected token.");
- }
- }
-
- // insert texture
- texture_list.push_back(texture);
- return true;
- }
-
- bool extract_TGP(const char* filename)
- {
- ifstream ifile(filename, ios::binary);
- if(!ifile) return error("Cannot open file.");
-
- unsigned int h01 = LE_read_uint32(ifile); // magic
- unsigned int h02 = LE_read_uint32(ifile); // 1
- unsigned int h03 = LE_read_uint32(ifile); // 0
- unsigned int h04 = LE_read_uint32(ifile); // offset to data
-
- // read filelist
- struct filedata {
- string name;
- unsigned int offset;
- unsigned int length;
- };
- deque<filedata> filelist;
- for(size_t i = 0; i < h04; i++)
- {
- // read filename
- char buffer[1024];
- ifile.read(&buffer[0], 0x60);
-
- // read offsets
- unsigned int o1, waste01;
- unsigned int o2, waste02;
- ifile.read((char*)&o1, sizeof(o1));
- ifile.read((char*)&waste01, sizeof(waste01));
- ifile.read((char*)&o2, sizeof(o2));
- ifile.read((char*)&waste02, sizeof(waste02));
-
- // add item
- filedata fd = { buffer, o1, o2 };
- filelist.push_back(fd);
- }
-
- // get full path filename
- char full_filename[1024];
- GetFullPathNameA(filename, 1024, full_filename, NULL);
- cout << full_filename << endl;
-
- // get full path
- char drive[1024];
- char dir[1024];
- _splitpath(full_filename, drive, dir, NULL, NULL);
- string full_pathname = drive;
- full_pathname += dir;
- cout << full_pathname.c_str() << endl;
-
- for(size_t i = 0; i < filelist.size(); i++)
- {
- // get full path filename
- string fname = full_pathname;
- fname += filelist[i].name;
-
- // get full path
- char drive[1024];
- char dir[1024];
- _splitpath(fname.c_str(), drive, dir, NULL, NULL);
- string fpath = drive;
- fpath += dir;
-
- // create path if not already created
- SHCreateDirectoryEx(NULL, fpath.c_str(), NULL);
-
- // create file
- ofstream ofile(fname, ios::binary);
- if(!ofile) return error("Could not create file.");
- cout << "Processing " << filelist[i].name.c_str() << "..." << endl;
-
- // move to offset and read data
- ifile.seekg(filelist[i].offset);
- char* data = new char[filelist[i].length];
- ifile.read(data, filelist[i].length);
-
- // save data
- ofile.write(data, filelist[i].length);
-
- // delete data
- delete[] data;
- data = 0;
- }
-
- return true;
- }
-
- bool parse(const char* data, deque<string>& list)
- {
- // must have data
- size_t size = strlen(data);
- if(size == 0) return false;
-
- // count spaces
- size_t spaces = 0;
- for(size_t i = 0; i < size; i++) if(data[i] == ' ') spaces++;
- if(spaces == size) return false;
-
- // parse
- size_t i = 0;
- while(i < size)
- {
- // find first non-whitespace character
- while(data[i] == ' ') i++;
- if(i == size) return true;
-
- // find next whitespace character
- size_t j = i + 1;
- while(data[j] != '\0' && data[j] != ' ') j++;
-
- // add string
- string temp(data);
- list.push_back(temp.substr(i, j - i));
-
- // increment
- i = j + 1;
- }
-
- return true;
- }
-
- string strip(const string& data, char c)
- {
- string retval = "";
- for(size_t i = 0; i < data.length(); i++) {
- if(data[i] == c) continue;
- else retval += data[i];
- }
- return retval;
- }
-
- string strip_trailing_spaces(const string& data)
- {
- string retval = "";
- for(size_t i = 0; i < data.length(); i++) {
- size_t j = (data.length() - 1) - i;
- if(data[j] == 0x09 || data[j] == 0x0A || data[j] == 0x0D) continue;
- else retval.push_back(data[j]);
- }
- std::reverse(retval.begin(), retval.end());
- return retval;
- }