Пример #1
0
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;
}
Пример #2
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;
}