bool ObjModel::loadMTLFile(const char* fileName) { cout << "Loading material file: " << fileName << endl; FILE* fp; string* modelPath = getCvarAddress_S("r_modelPath"); string canonicalPath = *modelPath + "obj/" + fileName; cout << "From file path: " << canonicalPath << endl; if( !(fp=fopen(canonicalPath.c_str(), "r")) ) { error = "OBJ Materials file not found"; Con_print("Obj: File not found - %s", canonicalPath.c_str()); return false; } MaterialManager* tm = getMaterialManager(); material_t* mat; while( !feof(fp) ) { char in[MAX_OBJ_LINE_LEN]; fgets(in, MAX_OBJ_LINE_LEN, fp); char incpy[MAX_OBJ_LINE_LEN]; #ifdef OBJMATDEBUG cout << "MAT Line: " << in << endl; #endif strcpy(incpy, in); // if its a comment or whitespace skip it if( in[0] == '#' || in[0] == ' ' || in[0] == '\n' || in[0] == '\r' || in[0] == '\t') continue; else { // otherwise we need to process some data char* token = strtok(in, WHITESPACE); if( token == NULL ) break; if( !strcmp(token, "newmtl") ) { material_t* newmat = new material_t; initializeMaterial(newmat); token = strtok(NULL, WHITESPACE); if( !tm->hasMaterial(token) ) { tm->addMaterial(token, newmat); mat = newmat; #ifdef OBJMATDEBUG cout << "New material created: " << token << endl; #endif } else { #ifdef OBJMATDEBUG cout << "MTL Error: Material redefinition: " << token << endl; #endif } } else if( !strcmp(token, "Ns") ) { sscanf(incpy, "Ns %f", &mat->Ns); } else if( !strcmp(token, "Ka") ) { sscanf(incpy, "Ka %f %f %f", &mat->Ka[0], &mat->Ka[1], &mat->Ka[2]); } else if( !strcmp(token, "Kd") ) { sscanf(incpy, "Kd %f %f %f", &mat->Kd[0], &mat->Kd[1], &mat->Kd[2]); } else if( !strcmp(token, "Ks") ) { sscanf(incpy, "Ks %f %f %f", &mat->Ks[0], &mat->Ks[1],& mat->Ks[2]); } else if( !strcmp(token, "Ni") ) { sscanf(incpy, "Ni %f", &mat->Ni); } else if( !strcmp(token, "d") ) { sscanf(incpy, "d %f", &mat->d); } else if( !strcmp(token, "illum") ) { sscanf(incpy, "illum %d", &mat->illum); } else if( !strcmp(token, "map_Kd") ) { token = strtok(NULL, WHITESPACE); strcpy(mat->map_Kd, token); #ifdef OBJMATDEBUG cout << "Loading texture: " << mat->map_Kd << endl; #endif getMaterialManager()->loadBitmap(mat->map_Kd); } } } fclose(fp); return true; }
//Loads the MD2 model MD2Model* MD2Model::load(const char* filename) { Vec3f xyzMin; Vec3f xyzMax; ifstream input; input.open(filename, istream::binary); Con_print("****MD2LOAD:START****"); char buffer[64]; input.read(buffer, 4); //Should be "IPD2", if this is an MD2 file if (buffer[0] != 'I' || buffer[1] != 'D' || buffer[2] != 'P' || buffer[3] != '2') { Con_print("MD2 Error: Wrong MD2 Version Found!"); return NULL; } if (readInt(input) != 8) { //The version number Con_print("MD2 Error: Wrong MD2 Version Number Found!"); return NULL; } int textureWidth = readInt(input); //The width of the textures int textureHeight = readInt(input); //The height of the textures readInt(input); //The number of bytes per frame int numTextures = readInt(input); //The number of textures if (numTextures != 1) { Con_print("MD2 Error: No Textures Found!"); return NULL; } int numVertices = readInt(input); //The number of vertices int numTexCoords = readInt(input); //The number of texture coordinates int numTriangles = readInt(input); //The number of triangles readInt(input); //The number of OpenGL commands int numFrames = readInt(input); //The number of frames //Offsets (number of bytes after the beginning of the file to the beginning //of where certain data appear) int textureOffset = readInt(input); //The offset to the textures int texCoordOffset = readInt(input); //The offset to the texture coordinates int triangleOffset = readInt(input); //The offset to the triangles int frameOffset = readInt(input); //The offset to the frames readInt(input); //The offset to the OpenGL commands readInt(input); //The offset to the end of the file MD2Model* model = new MD2Model(); MaterialManager* matsMgr = getMaterialManager(); //Load the texture input.seekg(textureOffset, ios_base::beg); input.read(buffer, 64); // FIXME // Hack to get the md2 models with pcx textures to load bmp version instead string s = buffer; s = s.substr(0, s.find_last_of(".")); s = s + ".bmp"; strcpy(buffer, s.c_str()); // END FIXME //////////////////////// if (strlen(buffer) < 5 || strcmp(buffer + strlen(buffer) - 4, ".bmp") != 0 ) { Con_print("MD2 Error: Couldn't parse texture name: %s", buffer); // Set texture not found because we can't load the texture that was set model->textureId = matsMgr->getGLTexID("not-found.bmp"); } else { if( !matsMgr->hasMaterial(buffer) ) matsMgr->loadBitmap(buffer); model->textureId = matsMgr->getGLTexID(buffer); } //Load the texture coordinates input.seekg(texCoordOffset, ios_base::beg); model->texCoords = new MD2TexCoord[numTexCoords]; for(int i = 0; i < numTexCoords; i++) { MD2TexCoord* texCoord = model->texCoords + i; texCoord->texCoordX = (float)readShort(input) / textureWidth; texCoord->texCoordY = 1 - (float)readShort(input) / textureHeight; } //Load the triangles input.seekg(triangleOffset, ios_base::beg); model->triangles = new MD2Triangle[numTriangles]; model->numTriangles = numTriangles; for(int i = 0; i < numTriangles; i++) { MD2Triangle* triangle = model->triangles + i; for(int j = 0; j < 3; j++) { triangle->vertices[j] = readUShort(input); } for(int j = 0; j < 3; j++) { triangle->texCoords[j] = readUShort(input); } } //Load the frames input.seekg(frameOffset, ios_base::beg); model->frames = new MD2Frame[numFrames]; model->numFrames = numFrames; for(int i = 0; i < numFrames; i++) { MD2Frame* frame = model->frames + i; frame->vertices = new MD2Vertex[numVertices]; Vec3f scale = readVec3f(input); Vec3f translation = readVec3f(input); input.read(frame->name, 16); for(int j = 0; j < numVertices; j++) { MD2Vertex* vertex = frame->vertices + j; input.read(buffer, 3); Vec3f v((unsigned char)buffer[0], (unsigned char)buffer[1], (unsigned char)buffer[2]); vertex->pos = translation + Vec3f(scale[0] * v[0], scale[1] * v[1], scale[2] * v[2]); // added to get dimensions of model at load time model->doDimensionCheck(vertex->pos); // end dimension add input.read(buffer, 1); int normalIndex = (int)((unsigned char)buffer[0]); vertex->normal = Vec3f(NORMALS[3 * normalIndex], NORMALS[3 * normalIndex + 1], NORMALS[3 * normalIndex + 2]); } } model->startFrame = 0; model->endFrame = numFrames - 1; Con_print("numFrames: %d", numFrames ); Con_print("****MD2LOAD:FINISH****"); Con_print("MD2 Dimensions: %.3f x %.3f x %.3f", model->xRadius*2, model->yRadius*2, model->zRadius*2); return model; }