Moved loading functionality to loader class.
This commit is contained in:
parent
bb1cf8dea7
commit
7e8b0d4c58
@ -1,4 +1,5 @@
|
|||||||
#include "application.hh"
|
#include "application.hh"
|
||||||
|
#include "loader.hh"
|
||||||
|
|
||||||
|
|
||||||
Application::Application() {
|
Application::Application() {
|
||||||
@ -25,6 +26,8 @@ void Application::init()
|
|||||||
|
|
||||||
// load Level
|
// load Level
|
||||||
level.load();
|
level.load();
|
||||||
|
Loader loader = Loader();
|
||||||
|
loader.load("Level1.xml", &level);
|
||||||
|
|
||||||
graphics.init(&level);
|
graphics.init(&level);
|
||||||
|
|
||||||
|
506
level.cc
506
level.cc
@ -1,73 +1,45 @@
|
|||||||
#include "level.hh"
|
#include "level.hh"
|
||||||
#include <string>
|
#include <string>
|
||||||
extern "C" {
|
|
||||||
#include "extern/lua/src/lua.h"
|
|
||||||
#include "extern/lua/src/lualib.h"
|
|
||||||
#include "extern/lua/src/lauxlib.h"
|
|
||||||
}
|
|
||||||
#include "extern/luabridge/LuaBridge.h"
|
|
||||||
using namespace tinyxml2;
|
|
||||||
|
|
||||||
//dowadiddydiddydumdiddydo
|
|
||||||
Level::Level(std::string levelNum){
|
Level::Level(std::string levelNum){
|
||||||
this->levelNum = levelNum;
|
this->levelNum = levelNum;
|
||||||
this->terrain = Terrain(levelNum);
|
this->terrain = Terrain(levelNum);
|
||||||
|
// default value
|
||||||
skydomeSize = 50.0f;
|
skydomeSize = 50.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Level::Level() {
|
Level::Level() {
|
||||||
}
|
}
|
||||||
//there she was just walking down the street singing
|
|
||||||
Level::~Level() {
|
Level::~Level() {
|
||||||
|
if (luaState!=nullptr) {
|
||||||
|
lua_close(luaState);
|
||||||
|
}
|
||||||
for(unsigned int i = 0; i<objects.size(); i++) {
|
for(unsigned int i = 0; i<objects.size(); i++) {
|
||||||
delete(objects.at(i));
|
delete(objects.at(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//dowadiddydiddydumdiddydoo!
|
|
||||||
void Level::errorCheck(XMLError error){
|
|
||||||
if (error) {
|
|
||||||
printf("XMLError: ");
|
|
||||||
if (error == XML_WRONG_ATTRIBUTE_TYPE) {
|
|
||||||
printf("Wrong attribute type.\n");
|
|
||||||
}
|
|
||||||
else if (error == XML_NO_ATTRIBUTE) {
|
|
||||||
printf("No attribute.\n");
|
|
||||||
}
|
|
||||||
else if (error == XML_CAN_NOT_CONVERT_TEXT) {
|
|
||||||
printf("Can not convert text.\n");
|
|
||||||
}
|
|
||||||
else if (error == XML_NO_TEXT_NODE) {
|
|
||||||
printf("No text.\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("Unknown error.\n");
|
|
||||||
}
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Level::load() {
|
void Level::load() {
|
||||||
//Intialize lua state
|
//Intialize lua state
|
||||||
lua_State *L = nullptr;
|
|
||||||
// Check if there's an existing state and close it
|
// Check if there's an existing state and close it
|
||||||
if(L != nullptr){
|
if(luaState != nullptr){
|
||||||
lua_close(L);
|
lua_close(luaState);
|
||||||
L = nullptr;
|
luaState = nullptr;
|
||||||
}
|
}
|
||||||
// Create a new lua state
|
// Create a new lua state
|
||||||
L = luaL_newstate();
|
luaState = luaL_newstate();
|
||||||
luaL_openlibs(L);
|
luaL_openlibs(luaState);
|
||||||
//Expose the class Level and its functions to Lua
|
//Expose the class Level and its functions to Lua
|
||||||
luabridge::getGlobalNamespace(L)
|
luabridge::getGlobalNamespace(luaState)
|
||||||
.beginClass<Level>("Level")
|
.beginClass<Level>("Level")
|
||||||
.addFunction("deleteObject", &Level::deleteObject)
|
.addFunction("deleteObject", &Level::deleteObject)
|
||||||
.addFunction("getObjectCount", &Level::getObjectCount)
|
.addFunction("getObjectCount", &Level::getPhysicsObjectsVectorSize)
|
||||||
.addFunction("moveObject", &Level::moveObject)
|
.addFunction("moveObject", &Level::moveObject)
|
||||||
.endClass();
|
.endClass();
|
||||||
//Push the level to Lua as a global variable
|
//Push the level to Lua as a global variable
|
||||||
luabridge::push(L, this);
|
luabridge::push(luaState, this);
|
||||||
lua_setglobal(L, "level");
|
lua_setglobal(luaState, "level");
|
||||||
|
|
||||||
|
|
||||||
this->physics = Physics();
|
this->physics = Physics();
|
||||||
@ -89,385 +61,6 @@ void Level::load() {
|
|||||||
|
|
||||||
//addTerrainPhysic
|
//addTerrainPhysic
|
||||||
physics.addTerrain(terrain.getHeightmapWidth(), terrain.getHeightmapHeight(), terrain.getHeightmap());
|
physics.addTerrain(terrain.getHeightmapWidth(), terrain.getHeightmapHeight(), terrain.getHeightmap());
|
||||||
|
|
||||||
//Loading from xml:
|
|
||||||
XMLDocument* doc = new XMLDocument();
|
|
||||||
const char* xmlFile = ("../Levels/ObjectSetups/Level" + levelNum + ".xml").c_str();
|
|
||||||
doc->LoadFile(xmlFile);
|
|
||||||
if (doc->ErrorID()!=0){
|
|
||||||
printf("Could not open ObjectSetupXml!\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//load global physic parameter
|
|
||||||
float friction;
|
|
||||||
XMLElement* physicsElement = doc->FirstChildElement("physics");
|
|
||||||
errorCheck(physicsElement->FirstChildElement("strength")->QueryFloatText(&strength));
|
|
||||||
errorCheck(physicsElement->FirstChildElement("friction")->QueryFloatText(&friction));
|
|
||||||
|
|
||||||
//load the skydome
|
|
||||||
XMLElement* skydomeElement = doc->FirstChildElement("skydome");
|
|
||||||
const char* charSkydomeTexture = skydomeElement->FirstChildElement("texture")->GetText();
|
|
||||||
if(charSkydomeTexture == NULL){
|
|
||||||
printf("XMLError: No skydomeTexture found.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
std::string skydomeTexture = charSkydomeTexture;
|
|
||||||
Model skydomeModel = Model("skydome.obj", skydomeSize);
|
|
||||||
Material skydomeMaterial = Material(skydomeTexture, 0.7f, 0.0f, 0.0f, 0.0f);
|
|
||||||
Object* skydomeObject = new Object(skydomeModel, skydomeMaterial, glm::vec3(0.0f, 0.0f, 0.0f),
|
|
||||||
glm::vec3(0.0f, 0.0f, 0.0f));
|
|
||||||
objects.push_back(skydomeObject);
|
|
||||||
skydome = skydomeObject;
|
|
||||||
|
|
||||||
//load lighting parameters
|
|
||||||
float rColour, gColour, bColour, alpha, xOffset, yOffset, zOffset, intensity;
|
|
||||||
XMLElement* ambientElement = doc->FirstChildElement("ambientLight");
|
|
||||||
errorCheck(ambientElement->FirstChildElement("rColour")->QueryFloatText(&rColour));
|
|
||||||
errorCheck(ambientElement->FirstChildElement("gColour")->QueryFloatText(&gColour));
|
|
||||||
errorCheck(ambientElement->FirstChildElement("bColour")->QueryFloatText(&bColour));
|
|
||||||
ambientLight = glm::vec3(rColour,gColour,bColour);
|
|
||||||
XMLElement* fogElement = doc->FirstChildElement("fogColour");
|
|
||||||
errorCheck(fogElement->FirstChildElement("rColour")->QueryFloatText(&rColour));
|
|
||||||
errorCheck(fogElement->FirstChildElement("gColour")->QueryFloatText(&gColour));
|
|
||||||
errorCheck(fogElement->FirstChildElement("bColour")->QueryFloatText(&bColour));
|
|
||||||
errorCheck(fogElement->FirstChildElement("alpha")->QueryFloatText(&alpha));
|
|
||||||
fogColour = glm::vec4(rColour,gColour,bColour, alpha);
|
|
||||||
XMLElement* directionalElement = doc->FirstChildElement("directionalLight");
|
|
||||||
errorCheck(directionalElement->FirstChildElement("xOffset")->QueryFloatText(&xOffset));
|
|
||||||
errorCheck(directionalElement->FirstChildElement("yOffset")->QueryFloatText(&yOffset));
|
|
||||||
errorCheck(directionalElement->FirstChildElement("zOffset")->QueryFloatText(&zOffset));
|
|
||||||
errorCheck(directionalElement->FirstChildElement("rColour")->QueryFloatText(&rColour));
|
|
||||||
errorCheck(directionalElement->FirstChildElement("gColour")->QueryFloatText(&gColour));
|
|
||||||
errorCheck(directionalElement->FirstChildElement("bColour")->QueryFloatText(&bColour));
|
|
||||||
errorCheck(directionalElement->FirstChildElement("intensity")->QueryFloatText(&intensity));
|
|
||||||
directionalLight = Light(glm::vec3(xOffset,yOffset,zOffset), glm::vec3(rColour,gColour,bColour), intensity);
|
|
||||||
|
|
||||||
//load Objects
|
|
||||||
std::vector<std::vector<int>> objectIdentifiers = std::vector<std::vector<int>>(); //The first entry is the index in objects, the second one the index in physicObjects, the others are idGreen, idBlue and objectNum.
|
|
||||||
XMLDocument* compositions = new XMLDocument();
|
|
||||||
const char* compositionsFile = "../Levels/ObjectSetups/Compositions.xml";
|
|
||||||
compositions->LoadFile(compositionsFile);
|
|
||||||
if (compositions->ErrorID()!=0){
|
|
||||||
printf("Could not open Compositions!\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
//iterate over all compositions in Level.xml
|
|
||||||
XMLElement* thisComposition = doc->FirstChildElement("composition");
|
|
||||||
for(; thisComposition; thisComposition=thisComposition->NextSiblingElement("composition")){
|
|
||||||
int thisType = 0;
|
|
||||||
errorCheck(thisComposition->FirstChildElement("typeID")->QueryIntText(&thisType));
|
|
||||||
//iterate over all compositions in Compositions.xml to find the one corresponding to the current composition
|
|
||||||
XMLElement* composition = compositions->FirstChildElement("composition");
|
|
||||||
for(; composition; composition=composition->NextSiblingElement("composition")){
|
|
||||||
int compositionType = 0;
|
|
||||||
errorCheck(composition->FirstChildElement("typeID")->QueryIntText(&compositionType));
|
|
||||||
//corect composition found
|
|
||||||
if(thisType == compositionType){
|
|
||||||
//iterate over all objects of the composition
|
|
||||||
XMLElement* xmlObject = composition->FirstChildElement("object");
|
|
||||||
int objectNum = 0;
|
|
||||||
for(; xmlObject; xmlObject=xmlObject->NextSiblingElement("object")){
|
|
||||||
const char* charModelPath = xmlObject->FirstChildElement("modelPath")->GetText();
|
|
||||||
if(charModelPath == NULL){
|
|
||||||
printf("XMLError: No modelPath found in object.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
std::string modelPath = charModelPath;
|
|
||||||
float objectScale, compScale;
|
|
||||||
errorCheck(xmlObject->FirstChildElement("scale")->QueryFloatText(&objectScale));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("scale")->QueryFloatText(&compScale));
|
|
||||||
Model model = Model(modelPath, objectScale * compScale);
|
|
||||||
//find the objectData for the current object
|
|
||||||
XMLElement* objectData = compositions->FirstChildElement("objectData");
|
|
||||||
for(; objectData; objectData=objectData->NextSiblingElement("objectData")){
|
|
||||||
const char* charDataModelPath = objectData->FirstChildElement("modelPath")->GetText();
|
|
||||||
if(charDataModelPath == NULL){
|
|
||||||
printf("XMLError: No modelPath found in objectData.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
std::string dataModelPath = charDataModelPath;
|
|
||||||
//objectData found
|
|
||||||
if(dataModelPath.compare(modelPath) == 0){
|
|
||||||
//create the object
|
|
||||||
float ambientFactor, diffuseFactor, specularFactor, shininess;
|
|
||||||
errorCheck(objectData->FirstChildElement("ambientFactor")->QueryFloatText(&ambientFactor));
|
|
||||||
errorCheck(objectData->FirstChildElement("diffuseFactor")->QueryFloatText(&diffuseFactor));
|
|
||||||
errorCheck(objectData->FirstChildElement("specularFactor")->QueryFloatText(&specularFactor));
|
|
||||||
errorCheck(objectData->FirstChildElement("shininess")->QueryFloatText(&shininess));
|
|
||||||
const char* charTexturePath = objectData->FirstChildElement("texturePath")->GetText();
|
|
||||||
if(charTexturePath == NULL){
|
|
||||||
printf("XMLError: No texturePath found in objectData.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
std::string texturePath = charTexturePath;
|
|
||||||
Material material = Material(texturePath, ambientFactor, diffuseFactor, specularFactor, shininess);
|
|
||||||
float compXPos, compYOffset, compZPos;
|
|
||||||
glm::vec3 objectOffset, compRot;
|
|
||||||
errorCheck(xmlObject->FirstChildElement("xOffset")->QueryFloatText(&objectOffset[0]));
|
|
||||||
errorCheck(xmlObject->FirstChildElement("yOffset")->QueryFloatText(&objectOffset[1]));
|
|
||||||
errorCheck(xmlObject->FirstChildElement("zOffset")->QueryFloatText(&objectOffset[2]));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("xPos")->QueryFloatText(&compXPos));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("yOffset")->QueryFloatText(&compYOffset));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("zPos")->QueryFloatText(&compZPos));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("xRot")->QueryFloatText(&compRot[0]));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("yRot")->QueryFloatText(&compRot[1]));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("zRot")->QueryFloatText(&compRot[2]));
|
|
||||||
compRot *= 0.0174532925; //transform degrees to radians
|
|
||||||
bool ignoreHeightmap;
|
|
||||||
errorCheck(composition->FirstChildElement("ignoreHeightmap")->QueryBoolText(&ignoreHeightmap));
|
|
||||||
if (!ignoreHeightmap){
|
|
||||||
compYOffset = compYOffset+terrain.getHeightmap()[int(compXPos-0.5+0.5*terrain.getHeightmapHeight())]
|
|
||||||
[int(compZPos-0.5+0.5*terrain.getHeightmapWidth())];
|
|
||||||
}
|
|
||||||
glm::vec3 compPos = glm::vec3(compXPos, compYOffset, compZPos);
|
|
||||||
objectOffset = objectOffset * compScale;
|
|
||||||
glm::vec4 rotatedObjectOffset = glm::rotate(compRot.x, glm::vec3(1.0f, 0.0f, 0.0f))
|
|
||||||
* glm::rotate(compRot.y, glm::vec3(0.0f, 1.0f, 0.0f))
|
|
||||||
* glm::rotate(compRot.z, glm::vec3(0.0f, 0.0f, 1.0f))
|
|
||||||
* glm::vec4(objectOffset, 0);
|
|
||||||
glm::vec3 objectPosition = compPos + glm::vec3(rotatedObjectOffset.x,rotatedObjectOffset.y,rotatedObjectOffset.z);
|
|
||||||
glm::vec3 objectRot;
|
|
||||||
errorCheck(xmlObject->FirstChildElement("xRot")->QueryFloatText(&objectRot[0]));
|
|
||||||
errorCheck(xmlObject->FirstChildElement("yRot")->QueryFloatText(&objectRot[1]));
|
|
||||||
errorCheck(xmlObject->FirstChildElement("zRot")->QueryFloatText(&objectRot[2]));
|
|
||||||
objectRot *= 0.0174532925; //transform degrees to radians
|
|
||||||
Object* object = new Object(model, material, objectPosition, compRot+objectRot);
|
|
||||||
objects.push_back(object);
|
|
||||||
|
|
||||||
physicObjects.push_back(object);
|
|
||||||
const char* charPhysicType = objectData->FirstChildElement("physicType")->GetText();
|
|
||||||
if(charPhysicType == NULL){
|
|
||||||
printf("XMLError: No physicType found.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//create an identifier for this object
|
|
||||||
std::vector<int> objectIdentifier = std::vector<int>(5);
|
|
||||||
objectIdentifier[0] = objects.size()-1;
|
|
||||||
objectIdentifier[1] = physicObjects.size()-1;
|
|
||||||
int idGreen, idBlue;
|
|
||||||
errorCheck(thisComposition->FirstChildElement("idGreen")->QueryIntText(&idGreen));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("idBlue")->QueryIntText(&idBlue));
|
|
||||||
objectIdentifier[2] = idGreen;
|
|
||||||
objectIdentifier[3] = idBlue;
|
|
||||||
objectIdentifier[4] = objectNum;
|
|
||||||
objectIdentifiers.push_back(objectIdentifier);
|
|
||||||
|
|
||||||
|
|
||||||
std::string physicType = charPhysicType;
|
|
||||||
//add object to physics
|
|
||||||
float mass;
|
|
||||||
errorCheck(xmlObject->FirstChildElement("mass")->QueryFloatText(&mass));
|
|
||||||
float dampningL, dampningA;
|
|
||||||
XMLElement* constraint = thisComposition->FirstChildElement("positionConstraint");
|
|
||||||
bool rotate = (constraint == NULL);
|
|
||||||
errorCheck(objectData->FirstChildElement("dampningL")->QueryFloatText(&dampningL));
|
|
||||||
errorCheck(objectData->FirstChildElement("dampningA")->QueryFloatText(&dampningA));
|
|
||||||
if (physicType.compare("Player") == 0){
|
|
||||||
float radius;
|
|
||||||
errorCheck(objectData->FirstChildElement("radius")->QueryFloatText(&radius));
|
|
||||||
radius *= objectScale*compScale;
|
|
||||||
this->physics.addPlayer(friction, radius, *object, mass, dampningL, dampningA, physicObjects.size());
|
|
||||||
}else if (physicType.compare("Box") == 0){
|
|
||||||
float width, height, length;
|
|
||||||
errorCheck(objectData->FirstChildElement("width")->QueryFloatText(&width));
|
|
||||||
errorCheck(objectData->FirstChildElement("height")->QueryFloatText(&height));
|
|
||||||
errorCheck(objectData->FirstChildElement("length")->QueryFloatText(&length));
|
|
||||||
width *= objectScale*compScale;
|
|
||||||
height *= objectScale*compScale;
|
|
||||||
length *= objectScale*compScale;
|
|
||||||
this->physics.addBox(width, height, length, *object, mass, dampningL, dampningA, physicObjects.size(), rotate);
|
|
||||||
}else if (physicType.compare("Button") == 0){
|
|
||||||
float width, height, length;
|
|
||||||
errorCheck(objectData->FirstChildElement("width")->QueryFloatText(&width));
|
|
||||||
errorCheck(objectData->FirstChildElement("height")->QueryFloatText(&height));
|
|
||||||
errorCheck(objectData->FirstChildElement("length")->QueryFloatText(&length));
|
|
||||||
width *= objectScale*compScale;
|
|
||||||
height *= objectScale*compScale;
|
|
||||||
length *= objectScale*compScale;
|
|
||||||
this->physics.addButton(width, height, length, *object, mass, dampningL, dampningA, physicObjects.size(), rotate);
|
|
||||||
}else if (physicType.compare("TriangleMesh") == 0){
|
|
||||||
this->physics.addTriangleMeshBody(*object, modelPath, mass, dampningL, dampningA, physicObjects.size(), objectScale*compScale, rotate);
|
|
||||||
} else{
|
|
||||||
printf("XMLError: Not a valid physicType.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(compositionType == 20){
|
|
||||||
cameraCenter = object;
|
|
||||||
}
|
|
||||||
}//objectData found
|
|
||||||
}//finding the objectData
|
|
||||||
|
|
||||||
objectNum = objectNum + 1;
|
|
||||||
}//iterating over all objects of the composition
|
|
||||||
|
|
||||||
//iterate over all lights of the composition
|
|
||||||
XMLElement* xmlLight = composition->FirstChildElement("light");
|
|
||||||
for(; xmlLight; xmlLight=xmlLight->NextSiblingElement("light")){
|
|
||||||
glm::vec3 compRot, lightOffset, lightColour;
|
|
||||||
float compScale, compXPos, compYOffset, compZPos, lightIntensity;
|
|
||||||
errorCheck(thisComposition->FirstChildElement("scale")->QueryFloatText(&compScale));
|
|
||||||
errorCheck(xmlLight->FirstChildElement("xOffset")->QueryFloatText(&lightOffset[0]));
|
|
||||||
errorCheck(xmlLight->FirstChildElement("yOffset")->QueryFloatText(&lightOffset[1]));
|
|
||||||
errorCheck(xmlLight->FirstChildElement("zOffset")->QueryFloatText(&lightOffset[2]));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("xPos")->QueryFloatText(&compXPos));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("yOffset")->QueryFloatText(&compYOffset));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("zPos")->QueryFloatText(&compZPos));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("xRot")->QueryFloatText(&compRot[0]));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("yRot")->QueryFloatText(&compRot[1]));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("zRot")->QueryFloatText(&compRot[2]));
|
|
||||||
errorCheck(xmlLight->FirstChildElement("rColour")->QueryFloatText(&lightColour[0]));
|
|
||||||
errorCheck(xmlLight->FirstChildElement("gColour")->QueryFloatText(&lightColour[1]));
|
|
||||||
errorCheck(xmlLight->FirstChildElement("bColour")->QueryFloatText(&lightColour[2]));
|
|
||||||
errorCheck(xmlLight->FirstChildElement("intensity")->QueryFloatText(&lightIntensity));
|
|
||||||
glm::vec3 compPos = glm::vec3(compXPos,
|
|
||||||
compYOffset+terrain.getHeightmap()[int(compXPos-0.5+0.5*terrain.getHeightmapHeight())]
|
|
||||||
[int(compZPos-0.5+0.5*terrain.getHeightmapWidth())],
|
|
||||||
compZPos);
|
|
||||||
lightOffset = lightOffset * compScale;
|
|
||||||
glm::vec4 rotatedLightOffset = glm::rotate(compRot.x, glm::vec3(1.0f, 0.0f, 0.0f))
|
|
||||||
* glm::rotate(compRot.y, glm::vec3(0.0f, 1.0f, 0.0f))
|
|
||||||
* glm::rotate(compRot.z, glm::vec3(0.0f, 0.0f, 1.0f))
|
|
||||||
* glm::vec4(lightOffset, 0);
|
|
||||||
glm::vec3 lightPosition = compPos + glm::vec3(rotatedLightOffset.x,rotatedLightOffset.y,rotatedLightOffset.z);
|
|
||||||
Light light = Light(lightPosition, lightColour, lightIntensity);
|
|
||||||
lights.push_back(light);
|
|
||||||
}//iterating over all lights of the composition
|
|
||||||
}//corect composition found
|
|
||||||
}//iterating over all compositions in Compositions.xml
|
|
||||||
}//iterating over all compositions in Level.xml
|
|
||||||
|
|
||||||
//load triggers
|
|
||||||
XMLElement* composition = doc->FirstChildElement("composition");
|
|
||||||
for(; composition; composition=composition->NextSiblingElement("composition")){
|
|
||||||
XMLElement* xmlTrigger = composition->FirstChildElement("trigger");
|
|
||||||
for(; xmlTrigger; xmlTrigger=xmlTrigger->NextSiblingElement("trigger")){
|
|
||||||
const char* charName = xmlTrigger->FirstChildElement("name")->GetText();
|
|
||||||
if(charName == NULL){
|
|
||||||
printf("XMLError: No name found for a trigger.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
std::string name = charName;
|
|
||||||
if (name.compare("-") != 0){
|
|
||||||
float xPos, yPos, zPos, distance;
|
|
||||||
bool isBigger;
|
|
||||||
int idGreen, idBlue, objectNum;
|
|
||||||
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("xPosition")->QueryFloatText(&xPos));
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("yPosition")->QueryFloatText(&yPos));
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("zPosition")->QueryFloatText(&zPos));
|
|
||||||
glm::vec3 position = glm::vec3(xPos, yPos, zPos);
|
|
||||||
const char* charTarget = xmlTrigger->FirstChildElement("targetIdGreen")->GetText();
|
|
||||||
if(charTarget == NULL){
|
|
||||||
printf("XMLError: No targetIdGreen found for a trigger.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
std::string stringTarget = charTarget;
|
|
||||||
if (stringTarget.compare("-") != 0){
|
|
||||||
int targetIdGreen = 0, targetIdBlue = 0;
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("targetIdGreen")->QueryIntText(&targetIdGreen));
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("targetIdBlue")->QueryIntText(&targetIdBlue));
|
|
||||||
XMLElement* thisComposition = doc->FirstChildElement("composition");
|
|
||||||
for(; thisComposition; thisComposition=thisComposition->NextSiblingElement("composition")){
|
|
||||||
int thisIdGreen, thisIdBlue;
|
|
||||||
errorCheck(thisComposition->FirstChildElement("idGreen")->QueryIntText(&thisIdGreen));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("idBlue")->QueryIntText(&thisIdBlue));
|
|
||||||
if (targetIdGreen == thisIdGreen && targetIdBlue == thisIdBlue){
|
|
||||||
glm::vec3 targetPosition;
|
|
||||||
errorCheck(thisComposition->FirstChildElement("xPos")->QueryFloatText(&targetPosition[0]));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("yOffset")->QueryFloatText(&targetPosition[1]));
|
|
||||||
errorCheck(thisComposition->FirstChildElement("zPos")->QueryFloatText(&targetPosition[2]));
|
|
||||||
targetPosition[1] += terrain.getHeightmap()[int(targetPosition[0]-0.5+0.5*terrain.getHeightmapHeight())]
|
|
||||||
[int(targetPosition[2]-0.5+0.5*terrain.getHeightmapWidth())];
|
|
||||||
position += targetPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("distance")->QueryFloatText(&distance));
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("isBiggerThan")->QueryBoolText(&isBigger));
|
|
||||||
errorCheck(composition->FirstChildElement("idGreen")->QueryIntText(&idGreen));
|
|
||||||
errorCheck(composition->FirstChildElement("idBlue")->QueryIntText(&idBlue));
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("objectNum")->QueryIntText(&objectNum));
|
|
||||||
Object* object=0;
|
|
||||||
bool ok = false;
|
|
||||||
for (unsigned int i = 0; i<objectIdentifiers.size(); i++){
|
|
||||||
if (objectIdentifiers[i][2]==idGreen && objectIdentifiers[i][3]==idBlue && objectIdentifiers[i][4]==objectNum){
|
|
||||||
object = objects[objectIdentifiers[i][1]]; //Index in physic objects
|
|
||||||
if(ok){
|
|
||||||
printf("2 objects have the same ID while loading triggers.");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!ok){
|
|
||||||
printf("No index found for a trigger object while loading triggers.");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
const char* charLuaScript = xmlTrigger->FirstChildElement("luaScript")->GetText();
|
|
||||||
if(charLuaScript == NULL){
|
|
||||||
printf("XMLError: No Lua script found for a trigger.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
std::string luaScript = charLuaScript;
|
|
||||||
|
|
||||||
int toChangeIdGreen, toChangeIdBlue, toChangeObjNum, objectToChange=-1;
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("toChangeIdGreen")->QueryIntText(&toChangeIdGreen));
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("toChangeIdBlue")->QueryIntText(&toChangeIdBlue));
|
|
||||||
errorCheck(xmlTrigger->FirstChildElement("toChangeObjNum")->QueryIntText(&toChangeObjNum));
|
|
||||||
for (unsigned int i = 0; i<objectIdentifiers.size(); i++){
|
|
||||||
if (objectIdentifiers[i][2]==toChangeIdGreen && objectIdentifiers[i][3]==toChangeIdBlue && objectIdentifiers[i][4]==toChangeObjNum){
|
|
||||||
objectToChange = objectIdentifiers[i][1]; //Index in physic objects
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (object != 0) {
|
|
||||||
Trigger trigger = Trigger(position, distance, isBigger, object, luaScript, L, objectToChange);
|
|
||||||
triggers.push_back(trigger);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("Triggering object not found.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}//triggers
|
|
||||||
|
|
||||||
//load positionConstraints
|
|
||||||
composition = doc->FirstChildElement("composition");
|
|
||||||
for(; composition; composition=composition->NextSiblingElement("composition")){
|
|
||||||
XMLElement* positionConstraint = composition->FirstChildElement("positionConstraint");
|
|
||||||
for(; positionConstraint; positionConstraint=positionConstraint->NextSiblingElement("positionConstraint")){
|
|
||||||
float xPos, yPos, zPos, strength;
|
|
||||||
int objectNum=0, idGreen=0, idBlue=0, objectIndex=0;
|
|
||||||
errorCheck(positionConstraint->FirstChildElement("xPosition")->QueryFloatText(&xPos));
|
|
||||||
errorCheck(positionConstraint->FirstChildElement("yPosition")->QueryFloatText(&yPos));
|
|
||||||
errorCheck(positionConstraint->FirstChildElement("zPosition")->QueryFloatText(&zPos));
|
|
||||||
errorCheck(positionConstraint->FirstChildElement("strength")->QueryFloatText(&strength));
|
|
||||||
errorCheck(positionConstraint->FirstChildElement("objectNum")->QueryIntText(&objectNum));
|
|
||||||
errorCheck(composition->FirstChildElement("idGreen")->QueryIntText(&idGreen));
|
|
||||||
errorCheck(composition->FirstChildElement("idBlue")->QueryIntText(&idBlue));
|
|
||||||
bool ok = false;
|
|
||||||
for (unsigned int i = 0; i<objectIdentifiers.size(); i++){
|
|
||||||
if (objectIdentifiers[i][2]==idGreen && objectIdentifiers[i][3]==idBlue && objectIdentifiers[i][4]==objectNum){
|
|
||||||
objectIndex = objectIdentifiers[i][1]; //Index in physic objects
|
|
||||||
if(ok){
|
|
||||||
printf("2 objects have the same ID while loading constraints.");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!ok){
|
|
||||||
printf("No index found for a trigger object while loading constraints.");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
glm::vec3 position = glm::vec3(xPos, yPos, zPos);
|
|
||||||
physics.addPositionConstraint(objectIndex, strength, position);
|
|
||||||
}
|
|
||||||
}//positionConstraints
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass,
|
void Level::render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass,
|
||||||
@ -513,10 +106,10 @@ void Level::update(float runTime, glm::vec2 mouseDelta, bool wPressed, bool aPre
|
|||||||
cameraCenter->setPosition(physics.getPos(0));
|
cameraCenter->setPosition(physics.getPos(0));
|
||||||
cameraCenter->setRotation(physics.getRotation(0));
|
cameraCenter->setRotation(physics.getRotation(0));
|
||||||
|
|
||||||
for(unsigned i = 0; i < physicObjects.size();i++)
|
for(unsigned i = 0; i < physicsObjects.size();i++)
|
||||||
{
|
{
|
||||||
physicObjects[i]->setPosition(physics.getPos(i));
|
physicsObjects[i]->setPosition(physics.getPos(i));
|
||||||
physicObjects[i]->setRotation(physics.getRotation(i));
|
physicsObjects[i]->setRotation(physics.getRotation(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
skydome->setPosition(glm::vec3(cameraCenter->getPosition().x,
|
skydome->setPosition(glm::vec3(cameraCenter->getPosition().x,
|
||||||
@ -559,11 +152,18 @@ void Level::setSkydomeSize(float size) {
|
|||||||
skydomeSize = size;
|
skydomeSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Level::getSkydomeSize() {
|
||||||
|
return this->skydomeSize;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Object*>* Level::getObjects() {
|
std::vector<Object*>* Level::getObjects() {
|
||||||
return &objects;
|
return &objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Object*>* Level::getPhysicsObjects() {
|
||||||
|
return &physicsObjects;
|
||||||
|
}
|
||||||
|
|
||||||
void Level::moveObject(int objectIndex, float strength, float xPos, float yPos, float zPos){
|
void Level::moveObject(int objectIndex, float strength, float xPos, float yPos, float zPos){
|
||||||
glm::vec3 position = glm::vec3(xPos, yPos, zPos);
|
glm::vec3 position = glm::vec3(xPos, yPos, zPos);
|
||||||
physics.removePositionConstraint(objectIndex);
|
physics.removePositionConstraint(objectIndex);
|
||||||
@ -572,7 +172,7 @@ void Level::moveObject(int objectIndex, float strength, float xPos, float yPos,
|
|||||||
|
|
||||||
//should not be used since objects does not get synchronized and deletion is not implemented in pyhsics
|
//should not be used since objects does not get synchronized and deletion is not implemented in pyhsics
|
||||||
void Level::deleteObject(int objectIndex){
|
void Level::deleteObject(int objectIndex){
|
||||||
physicObjects.erase(physicObjects.begin() + objectIndex);
|
physicsObjects.erase(physicsObjects.begin() + objectIndex);
|
||||||
for(unsigned int i = 0; i<triggers.size(); i++) {
|
for(unsigned int i = 0; i<triggers.size(); i++) {
|
||||||
if(triggers.at(i).deleteNotification(objectIndex)){
|
if(triggers.at(i).deleteNotification(objectIndex)){
|
||||||
triggers.erase(triggers.begin() + i);
|
triggers.erase(triggers.begin() + i);
|
||||||
@ -581,10 +181,62 @@ void Level::deleteObject(int objectIndex){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Level::getObjectCount(){
|
void Level::setStrength(float strength) {
|
||||||
return physicObjects.size();
|
this->strength = strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Level::setSkydomeObject(Object* object){
|
||||||
|
this->skydome = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::addObject(Object* object) {
|
||||||
|
objects.push_back(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::addPhysicsObject(Object* object) {
|
||||||
|
physicsObjects.push_back(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::setAmbientLight(glm::vec3 colour) {
|
||||||
|
this->ambientLight = colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::setFogColour(glm::vec4 colour) {
|
||||||
|
this->fogColour = colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::setDirectionalLight(Light light) {
|
||||||
|
this->directionalLight = light;
|
||||||
|
}
|
||||||
|
|
||||||
|
Physics* Level::getPhysics() {
|
||||||
|
return &physics;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Level::getObjectsVectorSize() {
|
||||||
|
return objects.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Level::getPhysicsObjectsVectorSize() {
|
||||||
|
return physicsObjects.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::setCameraCenter(Object* object) {
|
||||||
|
this->cameraCenter = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::addLight(Light light) {
|
||||||
|
this->lights.push_back(light);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::addTrigger(Trigger trigger) {
|
||||||
|
this->triggers.push_back(trigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_State* Level::getLuaState() {
|
||||||
|
return luaState;
|
||||||
|
}
|
||||||
|
|
||||||
|
Terrain* Level::getTerrain() {
|
||||||
|
return &terrain;
|
||||||
|
}
|
||||||
|
30
level.hh
30
level.hh
@ -9,9 +9,15 @@
|
|||||||
#include "material.hh"
|
#include "material.hh"
|
||||||
#include "camera.hh"
|
#include "camera.hh"
|
||||||
#include "physics.hh"
|
#include "physics.hh"
|
||||||
#include "tinyxml2.hh"
|
|
||||||
#include "trigger.hh"
|
#include "trigger.hh"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "extern/lua/src/lua.h"
|
||||||
|
#include "extern/lua/src/lualib.h"
|
||||||
|
#include "extern/lua/src/lauxlib.h"
|
||||||
|
}
|
||||||
|
#include "extern/luabridge/LuaBridge.h"
|
||||||
|
|
||||||
class Level {
|
class Level {
|
||||||
public:
|
public:
|
||||||
Level(std::string levelNum);
|
Level(std::string levelNum);
|
||||||
@ -29,15 +35,31 @@ class Level {
|
|||||||
glm::vec3 getCameraPosition();
|
glm::vec3 getCameraPosition();
|
||||||
glm::vec4 getFogColour();
|
glm::vec4 getFogColour();
|
||||||
void setSkydomeSize(float size);
|
void setSkydomeSize(float size);
|
||||||
|
float getSkydomeSize();
|
||||||
std::vector<Object*>* getObjects();
|
std::vector<Object*>* getObjects();
|
||||||
|
std::vector<Object*>* getPhysicsObjects();
|
||||||
void deleteObject(int objectIndex);
|
void deleteObject(int objectIndex);
|
||||||
int getObjectCount();
|
|
||||||
void moveObject(int objectIndex, float strength, float xPos, float yPos, float zPos);
|
void moveObject(int objectIndex, float strength, float xPos, float yPos, float zPos);
|
||||||
|
void setStrength(float strength);
|
||||||
|
void setSkydomeObject(Object* object);
|
||||||
|
void addObject(Object* object);
|
||||||
|
void addPhysicsObject(Object* object);
|
||||||
|
void setAmbientLight(glm::vec3 colour);
|
||||||
|
void setFogColour(glm::vec4 colour);
|
||||||
|
void setDirectionalLight(Light light);
|
||||||
|
Physics* getPhysics();
|
||||||
|
unsigned int getObjectsVectorSize();
|
||||||
|
unsigned int getPhysicsObjectsVectorSize();
|
||||||
|
void setCameraCenter(Object* object);
|
||||||
|
void addLight(Light light);
|
||||||
|
void addTrigger(Trigger trigger);
|
||||||
|
lua_State* getLuaState();
|
||||||
|
Terrain* getTerrain();
|
||||||
private:
|
private:
|
||||||
void errorCheck(tinyxml2::XMLError error);
|
lua_State* luaState=nullptr;
|
||||||
std::string levelNum;
|
std::string levelNum;
|
||||||
std::vector<Object*> objects;
|
std::vector<Object*> objects;
|
||||||
std::vector<Object*> physicObjects;
|
std::vector<Object*> physicsObjects;
|
||||||
std::vector<Light> lights;
|
std::vector<Light> lights;
|
||||||
std::vector<Trigger> triggers;
|
std::vector<Trigger> triggers;
|
||||||
glm::vec3 ambientLight;
|
glm::vec3 ambientLight;
|
||||||
|
410
loader.cc
Normal file
410
loader.cc
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
#include "loader.hh"
|
||||||
|
using namespace tinyxml2;
|
||||||
|
|
||||||
|
Loader::Loader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Loader::load(std::string filePath, Level* level) {
|
||||||
|
//Loading from xml:
|
||||||
|
XMLDocument* doc = new XMLDocument();
|
||||||
|
const char* xmlFile = ("../Levels/ObjectSetups/" + filePath).c_str();
|
||||||
|
doc->LoadFile(xmlFile);
|
||||||
|
if (doc->ErrorID()!=0){
|
||||||
|
printf("Could not open ObjectSetupXml!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//load global physic parameter
|
||||||
|
float friction, strength;
|
||||||
|
XMLElement* physicsElement = doc->FirstChildElement("physics");
|
||||||
|
errorCheck(physicsElement->FirstChildElement("strength")->QueryFloatText(&strength));
|
||||||
|
errorCheck(physicsElement->FirstChildElement("friction")->QueryFloatText(&friction));
|
||||||
|
level->setStrength(strength);
|
||||||
|
|
||||||
|
//load the skydome
|
||||||
|
XMLElement* skydomeElement = doc->FirstChildElement("skydome");
|
||||||
|
const char* charSkydomeTexture = skydomeElement->FirstChildElement("texture")->GetText();
|
||||||
|
if(charSkydomeTexture == NULL){
|
||||||
|
printf("XMLError: No skydomeTexture found.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
std::string skydomeTexture = charSkydomeTexture;
|
||||||
|
Model skydomeModel = Model("skydome.obj", level->getSkydomeSize());
|
||||||
|
Material skydomeMaterial = Material(skydomeTexture, 0.7f, 0.0f, 0.0f, 0.0f);
|
||||||
|
Object* skydomeObject = new Object(skydomeModel, skydomeMaterial, glm::vec3(0.0f, 0.0f, 0.0f),
|
||||||
|
glm::vec3(0.0f, 0.0f, 0.0f));
|
||||||
|
level->addObject(skydomeObject);
|
||||||
|
level->setSkydomeObject(skydomeObject);
|
||||||
|
|
||||||
|
//load lighting parameters
|
||||||
|
float rColour, gColour, bColour, alpha, xOffset, yOffset, zOffset, intensity;
|
||||||
|
XMLElement* ambientElement = doc->FirstChildElement("ambientLight");
|
||||||
|
errorCheck(ambientElement->FirstChildElement("rColour")->QueryFloatText(&rColour));
|
||||||
|
errorCheck(ambientElement->FirstChildElement("gColour")->QueryFloatText(&gColour));
|
||||||
|
errorCheck(ambientElement->FirstChildElement("bColour")->QueryFloatText(&bColour));
|
||||||
|
level->setAmbientLight(glm::vec3(rColour,gColour,bColour));
|
||||||
|
|
||||||
|
XMLElement* fogElement = doc->FirstChildElement("fogColour");
|
||||||
|
errorCheck(fogElement->FirstChildElement("rColour")->QueryFloatText(&rColour));
|
||||||
|
errorCheck(fogElement->FirstChildElement("gColour")->QueryFloatText(&gColour));
|
||||||
|
errorCheck(fogElement->FirstChildElement("bColour")->QueryFloatText(&bColour));
|
||||||
|
errorCheck(fogElement->FirstChildElement("alpha")->QueryFloatText(&alpha));
|
||||||
|
level->setFogColour(glm::vec4(rColour,gColour,bColour, alpha));
|
||||||
|
|
||||||
|
XMLElement* directionalElement = doc->FirstChildElement("directionalLight");
|
||||||
|
errorCheck(directionalElement->FirstChildElement("xOffset")->QueryFloatText(&xOffset));
|
||||||
|
errorCheck(directionalElement->FirstChildElement("yOffset")->QueryFloatText(&yOffset));
|
||||||
|
errorCheck(directionalElement->FirstChildElement("zOffset")->QueryFloatText(&zOffset));
|
||||||
|
errorCheck(directionalElement->FirstChildElement("rColour")->QueryFloatText(&rColour));
|
||||||
|
errorCheck(directionalElement->FirstChildElement("gColour")->QueryFloatText(&gColour));
|
||||||
|
errorCheck(directionalElement->FirstChildElement("bColour")->QueryFloatText(&bColour));
|
||||||
|
errorCheck(directionalElement->FirstChildElement("intensity")->QueryFloatText(&intensity));
|
||||||
|
level->setDirectionalLight(Light(glm::vec3(xOffset,yOffset,zOffset), glm::vec3(rColour,gColour,bColour), intensity));
|
||||||
|
|
||||||
|
//load Objects
|
||||||
|
std::vector<std::vector<int>> objectIdentifiers = std::vector<std::vector<int>>(); //The first entry is the index in objects, the second one the index in physicObjects, the others are idGreen, idBlue and objectNum.
|
||||||
|
XMLDocument* compositions = new XMLDocument();
|
||||||
|
//TODO move path to config.xml
|
||||||
|
const char* compositionsFile = "../Levels/ObjectSetups/Compositions.xml";
|
||||||
|
compositions->LoadFile(compositionsFile);
|
||||||
|
if (compositions->ErrorID()!=0){
|
||||||
|
printf("Could not open Compositions!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
//iterate over all compositions in Level.xml
|
||||||
|
XMLElement* thisComposition = doc->FirstChildElement("composition");
|
||||||
|
for(; thisComposition; thisComposition=thisComposition->NextSiblingElement("composition")){
|
||||||
|
int thisType = 0;
|
||||||
|
errorCheck(thisComposition->FirstChildElement("typeID")->QueryIntText(&thisType));
|
||||||
|
//iterate over all compositions in Compositions.xml to find the one corresponding to the current composition
|
||||||
|
XMLElement* composition = compositions->FirstChildElement("composition");
|
||||||
|
for(; composition; composition=composition->NextSiblingElement("composition")){
|
||||||
|
int compositionType = 0;
|
||||||
|
errorCheck(composition->FirstChildElement("typeID")->QueryIntText(&compositionType));
|
||||||
|
//corect composition found
|
||||||
|
if(thisType == compositionType){
|
||||||
|
//iterate over all objects of the composition
|
||||||
|
XMLElement* xmlObject = composition->FirstChildElement("object");
|
||||||
|
int objectNum = 0;
|
||||||
|
for(; xmlObject; xmlObject=xmlObject->NextSiblingElement("object")){
|
||||||
|
const char* charModelPath = xmlObject->FirstChildElement("modelPath")->GetText();
|
||||||
|
if(charModelPath == NULL){
|
||||||
|
printf("XMLError: No modelPath found in object.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
std::string modelPath = charModelPath;
|
||||||
|
float objectScale, compScale;
|
||||||
|
errorCheck(xmlObject->FirstChildElement("scale")->QueryFloatText(&objectScale));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("scale")->QueryFloatText(&compScale));
|
||||||
|
Model model = Model(modelPath, objectScale * compScale);
|
||||||
|
//find the objectData for the current object
|
||||||
|
XMLElement* objectData = compositions->FirstChildElement("objectData");
|
||||||
|
for(; objectData; objectData=objectData->NextSiblingElement("objectData")){
|
||||||
|
const char* charDataModelPath = objectData->FirstChildElement("modelPath")->GetText();
|
||||||
|
if(charDataModelPath == NULL){
|
||||||
|
printf("XMLError: No modelPath found in objectData.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
std::string dataModelPath = charDataModelPath;
|
||||||
|
//objectData found
|
||||||
|
if(dataModelPath.compare(modelPath) == 0){
|
||||||
|
//create the object
|
||||||
|
float ambientFactor, diffuseFactor, specularFactor, shininess;
|
||||||
|
errorCheck(objectData->FirstChildElement("ambientFactor")->QueryFloatText(&ambientFactor));
|
||||||
|
errorCheck(objectData->FirstChildElement("diffuseFactor")->QueryFloatText(&diffuseFactor));
|
||||||
|
errorCheck(objectData->FirstChildElement("specularFactor")->QueryFloatText(&specularFactor));
|
||||||
|
errorCheck(objectData->FirstChildElement("shininess")->QueryFloatText(&shininess));
|
||||||
|
const char* charTexturePath = objectData->FirstChildElement("texturePath")->GetText();
|
||||||
|
if(charTexturePath == NULL){
|
||||||
|
printf("XMLError: No texturePath found in objectData.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
std::string texturePath = charTexturePath;
|
||||||
|
Material material = Material(texturePath, ambientFactor, diffuseFactor, specularFactor, shininess);
|
||||||
|
float compXPos, compYOffset, compZPos;
|
||||||
|
glm::vec3 objectOffset, compRot;
|
||||||
|
errorCheck(xmlObject->FirstChildElement("xOffset")->QueryFloatText(&objectOffset[0]));
|
||||||
|
errorCheck(xmlObject->FirstChildElement("yOffset")->QueryFloatText(&objectOffset[1]));
|
||||||
|
errorCheck(xmlObject->FirstChildElement("zOffset")->QueryFloatText(&objectOffset[2]));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("xPos")->QueryFloatText(&compXPos));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("yOffset")->QueryFloatText(&compYOffset));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("zPos")->QueryFloatText(&compZPos));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("xRot")->QueryFloatText(&compRot[0]));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("yRot")->QueryFloatText(&compRot[1]));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("zRot")->QueryFloatText(&compRot[2]));
|
||||||
|
compRot *= 0.0174532925; //transform degrees to radians
|
||||||
|
bool ignoreHeightmap;
|
||||||
|
errorCheck(composition->FirstChildElement("ignoreHeightmap")->QueryBoolText(&ignoreHeightmap));
|
||||||
|
if (!ignoreHeightmap){
|
||||||
|
compYOffset = compYOffset+level->getTerrain()->getHeightmap()[int(compXPos-0.5+0.5*level->getTerrain()->getHeightmapHeight())]
|
||||||
|
[int(compZPos-0.5+0.5*level->getTerrain()->getHeightmapWidth())];
|
||||||
|
}
|
||||||
|
glm::vec3 compPos = glm::vec3(compXPos, compYOffset, compZPos);
|
||||||
|
objectOffset = objectOffset * compScale;
|
||||||
|
glm::vec4 rotatedObjectOffset = glm::rotate(compRot.x, glm::vec3(1.0f, 0.0f, 0.0f))
|
||||||
|
* glm::rotate(compRot.y, glm::vec3(0.0f, 1.0f, 0.0f))
|
||||||
|
* glm::rotate(compRot.z, glm::vec3(0.0f, 0.0f, 1.0f))
|
||||||
|
* glm::vec4(objectOffset, 0);
|
||||||
|
glm::vec3 objectPosition = compPos + glm::vec3(rotatedObjectOffset.x,rotatedObjectOffset.y,rotatedObjectOffset.z);
|
||||||
|
glm::vec3 objectRot;
|
||||||
|
errorCheck(xmlObject->FirstChildElement("xRot")->QueryFloatText(&objectRot[0]));
|
||||||
|
errorCheck(xmlObject->FirstChildElement("yRot")->QueryFloatText(&objectRot[1]));
|
||||||
|
errorCheck(xmlObject->FirstChildElement("zRot")->QueryFloatText(&objectRot[2]));
|
||||||
|
objectRot *= 0.0174532925; //transform degrees to radians
|
||||||
|
Object* object = new Object(model, material, objectPosition, compRot+objectRot);
|
||||||
|
level->addObject(object);
|
||||||
|
level->addPhysicsObject(object);
|
||||||
|
|
||||||
|
//create an identifier for this object
|
||||||
|
std::vector<int> objectIdentifier = std::vector<int>(5);
|
||||||
|
objectIdentifier[0] = level->getObjectsVectorSize()-1;
|
||||||
|
objectIdentifier[1] = level->getPhysicsObjectsVectorSize()-1;
|
||||||
|
int idGreen, idBlue;
|
||||||
|
errorCheck(thisComposition->FirstChildElement("idGreen")->QueryIntText(&idGreen));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("idBlue")->QueryIntText(&idBlue));
|
||||||
|
objectIdentifier[2] = idGreen;
|
||||||
|
objectIdentifier[3] = idBlue;
|
||||||
|
objectIdentifier[4] = objectNum;
|
||||||
|
objectIdentifiers.push_back(objectIdentifier);
|
||||||
|
|
||||||
|
//add object to physics
|
||||||
|
const char* charPhysicType = objectData->FirstChildElement("physicType")->GetText();
|
||||||
|
if(charPhysicType == NULL){
|
||||||
|
printf("XMLError: No physicType found.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
std::string physicType = charPhysicType;
|
||||||
|
float mass;
|
||||||
|
errorCheck(xmlObject->FirstChildElement("mass")->QueryFloatText(&mass));
|
||||||
|
float dampningL, dampningA;
|
||||||
|
XMLElement* constraint = thisComposition->FirstChildElement("positionConstraint");
|
||||||
|
bool rotate = (constraint == NULL);
|
||||||
|
errorCheck(objectData->FirstChildElement("dampningL")->QueryFloatText(&dampningL));
|
||||||
|
errorCheck(objectData->FirstChildElement("dampningA")->QueryFloatText(&dampningA));
|
||||||
|
if (physicType.compare("Player") == 0){
|
||||||
|
float radius;
|
||||||
|
errorCheck(objectData->FirstChildElement("radius")->QueryFloatText(&radius));
|
||||||
|
radius *= objectScale*compScale;
|
||||||
|
level->getPhysics()->addPlayer(friction, radius, *object, mass, dampningL, dampningA, level->getPhysicsObjectsVectorSize());
|
||||||
|
}else if (physicType.compare("Box") == 0){
|
||||||
|
float width, height, length;
|
||||||
|
errorCheck(objectData->FirstChildElement("width")->QueryFloatText(&width));
|
||||||
|
errorCheck(objectData->FirstChildElement("height")->QueryFloatText(&height));
|
||||||
|
errorCheck(objectData->FirstChildElement("length")->QueryFloatText(&length));
|
||||||
|
width *= objectScale*compScale;
|
||||||
|
height *= objectScale*compScale;
|
||||||
|
length *= objectScale*compScale;
|
||||||
|
level->getPhysics()->addBox(width, height, length, *object, mass, dampningL, dampningA, level->getPhysicsObjectsVectorSize(), rotate);
|
||||||
|
}else if (physicType.compare("Button") == 0){
|
||||||
|
float width, height, length;
|
||||||
|
errorCheck(objectData->FirstChildElement("width")->QueryFloatText(&width));
|
||||||
|
errorCheck(objectData->FirstChildElement("height")->QueryFloatText(&height));
|
||||||
|
errorCheck(objectData->FirstChildElement("length")->QueryFloatText(&length));
|
||||||
|
width *= objectScale*compScale;
|
||||||
|
height *= objectScale*compScale;
|
||||||
|
length *= objectScale*compScale;
|
||||||
|
level->getPhysics()->addButton(width, height, length, *object, mass, dampningL, dampningA, level->getPhysicsObjectsVectorSize(), rotate);
|
||||||
|
}else if (physicType.compare("TriangleMesh") == 0){
|
||||||
|
level->getPhysics()->addTriangleMeshBody(*object, modelPath, mass, dampningL, dampningA, level->getPhysicsObjectsVectorSize(), objectScale*compScale, rotate);
|
||||||
|
} else{
|
||||||
|
printf("XMLError: Not a valid physicType.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(compositionType == 20){
|
||||||
|
level->setCameraCenter(object);
|
||||||
|
}
|
||||||
|
}//objectData found
|
||||||
|
}//finding the objectData
|
||||||
|
|
||||||
|
objectNum = objectNum + 1;
|
||||||
|
}//iterating over all objects of the composition
|
||||||
|
|
||||||
|
//iterate over all lights of the composition
|
||||||
|
XMLElement* xmlLight = composition->FirstChildElement("light");
|
||||||
|
for(; xmlLight; xmlLight=xmlLight->NextSiblingElement("light")){
|
||||||
|
glm::vec3 compRot, lightOffset, lightColour;
|
||||||
|
float compScale, compXPos, compYOffset, compZPos, lightIntensity;
|
||||||
|
errorCheck(thisComposition->FirstChildElement("scale")->QueryFloatText(&compScale));
|
||||||
|
errorCheck(xmlLight->FirstChildElement("xOffset")->QueryFloatText(&lightOffset[0]));
|
||||||
|
errorCheck(xmlLight->FirstChildElement("yOffset")->QueryFloatText(&lightOffset[1]));
|
||||||
|
errorCheck(xmlLight->FirstChildElement("zOffset")->QueryFloatText(&lightOffset[2]));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("xPos")->QueryFloatText(&compXPos));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("yOffset")->QueryFloatText(&compYOffset));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("zPos")->QueryFloatText(&compZPos));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("xRot")->QueryFloatText(&compRot[0]));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("yRot")->QueryFloatText(&compRot[1]));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("zRot")->QueryFloatText(&compRot[2]));
|
||||||
|
errorCheck(xmlLight->FirstChildElement("rColour")->QueryFloatText(&lightColour[0]));
|
||||||
|
errorCheck(xmlLight->FirstChildElement("gColour")->QueryFloatText(&lightColour[1]));
|
||||||
|
errorCheck(xmlLight->FirstChildElement("bColour")->QueryFloatText(&lightColour[2]));
|
||||||
|
errorCheck(xmlLight->FirstChildElement("intensity")->QueryFloatText(&lightIntensity));
|
||||||
|
glm::vec3 compPos = glm::vec3(compXPos,
|
||||||
|
compYOffset+level->getTerrain()->getHeightmap()[int(compXPos-0.5+0.5*level->getTerrain()->getHeightmapHeight())]
|
||||||
|
[int(compZPos-0.5+0.5*level->getTerrain()->getHeightmapWidth())],
|
||||||
|
compZPos);
|
||||||
|
lightOffset = lightOffset * compScale;
|
||||||
|
glm::vec4 rotatedLightOffset = glm::rotate(compRot.x, glm::vec3(1.0f, 0.0f, 0.0f))
|
||||||
|
* glm::rotate(compRot.y, glm::vec3(0.0f, 1.0f, 0.0f))
|
||||||
|
* glm::rotate(compRot.z, glm::vec3(0.0f, 0.0f, 1.0f))
|
||||||
|
* glm::vec4(lightOffset, 0);
|
||||||
|
glm::vec3 lightPosition = compPos + glm::vec3(rotatedLightOffset.x,rotatedLightOffset.y,rotatedLightOffset.z);
|
||||||
|
Light light = Light(lightPosition, lightColour, lightIntensity);
|
||||||
|
level->addLight(light);
|
||||||
|
}//iterating over all lights of the composition
|
||||||
|
}//corect composition found
|
||||||
|
}//iterating over all compositions in Compositions.xml
|
||||||
|
}//iterating over all compositions in Level.xml
|
||||||
|
|
||||||
|
//load triggers
|
||||||
|
XMLElement* composition = doc->FirstChildElement("composition");
|
||||||
|
for(; composition; composition=composition->NextSiblingElement("composition")){
|
||||||
|
XMLElement* xmlTrigger = composition->FirstChildElement("trigger");
|
||||||
|
for(; xmlTrigger; xmlTrigger=xmlTrigger->NextSiblingElement("trigger")){
|
||||||
|
const char* charName = xmlTrigger->FirstChildElement("name")->GetText();
|
||||||
|
if(charName == NULL){
|
||||||
|
printf("XMLError: No name found for a trigger.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
std::string name = charName;
|
||||||
|
if (name.compare("-") != 0){
|
||||||
|
float xPos, yPos, zPos, distance;
|
||||||
|
bool isBigger;
|
||||||
|
int idGreen, idBlue, objectNum;
|
||||||
|
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("xPosition")->QueryFloatText(&xPos));
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("yPosition")->QueryFloatText(&yPos));
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("zPosition")->QueryFloatText(&zPos));
|
||||||
|
glm::vec3 position = glm::vec3(xPos, yPos, zPos);
|
||||||
|
const char* charTarget = xmlTrigger->FirstChildElement("targetIdGreen")->GetText();
|
||||||
|
if(charTarget == NULL){
|
||||||
|
printf("XMLError: No targetIdGreen found for a trigger.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
std::string stringTarget = charTarget;
|
||||||
|
if (stringTarget.compare("-") != 0){
|
||||||
|
int targetIdGreen = 0, targetIdBlue = 0;
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("targetIdGreen")->QueryIntText(&targetIdGreen));
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("targetIdBlue")->QueryIntText(&targetIdBlue));
|
||||||
|
XMLElement* thisComposition = doc->FirstChildElement("composition");
|
||||||
|
for(; thisComposition; thisComposition=thisComposition->NextSiblingElement("composition")){
|
||||||
|
int thisIdGreen, thisIdBlue;
|
||||||
|
errorCheck(thisComposition->FirstChildElement("idGreen")->QueryIntText(&thisIdGreen));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("idBlue")->QueryIntText(&thisIdBlue));
|
||||||
|
if (targetIdGreen == thisIdGreen && targetIdBlue == thisIdBlue){
|
||||||
|
glm::vec3 targetPosition;
|
||||||
|
errorCheck(thisComposition->FirstChildElement("xPos")->QueryFloatText(&targetPosition[0]));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("yOffset")->QueryFloatText(&targetPosition[1]));
|
||||||
|
errorCheck(thisComposition->FirstChildElement("zPos")->QueryFloatText(&targetPosition[2]));
|
||||||
|
targetPosition[1] += level->getTerrain()->getHeightmap()[int(targetPosition[0]-0.5+0.5*level->getTerrain()->getHeightmapHeight())]
|
||||||
|
[int(targetPosition[2]-0.5+0.5*level->getTerrain()->getHeightmapWidth())];
|
||||||
|
position += targetPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("distance")->QueryFloatText(&distance));
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("isBiggerThan")->QueryBoolText(&isBigger));
|
||||||
|
errorCheck(composition->FirstChildElement("idGreen")->QueryIntText(&idGreen));
|
||||||
|
errorCheck(composition->FirstChildElement("idBlue")->QueryIntText(&idBlue));
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("objectNum")->QueryIntText(&objectNum));
|
||||||
|
Object* object=0;
|
||||||
|
bool ok = false;
|
||||||
|
for (unsigned int i = 0; i<objectIdentifiers.size(); i++){
|
||||||
|
if (objectIdentifiers[i][2]==idGreen && objectIdentifiers[i][3]==idBlue && objectIdentifiers[i][4]==objectNum){
|
||||||
|
object = level->getPhysicsObjects()->at(objectIdentifiers[i][1]); //Index in physics objects
|
||||||
|
if(ok){
|
||||||
|
printf("2 objects have the same ID while loading triggers.");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!ok){
|
||||||
|
printf("No index found for a trigger object while loading triggers.");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
const char* charLuaScript = xmlTrigger->FirstChildElement("luaScript")->GetText();
|
||||||
|
if(charLuaScript == NULL){
|
||||||
|
printf("XMLError: No Lua script found for a trigger.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
std::string luaScript = charLuaScript;
|
||||||
|
|
||||||
|
int toChangeIdGreen, toChangeIdBlue, toChangeObjNum, objectToChange=-1;
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("toChangeIdGreen")->QueryIntText(&toChangeIdGreen));
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("toChangeIdBlue")->QueryIntText(&toChangeIdBlue));
|
||||||
|
errorCheck(xmlTrigger->FirstChildElement("toChangeObjNum")->QueryIntText(&toChangeObjNum));
|
||||||
|
for (unsigned int i = 0; i<objectIdentifiers.size(); i++){
|
||||||
|
if (objectIdentifiers[i][2]==toChangeIdGreen && objectIdentifiers[i][3]==toChangeIdBlue && objectIdentifiers[i][4]==toChangeObjNum){
|
||||||
|
objectToChange = objectIdentifiers[i][1]; //Index in physic objects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (object != 0) {
|
||||||
|
Trigger trigger = Trigger(position, distance, isBigger, object, luaScript, level->getLuaState(), objectToChange);
|
||||||
|
level->addTrigger(trigger);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Triggering object not found.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//triggers
|
||||||
|
|
||||||
|
//load positionConstraints
|
||||||
|
composition = doc->FirstChildElement("composition");
|
||||||
|
for(; composition; composition=composition->NextSiblingElement("composition")){
|
||||||
|
XMLElement* positionConstraint = composition->FirstChildElement("positionConstraint");
|
||||||
|
for(; positionConstraint; positionConstraint=positionConstraint->NextSiblingElement("positionConstraint")){
|
||||||
|
float xPos, yPos, zPos, strength;
|
||||||
|
int objectNum=0, idGreen=0, idBlue=0, objectIndex=0;
|
||||||
|
errorCheck(positionConstraint->FirstChildElement("xPosition")->QueryFloatText(&xPos));
|
||||||
|
errorCheck(positionConstraint->FirstChildElement("yPosition")->QueryFloatText(&yPos));
|
||||||
|
errorCheck(positionConstraint->FirstChildElement("zPosition")->QueryFloatText(&zPos));
|
||||||
|
errorCheck(positionConstraint->FirstChildElement("strength")->QueryFloatText(&strength));
|
||||||
|
errorCheck(positionConstraint->FirstChildElement("objectNum")->QueryIntText(&objectNum));
|
||||||
|
errorCheck(composition->FirstChildElement("idGreen")->QueryIntText(&idGreen));
|
||||||
|
errorCheck(composition->FirstChildElement("idBlue")->QueryIntText(&idBlue));
|
||||||
|
bool ok = false;
|
||||||
|
for (unsigned int i = 0; i<objectIdentifiers.size(); i++){
|
||||||
|
if (objectIdentifiers[i][2]==idGreen && objectIdentifiers[i][3]==idBlue && objectIdentifiers[i][4]==objectNum){
|
||||||
|
objectIndex = objectIdentifiers[i][1]; //Index in physic objects
|
||||||
|
if(ok){
|
||||||
|
printf("2 objects have the same ID while loading constraints.");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!ok){
|
||||||
|
printf("No index found for a trigger object while loading constraints.");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
glm::vec3 position = glm::vec3(xPos, yPos, zPos);
|
||||||
|
level->getPhysics()->addPositionConstraint(objectIndex, strength, position);
|
||||||
|
}
|
||||||
|
}//positionConstraints
|
||||||
|
}
|
||||||
|
|
||||||
|
void Loader::errorCheck(XMLError error){
|
||||||
|
if (error) {
|
||||||
|
printf("XMLError: ");
|
||||||
|
if (error == XML_WRONG_ATTRIBUTE_TYPE) {
|
||||||
|
printf("Wrong attribute type.\n");
|
||||||
|
}
|
||||||
|
else if (error == XML_NO_ATTRIBUTE) {
|
||||||
|
printf("No attribute.\n");
|
||||||
|
}
|
||||||
|
else if (error == XML_CAN_NOT_CONVERT_TEXT) {
|
||||||
|
printf("Can not convert text.\n");
|
||||||
|
}
|
||||||
|
else if (error == XML_NO_TEXT_NODE) {
|
||||||
|
printf("No text.\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Unknown error.\n");
|
||||||
|
}
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user