multiple SceneManagers e.g to use with multiple viewports.
Also a scene node factory works fine in a single SceneManager design,
there's a problem using more than one SceneManager,
as each newly created SceneManager by
ISceneManager::createNewSceneManager(bool cloneContent=false)
is not aware of the factory.
Also there is a workaround to the problem
creating two instances of the factory and pass to each SceneManager
a pointer to it's own factory:
ISceneNodeFactory*
Factory1 = new CSceneNodeFactory(device->getSceneManager());
device->getSceneManager()->registerSceneNodeFactory(Factory1);
Factory1->drop();
ISceneNodeFactory*
Factory2 = new CSceneNodeFactory(device->getSceneManager());
device->getSceneManager()->createNewSceneManager()->registerSceneNodeFactory(Factory2);
Factory2->drop();
There is the drawback that it would waste double memory
for the second factory.
The other approch creating only one instance of the factory for
both SceneManagers
Code: Select all
ISceneNodeFactory*
Factory = new CSceneNodeFactory(); //will not compile
device->getSceneManager()->registerSceneNodeFactory(Factory);
device->getSceneManager()->createNewSceneManager()->registerSceneNodeFactory(Factory);
Factory->drop();
The reason is, that the factory stores a fixed pointer to
it's hosting SceneManager, as it's passed by the constructor.
However, for managing a SceneNodeFactory with multiple
SceneManagers I made following minimal invasive changes to the engine:
ISceneNodeFactory.h
Code: Select all
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __I_SCENE_NODE_FACTORY_H_INCLUDED__
#define __I_SCENE_NODE_FACTORY_H_INCLUDED__
#include "IReferenceCounted.h"
#include "ESceneNodeTypes.h"
namespace irr
{
namespace scene
{
class ISceneNode;
// ADDED: forward declarations
class ISceneManager; // ADDED
class CSceneManager; // ADDED
class ISceneNodeFactory : public virtual IReferenceCounted
{
// ADDED: let the scene manager class have access to the protected method.
friend CSceneManager;
public:
virtual ~ISceneNodeFactory() {}
virtual ISceneNode* addSceneNode(ESCENE_NODE_TYPE type, ISceneNode* parent=0) = 0;
virtual ISceneNode* addSceneNode(const c8* typeName, ISceneNode* parent=0) = 0;
virtual u32 getCreatableSceneNodeTypeCount() const = 0;
virtual ESCENE_NODE_TYPE getCreateableSceneNodeType(u32 idx) const = 0;
virtual const c8* getCreateableSceneNodeTypeName(u32 idx) const = 0;
virtual const c8* getCreateableSceneNodeTypeName(ESCENE_NODE_TYPE type) const = 0;
protected:
//! ADDED: let the scene manager class store it's pointer.
virtual void setSceneManager(ISceneManager* mgr) = 0;
};
} // end namespace scene
} // end namespace irr
#endif
to change this class too:
CDefaultSceneNodeFactory.h
Code: Select all
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_DEFAULT_SCENE_NODE_FACTORY_H_INCLUDED__
#define __C_DEFAULT_SCENE_NODE_FACTORY_H_INCLUDED__
#include "ISceneNodeFactory.h"
#include "irrArray.h"
#include "irrString.h"
namespace irr
{
namespace scene
{
class ISceneNode;
// DELETED: forward declaration is included now already thru the interface
// class ISceneManager;
class CDefaultSceneNodeFactory : public ISceneNodeFactory
{
public:
// ADDED: new constructor taking void
CDefaultSceneNodeFactory(void);
// DELETED: old ctor taking pointer of the scene manager
//CDefaultSceneNodeFactory(ISceneManager* mgr);
virtual ISceneNode* addSceneNode(ESCENE_NODE_TYPE type, ISceneNode* parent=0);
virtual ISceneNode* addSceneNode(const c8* typeName, ISceneNode* parent=0);
virtual u32 getCreatableSceneNodeTypeCount() const;
virtual const c8* getCreateableSceneNodeTypeName(u32 idx) const;
virtual ESCENE_NODE_TYPE getCreateableSceneNodeType(u32 idx) const;
virtual const c8* getCreateableSceneNodeTypeName(ESCENE_NODE_TYPE type) const;
protected:
//! ADDED: implementation of interface method.
virtual void setSceneManager(ISceneManager* mgr);
private:
ESCENE_NODE_TYPE getTypeFromName(const c8* name) const;
struct SSceneNodeTypePair
{
SSceneNodeTypePair(ESCENE_NODE_TYPE type, const c8* name)
: Type(type), TypeName(name)
{}
ESCENE_NODE_TYPE Type;
core::stringc TypeName;
};
core::array<SSceneNodeTypePair> SupportedSceneNodeTypes;
ISceneManager* Manager;
};
} // end namespace scene
} // end namespace irr
#endif
CDefaultSceneNodeFactory.cpp
Code: Select all
// ADDED: new constructor taking void replaces old one
CDefaultSceneNodeFactory::CDefaultSceneNodeFactory(void)
{
// don't grab the scene manager here to prevent cyclic references
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_CUBE, "cube"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_SPHERE, "sphere"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_TEXT, "text"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_WATER_SURFACE, "waterSurface"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_TERRAIN, "terrain"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_SKY_BOX, "skyBox"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_SHADOW_VOLUME, "shadowVolume"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_OCT_TREE, "octTree"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_MESH, "mesh"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_LIGHT, "light"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_EMPTY, "empty"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_DUMMY_TRANSFORMATION, "dummyTransformation"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_CAMERA, "camera"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_CAMERA_MAYA, "cameraMaya"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_CAMERA_FPS, "cameraFPS"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_BILLBOARD, "billBoard"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_ANIMATED_MESH, "animatedMesh"));
SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_PARTICLE_SYSTEM, "particleSystem"));
// SupportedSceneNodeTypes.push_back(SSceneNodeTypePair(ESNT_MD3_SCENE_NODE, "md3"));
}
// ADDED: implementation of interface method
void CDefaultSceneNodeFactory::setSceneManager(ISceneManager* mgr)
{
Manager = mgr;
};
that is responsible for managing the factory.
CSceneManager.cpp
Code: Select all
//! constructor
CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
gui::ICursorControl* cursorControl, IMeshCache* cache,
gui::IGUIEnvironment* gui)
: ISceneNode(0, 0), Driver(driver), FileSystem(fs), GUIEnvironment(gui),
CursorControl(cursorControl), CollisionManager(0), MeshManipulator(0),
ActiveCamera(0), ShadowColor(150,0,0,0), AmbientLight(0,0,0,0),
MeshCache(cache), CurrentRendertime(ESNRP_COUNT),
IRR_XML_FORMAT_SCENE(L"irr_scene"), IRR_XML_FORMAT_NODE(L"node"), IRR_XML_FORMAT_NODE_ATTR_TYPE(L"type")
{
...
// code omitted
...
// factories
ISceneNodeFactory*
factory = new CDefaultSceneNodeFactory();
//ADDED: Dont' forget the default scene Manager via new interface method
factory->setSceneManager(this);
registerSceneNodeFactory(factory);
factory->drop();
ISceneNodeAnimatorFactory* animatorFactory = new CDefaultSceneNodeAnimatorFactory(this);
registerSceneNodeAnimatorFactory(animatorFactory);
animatorFactory->drop();
}
//! Returns a scene node factory by index
ISceneNodeFactory* CSceneManager::getSceneNodeFactory(u32 index)
{
if (index<SceneNodeFactoryList.size())
{
ISceneNodeFactory*
factory = SceneNodeFactoryList[index];
factory->setSceneManager(this); //ADDED: store the pointer here when it's needed
return factory;
}
return 0;
}
The shown code provides multiple SceneManager support for a custom SceneNodeFactory.
The code examle in the upper section will compile now, as the constructor of the factory
will not take any argument. It is no more necessary to create more
than one instance of a custom SceneNodeFactory.
References
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=25654
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=23514
http://irrlicht.sourceforge.net/phpBB2/ ... enemanager