DotScene Loader with User Data Class
From Ogre Wiki
Updated DotScene loader code (with user properties)
The following is based on the code found in the page DotScene Loader with User Data. It can be found below for cut and paste or you can download this zip file(Please note that the code in the ZIP might be out of date and not resemble the code you see here in the wiki).
Here is the modification (by Alphamax) for adding support of camera and particle system : --> XXX <-- You can add easily more stuff
TWO: Added support for subentities (used by the OgreMax exporter to define materials)
Header File (DotScene.h)
/*------------------------------------------------------------------------------
* 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)
/*------------------------------------------------------------------------------
* 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 ^^).

