#include "IFileSystem.h"\r
#include "SAnimatedMesh.h"\r
#include "CMeshCache.h"\r
-#include "ISceneUserDataSerializer.h"\r
#include "IGUIEnvironment.h"\r
#include "IMaterialRenderer.h"\r
#include "IReadFile.h"\r
#include "IWriteFile.h"\r
-#include "ISceneLoader.h"\r
-#include "EProfileIDs.h"\r
-#include "IProfiler.h"\r
\r
#include "os.h"\r
\r
-// We need this include for the case of skinned mesh support without\r
-// any such loader\r
-#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_\r
#include "CSkinnedMesh.h"\r
-#endif\r
-\r
-#ifdef _IRR_COMPILE_WITH_X_LOADER_\r
#include "CXMeshFileLoader.h"\r
-#endif\r
-\r
-#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_\r
#include "COBJMeshFileLoader.h"\r
-#endif\r
-\r
-#ifdef _IRR_COMPILE_WITH_B3D_LOADER_\r
#include "CB3DMeshFileLoader.h"\r
-#endif\r
-\r
-#ifdef _IRR_COMPILE_WITH_BILLBOARD_SCENENODE_\r
#include "CBillboardSceneNode.h"\r
-#endif // _IRR_COMPILE_WITH_BILLBOARD_SCENENODE_\r
#include "CAnimatedMeshSceneNode.h"\r
#include "CCameraSceneNode.h"\r
#include "CMeshSceneNode.h"\r
#include "CDummyTransformationSceneNode.h"\r
#include "CEmptySceneNode.h"\r
\r
-#include "CDefaultSceneNodeFactory.h"\r
-\r
#include "CSceneCollisionManager.h"\r
\r
-#include <locale.h>\r
-\r
namespace irr\r
{\r
namespace scene\r
\r
// set scene parameters\r
Parameters = new io::CAttributes();\r
- Parameters->setAttribute(DEBUG_NORMAL_LENGTH, 1.f);\r
- Parameters->setAttribute(DEBUG_NORMAL_COLOR, video::SColor(255, 34, 221, 221));\r
\r
// create collision manager\r
CollisionManager = new CSceneCollisionManager(this, Driver);\r
// TODO: now that we have multiple scene managers, these should be\r
// shallow copies from the previous manager if there is one.\r
\r
- #ifdef _IRR_COMPILE_WITH_X_LOADER_\r
MeshLoaderList.push_back(new CXMeshFileLoader(this, FileSystem));\r
- #endif\r
- #ifdef _IRR_COMPILE_WITH_OBJ_LOADER_\r
MeshLoaderList.push_back(new COBJMeshFileLoader(this, FileSystem));\r
- #endif\r
- #ifdef _IRR_COMPILE_WITH_B3D_LOADER_\r
MeshLoaderList.push_back(new CB3DMeshFileLoader(this));\r
- #endif\r
-\r
- // factories\r
- ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this);\r
- registerSceneNodeFactory(factory);\r
- factory->drop();\r
-\r
- IRR_PROFILE(\r
- static bool initProfile = false;\r
- if (!initProfile )\r
- {\r
- initProfile = true;\r
- getProfiler().add(EPID_SM_DRAW_ALL, L"drawAll", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_ANIMATE, L"animate", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_CAMERAS, L"cameras", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_LIGHTS, L"lights", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_SKYBOXES, L"skyboxes", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_DEFAULT, L"defaultnodes", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_SHADOWS, L"shadows", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_TRANSPARENT, L"transp.nodes", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_EFFECT, L"effectnodes", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_RENDER_GUI_NODES, L"guinodes", L"Irrlicht scene");\r
- getProfiler().add(EPID_SM_REGISTER, L"reg.render.node", L"Irrlicht scene");\r
- }\r
- )\r
}\r
\r
\r
for (i=0; i<MeshLoaderList.size(); ++i)\r
MeshLoaderList[i]->drop();\r
\r
- for (i=0; i<SceneLoaderList.size(); ++i)\r
- SceneLoaderList[i]->drop();\r
-\r
if (ActiveCamera)\r
ActiveCamera->drop();\r
ActiveCamera = 0;\r
if (Parameters)\r
Parameters->drop();\r
\r
- for (i=0; i<SceneNodeFactoryList.size(); ++i)\r
- SceneNodeFactoryList[i]->drop();\r
-\r
// remove all nodes before dropping the driver\r
// as render targets may be destroyed twice\r
\r
video::SColor colorTop, video::SColor colorBottom\r
)\r
{\r
-#ifdef _IRR_COMPILE_WITH_BILLBOARD_SCENENODE_\r
if (!parent)\r
parent = this;\r
\r
node->drop();\r
\r
return node;\r
-#else\r
- return 0;\r
-#endif\r
}\r
\r
\r
//! registers a node for rendering it at a specific time.\r
u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDER_PASS pass)\r
{\r
- IRR_PROFILE(CProfileScope p1(EPID_SM_REGISTER);)\r
u32 taken = 0;\r
\r
switch(pass)\r
taken = 1;\r
}\r
\r
+ // as of yet unused\r
+ case ESNRP_LIGHT:\r
+ case ESNRP_SHADOW:\r
case ESNRP_NONE: // ignore this one\r
break;\r
}\r
\r
-#ifdef _IRR_SCENEMANAGER_DEBUG\r
- s32 index = Parameters->findAttribute("calls");\r
- Parameters->setAttribute(index, Parameters->getAttributeAsInt(index)+1);\r
-\r
- if (!taken)\r
- {\r
- index = Parameters->findAttribute("culled");\r
- Parameters->setAttribute(index, Parameters->getAttributeAsInt(index)+1);\r
- }\r
-#endif\r
-\r
return taken;\r
}\r
\r
//! draws all scene nodes\r
void CSceneManager::drawAll()\r
{\r
- IRR_PROFILE(CProfileScope psAll(EPID_SM_DRAW_ALL);)\r
-\r
if (!Driver)\r
return;\r
\r
-#ifdef _IRR_SCENEMANAGER_DEBUG\r
- // reset attributes\r
- Parameters->setAttribute("culled", 0);\r
- Parameters->setAttribute("calls", 0);\r
- Parameters->setAttribute("drawn_solid", 0);\r
- Parameters->setAttribute("drawn_transparent", 0);\r
- Parameters->setAttribute("drawn_transparent_effect", 0);\r
-#endif\r
-\r
u32 i; // new ISO for scoping problem in some compilers\r
\r
// reset all transforms\r
Driver->setAllowZWriteOnTransparent(Parameters->getAttributeAsBool(ALLOW_ZWRITE_ON_TRANSPARENT));\r
\r
// do animations and other stuff.\r
- IRR_PROFILE(getProfiler().start(EPID_SM_ANIMATE));\r
OnAnimate(os::Timer::getTime());\r
- IRR_PROFILE(getProfiler().stop(EPID_SM_ANIMATE));\r
\r
/*!\r
First Scene Node for prerendering should be the active camera\r
consistent Camera is needed for culling\r
*/\r
- IRR_PROFILE(getProfiler().start(EPID_SM_RENDER_CAMERAS));\r
camWorldPos.set(0,0,0);\r
if (ActiveCamera)\r
{\r
ActiveCamera->render();\r
camWorldPos = ActiveCamera->getAbsolutePosition();\r
}\r
- IRR_PROFILE(getProfiler().stop(EPID_SM_RENDER_CAMERAS));\r
\r
// let all nodes register themselves\r
OnRegisterSceneNode();\r
\r
//render camera scenes\r
{\r
- IRR_PROFILE(CProfileScope psCam(EPID_SM_RENDER_CAMERAS);)\r
CurrentRenderPass = ESNRP_CAMERA;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
\r
CameraList.set_used(0);\r
}\r
- \r
+\r
// render skyboxes\r
{\r
- IRR_PROFILE(CProfileScope psSkyBox(EPID_SM_RENDER_SKYBOXES);)\r
CurrentRenderPass = ESNRP_SKY_BOX;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
\r
SkyBoxList.set_used(0);\r
}\r
- \r
+\r
// render default objects\r
{\r
- IRR_PROFILE(CProfileScope psDefault(EPID_SM_RENDER_DEFAULT);)\r
CurrentRenderPass = ESNRP_SOLID;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
for (i=0; i<SolidNodeList.size(); ++i)\r
SolidNodeList[i].Node->render();\r
\r
-#ifdef _IRR_SCENEMANAGER_DEBUG\r
- Parameters->setAttribute("drawn_solid", (s32) SolidNodeList.size() );\r
-#endif\r
SolidNodeList.set_used(0);\r
}\r
\r
// render transparent objects.\r
{\r
- IRR_PROFILE(CProfileScope psTrans(EPID_SM_RENDER_TRANSPARENT);)\r
CurrentRenderPass = ESNRP_TRANSPARENT;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
for (i=0; i<TransparentNodeList.size(); ++i)\r
TransparentNodeList[i].Node->render();\r
\r
-#ifdef _IRR_SCENEMANAGER_DEBUG\r
- Parameters->setAttribute ( "drawn_transparent", (s32) TransparentNodeList.size() );\r
-#endif\r
TransparentNodeList.set_used(0);\r
}\r
\r
// render transparent effect objects.\r
{\r
- IRR_PROFILE(CProfileScope psEffect(EPID_SM_RENDER_EFFECT);)\r
CurrentRenderPass = ESNRP_TRANSPARENT_EFFECT;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
\r
for (i=0; i<TransparentEffectNodeList.size(); ++i)\r
TransparentEffectNodeList[i].Node->render();\r
-#ifdef _IRR_SCENEMANAGER_DEBUG\r
- Parameters->setAttribute("drawn_transparent_effect", (s32) TransparentEffectNodeList.size());\r
-#endif\r
+\r
TransparentEffectNodeList.set_used(0);\r
}\r
\r
// render custom gui nodes\r
{\r
- IRR_PROFILE(CProfileScope psEffect(EPID_SM_RENDER_GUI_NODES);)\r
CurrentRenderPass = ESNRP_GUI;\r
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRenderPass) != 0);\r
\r
for (i=0; i<GuiNodeList.size(); ++i)\r
GuiNodeList[i]->render();\r
-#ifdef _IRR_SCENEMANAGER_DEBUG\r
- Parameters->setAttribute("drawn_gui_nodes", (s32) GuiNodeList.size());\r
-#endif\r
+\r
GuiNodeList.set_used(0);\r
}\r
clearDeletionList();\r
}\r
\r
\r
-//! Adds an external scene loader.\r
-void CSceneManager::addExternalSceneLoader(ISceneLoader* externalLoader)\r
-{\r
- if (!externalLoader)\r
- return;\r
-\r
- externalLoader->grab();\r
- SceneLoaderList.push_back(externalLoader);\r
-}\r
-\r
-\r
-//! Returns the number of scene loaders\r
-u32 CSceneManager::getSceneLoaderCount() const\r
-{\r
- return SceneLoaderList.size();\r
-}\r
-\r
-\r
-//! Retrieve the given scene loader\r
-ISceneLoader* CSceneManager::getSceneLoader(u32 index) const\r
-{\r
- if (index < SceneLoaderList.size())\r
- return SceneLoaderList[index];\r
- else\r
- return 0;\r
-}\r
-\r
//! Returns a pointer to the scene collision manager.\r
ISceneCollisionManager* CSceneManager::getSceneCollisionManager()\r
{\r
ISceneNode* node = 0;\r
\r
const ISceneNodeList& list = start->getChildren();\r
- ISceneNodeList::ConstIterator it = list.begin();\r
+ ISceneNodeList::const_iterator it = list.begin();\r
for (; it!=list.end(); ++it)\r
{\r
node = getSceneNodeFromName(name, *it);\r
ISceneNode* node = 0;\r
\r
const ISceneNodeList& list = start->getChildren();\r
- ISceneNodeList::ConstIterator it = list.begin();\r
+ ISceneNodeList::const_iterator it = list.begin();\r
for (; it!=list.end(); ++it)\r
{\r
node = getSceneNodeFromId(id, *it);\r
ISceneNode* node = 0;\r
\r
const ISceneNodeList& list = start->getChildren();\r
- ISceneNodeList::ConstIterator it = list.begin();\r
+ ISceneNodeList::const_iterator it = list.begin();\r
for (; it!=list.end(); ++it)\r
{\r
node = getSceneNodeFromType(type, *it);\r
outNodes.push_back(start);\r
\r
const ISceneNodeList& list = start->getChildren();\r
- ISceneNodeList::ConstIterator it = list.begin();\r
+ ISceneNodeList::const_iterator it = list.begin();\r
\r
for (; it!=list.end(); ++it)\r
{\r
}\r
\r
\r
-//! Returns the default scene node factory which can create all built in scene nodes\r
-ISceneNodeFactory* CSceneManager::getDefaultSceneNodeFactory()\r
-{\r
- return getSceneNodeFactory(0);\r
-}\r
-\r
-\r
-//! Adds a scene node factory to the scene manager.\r
-void CSceneManager::registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd)\r
-{\r
- if (factoryToAdd)\r
- {\r
- factoryToAdd->grab();\r
- SceneNodeFactoryList.push_back(factoryToAdd);\r
- }\r
-}\r
-\r
-\r
-//! Returns amount of registered scene node factories.\r
-u32 CSceneManager::getRegisteredSceneNodeFactoryCount() const\r
-{\r
- return SceneNodeFactoryList.size();\r
-}\r
-\r
-\r
-//! Returns a scene node factory by index\r
-ISceneNodeFactory* CSceneManager::getSceneNodeFactory(u32 index)\r
-{\r
- if (index < SceneNodeFactoryList.size())\r
- return SceneNodeFactoryList[index];\r
-\r
- return 0;\r
-}\r
-\r
-//! Saves the current scene into a file.\r
-//! \param filename: Name of the file .\r
-bool CSceneManager::saveScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer, ISceneNode* node)\r
-{\r
- bool ret = false;\r
- io::IWriteFile* file = FileSystem->createAndWriteFile(filename);\r
- if (file)\r
- {\r
- ret = saveScene(file, userDataSerializer, node);\r
- file->drop();\r
- }\r
- else\r
- os::Printer::log("Unable to open file", filename, ELL_ERROR);\r
-\r
- return ret;\r
-}\r
-\r
-\r
-//! Saves the current scene into a file.\r
-bool CSceneManager::saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer, ISceneNode* node)\r
-{\r
- return false;\r
-}\r
-\r
-\r
-//! Loads a scene.\r
-bool CSceneManager::loadScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer, ISceneNode* rootNode)\r
-{\r
- io::IReadFile* file = FileSystem->createAndOpenFile(filename);\r
- if (!file)\r
- {\r
- os::Printer::log("Unable to open scene file", filename.c_str(), ELL_ERROR);\r
- return false;\r
- }\r
-\r
- const bool ret = loadScene(file, userDataSerializer, rootNode);\r
- file->drop();\r
-\r
- return ret;\r
-}\r
-\r
-\r
-//! Loads a scene. Note that the current scene is not cleared before.\r
-bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer, ISceneNode* rootNode)\r
-{\r
- if (!file)\r
- {\r
- os::Printer::log("Unable to open scene file", ELL_ERROR);\r
- return false;\r
- }\r
-\r
- bool ret = false;\r
-\r
- // try scene loaders in reverse order\r
- s32 i = SceneLoaderList.size()-1;\r
- for (; i >= 0 && !ret; --i)\r
- if (SceneLoaderList[i]->isALoadableFileFormat(file))\r
- ret = SceneLoaderList[i]->loadScene(file, userDataSerializer, rootNode);\r
-\r
- if (!ret)\r
- os::Printer::log("Could not load scene file, perhaps the format is unsupported: ", file->getFileName().c_str(), ELL_ERROR);\r
-\r
- return ret;\r
-}\r
-\r
-\r
-//! Returns a typename from a scene node type or null if not found\r
-const c8* CSceneManager::getSceneNodeTypeName(ESCENE_NODE_TYPE type)\r
-{\r
- const char* name = 0;\r
-\r
- for (s32 i=(s32)SceneNodeFactoryList.size()-1; !name && i>=0; --i)\r
- name = SceneNodeFactoryList[i]->getCreateableSceneNodeTypeName(type);\r
-\r
- return name;\r
-}\r
-\r
-//! Adds a scene node to the scene by name\r
-ISceneNode* CSceneManager::addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent)\r
-{\r
- ISceneNode* node = 0;\r
-\r
- for (s32 i=(s32)SceneNodeFactoryList.size()-1; i>=0 && !node; --i)\r
- node = SceneNodeFactoryList[i]->addSceneNode(sceneNodeTypeName, parent);\r
-\r
- return node;\r
-}\r
-\r
-//! Writes attributes of the scene node.\r
-void CSceneManager::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const\r
-{\r
- out->addString ("Name", Name.c_str());\r
- out->addInt ("Id", ID );\r
- out->addColorf ("AmbientLight", AmbientLight);\r
-\r
- // fog attributes from video driver\r
- video::SColor color;\r
- video::E_FOG_TYPE fogType;\r
- f32 start, end, density;\r
- bool pixelFog, rangeFog;\r
-\r
- Driver->getFog(color, fogType, start, end, density, pixelFog, rangeFog);\r
-\r
- out->addEnum("FogType", fogType, video::FogTypeNames);\r
- out->addColorf("FogColor", color);\r
- out->addFloat("FogStart", start);\r
- out->addFloat("FogEnd", end);\r
- out->addFloat("FogDensity", density);\r
- out->addBool("FogPixel", pixelFog);\r
- out->addBool("FogRange", rangeFog);\r
-}\r
-\r
-//! Reads attributes of the scene node.\r
-void CSceneManager::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)\r
-{\r
- Name = in->getAttributeAsString("Name");\r
- ID = in->getAttributeAsInt("Id");\r
- AmbientLight = in->getAttributeAsColorf("AmbientLight");\r
-\r
- // fog attributes\r
- video::SColor color;\r
- video::E_FOG_TYPE fogType;\r
- f32 start, end, density;\r
- bool pixelFog, rangeFog;\r
- if (in->existsAttribute("FogType"))\r
- {\r
- fogType = (video::E_FOG_TYPE) in->getAttributeAsEnumeration("FogType", video::FogTypeNames);\r
- color = in->getAttributeAsColorf("FogColor").toSColor();\r
- start = in->getAttributeAsFloat("FogStart");\r
- end = in->getAttributeAsFloat("FogEnd");\r
- density = in->getAttributeAsFloat("FogDensity");\r
- pixelFog = in->getAttributeAsBool("FogPixel");\r
- rangeFog = in->getAttributeAsBool("FogRange");\r
- Driver->setFog(color, fogType, start, end, density, pixelFog, rangeFog);\r
- }\r
-\r
- RelativeTranslation.set(0,0,0);\r
- RelativeRotation.set(0,0,0);\r
- RelativeScale.set(1,1,1);\r
- IsVisible = true;\r
- AutomaticCullingState = scene::EAC_BOX;\r
- DebugDataVisible = scene::EDS_OFF;\r
- IsDebugObject = false;\r
-\r
- updateAbsolutePosition();\r
-}\r
-\r
-\r
//! Sets ambient color of the scene\r
void CSceneManager::setAmbientLight(const video::SColorf &ambientColor)\r
{\r
//! Get a skinned mesh, which is not available as header-only code\r
ISkinnedMesh* CSceneManager::createSkinnedMesh()\r
{\r
-#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_\r
return new CSkinnedMesh();\r
-#else\r
- return 0;\r
-#endif\r
}\r
\r
//! Returns a mesh writer implementation if available\r
IMeshWriter* CSceneManager::createMeshWriter(EMESH_WRITER_TYPE type)\r
{\r
- switch(type)\r
- {\r
- case EMWT_IRR_MESH:\r
- case EMWT_COLLADA:\r
- return 0;\r
- case EMWT_STL:\r
-#ifdef _IRR_COMPILE_WITH_STL_WRITER_\r
- return new CSTLMeshWriter(this);\r
-#else\r
- return 0;\r
-#endif\r
- case EMWT_OBJ:\r
-#ifdef _IRR_COMPILE_WITH_OBJ_WRITER_\r
- return new COBJMeshWriter(this, FileSystem);\r
-#else\r
- return 0;\r
-#endif\r
-\r
- case EMWT_PLY:\r
-#ifdef _IRR_COMPILE_WITH_PLY_WRITER_\r
- return new CPLYMeshWriter();\r
-#else\r
- return 0;\r
-#endif\r
-\r
- case EMWT_B3D:\r
-#ifdef _IRR_COMPILE_WITH_B3D_WRITER_\r
- return new CB3DMeshWriter();\r
-#else\r
- return 0;\r
-#endif\r
- }\r
-\r
return 0;\r
}\r
\r