#include "ObjConverter.h" #include "SceneEntity.h" #include "Transform3.h" #include "Geometry.h" #include "Shape.h" #include "Material.h" #include "Texture.h" using namespace CHCDemoEngine; using namespace std; static void LoadIndices(char *str, const VertexArray &vertices, const VertexArray &normals, const vector > &texcoords, VertexArray &faceVertices, VertexArray &faceNormals, vector > &faceTexcoords ) { vector substrings; // extract the triples of the form v/t/n v/t/n ... char *pch = strtok(str + 1, " "); while (pch != NULL) { substrings.push_back(pch); pch = strtok(NULL, " "); } vector indices; vector nIndices; vector tIndices; for (size_t i = 0; i < substrings.size(); ++ i) { // vertex, normal and texture indices char *str = strtok(substrings[i], "/"); int index = (int)strtol(str, NULL, 10) - 1; str = strtok(substrings[i], "/"); int tIndex = (int)strtol(str, NULL, 10) - 1; str = strtok(substrings[i], "/"); int nIndex = (int)strtol(str, NULL, 10) - 1; // store indices if (index >= 0) { indices.push_back(index); nIndices.push_back(nIndex); tIndices.push_back(tIndex); } // new triangle found if (indices.size() > 2) { int idx2 = (int)indices.size() - 2; int idx3 = (int)indices.size() - 1; faceVertices.push_back(vertices[indices[0]]); faceVertices.push_back(vertices[indices[idx2]]); faceVertices.push_back(vertices[indices[idx3]]); faceNormals.push_back(normals[nIndices[0]]); faceNormals.push_back(normals[nIndices[idx2]]); faceNormals.push_back(normals[nIndices[idx3]]); faceTexcoords.push_back(texcoords[tIndices[0]]); faceTexcoords.push_back(texcoords[tIndices[idx2]]); faceTexcoords.push_back(texcoords[tIndices[idx3]]); } } } static Shape *LoadShape(const VertexArray &faceVertices, const VertexArray &faceNormals, const vector > &faceTexcoords, SceneEntity *parent) { int numElements = (int)faceVertices.size(); // convert the triangles to geometry Vector3 *_vertices = new Vector3[numElements]; Vector3 *_normals = new Vector3[numElements]; float *_texcoords = new float[numElements * 2]; for (int i = 0; i < numElements; ++ i) { _vertices[i].x = faceVertices[i].x; _vertices[i].y = -faceVertices[i].z; _vertices[i].z = faceVertices[i].y; _normals[i].x = faceNormals[i].x; _normals[i].y = -faceNormals[i].z; _normals[i].z = faceNormals[i].y; //_texcoords[i * 2 + 0] = faceTexcoords[i].second; //_texcoords[i * 2 + 1] = faceTexcoords[i].first; _texcoords[i * 2 + 0] = faceTexcoords[i].first; _texcoords[i * 2 + 1] = faceTexcoords[i].second; } cout<<"number of triangles in geometry: " << numElements / 3 << endl; // Material *mat = new Material(RgbaColor(0, 1, 0, 1)); Material *mat = new Material(); mat->SetAmbient(RgbaColor(0, 0, 0, 0)); mat->SetDiffuse(RgbaColor(0, 0, 0, 0)); mat->SetCullFaceEnabled(false); Geometry *geom = new Geometry(_vertices, _normals, _texcoords, numElements, false); Shape *shape = new Shape(geom, mat, parent); return shape; } SceneEntity * ObjConverter::Load(const string &filename) const { FILE *file; if ((file = fopen(filename.c_str(), "rt")) == NULL) { return NULL; } Vector3 v(470.398f, 240.364f, 182.5f); Matrix4x4 m = TranslationMatrix(v); Transform3 *trafo = new Transform3(m); SceneEntity *sceneEntity = new SceneEntity(trafo); LODLevel *lodLevel = new LODLevel(0); VertexArray faceVertices; VertexArray faceNormals; vector > faceTexcoords; VertexArray vertices; VertexArray normals; vector > texcoords; vector indices; int line = 0; char str[100000]; // hack Texture *tex = new Texture(model_path + "wood.jpg"); tex->Create(); while (fgets(str, 100000, file) != NULL) { switch (str[0]) { case 'v': // vertex or normal { float x, y, z; switch (str[1]) { case 'n' : sscanf(str + 2, "%f %f %f", &x, &y, &z); normals.push_back(Vector3(x, y, z)); break; case 't': sscanf(str + 2, "%f %f", &x, &y); texcoords.push_back(pair(x, y)); break; default: sscanf(str + 1, "%f %f %f", &x, &y, &z); vertices.push_back(Vector3(x, y, z)); //cout <<"v " << x << " " << y << " "<< z << " "; } break; } case 'f': { ////////// //-- indices in the current line LoadIndices(str, vertices, normals, texcoords, faceVertices, faceNormals, faceTexcoords); break; } // end face case 'g': #if 0 { Shape *shape = LoadShape(faceVertices, faceNormals, faceTexcoords, sceneEntity); shape->GetMaterial()->SetTexture(tex); sceneEntity->AddShape(shape); lodLevel->AddShape(shape); faceVertices.clear(); faceNormals.clear(); faceTexcoords.clear(); } #endif break; default: break; } ++ line; } fclose(file); if (!faceVertices.empty()) { Shape *shape = LoadShape(faceVertices, faceNormals, faceTexcoords, sceneEntity); //shape->GetMaterial()->SetTexture(tex); sceneEntity->AddShape(shape); lodLevel->AddShape(shape); } sceneEntity->AddLODLevel(lodLevel); return sceneEntity; }