DotScene loader class (with user properties)
Based on DotScene Loader with User Data.
Table of contents
Header File (DotScene.h)
Copy to clipboard
/*------------------------------------------------------------------------------ * DotScene.h * * This file provides some methods for the parsing of a .scene file, with * support for userData. *------------------------------------------------------------------------------*/ #ifndef DOT_SCENE_H #define DOT_SCENE_H #include <Ogre.h> #include <vector> #include "tinyxml.h" class nodeProperty { public: Ogre::String nodeName; Ogre::String propertyNm; Ogre::String valueName; Ogre::String typeName; nodeProperty(Ogre::String node,Ogre::String propertyName,Ogre::String value,Ogre::String type) { nodeName = node; propertyNm = propertyName; valueName = value; typeName = type; } }; class CDotScene { public: CDotScene() : mSceneMgr(0) {} virtual ~CDotScene() {} void parseDotScene( const Ogre::String &SceneName, const Ogre::String& groupName, Ogre::SceneManager *yourSceneMgr, Ogre::SceneNode *pAttachNode = NULL, Ogre::String sPrependNode = ""); Ogre::String getProperty(Ogre::String ndNm, Ogre::String prop); std::vector<nodeProperty> nodeProperties; protected: void processNode(TiXmlElement *XMLNode, Ogre::SceneNode *pAttach); Ogre::SceneManager *mSceneMgr; Ogre::String m_sPrependNode; }; #endif
Source File (DotScene.cpp)
Copy to clipboard
/*------------------------------------------------------------------------------ * DotScene.cpp * * This file provides some methods for the parsing of a .scene file, with * support for userData. *------------------------------------------------------------------------------*/ #include "DotScene.h" //--> #include "ogre.h" //<-- using namespace std; using namespace Ogre; static Light* LoadLight( TiXmlElement *XMLLight, SceneManager *mSceneMgr ) { TiXmlElement *XMLDiffuse, *XMLSpecular, *XMLAttentuation, *XMLPosition; // Create a light (point | directional | spot | radPoint) Light* l = mSceneMgr->createLight( XMLLight->Attribute("name") ); if( !XMLLight->Attribute("type") || String(XMLLight->Attribute("type")) == "point" ) l->setType( Light::LT_POINT ); else if( String(XMLLight->Attribute("type")) == "directional") l->setType( Light::LT_DIRECTIONAL ); else if( String(XMLLight->Attribute("type")) == "spot") l->setType( Light::LT_SPOTLIGHT ); else if( String(XMLLight->Attribute("type")) == "radPoint") l->setType( Light::LT_POINT ); XMLDiffuse = XMLLight->FirstChildElement("colourDiffuse"); if( XMLDiffuse ){ ColourValue Diffuse; Diffuse.r = Ogre::StringConverter::parseReal( XMLDiffuse->Attribute("r") ); Diffuse.g = Ogre::StringConverter::parseReal( XMLDiffuse->Attribute("g") ); Diffuse.b = Ogre::StringConverter::parseReal( XMLDiffuse->Attribute("b") ); Diffuse.a = 1; l->setDiffuseColour(Diffuse); } XMLSpecular = XMLLight->FirstChildElement("colourSpecular"); if( XMLSpecular ){ ColourValue Specular; Specular.r = Ogre::StringConverter::parseReal( XMLSpecular->Attribute("r") ); Specular.g = Ogre::StringConverter::parseReal( XMLSpecular->Attribute("g") ); Specular.b = Ogre::StringConverter::parseReal( XMLSpecular->Attribute("b") ); Specular.a = 1; l->setSpecularColour(Specular); } XMLAttentuation = XMLLight->FirstChildElement("lightAttenuation"); if( XMLAttentuation ) { //get defaults incase not all values specified Real range, constant, linear, quadratic; range = l->getAttenuationRange(); constant = l->getAttenuationConstant(); linear = l->getAttenuationLinear(); quadratic = l->getAttenuationQuadric(); if( XMLAttentuation->Attribute("range") ) range = StringConverter::parseReal( XMLAttentuation->Attribute("range") ); if( XMLAttentuation->Attribute("constant") ) constant = StringConverter::parseReal( XMLAttentuation->Attribute("constant") ); if( XMLAttentuation->Attribute("linear") ) linear = StringConverter::parseReal( XMLAttentuation->Attribute("linear") ); if( XMLAttentuation->Attribute("quadratic") ) quadratic = StringConverter::parseReal( XMLAttentuation->Attribute("quadratic") ); l->setAttenuation( range, constant, linear, quadratic ); } XMLPosition = XMLLight->FirstChildElement("position"); if( XMLPosition ) { Vector3 p = Vector3(0,0,0); if( XMLPosition->Attribute("x") ) p.x = StringConverter::parseReal( XMLPosition->Attribute("x") ); if( XMLPosition->Attribute("y") ) p.y = StringConverter::parseReal( XMLPosition->Attribute("y") ); if( XMLPosition->Attribute("z") ) p.z = StringConverter::parseReal( XMLPosition->Attribute("z") ); l->setPosition( p ); } //castShadows (true | false) "true" l->setCastShadows( true ); if( XMLLight->Attribute("castShadows") ) if( String(XMLLight->Attribute("castShadows")) == "false" ) l->setCastShadows( false ); //visible (true | false) "true" l->setVisible( true ); if( XMLLight->Attribute("visible") ) if( String(XMLLight->Attribute("visible")) == "false" ) l->setVisible( false ); return l; } void CDotScene::parseDotScene( const String &SceneName, const String& groupName, SceneManager *yourSceneMgr, SceneNode *pAttachNode, String sPrependNode) { // set up shared object values m_sPrependNode = sPrependNode; mSceneMgr = yourSceneMgr; TiXmlDocument *XMLDoc; TiXmlElement *XMLRoot, *XMLNodes; try { DataStreamPtr pStream = ResourceGroupManager::getSingleton(). openResource( SceneName, groupName ); String data = pStream->getAsString(); // Open the .scene File XMLDoc = new TiXmlDocument(); XMLDoc->Parse( data.c_str() ); pStream->close(); pStream.setNull(); if( XMLDoc->Error() ) { //We'll just log, and continue on gracefully LogManager::getSingleton().logMessage("[dotSceneLoader] The TiXmlDocument reported an error"); delete XMLDoc; return; } } catch(...) { //We'll just log, and continue on gracefully LogManager::getSingleton().logMessage("[dotSceneLoader] Error creating TiXmlDocument"); delete XMLDoc; return; } // Validate the File XMLRoot = XMLDoc->RootElement(); if( String( XMLRoot->Value()) != "scene" ) { LogManager::getSingleton().logMessage( "[dotSceneLoader]Error: Invalid .scene File. Missing <scene>" ); delete XMLDoc; return; } // figure out where to attach any nodes we create if(pAttachNode == NULL) { pAttachNode = mSceneMgr->getRootSceneNode(); } XMLNodes = XMLRoot->FirstChildElement( "nodes" ); // Read in the scene nodes if( XMLNodes ) { processNode(XMLNodes->FirstChildElement( "node" ), pAttachNode); } // Close the XML File delete XMLDoc; } void CDotScene::processNode(TiXmlElement *XMLNode, SceneNode *pAttach) { TiXmlElement *XMLPosition, *XMLRotation, *XMLScale, *XMLEntity, *XMLSubEntity, *XMLBillboardSet, *XMLLight, *XMLUserData; while( XMLNode ) { // Process the current node // Grab the name of the node String NodeName = XMLNode->Attribute("name"); // First create the new scene node SceneNode* NewNode = pAttach->createChildSceneNode( m_sPrependNode + NodeName ); Vector3 TempVec; String TempValue; // Now position it... XMLPosition = XMLNode->FirstChildElement("position"); if( XMLPosition ){ TempValue = XMLPosition->Attribute("x"); TempVec.x = StringConverter::parseReal(TempValue); TempValue = XMLPosition->Attribute("y"); TempVec.y = StringConverter::parseReal(TempValue); TempValue = XMLPosition->Attribute("z"); TempVec.z = StringConverter::parseReal(TempValue); NewNode->setPosition( TempVec ); } // Rotate it... XMLRotation = XMLNode->FirstChildElement("rotation"); if( XMLRotation ){ Quaternion TempQuat; TempValue = XMLRotation->Attribute("qx"); TempQuat.x = StringConverter::parseReal(TempValue); TempValue = XMLRotation->Attribute("qy"); TempQuat.y = StringConverter::parseReal(TempValue); TempValue = XMLRotation->Attribute("qz"); TempQuat.z = StringConverter::parseReal(TempValue); TempValue = XMLRotation->Attribute("qw"); TempQuat.w = StringConverter::parseReal(TempValue); NewNode->setOrientation( TempQuat ); } // Scale it. XMLScale = XMLNode->FirstChildElement("scale"); if( XMLScale ){ TempValue = XMLScale->Attribute("x"); TempVec.x = StringConverter::parseReal(TempValue); TempValue = XMLScale->Attribute("y"); TempVec.y = StringConverter::parseReal(TempValue); TempValue = XMLScale->Attribute("z"); TempVec.z = StringConverter::parseReal(TempValue); NewNode->setScale( TempVec ); } XMLLight = XMLNode->FirstChildElement( "light" ); if( XMLLight ) NewNode->attachObject( LoadLight( XMLLight, mSceneMgr ) ); // Check for an Entity XMLEntity = XMLNode->FirstChildElement("entity"); if( XMLEntity ) { String EntityName, EntityMeshFilename; EntityName = XMLEntity->Attribute( "name" ); EntityMeshFilename = XMLEntity->Attribute( "meshFile" ); // Create entity Entity* NewEntity = mSceneMgr->createEntity(EntityName, EntityMeshFilename); //castShadows (true | false) "true" NewEntity->setCastShadows( true ); if( XMLEntity->Attribute("castShadows") ) if( String(XMLEntity->Attribute("castShadows")) == "false" ) NewEntity->setCastShadows( false ); // Go though sub entities XMLSubEntity = XMLEntity->FirstChildElement( "subentities" ); if( XMLSubEntity ) { XMLSubEntity = XMLSubEntity->FirstChildElement( "subentity" ); while( XMLSubEntity ) { Ogre::SubEntity* subEntity; uint subEntityIndex; subEntityIndex = Ogre::StringConverter::parseInt( XMLSubEntity->Attribute( "index" ) ); subEntity = NewEntity->getSubEntity( subEntityIndex ); if( XMLSubEntity->Attribute( "materialName" ) ) subEntity->setMaterialName( XMLSubEntity->Attribute( "materialName" ) ); XMLSubEntity= XMLSubEntity->NextSiblingElement( "subentity" ); } } NewNode->attachObject( NewEntity ); } XMLBillboardSet = XMLNode->FirstChildElement( "billboardSet" ); if( XMLBillboardSet ) { String TempValue; BillboardSet* bSet = mSceneMgr->createBillboardSet( NewNode->getName() ); BillboardType Type; TempValue = XMLBillboardSet->Attribute( "type" ); if( TempValue == "orientedCommon" ) Type = BBT_ORIENTED_COMMON; else if( TempValue == "orientedSelf" ) Type = BBT_ORIENTED_SELF; else Type = BBT_POINT; BillboardOrigin Origin; TempValue = XMLBillboardSet->Attribute( "type" ); if( TempValue == "bottom_left" ) Origin = BBO_BOTTOM_LEFT; else if( TempValue == "bottom_center" ) Origin = BBO_BOTTOM_CENTER; else if( TempValue == "bottomRight" ) Origin = BBO_BOTTOM_RIGHT; else if( TempValue == "left" ) Origin = BBO_CENTER_LEFT; else if( TempValue == "right" ) Origin = BBO_CENTER_RIGHT; else if( TempValue == "topLeft" ) Origin = BBO_TOP_LEFT; else if( TempValue == "topCenter" ) Origin = BBO_TOP_CENTER; else if( TempValue == "topRight" ) Origin = BBO_TOP_RIGHT; else Origin = BBO_CENTER; bSet->setBillboardType( Type ); bSet->setBillboardOrigin( Origin ); TempValue = XMLBillboardSet->Attribute( "name" ); bSet->setMaterialName( TempValue ); int width, height; width = (int) StringConverter::parseReal( XMLBillboardSet->Attribute( "width" ) ); height = (int) StringConverter::parseReal( XMLBillboardSet->Attribute( "height" ) ); bSet->setDefaultDimensions( width, height ); bSet->setVisible( true ); NewNode->attachObject( bSet ); TiXmlElement *XMLBillboard; XMLBillboard = XMLBillboardSet->FirstChildElement( "billboard" ); while( XMLBillboard ) { Billboard *b; // TempValue; TempVec = Vector3( 0, 0, 0 ); ColourValue TempColour(1,1,1,1); XMLPosition = XMLBillboard->FirstChildElement( "position" ); if( XMLPosition ){ TempValue = XMLPosition->Attribute("x"); TempVec.x = StringConverter::parseReal(TempValue); TempValue = XMLPosition->Attribute("y"); TempVec.y = StringConverter::parseReal(TempValue); TempValue = XMLPosition->Attribute("z"); TempVec.z = StringConverter::parseReal(TempValue); } TiXmlElement* XMLColour = XMLBillboard->FirstChildElement( "colourDiffuse" ); if( XMLColour ){ TempValue = XMLColour->Attribute("r"); TempColour.r = StringConverter::parseReal(TempValue); TempValue = XMLColour->Attribute("g"); TempColour.g = StringConverter::parseReal(TempValue); TempValue = XMLColour->Attribute("b"); TempColour.b = StringConverter::parseReal(TempValue); } b = bSet->createBillboard( TempVec, TempColour); XMLBillboard = XMLBillboard->NextSiblingElement( "billboard" ); } } XMLUserData = XMLNode->FirstChildElement( "userData" ); if ( XMLUserData ) { TiXmlElement *XMLProperty; XMLProperty = XMLUserData->FirstChildElement("property"); while ( XMLProperty ) { String first = NewNode->getName(); String second = XMLProperty->Attribute("name"); String third = XMLProperty->Attribute("data"); String type = XMLProperty->Attribute("type"); nodeProperty newProp(first,second,third,type); nodeProperties.push_back(newProp); XMLProperty = XMLProperty->NextSiblingElement("property"); } } //--> /* /* Added by @lpha_Max ! :-) * "Global" vars : * NewNode --> Node where attach the object... * mSceneMgr --> SceneManager */ TiXmlElement* XMLCamera = XMLNode->FirstChildElement( "camera" ); if ( XMLCamera ) { String CameraName = XMLCamera->Attribute( "name" ); Camera *cam = mSceneMgr->createCamera(CameraName); NewNode->attachObject(cam); } TiXmlElement* XMLParticle = XMLNode->FirstChildElement( "particleSystem" ); if ( XMLParticle ) { String ParticleName = XMLParticle->Attribute( "name" ); String ParticleFile = XMLParticle->Attribute( "file" ); ParticleSystem* ParticleS = mSceneMgr->createParticleSystem(ParticleName, ParticleFile); NewNode->attachObject(ParticleS); } //<-- TiXmlElement * ChildXMLNode; ChildXMLNode = XMLNode->FirstChildElement( "node" ); if(ChildXMLNode) processNode(ChildXMLNode, NewNode); // recurse to do all my children XMLNode = XMLNode->NextSiblingElement( "node" ); // process my next sibling } } String CDotScene::getProperty(String ndNm, String prop) { for ( unsigned int i = 0 ; i < nodeProperties.size(); i++ ) { if ( nodeProperties[i].nodeName == ndNm && nodeProperties[i].propertyNm == prop ) { return nodeProperties[i].valueName; } } return " "; }
Originally written by nikki, modified by madmark (and a very little bit contribution of alphamax ^^).