You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

129 lines
3.1 KiB

#include <string>
#include <glm/glm.hpp>
#include <rapidjson/document.h>
#include <rapidjson/schema.h>
#include <rapidjson/stringbuffer.h>
#include "aixlog.hpp"
#include "entity.h"
#include "mesh.h"
#include "util.h"
#include "scene_loader.h"
// forward declarations
bool parseFile(rapidjson::Document& doc, const char* data_dir, const char* file_name);
bool validateScene(rapidjson::Document& schema_doc, rapidjson::Document& scene_doc,
const char* scene_file);
// interface
bool
slLoadFile(
const char* data_dir,
const char* scene_file,
const char* schema_file,
Entity* entity_array,
uint& entity_count,
uint max_entities)
{
if (entity_array == nullptr) {
LOG(ERROR) << "entity array not initialized\n";
return false;
}
LOG(INFO) << "Loading scene file: " << scene_file << "\n";
rapidjson::Document doc, schema_doc;
bool retDoc = parseFile(doc, data_dir, scene_file);
bool retSchema = parseFile(schema_doc, data_dir, schema_file);
if (!retDoc || !retSchema || !validateScene(schema_doc, doc, scene_file))
return false;
// camera
const rapidjson::Value& cam = doc["camera"];
// hex grid
// entities
const rapidjson::Value& e = doc["entities"];
if (e.Size() > max_entities) {
LOG(ERROR) << "entity count: " << e.Size() << ", was more than max_entities: "
<< max_entities << "\n";
return false;
}
for (uint i = 0; i < e.Size(); i++) {
meMeshGroup mg;
std::string model_path;
model_path.append(data_dir).append("/").append(e[i]["model_file"].GetString());
if (meLoadFromFile(model_path.c_str(), mg)) {
Entity& e = entity_array[entity_count];
e.mesh_group = mg;
//
e.scale = glm::vec3(10,10,10);
e.translation = glm::vec3(640, 500, 0);
//
} else {
LOG(ERROR) << "Error loading mesh file\n";
return false;
}
entity_count++;
}
// lights
return true;
}
bool
parseFile(rapidjson::Document& doc, const char* data_dir, const char* file_name)
{
bool ret = true;
std::string file_path;
file_path.append(data_dir).append("/").append(file_name);
char* contents = utilDumpTextFile(file_path.c_str());
if (contents == nullptr) {
LOG(ERROR) << "Error reading file: " << file_name << "\n";
ret = false;
}
if (doc.Parse(contents).HasParseError() || !doc.IsObject()) {
LOG(ERROR) << "Error parrsing scene file: " << file_name << "\n";
ret = false;
}
utilSafeFree(contents);
return ret;
}
bool
validateScene(rapidjson::Document& schema_doc, rapidjson::Document& scene_doc, const char* scene_file)
{
rapidjson::SchemaDocument schema(schema_doc);
rapidjson::SchemaValidator validator(schema);
if (!scene_doc.Accept(validator)) {
LOG(ERROR) << "Error validating scene file: " << scene_file << "\n";
rapidjson::StringBuffer sb;
validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
LOG(ERROR) << "Invalid schema: " << sb.GetString() << "\n";
LOG(ERROR) << "Invalid keyword:" << validator.GetInvalidSchemaKeyword() << "\n";
sb.Clear();
validator.GetInvalidDocumentPointer().StringifyUriFragment(sb);
LOG(ERROR) << "Invalid Document: " << sb.GetString() << "\n";
return false;
}
LOG(INFO) << "scene file: " << scene_file << " passed schema validation\n";
return true;
}