// %flair:license{ // This file is part of the Flair framework distributed under the // CECILL-C License, Version 1.0. // %flair:license} // created: 2013/08/02 // filename: Parser.cpp // // author: César Richard // Copyright Heudiasyc UMR UTC/CNRS 7253 // // version: $Id: $ // // purpose: classe chargeant un XML decrivant une map // /*********************************************************************/ #ifdef GL #include "Parser.h" #include "Simulator.h" #include "GenericObject.h" #include #include #include "GenericObject.h" using namespace irr; using namespace irr::core; using namespace irr::scene; using namespace irr::video; using namespace flair::core; using namespace flair::simulator; // todo: getMeshVect doit plutot donner point3D et euler // adaptr le xml et la dtd namespace flair { namespace simulator { Parser::Parser(Simulator *parent, int app_width, int app_height, int scene_width, int scene_height, std::string media_path, std::string xmlFile) : Gui(parent, "Parser", app_width, app_height, scene_width, scene_height, media_path) { this->media_path = media_path; this->parent = parent; xmlNode *root_element = NULL; doc = xmlReadFile(xmlFile.c_str(), NULL, 0); xmlDtdPtr dtd = NULL; dtd = xmlParseDTD(NULL, (const xmlChar *)(media_path.append("/scene.dtd").c_str())); if (dtd == NULL) { // xmlGenericError(xmlGenericErrorContext, Err("Could not parse DTD scene.dtd\n"); } else { xmlValidCtxt cvp; cvp.userData = (void *)stderr; cvp.error = (xmlValidityErrorFunc)fprintf; cvp.warning = (xmlValidityWarningFunc)fprintf; if (!xmlValidateDtd(&cvp, doc, dtd)) { // xmlGenericError(xmlGenericErrorContext, Err("Document does not validate against scene.dtd\n"); } } if (doc == NULL) { Err("error: could not parse file %s\n", xmlFile.c_str()); } else { /* * Get the root element node */ root_element = xmlDocGetRootElement(doc); processElements(root_element); } } Parser::~Parser() { if (doc != NULL) { /* * free the document */ xmlFreeDoc(doc); ; } /* *Free the global variables that may *have been allocated by the parser. */ xmlCleanupParser(); } /* Recursive function that prints the XML structure */ void Parser::processElements(xmlNode *a_node) { xmlNode *cur_node = NULL; for (cur_node = a_node; cur_node; cur_node = cur_node->next) { if (cur_node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(cur_node->name, (xmlChar *)"params")) { processParams(cur_node->children); } else if (xmlStrEqual(cur_node->name, (xmlChar *)"objects")) { processObjects(cur_node->children); } else { processElements(cur_node->children); } } } } void Parser::processObjects(xmlNode *a_node) { FILE *fp; std::string fileName; xmlNode *cur_node = NULL; const IGeometryCreator *geo; geo = getGui()->getSceneManager()->getGeometryCreator(); for (cur_node = a_node; cur_node; cur_node = cur_node->next) { if (xmlStrEqual(cur_node->name, (xmlChar *)"mesh")) { fileName = this->media_path; fp = NULL; fp = fopen(fileName.append((char *)xmlGetProp( cur_node, (xmlChar *)"model")).c_str(), "rb"); if (fp != NULL) { GenericObject *object = new GenericObject(parent, "Object", getSceneManager()); object->setMesh(getGui()->getMesh( (char *)xmlGetProp(cur_node, (xmlChar *)"model"))); object->setPosition( getMeshVect(cur_node->children, (xmlChar *)"position")); object->setRotation( getMeshVect(cur_node->children, (xmlChar *)"rotation")); object->setScale(getMeshVect(cur_node->children, (xmlChar *)"scale")); object->render(); } else { Err("FATAL ERROR : File %s doesn't exist !\r\n", (char *)xmlGetProp(cur_node, (xmlChar *)"model")); } } else if (xmlStrEqual(cur_node->name, (xmlChar *)"cylinder")) { GenericObject *object = new GenericObject(parent, "Object", getSceneManager()); object->setMesh(geo->createCylinderMesh( ToIrrlichtScale( atof((char *)xmlGetProp(cur_node, (xmlChar *)"radius"))), ToIrrlichtScale( atof((char *)xmlGetProp(cur_node, (xmlChar *)"length"))), atof((char *)xmlGetProp(cur_node, (xmlChar *)"tesselation")), SColor(100, 255, 100, 100))); object->setPosition( getMeshVect(cur_node->children, (xmlChar *)"position")); object->setRotation( getMeshVect(cur_node->children, (xmlChar *)"rotation")); object->setScale(getMeshVect(cur_node->children, (xmlChar *)"scale")); // object->setMaterialTexture(0,getTexture("/home/apeiron/igep/uav_dev_svn/trunk/media/nskinbl.jpg")); object->setMaterialType(video::EMT_SOLID); object->render(); } else if (xmlStrEqual(cur_node->name, (xmlChar *)"eight")) { GenericObject *object = new GenericObject(parent, "Object", getSceneManager()); object->setMesh(geo->createCubeMesh( vector3df(atof((char *)xmlGetProp(cur_node, (xmlChar *)"length")), atof((char *)xmlGetProp(cur_node, (xmlChar *)"width")), atof((char *)xmlGetProp(cur_node, (xmlChar *)"eight"))))); object->setPosition( getMeshVect(cur_node->children, (xmlChar *)"position")); object->setRotation( getMeshVect(cur_node->children, (xmlChar *)"rotation")); object->setScale(getMeshVect(cur_node->children, (xmlChar *)"scale")); object->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL); // object->getMaterial(0).Textures[0] = // getTexture("/home/apeiron/igep/uav_dev_svn/trunk/media/nskinbl.jpg"); object->setMaterialFlag(EMF_LIGHTING, false); object->render(); } } } void Parser::processParams(xmlNode *a_node) { xmlNode *cur_node = NULL; for (cur_node = a_node; cur_node; cur_node = cur_node->next) { if (xmlStrEqual(cur_node->name, (xmlChar *)"archive")) { std::string file = media_path + "/" + (char *)xmlGetProp(cur_node, (xmlChar *)"path"); getDevice()->getFileSystem()->addFileArchive(file.c_str()); } else if (xmlStrEqual(cur_node->name, (xmlChar *)"mesh")) { setMesh((char *)xmlGetProp(cur_node, (xmlChar *)"model"), getSceneVect(cur_node->children, (xmlChar *)"position"), getSceneVect(cur_node->children, (xmlChar *)"rotation"), getSceneVect(cur_node->children, (xmlChar *)"scale", true)); } } } // todo rendre un vector3D framework // retirer irr::core::vector3df ToIrrlichtCoordinates(irr::core::vector3df // vect); vector3df Parser::getMeshVect(xmlNode *mesh_node, xmlChar *param) { xmlNode *cur_node = NULL; for (cur_node = mesh_node; cur_node; cur_node = cur_node->next) { if (xmlStrEqual(cur_node->name, param)) { return vector3df(atof((char *)xmlGetProp(cur_node, (xmlChar *)"x")), atof((char *)xmlGetProp(cur_node, (xmlChar *)"y")), atof((char *)xmlGetProp(cur_node, (xmlChar *)"z"))); } } return vector3df(0, 0, 0); } vector3df Parser::getSceneVect(xmlNode *mesh_node, xmlChar *param, bool isScale) { xmlNode *cur_node = NULL; for (cur_node = mesh_node; cur_node; cur_node = cur_node->next) { if (xmlStrEqual(cur_node->name, param)) { if (isScale) { return vector3df(atof((char *)xmlGetProp(cur_node, (xmlChar *)"x")), atof((char *)xmlGetProp(cur_node, (xmlChar *)"z")), atof((char *)xmlGetProp(cur_node, (xmlChar *)"y"))); } return vector3df(atof((char *)xmlGetProp(cur_node, (xmlChar *)"x")), -atof((char *)xmlGetProp(cur_node, (xmlChar *)"z")), atof((char *)xmlGetProp(cur_node, (xmlChar *)"y"))); } } return vector3df(0, 0, 0); } } // end namespace simulator } // end namespace flair #endif // GL