Exemplo n.º 1
0
Scene *SceneParser::loadScene(KeyValues *data)
{
  Scene *scene = new Scene();

  KeyValues *key = data->firstSubKey();
  while(key) {
    const char *name = key->name();

    if(strcmp(name, "object") == 0) {
      Object *object = loadObject(key);
      if(object) {
        scene->addObject(object);
      }
      else {
        fprintf(stderr, "Failed to load Object\n");
      }
    }
    else if(strcmp(name, "light") == 0) {
      Light *light = loadLight(key);
      if(light) {
        scene->addLight(light);
      }
      else {
        fprintf(stderr, "Failed to load Light\n");
      }
    }
    else {
      fprintf(stderr, "Unknown element: %s\n", name);
    }

    key = key->nextKey();
  }


  return scene;
}
Exemplo n.º 2
0
Object *SceneParser::loadObject(KeyValues *data)
{
  const char *format = data->getString("format");
  if(!format) {
    fprintf(stderr, "Key 'format' not found on Object\n");
    return NULL;
  }

  Mesh *mesh;
  if(strcmp("OFF", format) == 0 || strcmp("PLY", format) == 0) {
    const char *file = data->getString("file");
    if(!file) {
      fprintf(stderr, "Key 'file' not found on Object\n");
      return NULL;
    }
    char *filename = resolvePath(file);

    MeshData *meshData;

    if(strcmp("OFF", format) == 0) {
      meshData = MeshLoaderOFF::load(filename);
    }
    else if(strcmp("PLY", format) == 0) {
      meshData = MeshLoaderPLY::load(filename);
    }

    if(!meshData) {
      fprintf(stderr, "Failed to load MeshData of %s\n", filename);
      delete[] filename;
      return NULL;
    }

    if(data->getInt("normalize", 1)) {
      meshData->normalize();
    }
    if(data->getInt("normals", 0)) {
      meshData->computeNormals();
    }

    const char *texcoords = data->getString("texcoords");
    if(texcoords) {
      MeshData::TexCoordsMethod method;
      if(strcmp(texcoords, "sphere") == 0) {
        method = MeshData::TexCoordsSphere;
      }
      else if(strcmp(texcoords, "cylinder") == 0) {
        method = MeshData::TexCoordsCylinder;
      }
      meshData->genTexCoords(method);
    }

    if(data->getInt("tangents", 0)) {
      meshData->genTangents();
    }

    mesh = new Mesh(meshData);

    delete meshData;
    delete[] filename;
  }
  else {
    fprintf(stderr, "Invalid object format: %s\n", format);
    return NULL;
  }

  Material *material = NULL;
  QGLShaderProgram *shaderProgram = new QGLShaderProgram();

  KeyValues *key;

  bool error = false;
  key = data->firstSubKey();
  while(key) {
    if(strcmp(key->name(), "shader") == 0) {
      QGLShader *shader = loadShader(key);
      if(shader) {
        shaderProgram->addShader(shader);
      }
      else {
        fprintf(stderr, "Failed to load shader\n");
        error = true;
        break;
      }
    }
    else if (strcmp(key->name(), "material") == 0) {
      if(material) {
        fprintf(stderr, "Duplicated material definition\n");
      }
      else {
        material = loadMaterial(key);
      }
    }
    key = key->nextKey();
  }

  if(!shaderProgram->link()) {
    fprintf(stderr, "Failed to link shader program\n");
    error = true;
  }

  if(error) {
    if(material) {
      delete material;
    }
    delete shaderProgram;
    delete mesh;
    return NULL;
  }

  Object *object = new Object(mesh, shaderProgram, material);

  object->scale(data->getFloat("scale", 1.0));

  float pitch = data->getFloat("pitch", 0.0);
  float yaw = data->getFloat("yaw", 0.0);
  object->rotation(pitch, yaw);

  const char *position = data->getString("position");
  if(position) {
    object->position(strtoV3D(position));
  }

  key = data->firstSubKey();
  while(key) {
    if (strcmp(key->name(), "texture") == 0) {
      Texture *texture = loadTexture(key);
      if(texture) {
        object->addTexture(texture);
      }
      else {
        fprintf(stderr, "Failed to load texture\n");
        error = true;
        break;
      }
    }
    key = key->nextKey();
  }

  if(error) {
    return object;
  }

  return object;
}