home *** CD-ROM | disk | FTP | other *** search
- #include "stdafx.h"
-
- struct quaternion {
- float a, b, c, d;
- };
-
- struct bone {
- unsigned short index;
- unsigned short parent_index;
- char name[128];
- float relative_x;
- float relative_y;
- float relative_z;
- float absolute_x;
- float absolute_y;
- float absolute_z;
- quaternion q_relative;
- quaternion q_absolute;
- std::set<unsigned short> children;
- };
-
- bool extract_bmd6model(const char* filename, const char* savename, const char* bonename);
- bool extract_bmodel(const char* filename, const char* savename);
- bool extract_all_models_1(void);
- bool extract_all_models_2(void);
- void traverse_hierarchy(unsigned short node, std::deque<bone>& tree);
-
- int main()
- {
- extract_all_models_1();
- extract_all_models_2();
- return -1;
- }
-
- bool extract_all_models_1(void)
- {
- // get all ism2 files
- deque<string> namelist;
- if(!get_filename_list(namelist, "bmodel")) return false;
-
- // create a list of save filenames
- deque<string> savelist;
- deque<string> bonelist;
- deque<string> dbuglist;
- for(size_t i = 0; i < namelist.size(); i++)
- {
- // extract filename parameters
- char param1[MAX_PATH];
- char param2[MAX_PATH];
- char param3[MAX_PATH];
- char param4[MAX_PATH];
- _splitpath(namelist[i].c_str(), param1, param2, param3, param4);
-
- // change extension
- string savename(param1);
- savename += param2;
- savename += param3;
- savename += ".ls";
- savelist.push_back(savename);
- }
-
- // extract
- for(size_t i = 0; i < namelist.size(); i++)
- extract_bmodel(namelist[i].c_str(), savelist[i].c_str());
-
- return true;
- }
-
- bool extract_all_models_2(void)
- {
- // get all ism2 files
- deque<string> namelist;
- if(!get_filename_list(namelist, "bmd6model")) return false;
-
- // create a list of save filenames
- deque<string> savelist;
- deque<string> bonelist;
- deque<string> dbuglist;
- for(size_t i = 0; i < namelist.size(); i++)
- {
- // extract filename parameters
- char param1[MAX_PATH];
- char param2[MAX_PATH];
- char param3[MAX_PATH];
- char param4[MAX_PATH];
- _splitpath(namelist[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 bonename(param1);
- bonename += param2;
- bonename += param3;
- bonename += "_bones.ls";
- bonelist.push_back(bonename);
-
- // change extension
- string dbugname(param1);
- dbugname += param2;
- dbugname += param3;
- dbugname += ".txt";
- dbuglist.push_back(dbugname);
- }
-
- // extract
- for(size_t i = 0; i < namelist.size(); i++)
- extract_bmd6model(namelist[i].c_str(), savelist[i].c_str(), bonelist[i].c_str());
-
- return true;
- }
-
- bool extract_bmodel(const char* filename, const char* savename)
- {
- // open file
- std::cout << "Processing file: " << filename << std::endl;
- ifstream ifile(filename, ios::binary);
- if(!ifile) return error("Could not open file.");
-
- // magic number
- if(BE_read_uint32(ifile) != 0x184C4D42) return error("Invalid magic number.");
- BE_read_uint32(ifile); // 0 or some number
- unsigned int n_surfaces = BE_read_uint32(ifile); // 1, 2, 3
-
- // create output file
- ofstream ofile(savename);
- ofile << "main" << endl;
- ofile << "{" << endl;
-
- // loop through surfaces
- size_t namelen = LE_read_uint32(ifile);
- size_t surface = 0;
- do {
- // read texture filename
- char name[1024];
- memset(name, 0, 1024);
- ifile.read(name, namelen);
-
- // store texture
- ofile << " editbegin();" << endl;
- ofile << " uvmap = VMap(\"texture\", \"" << name << "\", 2);" << endl;
- ofile << " editend();" << endl;
-
- // set layer and surface
- ofile << " lyrsetfg(" << (surface + 1) << ");" << endl;
- ofile << " setsurface(\"" << name << "\");" << endl;
-
- // read 4-bytes (0xFFFFFFFF, 0, or 1)
- BE_read_uint32(ifile);
-
- // read point information
- size_t n_points = BE_read_uint32(ifile);
- size_t n_values = BE_read_uint32(ifile);
- size_t filetype = BE_read_uint32(ifile);
- cout << " points = " << n_points << endl;
- cout << " values = " << n_values << endl;
- cout << " filetype = " << filetype << endl;
-
- if(filetype == 0x1F)
- {
- // read 40 bytes
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
-
- // read points
- ofile << " editbegin();" << endl;
- for(size_t i = 0; i < n_points; i++) {
- float x = BE_read_float(ifile);
- float y = BE_read_float(ifile);
- float z = BE_read_float(ifile);
- float u = BE_read_float(ifile);
- float v = BE_read_float(ifile);
- BE_read_uint32(ifile);
- BE_read_uint32(ifile);
- BE_read_uint32(ifile);
- ofile << " pointlist[" << i + 1 << "]" << " = " << "addpoint(" << x << "," << y << "," << z << ");" << endl;
- ofile << " uvmap.setValue(pointlist[" << (i + 1) << "]," << "@" << u << "," << v << "@);" << endl;
- }
- ofile << " editend();" << endl;
-
- // read triangles
- if(n_values % 3) return error("Indicies must be divisible by 3 for type 0x1F.");
-
- // read triangles
- ofile << " editbegin();" << endl;
- boost::shared_array<unsigned short> data(new unsigned short[n_values]);
- ifile.read((char*)&data.get()[0], n_values*sizeof(unsigned short));
- for(size_t i = 0; i < n_values; i++) reverse_byte_order(&data.get()[i]);
- ofile << " editbegin();" << endl;
- size_t index = 0;
- for(size_t i = 0; i < n_values/3; i++) {
- unsigned short a = data.get()[index++] + 1;
- unsigned short b = data.get()[index++] + 1;
- unsigned short c = data.get()[index++] + 1;
- ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
- }
- ofile << " editend();" << endl;
- }
- else if(filetype == 0x63)
- {
- // read 40 bytes
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
-
- // read points
- struct point { short x, y, z, w; unsigned short u, v; };
- boost::shared_array<point> points(new point[n_points]);
- ifile.read((char*)&points.get()[0], n_points*sizeof(point));
-
- ofile << " editbegin();" << endl;
- for(size_t i = 0; i < n_points; i++) {
- reverse_byte_order(&points[i].x);
- reverse_byte_order(&points[i].y);
- reverse_byte_order(&points[i].z);
- reverse_byte_order(&points[i].w);
- reverse_byte_order(&points[i].u);
- reverse_byte_order(&points[i].v);
- float x = points[i].x/32767.0f;
- float y = points[i].y/32767.0f;
- float z = points[i].z/32767.0f;
- float u = points[i].u/65535.0f;
- float v = points[i].v/65535.0f;
- ofile << " pointlist[" << i + 1 << "]" << " = " << "addpoint(" << x << "," << y << "," << z << ");" << endl;
- ofile << " uvmap.setValue(pointlist[" << (i + 1) << "]," << "@" << u << "," << v << "@);" << endl;
- }
- ofile << " editend();" << endl;
-
- // read triangles
- if(n_values % 3) return error("Indicies must be divisible by 3 for type 0x1F.");
-
- // read triangles
- ofile << " editbegin();" << endl;
- boost::shared_array<unsigned short> data(new unsigned short[n_values]);
- ifile.read((char*)&data.get()[0], n_values*sizeof(unsigned short));
- for(size_t i = 0; i < n_values; i++) reverse_byte_order(&data.get()[i]);
- ofile << " editbegin();" << endl;
- size_t index = 0;
- for(size_t i = 0; i < n_values/3; i++) {
- unsigned short a = data.get()[index++] + 1;
- unsigned short b = data.get()[index++] + 1;
- unsigned short c = data.get()[index++] + 1;
- ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
- }
- ofile << " editend();" << endl;
- }
- else if(filetype == 0x077)
- {
- // read 40 bytes
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
-
- // read points (20 bytes per point)
- struct point { short x, y, z; unsigned short a, b, c, d, e, f, g; };
- boost::shared_array<point> points(new point[n_points]);
- ifile.read((char*)&points.get()[0], n_points*sizeof(point));
-
- ofile << " editbegin();" << endl;
- for(size_t i = 0; i < n_points; i++) {
- reverse_byte_order(&points[i].x);
- reverse_byte_order(&points[i].y);
- reverse_byte_order(&points[i].z);
- reverse_byte_order(&points[i].a);
- reverse_byte_order(&points[i].b);
- reverse_byte_order(&points[i].c);
- reverse_byte_order(&points[i].d);
- reverse_byte_order(&points[i].e);
- reverse_byte_order(&points[i].f);
- reverse_byte_order(&points[i].g);
- float x = points[i].x/32767.0f;
- float y = points[i].y/32767.0f;
- float z = points[i].z/32767.0f;
- float a = points[i].a/65535.0f;
- float b = points[i].b/65535.0f;
- float c = points[i].c/65535.0f;
- float d = points[i].d/65535.0f;
- float e = points[i].e/65535.0f;
- float f = points[i].f/65535.0f;
- float g = points[i].g/65535.0f;
- ofile << " pointlist[" << i + 1 << "]" << " = " << "addpoint(" << x << "," << y << "," << z << ");" << endl;
- ofile << " uvmap.setValue(pointlist[" << (i + 1) << "]," << "@" << b << "," << c << "@);" << endl;
- }
- ofile << " editend();" << endl;
-
- // read triangles
- if(n_values % 3) return error("Indicies must be divisible by 3 for type 0x1F.");
-
- // read triangles
- ofile << " editbegin();" << endl;
- boost::shared_array<unsigned short> data(new unsigned short[n_values]);
- ifile.read((char*)&data.get()[0], n_values*sizeof(unsigned short));
- for(size_t i = 0; i < n_values; i++) reverse_byte_order(&data.get()[i]);
- ofile << " editbegin();" << endl;
- size_t index = 0;
- for(size_t i = 0; i < n_values/3; i++) {
- unsigned short a = data.get()[index++] + 1;
- unsigned short b = data.get()[index++] + 1;
- unsigned short c = data.get()[index++] + 1;
- ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
- }
- ofile << " editend();" << endl;
- }
- else if(filetype == 0x21F)
- {
- // read 40 bytes
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
-
- // read points
- ofile << " editbegin();" << endl;
- for(size_t i = 0; i < n_points; i++) {
- float x = BE_read_float(ifile);
- float y = BE_read_float(ifile);
- float z = BE_read_float(ifile);
- float u = BE_read_float(ifile);
- float v = BE_read_float(ifile);
- BE_read_uint32(ifile);
- BE_read_uint32(ifile);
- BE_read_uint32(ifile);
- ofile << " pointlist[" << i + 1 << "]" << " = " << "addpoint(" << x << "," << y << "," << z << ");" << endl;
- ofile << " uvmap.setValue(pointlist[" << (i + 1) << "]," << "@" << u << "," << v << "@);" << endl;
- }
- ofile << " editend();" << endl;
-
- // read triangles
- ofile << " editbegin();" << endl;
- deque<unsigned short> data;
- for(size_t i = 0; i < n_values; i++)
- {
- unsigned short temp = BE_read_uint16(ifile);
- if(temp != 0xFFFF) data.push_back(temp);
-
- if(temp == 0xFFFF || i == n_values - 1)
- {
- // must have at least 3 elements
- if(data.size() < 3)
- return error("Expecting at least three tristrip indices.");
-
- // process first triangle
- unsigned short a = data[0] + 1;
- unsigned short b = data[1] + 1;
- unsigned short c = data[2] + 1;
- ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
-
- // process deque
- for(size_t j = 3; j < data.size(); j++) {
- a = b;
- b = c;
- c = data[j] + 1;
- if(j % 2) ofile << " addtriangle(pointlist[" << a << "], pointlist[" << b << "], pointlist[" << c << "]);" << endl;
- else ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
- }
-
- // clear deque
- data.erase(data.begin(), data.end());
- data.clear();
- }
- }
- ofile << " editend();" << endl;
- break;
- }
- else if(filetype == 0x263)
- {
- // read 40 bytes
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
-
- // read points
- struct point { short x, y, z, w; unsigned short u, v; };
- boost::shared_array<point> points(new point[n_points]);
- ifile.read((char*)&points.get()[0], n_points*sizeof(point));
-
- ofile << " editbegin();" << endl;
- for(size_t i = 0; i < n_points; i++) {
- reverse_byte_order(&points[i].x);
- reverse_byte_order(&points[i].y);
- reverse_byte_order(&points[i].z);
- reverse_byte_order(&points[i].w);
- reverse_byte_order(&points[i].u);
- reverse_byte_order(&points[i].v);
- float x = points[i].x/32767.0f;
- float y = points[i].y/32767.0f;
- float z = points[i].z/32767.0f;
- float u = points[i].u/65535.0f;
- float v = points[i].v/65535.0f;
- ofile << " pointlist[" << i + 1 << "]" << " = " << "addpoint(" << x << "," << y << "," << z << ");" << endl;
- ofile << " uvmap.setValue(pointlist[" << (i + 1) << "]," << "@" << u << "," << v << "@);" << endl;
- }
- ofile << " editend();" << endl;
-
- // read triangles
- ofile << " editbegin();" << endl;
- deque<unsigned short> data;
- for(size_t i = 0; i < n_values; i++)
- {
- unsigned short temp = BE_read_uint16(ifile);
- if(temp != 0xFFFF) data.push_back(temp);
-
- if(temp == 0xFFFF || i == n_values - 1)
- {
- // must have at least 3 elements
- if(data.size() < 3)
- return error("Expecting at least three tristrip indices.");
-
- // process first triangle
- unsigned short a = data[0] + 1;
- unsigned short b = data[1] + 1;
- unsigned short c = data[2] + 1;
- ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
-
- // process deque
- for(size_t j = 3; j < data.size(); j++) {
- a = b;
- b = c;
- c = data[j] + 1;
- if(j % 2) ofile << " addtriangle(pointlist[" << a << "], pointlist[" << b << "], pointlist[" << c << "]);" << endl;
- else ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
- }
-
- // clear deque
- data.erase(data.begin(), data.end());
- data.clear();
- }
- }
- ofile << " editend();" << endl;
- }
- else if(filetype == 0x277)
- {
- // read 40 bytes
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
-
- // read points
- struct point { short x, y, z; unsigned short a, b, c, d, e, f, g; };
- boost::shared_array<point> points(new point[n_points]);
- ifile.read((char*)&points.get()[0], n_points*sizeof(point));
-
- ofile << " editbegin();" << endl;
- for(size_t i = 0; i < n_points; i++) {
- reverse_byte_order(&points[i].x);
- reverse_byte_order(&points[i].y);
- reverse_byte_order(&points[i].z);
- reverse_byte_order(&points[i].a);
- reverse_byte_order(&points[i].b);
- reverse_byte_order(&points[i].c);
- reverse_byte_order(&points[i].d);
- reverse_byte_order(&points[i].e);
- reverse_byte_order(&points[i].f);
- reverse_byte_order(&points[i].g);
- float x = points[i].x/32767.0f;
- float y = points[i].y/32767.0f;
- float z = points[i].z/32767.0f;
- float a = points[i].a/65535.0f;
- float b = points[i].b/65535.0f;
- float c = points[i].c/65535.0f;
- float d = points[i].d/65535.0f;
- float e = points[i].e/65535.0f;
- float f = points[i].f/65535.0f;
- float g = points[i].g/65535.0f;
- ofile << " pointlist[" << i + 1 << "]" << " = " << "addpoint(" << x << "," << y << "," << z << ");" << endl;
- ofile << " uvmap.setValue(pointlist[" << (i + 1) << "]," << "@" << b << "," << c << "@);" << endl;
- }
- ofile << " editend();" << endl;
-
- // read triangles
- ofile << " editbegin();" << endl;
- deque<unsigned short> data;
- for(size_t i = 0; i < n_values; i++)
- {
- unsigned short temp = BE_read_uint16(ifile);
- if(temp != 0xFFFF) data.push_back(temp);
-
- if(temp == 0xFFFF || i == n_values - 1)
- {
- // must have at least 3 elements
- if(data.size() > 2)
- {
- // process first triangle
- unsigned short a = data[0] + 1;
- unsigned short b = data[1] + 1;
- unsigned short c = data[2] + 1;
- ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
-
- // process deque
- for(size_t j = 3; j < data.size(); j++) {
- a = b;
- b = c;
- c = data[j] + 1;
- if(j % 2) ofile << " addtriangle(pointlist[" << a << "], pointlist[" << b << "], pointlist[" << c << "]);" << endl;
- else ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
- }
- }
-
- // clear deque
- data.erase(data.begin(), data.end());
- data.clear();
- }
- }
- ofile << " editend();" << endl;
- }
- else {
- Sleep(10000);
- return error("Cannot process surface. Unknown surface type.");
- }
-
- // increment number of surfaces processed
- surface++;
-
- // read footer
- char footer[28];
- ifile.read(&footer[0], 28);
-
- // continue processing?
- if(BE_read_uint32(ifile) != 0x184C4D42) {
- Sleep(10000);
- return error("Invalid magic number.");
- }
- namelen = LE_read_uint32(ifile);
- }
- while(surface < n_surfaces);
-
- // finalize lscript
- ofile << "}" << endl;
-
- return true;
- }
-
- void traverse_hierarchy(unsigned short node, std::deque<bone>& tree)
- {
- typedef std::set<unsigned short>::iterator set_iterator;
- for(set_iterator i = tree[node].children.begin(); i != tree[node].children.end(); i++) {
- tree[*i].absolute_x += tree[node].relative_x;
- tree[*i].absolute_y += tree[node].relative_y;
- tree[*i].absolute_z += tree[node].relative_z;
- traverse_hierarchy(*i, tree);
- }
- }
-
- bool extract_bmd6model(const char* filename, const char* savename, const char* bonename)
- {
- std::cout << "Processing file: " << filename << std::endl;
- ifstream ifile(filename, ios::binary);
- if(!ifile) return error("Could not open file.");
-
- // 0x00
- BE_read_uint32(ifile);
- BE_read_uint16(ifile);
- BE_read_uint16(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
-
- // 0x10
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
-
- // 0x20
- BE_read_uint08(ifile);
- BE_read_uint16(ifile);
- BE_read_uint16(ifile);
- BE_read_uint16(ifile);
- BE_read_uint16(ifile);
- BE_read_uint16(ifile);
-
- unsigned short offset1 = BE_read_uint16(ifile); cout << "offset1 = " << offset1 << endl;
- unsigned short offset2 = BE_read_uint16(ifile);
- unsigned short n_strings_actual = BE_read_uint16(ifile);
- unsigned short n_strings = (n_strings_actual + 7) & (~7);
- boost::shared_array<unsigned short> offsets(new unsigned short[22]);
- ifile.read((char*)&offsets[0], 44);
- for(size_t i = 0; i < 22; i++) reverse_byte_order(&offsets[i]);
-
- // bone list
- std::deque<bone> bone_list;
- for(size_t i = 0; i < n_strings; i++) {
- bone b = { i, 0xFFFF, "", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
- bone_list.push_back(b);
- }
-
- // read quaternions
- cout << "n_strings_actual = " << n_strings_actual << endl;
- cout << "n_strings = " << n_strings << endl;
- for(size_t i = 0; i < n_strings; i++) {
- float q[4];
- ifile.read((char*)&q[0], 16);
- reverse_byte_order(&q[0]);
- reverse_byte_order(&q[1]);
- reverse_byte_order(&q[2]);
- reverse_byte_order(&q[3]);
- bone_list[i].q_relative.a = q[0];
- bone_list[i].q_relative.b = q[1];
- bone_list[i].q_relative.c = q[2];
- bone_list[i].q_relative.d = q[3];
- bone_list[i].q_absolute.a = q[0];
- bone_list[i].q_absolute.b = q[1];
- bone_list[i].q_absolute.c = q[2];
- bone_list[i].q_absolute.d = q[3];
- //cout << "q = " << q[0] << "," << q[1] << "," << q[2] << "," << q[3] << endl;
- }
-
- // read scale data
- for(size_t i = 0; i < n_strings; i++) {
- float s[3];
- ifile.read((char*)&s[0], 12);
- reverse_byte_order(&s[0]);
- reverse_byte_order(&s[1]);
- reverse_byte_order(&s[2]);
- }
-
- // read translation data
- deque<sl::vector3D<float>> translation_data;
- for(size_t i = 0; i < n_strings; i++) {
- float t[3];
- ifile.read((char*)&t[0], 12);
- reverse_byte_order(&t[0]);
- reverse_byte_order(&t[1]);
- reverse_byte_order(&t[2]);
- sl::vector3D<float> temp(t[0], t[1], t[2]);
- translation_data.push_back(temp);
- bone_list[i].relative_x = bone_list[i].absolute_x = t[0];
- bone_list[i].relative_y = bone_list[i].absolute_y = t[1];
- bone_list[i].relative_z = bone_list[i].absolute_z = t[2];
- }
-
- // read bone parent data
- typedef std::map<unsigned short, std::set<unsigned short>> map_type;
-
- // bone hierarchy
- for(size_t i = 0; i < n_strings; i++)
- {
- // get parent
- unsigned short parent;
- ifile.read((char*)&parent, sizeof(parent));
- reverse_byte_order(&parent);
-
- // add child
- if(parent == 0xFFFF) continue;
- bone_list[parent].children.insert(i);
- bone_list[i].parent_index = parent;
- }
-
- traverse_hierarchy(0, bone_list);
-
- // move to bone strings
- ifile.seekg(0x2D + offset1);
-
- // read bone strings
- for(size_t i = 0; i < n_strings; i++) {
- unsigned int slen = LE_read_uint32(ifile);
- if(!slen) continue;
- char buffer[1024];
- ifile.read((char*)&buffer[0], slen);
- buffer[slen] = '\0';
- memmove(bone_list[i].name, buffer, strlen(buffer) + 1);
- }
-
- // open destination file
- //ofstream bfile(bonename);
- //if(!bfile) return error("Could not create output file.");
-
- // save bone heirarchy
- //bfile << "@version 2.3" << endl;
- //bfile << "@warnings" << endl;
- //bfile << "@script generic" << endl;
- //bfile << "@name ShowHide" << endl;
- //bfile << "generic" << endl;
- //bfile << "{" << endl;
-
- for(size_t i = 0; i < bone_list.size(); i++)
- {
- // add child bone
- if(bone_list[i].parent_index != 0xFFFF) {
- //bfile << " SelectByName(\"" << bone_list[bone_list[i].parent_index].name << "\");" << endl;
- //bfile << " AddChildBone(\"" << bone_list[i].name << "\");" << endl;
- //bfile << " BoneType(2);" << endl;
- //bfile << " Position(" << bone_list[i].absolute_x << "," << bone_list[i].absolute_y << "," << bone_list[i].absolute_z << ");" << endl;
- }
- else if(strlen(bone_list[i].name) > 0) {
- //bfile << " AddBone(\"" << bone_list[i].name << "\");" << endl;
- //bfile << " BoneType(2);" << endl;
- //bfile << " Position(" << bone_list[i].absolute_x << "," << bone_list[i].absolute_y << "," << bone_list[i].absolute_z << ");" << endl;
- }
- }
- //bfile << "}" << endl;
-
- // read bone information
- boost::shared_array<unsigned char> bone_info(new unsigned char[n_strings]);
- ifile.read((char*)&bone_info.get()[0], n_strings);
-
- // read rotation matrices
- size_t bone_matrix_size = 12*n_strings;
- boost::shared_array<float> bone_matrix(new float[bone_matrix_size]);
- ifile.read((char*)&bone_matrix.get()[0], bone_matrix_size*sizeof(float));
- for(size_t i = 0; i < bone_matrix_size; i++) reverse_byte_order(&bone_matrix.get()[i]);
-
- // read (min, max)
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
-
- // read number of surfaces
- size_t surfaces = BE_read_uint32(ifile);
- if(!surfaces) return error("No surfaces");
- cout << " surfaces = " << surfaces << endl;
-
- // create file
- ofstream ofile(savename);
- ofile << "main" << endl;
- ofile << "{" << endl;
-
- // for each surface
- for(size_t s = 0; s < surfaces; s++)
- {
- // read surface name
- char sname[1024];
- memset(sname, 0, 1024);
- unsigned int sname_size = LE_read_uint32(ifile);
- if(sname_size) ifile.read(&sname[0], sname_size);
- else sprintf(sname, "surface_%d", s);
-
- // read path name
- char pname[1024];
- memset(pname, 0, 1024);
- unsigned int pname_size = LE_read_uint32(ifile);
- if(pname_size) ifile.read(&pname[0], pname_size);
- else sprintf(pname, "path_%d", s);
-
- // set foreground layer and surface name
- ofile << " lyrsetfg(" << (s + 1) << ");" << endl;
- ofile << " setsurface(\"" << sname << "\");" << endl;
-
- // create UV map
- ofile << " editbegin();" << endl;
- ofile << " uvmap_" << (s + 1) << " = VMap(\"texture\", \"" << sname << "\", 2);" << endl;
- ofile << " editend();" << endl;
-
- // read surface information
- unsigned char infobyte = BE_read_uint08(ifile);
- size_t n_points = BE_read_uint32(ifile);
- size_t n_triangles = BE_read_uint32(ifile);
- cout << " points = " << n_points << endl;
- cout << " triangles = " << n_triangles << endl;
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
- BE_read_float(ifile);
-
- // read points
- ofile << " editbegin();" << endl;
- for(size_t i = 0; i < n_points; i++)
- {
- float x = BE_read_float(ifile);
- float y = BE_read_float(ifile);
- float z = BE_read_float(ifile);
- float u = BE_read_float(ifile);
- float v = BE_read_float(ifile);
- BE_read_uint16(ifile);
- BE_read_uint16(ifile);
- BE_read_uint16(ifile);
- BE_read_uint16(ifile);
- BE_read_uint16(ifile);
- BE_read_uint16(ifile);
- ofile << " pointlist[" << i + 1 << "]" << " = " << "addpoint(" << x << "," << y << "," << z << ");" << endl;
- ofile << " uvmap_" << (s + 1) << ".setValue(pointlist[" << (i + 1) << "]," << "@" << u << "," << v << "@);" << endl;
- }
- ofile << " editend();" << endl;
-
- // read triangles
- boost::shared_array<unsigned short> data(new unsigned short[n_triangles*3]);
- ifile.read((char*)&data.get()[0], n_triangles*3*sizeof(unsigned short));
- for(size_t i = 0; i < 3*n_triangles; i++) reverse_byte_order(&data.get()[i]);
- ofile << " editbegin();" << endl;
- size_t index = 0;
- for(size_t i = 0; i < n_triangles; i++) {
- unsigned short a = data.get()[index++] + 1;
- unsigned short b = data.get()[index++] + 1;
- unsigned short c = data.get()[index++] + 1;
- ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
- }
- ofile << " editend();" << endl;
-
- // padding?
- BE_read_uint32(ifile); // usually 0
- BE_read_uint32(ifile); // usually number of bones repeated
- unsigned int has_weights = BE_read_uint08(ifile); // usually 0, but can be 1
- BE_read_uint32(ifile); // usually 0
-
- // load weights
- if(has_weights) {
- boost::shared_array<float> weights(new float[n_points]);
- ifile.read((char*)&weights.get()[0], n_points*sizeof(float));
- for(size_t i = 0; i < n_points; i++) reverse_byte_order(&weights[i]);
- }
- }
-
- ofile << "}" << endl;
-
- return true;
- }