int SearObject::load(const std::string &filename) { bool big_endian = false; FILE *fp = fopen(filename.c_str(), "rb"); if (fp == 0) { fprintf(stderr, "[SearObject] Error opening %s for reading\n", filename.c_str()); return 1; } SearObjectHeader soh; if (fread(&soh, sizeof(SearObjectHeader), 1, fp) != 1) { // Error reading header fprintf(stderr, "[SearObject] Error reading SearObject header in %s\n", filename.c_str()); fclose(fp); return 1; } // Check Magic if (strncmp(soh.magic, "SEARSTAT", 8)) { fprintf(stderr, "[SearObject] Bad magic - unknown file format.\n"); fclose(fp); return 1; } // Check Endianess // Does this check actually work? Or should we convert into a chars and // compare char order instead? if (soh.byte_order == 0x00FF) { big_endian = true; printf("[SearObject] Swapping byte order\n"); swap_bytes_uint32_t(soh.num_meshes); } // Check Version if (soh.version != 1) { fprintf(stderr, "[SearObject] SearObject Version %d is unsupported. Version %d expected.\n", soh.version, 1); fclose(fp); return 1; } SearObjectMesh som; TextureID tex_id = NO_TEXTURE_ID; TextureID tex_mask_id = NO_TEXTURE_ID; uint32_t *uptr; float *fptr; int c,x,y; for (uint32_t i = 0; i < soh.num_meshes; ++i) { if (fread(&som, sizeof(SearObjectMesh), 1, fp) != 1) { fprintf(stderr, "[SearObject] Error reading SearObject Mesh in %s\n", filename.c_str()); fclose(fp); return 1; } if (big_endian) { swap_bytes_uint32_t(som.num_vertices); swap_bytes_uint32_t(som.num_faces); for (x = 0; x < 4; ++x) { for (y = 0; y < 4; ++y) { swap_bytes_float(som.mesh_transform[x][y]); swap_bytes_float(som.texture_transform[x][y]); } } for (x = 0; x < 4; ++x) { swap_bytes_float(som.ambient[x]); swap_bytes_float(som.diffuse[x]); swap_bytes_float(som.specular[x]); swap_bytes_float(som.emissive[x]); } swap_bytes_float(som.shininess); } StaticObject* so = new StaticObject(); so->init(); so->setNumPoints(som.num_vertices); so->setNumFaces(som.num_faces); // Does this use all 256 chars, or only up to 256? som.texture_map[255] = '\0'; // Make sure the string is null-terminated std::string tex_name(som.texture_map); // See if config file has a mapping m_config.clean(tex_name); if (m_config.findItem(tex_name, KEY_texture_map_0)) { tex_name = (std::string)m_config.getItem(tex_name, KEY_texture_map_0); } // Get texture ids tex_id = RenderSystem::getInstance().requestTexture(tex_name); tex_mask_id = RenderSystem::getInstance().requestTexture(tex_name, true); so->setTexture(0, tex_id, tex_mask_id); // Set transform matrices so->getMatrix().setMatrix(som.mesh_transform); so->getTexMatrix().setMatrix(som.texture_transform); // Set Materials so->setAmbient(som.ambient); so->setDiffuse(som.diffuse); so->setSpecular(som.specular); so->setEmission(som.emissive); so->setShininess(som.shininess); // Read in the vertex data array so->createVertexData(som.num_vertices * 3); fread(so->getVertexDataPtr(), sizeof(float), som.num_vertices * 3, fp); if (big_endian) { fptr = so->getVertexDataPtr(); c = som.num_vertices * 3; while (c--) swap_bytes_float(*fptr++); } so->createNormalData(som.num_vertices * 3); fread(so->getNormalDataPtr(), sizeof(float), som.num_vertices * 3, fp); if (big_endian) { fptr = so->getNormalDataPtr(); c = som.num_vertices * 3; while (c--) swap_bytes_float(*fptr++); } so->createTextureData(som.num_vertices * 2); fread(so->getTextureDataPtr(), sizeof(float), som.num_vertices * 2, fp); if (big_endian) { fptr = so->getTextureDataPtr(); c = som.num_vertices * 2; while (c--) swap_bytes_float(*fptr++); } if (som.num_faces > 0) { so->createIndices(som.num_faces * 3); fread(so->getIndicesPtr(), sizeof(uint32_t), som.num_faces * 3, fp); if (big_endian) { uptr = (uint32_t*)so->getIndicesPtr(); c = som.num_faces * 3; while (c--) swap_bytes_uint32_t(*uptr++); } } m_static_objects.push_back(so); } fclose(fp); return 0; }
int LibModelFile::init(const std::string &filename) { assert(m_initialised == false); std::string object; if (m_config.readFromFile(filename)) { if (m_config.findItem(SECTION_model, KEY_filename)) { object = (std::string)m_config.getItem(SECTION_model, KEY_filename); } else { fprintf(stderr, "[LibModelFile] Error: No md3 filename specified.\n"); return 1; } } else { fprintf(stderr, "[LibModelFile] Error reading %s as varconf file. Trying as .md3 file.\n", filename.c_str()); object = filename; } // Initialise transform matrix float matrix[4][4]; for (int j = 0; j < 4; ++j) { for (int i = 0; i < 4; ++i) { if (i == j) matrix[j][i] = 1.0f; else matrix[j][i] = 0.0f; } } if (m_config.findItem(SECTION_model, KEY_rotation)) { const std::string &str=(std::string)m_config.getItem(SECTION_model, KEY_rotation); float w,x,y,z; sscanf(str.c_str(), "%f;%f;%f;%f", &w, &x, &y, &z); WFMath::Quaternion q(w,x,y,z); QuatToMatrix(q, matrix); } if (m_config.findItem(SECTION_model, KEY_scale)) { double s = (double)m_config.getItem(SECTION_model, KEY_scale); for (int i = 0; i < 4; ++i) matrix[i][i] *= s; } System::instance()->getFileHandler()->getFilePath(object); // Load md3 file // if (debug) printf("[LibModelFile] Loading: %s\n", object.c_str()); libmd3_file *modelFile = libmd3_file_load(object.c_str()); if (!modelFile) { fprintf(stderr, "[LibModelFile] Error loading %s file\n", object.c_str()); return 1; } for (int i = 0; i < modelFile->header->mesh_count; ++i) { libmd3_unpack_normals(&modelFile->meshes[i]); } // Get mesh data libmd3_mesh *meshp = modelFile->meshes; for (int i = 0; i < modelFile->header->mesh_count; ++i, ++meshp) { StaticObject* so = new StaticObject(); so->init(); // Get Texture data from Mesh int texture_id = NO_TEXTURE_ID; int texture_mask_id = NO_TEXTURE_ID; if (meshp->mesh_header->skin_count != 0) { std::string name = (const char*)(meshp->skins[0].name); m_config.clean(name); // Check for texture name overrides in vconf file // Backwards compatibility. if (m_config.findItem(name, KEY_filename)) { name = (std::string)m_config.getItem(name, KEY_filename); } // Check for texture name overrides in vconf file // New method if (m_config.findItem(name, KEY_texture_map_0)) { name = (std::string)m_config.getItem(name, KEY_texture_map_0); } // Request Texture ID texture_id = RenderSystem::getInstance().requestTexture(name); texture_mask_id = RenderSystem::getInstance().requestTexture(name, true); float m[4]; if (m_config.findItem(name, KEY_ambient)) { const std::string &str = (std::string)m_config.getItem(name, KEY_ambient); sscanf(str.c_str(), "%f;%f;%f;%f", &m[0], &m[1], &m[2], &m[3]); so->setAmbient(m); } if (m_config.findItem(name, KEY_diffuse)) { const std::string &str = (std::string)m_config.getItem(name, KEY_diffuse); sscanf(str.c_str(), "%f;%f;%f;%f", &m[0], &m[1], &m[2], &m[3]); so->setDiffuse(m); } if (m_config.findItem(name, KEY_specular)) { const std::string &str = (std::string)m_config.getItem(name, KEY_specular); sscanf(str.c_str(), "%f;%f;%f;%f", &m[0], &m[1], &m[2], &m[3]); so->setSpecular(m); } if (m_config.findItem(name, KEY_emission)) { const std::string &str = (std::string)m_config.getItem(name, KEY_emission); sscanf(str.c_str(), "%f;%f;%f;%f", &m[0], &m[1], &m[2], &m[3]); so->setEmission(m); } if (m_config.findItem(name, KEY_shininess)) { so->setShininess((double)m_config.getItem(name, KEY_shininess)); } } // Set the transform so->getMatrix().setMatrix(matrix); // Set the textures so->setTexture(0, texture_id, texture_mask_id); so->setNumPoints(meshp->mesh_header->vertex_count); so->setNumFaces(meshp->mesh_header->triangle_count); // Copy data into array. so->createVertexData(meshp->mesh_header->vertex_count * 3); float *ptr = so->getVertexDataPtr(); for (int i = 0; i < meshp->mesh_header->vertex_count * 3; ++i) { ptr[i] = default_scale * (float)meshp->vertices[i]; } so->copyTextureData(meshp->texcoords, meshp->mesh_header->vertex_count * 2); so->copyNormalData(meshp->normals, meshp->mesh_header->vertex_count * 3); so->copyIndices(meshp->triangles, meshp->mesh_header->triangle_count * 3); m_static_objects.push_back(so); } libmd3_file_free(modelFile); bool ignore_minus_z = false; Scaling scale = SCALE_NONE; Alignment align = ALIGN_NONE; bool process_model = false; if (m_config.findItem(SECTION_model, KEY_ignore_minus_z)) { if ((bool)m_config.getItem(SECTION_model, KEY_ignore_minus_z)) { process_model = true; ignore_minus_z = true; } } if (m_config.findItem(SECTION_model, KEY_z_align)) { if ((bool)m_config.getItem(SECTION_model, KEY_z_align)) { process_model = true; align = ALIGN_Z; } } if (m_config.findItem(SECTION_model, KEY_scale_isotropic)) { if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic)) { process_model = true; scale = SCALE_ISOTROPIC; } } else if (m_config.findItem(SECTION_model, KEY_scale_isotropic_x)) { if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic_x)) { process_model = true; scale = SCALE_ISOTROPIC_Z; } } else if (m_config.findItem(SECTION_model, KEY_scale_isotropic_y)) { if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic_y)) { process_model = true; scale = SCALE_ISOTROPIC_Y; } } else if (m_config.findItem(SECTION_model, KEY_scale_isotropic_z)) { if ((bool)m_config.getItem(SECTION_model, KEY_scale_isotropic_z)) { process_model = true; scale = SCALE_ISOTROPIC_Z; } } if (m_config.findItem(SECTION_model, KEY_scale_anisotropic)) { if ((bool)m_config.getItem(SECTION_model, KEY_scale_anisotropic)) { process_model = true; scale = SCALE_ANISOTROPIC; } } if (process_model == true) { scale_object(m_static_objects, scale, align, ignore_minus_z); } contextCreated(); m_initialised = true; return 0; }