1
// Copyright (C) 2002-2011 Nikolaus Gebhardt
2
// This file is part of the "Irrlicht Engine".
3
// For conditions of distribution and use, see copyright notice in irrlicht.h
5
#include "IrrCompileConfig.h"
6
#include "CSceneManager.h"
7
#include "IVideoDriver.h"
8
#include "IFileSystem.h"
9
#include "SAnimatedMesh.h"
10
#include "CMeshCache.h"
11
#include "IXMLWriter.h"
12
#include "ISceneUserDataSerializer.h"
13
#include "IGUIEnvironment.h"
14
#include "IMaterialRenderer.h"
15
#include "IReadFile.h"
16
#include "IWriteFile.h"
17
#include "ISceneLoader.h"
21
// We need this include for the case of skinned mesh support without
23
#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
24
#include "CSkinnedMesh.h"
27
#ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_
28
#include "CIrrMeshFileLoader.h"
31
#ifdef _IRR_COMPILE_WITH_BSP_LOADER_
32
#include "CBSPMeshFileLoader.h"
35
#ifdef _IRR_COMPILE_WITH_MD2_LOADER_
36
#include "CMD2MeshFileLoader.h"
39
#ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_
40
#include "CAnimatedMeshHalfLife.h"
43
#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
44
#include "CMS3DMeshFileLoader.h"
47
#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
48
#include "C3DSMeshFileLoader.h"
51
#ifdef _IRR_COMPILE_WITH_X_LOADER_
52
#include "CXMeshFileLoader.h"
55
#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
56
#include "COCTLoader.h"
59
#ifdef _IRR_COMPILE_WITH_CSM_LOADER_
60
#include "CCSMLoader.h"
63
#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
64
#include "CLMTSMeshFileLoader.h"
67
#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
68
#include "CMY3DMeshFileLoader.h"
71
#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
72
#include "CColladaFileLoader.h"
75
#ifdef _IRR_COMPILE_WITH_DMF_LOADER_
76
#include "CDMFLoader.h"
79
#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
80
#include "COgreMeshFileLoader.h"
83
#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
84
#include "COBJMeshFileLoader.h"
87
#ifdef _IRR_COMPILE_WITH_MD3_LOADER_
88
#include "CMD3MeshFileLoader.h"
91
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
92
#include "CB3DMeshFileLoader.h"
95
#ifdef _IRR_COMPILE_WITH_LWO_LOADER_
96
#include "CLWOMeshFileLoader.h"
99
#ifdef _IRR_COMPILE_WITH_STL_LOADER_
100
#include "CSTLMeshFileLoader.h"
103
#ifdef _IRR_COMPILE_WITH_PLY_LOADER_
104
#include "CPLYMeshFileLoader.h"
107
#ifdef _IRR_COMPILE_WITH_SMF_LOADER_
108
#include "CSMFMeshFileLoader.h"
111
#ifdef _IRR_COMPILE_WITH_IRR_SCENE_LOADER_
112
#include "CSceneLoaderIrr.h"
115
#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_
116
#include "CColladaMeshWriter.h"
119
#ifdef _IRR_COMPILE_WITH_IRR_WRITER_
120
#include "CIrrMeshWriter.h"
123
#ifdef _IRR_COMPILE_WITH_STL_WRITER_
124
#include "CSTLMeshWriter.h"
127
#ifdef _IRR_COMPILE_WITH_OBJ_WRITER_
128
#include "COBJMeshWriter.h"
131
#ifdef _IRR_COMPILE_WITH_PLY_WRITER_
132
#include "CPLYMeshWriter.h"
135
#include "CCubeSceneNode.h"
136
#include "CSphereSceneNode.h"
137
#include "CAnimatedMeshSceneNode.h"
138
#include "COctreeSceneNode.h"
139
#include "CCameraSceneNode.h"
140
#include "CLightSceneNode.h"
141
#include "CBillboardSceneNode.h"
142
#include "CMeshSceneNode.h"
143
#include "CSkyBoxSceneNode.h"
144
#include "CSkyDomeSceneNode.h"
145
#include "CParticleSystemSceneNode.h"
146
#include "CDummyTransformationSceneNode.h"
147
#include "CWaterSurfaceSceneNode.h"
148
#include "CTerrainSceneNode.h"
149
#include "CEmptySceneNode.h"
150
#include "CTextSceneNode.h"
151
#include "CQuake3ShaderSceneNode.h"
152
#include "CVolumeLightSceneNode.h"
154
#include "CDefaultSceneNodeFactory.h"
156
#include "CSceneCollisionManager.h"
157
#include "CTriangleSelector.h"
158
#include "COctreeTriangleSelector.h"
159
#include "CTriangleBBSelector.h"
160
#include "CMetaTriangleSelector.h"
161
#include "CTerrainTriangleSelector.h"
163
#include "CSceneNodeAnimatorRotation.h"
164
#include "CSceneNodeAnimatorFlyCircle.h"
165
#include "CSceneNodeAnimatorFlyStraight.h"
166
#include "CSceneNodeAnimatorTexture.h"
167
#include "CSceneNodeAnimatorCollisionResponse.h"
168
#include "CSceneNodeAnimatorDelete.h"
169
#include "CSceneNodeAnimatorFollowSpline.h"
170
#include "CSceneNodeAnimatorCameraFPS.h"
171
#include "CSceneNodeAnimatorCameraMaya.h"
172
#include "CDefaultSceneNodeAnimatorFactory.h"
174
#include "CGeometryCreator.h"
176
//! Enable debug features
177
#define SCENEMANAGER_DEBUG
185
CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
186
gui::ICursorControl* cursorControl, IMeshCache* cache,
187
gui::IGUIEnvironment* gui)
188
: ISceneNode(0, 0), Driver(driver), FileSystem(fs), GUIEnvironment(gui),
189
CursorControl(cursorControl), CollisionManager(0),
190
ActiveCamera(0), ShadowColor(150,0,0,0), AmbientLight(0,0,0,0),
191
MeshCache(cache), CurrentRendertime(ESNRP_NONE), LightManager(0),
192
IRR_XML_FORMAT_SCENE(L"irr_scene"), IRR_XML_FORMAT_NODE(L"node"), IRR_XML_FORMAT_NODE_ATTR_TYPE(L"type")
195
ISceneManager::setDebugName("CSceneManager ISceneManager");
196
ISceneNode::setDebugName("CSceneManager ISceneNode");
199
// root node's scene manager
202
// set scene parameters
203
Parameters.setAttribute( DEBUG_NORMAL_LENGTH, 1.f );
204
Parameters.setAttribute( DEBUG_NORMAL_COLOR, video::SColor(255, 34, 221, 221));
213
CursorControl->grab();
216
GUIEnvironment->grab();
218
// create mesh cache if not there already
220
MeshCache = new CMeshCache();
224
// create collision manager
225
CollisionManager = new CSceneCollisionManager(this, Driver);
227
// create geometry creator
228
GeometryCreator = new CGeometryCreator();
230
// add file format loaders. add the least commonly used ones first,
231
// as these are checked last
233
// TODO: now that we have multiple scene managers, these should be
234
// shallow copies from the previous manager if there is one.
236
#ifdef _IRR_COMPILE_WITH_STL_LOADER_
237
MeshLoaderList.push_back(new CSTLMeshFileLoader());
239
#ifdef _IRR_COMPILE_WITH_PLY_LOADER_
240
MeshLoaderList.push_back(new CPLYMeshFileLoader());
242
#ifdef _IRR_COMPILE_WITH_SMF_LOADER_
243
MeshLoaderList.push_back(new CSMFMeshFileLoader(Driver));
245
#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
246
MeshLoaderList.push_back(new COCTLoader(this, FileSystem));
248
#ifdef _IRR_COMPILE_WITH_CSM_LOADER_
249
MeshLoaderList.push_back(new CCSMLoader(this, FileSystem));
251
#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
252
MeshLoaderList.push_back(new CLMTSMeshFileLoader(FileSystem, Driver, &Parameters));
254
#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
255
MeshLoaderList.push_back(new CMY3DMeshFileLoader(this, FileSystem));
257
#ifdef _IRR_COMPILE_WITH_DMF_LOADER_
258
MeshLoaderList.push_back(new CDMFLoader(this, FileSystem));
260
#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
261
MeshLoaderList.push_back(new COgreMeshFileLoader(FileSystem, Driver));
263
#ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_
264
MeshLoaderList.push_back(new CHalflifeMDLMeshFileLoader( this ));
266
#ifdef _IRR_COMPILE_WITH_MD3_LOADER_
267
MeshLoaderList.push_back(new CMD3MeshFileLoader( this));
269
#ifdef _IRR_COMPILE_WITH_LWO_LOADER_
270
MeshLoaderList.push_back(new CLWOMeshFileLoader(this, FileSystem));
272
#ifdef _IRR_COMPILE_WITH_MD2_LOADER_
273
MeshLoaderList.push_back(new CMD2MeshFileLoader());
275
#ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_
276
MeshLoaderList.push_back(new CIrrMeshFileLoader(this, FileSystem));
278
#ifdef _IRR_COMPILE_WITH_BSP_LOADER_
279
MeshLoaderList.push_back(new CBSPMeshFileLoader(this, FileSystem));
281
#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
282
MeshLoaderList.push_back(new CColladaFileLoader(this, FileSystem));
284
#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
285
MeshLoaderList.push_back(new C3DSMeshFileLoader(this, FileSystem));
287
#ifdef _IRR_COMPILE_WITH_X_LOADER_
288
MeshLoaderList.push_back(new CXMeshFileLoader(this, FileSystem));
290
#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
291
MeshLoaderList.push_back(new CMS3DMeshFileLoader(Driver));
293
#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
294
MeshLoaderList.push_back(new COBJMeshFileLoader(this, FileSystem));
296
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
297
MeshLoaderList.push_back(new CB3DMeshFileLoader(this));
301
#ifdef _IRR_COMPILE_WITH_IRR_SCENE_LOADER_
302
SceneLoaderList.push_back(new CSceneLoaderIrr(this, FileSystem));
307
ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this);
308
registerSceneNodeFactory(factory);
311
ISceneNodeAnimatorFactory* animatorFactory = new CDefaultSceneNodeAnimatorFactory(this, CursorControl);
312
registerSceneNodeAnimatorFactory(animatorFactory);
313
animatorFactory->drop();
318
CSceneManager::~CSceneManager()
322
//! force to remove hardwareTextures from the driver
323
//! because Scenes may hold internally data bounded to sceneNodes
324
//! which may be destroyed twice
326
Driver->removeAllHardwareBuffers();
332
CursorControl->drop();
334
if (CollisionManager)
335
CollisionManager->drop();
338
GeometryCreator->drop();
341
GUIEnvironment->drop();
344
for (i=0; i<MeshLoaderList.size(); ++i)
345
MeshLoaderList[i]->drop();
347
for (i=0; i<SceneLoaderList.size(); ++i)
348
SceneLoaderList[i]->drop();
351
ActiveCamera->drop();
357
for (i=0; i<SceneNodeFactoryList.size(); ++i)
358
SceneNodeFactoryList[i]->drop();
360
for (i=0; i<SceneNodeAnimatorFactoryList.size(); ++i)
361
SceneNodeAnimatorFactoryList[i]->drop();
364
LightManager->drop();
366
// remove all nodes and animators before dropping the driver
367
// as render targets may be destroyed twice
377
//! gets an animateable mesh. loads it if needed. returned pointer must not be dropped.
378
IAnimatedMesh* CSceneManager::getMesh(const io::path& filename)
380
IAnimatedMesh* msh = MeshCache->getMeshByName(filename);
384
io::IReadFile* file = FileSystem->createAndOpenFile(filename);
387
os::Printer::log("Could not load mesh, because file could not be opened: ", filename, ELL_ERROR);
391
// iterate the list in reverse order so user-added loaders can override the built-in ones
392
s32 count = MeshLoaderList.size();
393
for (s32 i=count-1; i>=0; --i)
395
if (MeshLoaderList[i]->isALoadableFileExtension(filename))
397
// reset file to avoid side effects of previous calls to createMesh
399
msh = MeshLoaderList[i]->createMesh(file);
402
MeshCache->addMesh(filename, msh);
412
os::Printer::log("Could not load mesh, file format seems to be unsupported", filename, ELL_ERROR);
414
os::Printer::log("Loaded mesh", filename, ELL_INFORMATION);
420
//! gets an animateable mesh. loads it if needed. returned pointer must not be dropped.
421
IAnimatedMesh* CSceneManager::getMesh(io::IReadFile* file)
426
io::path name = file->getFileName();
427
IAnimatedMesh* msh = MeshCache->getMeshByName(file->getFileName());
431
// iterate the list in reverse order so user-added loaders can override the built-in ones
432
s32 count = MeshLoaderList.size();
433
for (s32 i=count-1; i>=0; --i)
435
if (MeshLoaderList[i]->isALoadableFileExtension(name))
437
// reset file to avoid side effects of previous calls to createMesh
439
msh = MeshLoaderList[i]->createMesh(file);
442
MeshCache->addMesh(file->getFileName(), msh);
450
os::Printer::log("Could not load mesh, file format seems to be unsupported", file->getFileName(), ELL_ERROR);
452
os::Printer::log("Loaded mesh", file->getFileName(), ELL_INFORMATION);
458
//! returns the video driver
459
video::IVideoDriver* CSceneManager::getVideoDriver()
465
//! returns the GUI Environment
466
gui::IGUIEnvironment* CSceneManager::getGUIEnvironment()
468
return GUIEnvironment;
471
//! Get the active FileSystem
472
/** \return Pointer to the FileSystem
473
This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
474
io::IFileSystem* CSceneManager::getFileSystem()
479
//! Adds a text scene node, which is able to display
480
//! 2d text at a position in three dimensional space
481
ITextSceneNode* CSceneManager::addTextSceneNode(gui::IGUIFont* font,
482
const wchar_t* text, video::SColor color, ISceneNode* parent,
483
const core::vector3df& position, s32 id)
491
ITextSceneNode* t = new CTextSceneNode(parent, this, id, font,
492
getSceneCollisionManager(), position, text, color);
499
//! Adds a text scene node, which uses billboards
500
IBillboardTextSceneNode* CSceneManager::addBillboardTextSceneNode(gui::IGUIFont* font,
501
const wchar_t* text, ISceneNode* parent,
502
const core::dimension2d<f32>& size,
503
const core::vector3df& position, s32 id,
504
video::SColor colorTop, video::SColor colorBottom)
506
if (!font && GUIEnvironment)
507
font = GUIEnvironment->getBuiltInFont();
515
IBillboardTextSceneNode* node = new CBillboardTextSceneNode(parent, this, id, font, text, position, size,
516
colorTop, colorBottom);
524
//! Adds a scene node, which can render a quake3 shader
525
IMeshSceneNode* CSceneManager::addQuake3SceneNode(const IMeshBuffer* meshBuffer,
526
const quake3::IShader * shader,
527
ISceneNode* parent, s32 id )
529
#ifdef _IRR_COMPILE_WITH_BSP_LOADER_
536
CQuake3ShaderSceneNode* node = new CQuake3ShaderSceneNode( parent,
537
this, id, FileSystem,
538
meshBuffer, shader );
548
//! adds Volume Lighting Scene Node.
549
//! the returned pointer must not be dropped.
550
IVolumeLightSceneNode* CSceneManager::addVolumeLightSceneNode(
551
ISceneNode* parent, s32 id,
552
const u32 subdivU, const u32 subdivV,
553
const video::SColor foot, const video::SColor tail,
554
const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
559
IVolumeLightSceneNode* node = new CVolumeLightSceneNode(parent, this, id, subdivU, subdivV, foot, tail, position, rotation, scale);
566
//! adds a test scene node for test purposes to the scene. It is a simple cube of (1,1,1) size.
567
//! the returned pointer must not be dropped.
568
IMeshSceneNode* CSceneManager::addCubeSceneNode(f32 size, ISceneNode* parent,
569
s32 id, const core::vector3df& position,
570
const core::vector3df& rotation, const core::vector3df& scale)
575
IMeshSceneNode* node = new CCubeSceneNode(size, parent, this, id, position, rotation, scale);
582
//! Adds a sphere scene node for test purposes to the scene.
583
IMeshSceneNode* CSceneManager::addSphereSceneNode(f32 radius, s32 polyCount,
584
ISceneNode* parent, s32 id, const core::vector3df& position,
585
const core::vector3df& rotation, const core::vector3df& scale)
590
IMeshSceneNode* node = new CSphereSceneNode(radius, polyCount, polyCount, parent, this, id, position, rotation, scale);
597
//! adds a scene node for rendering a static mesh
598
//! the returned pointer must not be dropped.
599
IMeshSceneNode* CSceneManager::addMeshSceneNode(IMesh* mesh, ISceneNode* parent, s32 id,
600
const core::vector3df& position, const core::vector3df& rotation,
601
const core::vector3df& scale, bool alsoAddIfMeshPointerZero)
603
if (!alsoAddIfMeshPointerZero && !mesh)
609
IMeshSceneNode* node = new CMeshSceneNode(mesh, parent, this, id, position, rotation, scale);
616
//! Adds a scene node for rendering a animated water surface mesh.
617
ISceneNode* CSceneManager::addWaterSurfaceSceneNode(IMesh* mesh, f32 waveHeight, f32 waveSpeed, f32 waveLength,
618
ISceneNode* parent, s32 id, const core::vector3df& position,
619
const core::vector3df& rotation, const core::vector3df& scale)
624
ISceneNode* node = new CWaterSurfaceSceneNode(waveHeight, waveSpeed, waveLength,
625
mesh, parent, this, id, position, rotation, scale);
633
//! adds a scene node for rendering an animated mesh model
634
IAnimatedMeshSceneNode* CSceneManager::addAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, s32 id,
635
const core::vector3df& position, const core::vector3df& rotation,
636
const core::vector3df& scale, bool alsoAddIfMeshPointerZero)
638
if (!alsoAddIfMeshPointerZero && !mesh)
644
IAnimatedMeshSceneNode* node =
645
new CAnimatedMeshSceneNode(mesh, parent, this, id, position, rotation, scale);
652
//! Adds a scene node for rendering using a octree to the scene graph. This a good method for rendering
653
//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much
654
//! faster then a bsp tree.
655
IMeshSceneNode* CSceneManager::addOctreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent,
656
s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero)
658
if (!alsoAddIfMeshPointerZero && (!mesh || !mesh->getFrameCount()))
661
return addOctreeSceneNode(mesh ? mesh->getMesh(0) : 0,
662
parent, id, minimalPolysPerNode,
663
alsoAddIfMeshPointerZero);
667
//! Adds a scene node for rendering using a octree. This a good method for rendering
668
//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much
669
//! faster then a bsp tree.
670
IMeshSceneNode* CSceneManager::addOctreeSceneNode(IMesh* mesh, ISceneNode* parent,
671
s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero)
673
if (!alsoAddIfMeshPointerZero && !mesh)
679
COctreeSceneNode* node = new COctreeSceneNode(parent, this, id, minimalPolysPerNode);
691
//! Adds a camera scene node to the tree and sets it as active camera.
692
//! \param position: Position of the space relative to its parent where the camera will be placed.
693
//! \param lookat: Position where the camera will look at. Also known as target.
694
//! \param parent: Parent scene node of the camera. Can be null. If the parent moves,
695
//! the camera will move too.
696
//! \return Returns pointer to interface to camera
697
ICameraSceneNode* CSceneManager::addCameraSceneNode(ISceneNode* parent,
698
const core::vector3df& position, const core::vector3df& lookat, s32 id,
704
ICameraSceneNode* node = new CCameraSceneNode(parent, this, id, position, lookat);
707
setActiveCamera(node);
714
//! Adds a camera scene node which is able to be controlled with the mouse similar
715
//! to in the 3D Software Maya by Alias Wavefront.
716
//! The returned pointer must not be dropped.
717
ICameraSceneNode* CSceneManager::addCameraSceneNodeMaya(ISceneNode* parent,
718
f32 rotateSpeed, f32 zoomSpeed, f32 translationSpeed, s32 id,
721
ICameraSceneNode* node = addCameraSceneNode(parent, core::vector3df(),
722
core::vector3df(0,0,100), id, makeActive);
725
ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraMaya(CursorControl,
726
rotateSpeed, zoomSpeed, translationSpeed);
728
node->addAnimator(anm);
736
//! Adds a camera scene node which is able to be controlled with the mouse and keys
737
//! like in most first person shooters (FPS):
738
ICameraSceneNode* CSceneManager::addCameraSceneNodeFPS(ISceneNode* parent,
739
f32 rotateSpeed, f32 moveSpeed, s32 id, SKeyMap* keyMapArray,
740
s32 keyMapSize, bool noVerticalMovement, f32 jumpSpeed,
741
bool invertMouseY, bool makeActive)
743
ICameraSceneNode* node = addCameraSceneNode(parent, core::vector3df(),
744
core::vector3df(0,0,100), id, makeActive);
747
ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraFPS(CursorControl,
748
rotateSpeed, moveSpeed, jumpSpeed,
749
keyMapArray, keyMapSize, noVerticalMovement, invertMouseY);
751
// Bind the node's rotation to its target. This is consistent with 1.4.2 and below.
752
node->bindTargetAndRotation(true);
753
node->addAnimator(anm);
761
//! Adds a dynamic light scene node. The light will cast dynamic light on all
762
//! other scene nodes in the scene, which have the material flag video::MTF_LIGHTING
763
//! turned on. (This is the default setting in most scene nodes).
764
ILightSceneNode* CSceneManager::addLightSceneNode(ISceneNode* parent,
765
const core::vector3df& position, video::SColorf color, f32 range, s32 id)
770
ILightSceneNode* node = new CLightSceneNode(parent, this, id, position, color, range);
777
//! Adds a billboard scene node to the scene. A billboard is like a 3d sprite: A 2d element,
778
//! which always looks to the camera. It is usually used for things like explosions, fire,
779
//! lensflares and things like that.
780
IBillboardSceneNode* CSceneManager::addBillboardSceneNode(ISceneNode* parent,
781
const core::dimension2d<f32>& size, const core::vector3df& position, s32 id,
782
video::SColor colorTop, video::SColor colorBottom
788
IBillboardSceneNode* node = new CBillboardSceneNode(parent, this, id, position, size,
789
colorTop, colorBottom);
796
//! Adds a skybox scene node. A skybox is a big cube with 6 textures on it and
797
//! is drawn around the camera position.
798
ISceneNode* CSceneManager::addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom,
799
video::ITexture* left, video::ITexture* right, video::ITexture* front,
800
video::ITexture* back, ISceneNode* parent, s32 id)
805
ISceneNode* node = new CSkyBoxSceneNode(top, bottom, left, right,
806
front, back, parent, this, id);
813
//! Adds a skydome scene node. A skydome is a large (half-) sphere with a
814
//! panoramic texture on it and is drawn around the camera position.
815
ISceneNode* CSceneManager::addSkyDomeSceneNode(video::ITexture* texture,
816
u32 horiRes, u32 vertRes, f32 texturePercentage,f32 spherePercentage, f32 radius,
817
ISceneNode* parent, s32 id)
822
ISceneNode* node = new CSkyDomeSceneNode(texture, horiRes, vertRes,
823
texturePercentage, spherePercentage, radius, parent, this, id);
830
//! Adds a particle system scene node.
831
IParticleSystemSceneNode* CSceneManager::addParticleSystemSceneNode(
832
bool withDefaultEmitter, ISceneNode* parent, s32 id,
833
const core::vector3df& position, const core::vector3df& rotation,
834
const core::vector3df& scale)
839
IParticleSystemSceneNode* node = new CParticleSystemSceneNode(withDefaultEmitter,
840
parent, this, id, position, rotation, scale);
847
//! Adds a terrain scene node to the scene graph.
848
ITerrainSceneNode* CSceneManager::addTerrainSceneNode(
849
const io::path& heightMapFileName,
850
ISceneNode* parent, s32 id,
851
const core::vector3df& position,
852
const core::vector3df& rotation,
853
const core::vector3df& scale,
854
video::SColor vertexColor,
855
s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, s32 smoothFactor,
856
bool addAlsoIfHeightmapEmpty)
858
io::IReadFile* file = FileSystem->createAndOpenFile(heightMapFileName);
860
if (!file && !addAlsoIfHeightmapEmpty)
862
os::Printer::log("Could not load terrain, because file could not be opened.",
863
heightMapFileName, ELL_ERROR);
867
ITerrainSceneNode* terrain = addTerrainSceneNode(file, parent, id,
868
position, rotation, scale, vertexColor, maxLOD, patchSize,
869
smoothFactor, addAlsoIfHeightmapEmpty);
877
//! Adds a terrain scene node to the scene graph.
878
ITerrainSceneNode* CSceneManager::addTerrainSceneNode(
879
io::IReadFile* heightMapFile,
880
ISceneNode* parent, s32 id,
881
const core::vector3df& position,
882
const core::vector3df& rotation,
883
const core::vector3df& scale,
884
video::SColor vertexColor,
885
s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize,
887
bool addAlsoIfHeightmapEmpty)
892
if (!heightMapFile && !addAlsoIfHeightmapEmpty)
894
os::Printer::log("Could not load terrain, because file could not be opened.", ELL_ERROR);
898
CTerrainSceneNode* node = new CTerrainSceneNode(parent, this, FileSystem, id,
899
maxLOD, patchSize, position, rotation, scale);
901
if (!node->loadHeightMap(heightMapFile, vertexColor, smoothFactor))
903
if (!addAlsoIfHeightmapEmpty)
916
//! Adds an empty scene node.
917
ISceneNode* CSceneManager::addEmptySceneNode(ISceneNode* parent, s32 id)
922
ISceneNode* node = new CEmptySceneNode(parent, this, id);
929
//! Adds a dummy transformation scene node to the scene graph.
930
IDummyTransformationSceneNode* CSceneManager::addDummyTransformationSceneNode(
931
ISceneNode* parent, s32 id)
936
IDummyTransformationSceneNode* node = new CDummyTransformationSceneNode(
943
//! Adds a Hill Plane mesh to the mesh pool. The mesh is generated on the fly
944
//! and looks like a plane with some hills on it. You can specify how many hills
945
//! there should be on the plane and how high they should be. Also you must
946
//! specify a name for the mesh, because the mesh is added to the mesh pool,
947
//! and can be retrieved again using ISceneManager::getMesh with the name as
949
IAnimatedMesh* CSceneManager::addHillPlaneMesh(const io::path& name,
950
const core::dimension2d<f32>& tileSize,
951
const core::dimension2d<u32>& tileCount,
952
video::SMaterial* material, f32 hillHeight,
953
const core::dimension2d<f32>& countHills,
954
const core::dimension2d<f32>& textureRepeatCount)
956
if (MeshCache->isMeshLoaded(name))
957
return MeshCache->getMeshByName(name);
959
IMesh* mesh = GeometryCreator->createHillPlaneMesh(tileSize,
960
tileCount, material, hillHeight, countHills,
965
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
972
animatedMesh->addMesh(mesh);
974
animatedMesh->recalculateBoundingBox();
976
MeshCache->addMesh(name, animatedMesh);
977
animatedMesh->drop();
983
//! Adds a terrain mesh to the mesh pool.
984
IAnimatedMesh* CSceneManager::addTerrainMesh(const io::path& name,
985
video::IImage* texture, video::IImage* heightmap,
986
const core::dimension2d<f32>& stretchSize,
988
const core::dimension2d<u32>& defaultVertexBlockSize)
990
if (MeshCache->isMeshLoaded(name))
991
return MeshCache->getMeshByName(name);
993
const bool debugBorders=false;
994
IMesh* mesh = GeometryCreator->createTerrainMesh(texture, heightmap,
995
stretchSize, maxHeight, getVideoDriver(),
996
defaultVertexBlockSize, debugBorders);
1000
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
1007
animatedMesh->addMesh(mesh);
1009
animatedMesh->recalculateBoundingBox();
1011
MeshCache->addMesh(name, animatedMesh);
1012
animatedMesh->drop();
1014
return animatedMesh;
1018
//! Adds an arrow mesh to the mesh pool.
1019
IAnimatedMesh* CSceneManager::addArrowMesh(const io::path& name,
1020
video::SColor vtxColor0, video::SColor vtxColor1,
1021
u32 tesselationCylinder, u32 tesselationCone, f32 height,
1022
f32 cylinderHeight, f32 width0,f32 width1)
1024
if (MeshCache->isMeshLoaded(name))
1025
return MeshCache->getMeshByName(name);
1027
IMesh* mesh = GeometryCreator->createArrowMesh( tesselationCylinder,
1028
tesselationCone, height, cylinderHeight, width0,width1,
1029
vtxColor0, vtxColor1);
1033
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
1040
animatedMesh->addMesh(mesh);
1042
animatedMesh->recalculateBoundingBox();
1044
MeshCache->addMesh(name, animatedMesh);
1045
animatedMesh->drop();
1047
return animatedMesh;
1051
//! Adds a static sphere mesh to the mesh pool.
1052
IAnimatedMesh* CSceneManager::addSphereMesh(const io::path& name,
1053
f32 radius, u32 polyCountX, u32 polyCountY)
1055
if (MeshCache->isMeshLoaded(name))
1056
return MeshCache->getMeshByName(name);
1058
IMesh* mesh = GeometryCreator->createSphereMesh(radius, polyCountX, polyCountY);
1062
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
1069
animatedMesh->addMesh(mesh);
1071
animatedMesh->recalculateBoundingBox();
1073
MeshCache->addMesh(name, animatedMesh);
1074
animatedMesh->drop();
1076
return animatedMesh;
1081
//! Adds a static volume light mesh to the mesh pool.
1082
IAnimatedMesh* CSceneManager::addVolumeLightMesh(const io::path& name,
1083
const u32 SubdivideU, const u32 SubdivideV,
1084
const video::SColor FootColor, const video::SColor TailColor)
1086
if (MeshCache->isMeshLoaded(name))
1087
return MeshCache->getMeshByName(name);
1089
IMesh* mesh = GeometryCreator->createVolumeLightMesh(SubdivideU, SubdivideV, FootColor, TailColor);
1093
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
1100
animatedMesh->addMesh(mesh);
1102
animatedMesh->recalculateBoundingBox();
1104
MeshCache->addMesh(name, animatedMesh);
1105
animatedMesh->drop();
1107
return animatedMesh;
1111
//! Returns the root scene node. This is the scene node wich is parent
1112
//! of all scene nodes. The root scene node is a special scene node which
1113
//! only exists to manage all scene nodes. It is not rendered and cannot
1114
//! be removed from the scene.
1115
//! \return Returns a pointer to the root scene node.
1116
ISceneNode* CSceneManager::getRootSceneNode()
1122
//! Returns the current active camera.
1123
//! \return The active camera is returned. Note that this can be NULL, if there
1124
//! was no camera created yet.
1125
ICameraSceneNode* CSceneManager::getActiveCamera() const
1127
return ActiveCamera;
1131
//! Sets the active camera. The previous active camera will be deactivated.
1132
//! \param camera: The new camera which should be active.
1133
void CSceneManager::setActiveCamera(ICameraSceneNode* camera)
1138
ActiveCamera->drop();
1140
ActiveCamera = camera;
1144
//! renders the node.
1145
void CSceneManager::render()
1150
//! returns the axis aligned bounding box of this node
1151
const core::aabbox3d<f32>& CSceneManager::getBoundingBox() const
1153
_IRR_DEBUG_BREAK_IF(true) // Bounding Box of Scene Manager wanted.
1155
// should never be used.
1156
return *((core::aabbox3d<f32>*)0);
1160
//! returns if node is culled
1161
bool CSceneManager::isCulled(const ISceneNode* node) const
1163
const ICameraSceneNode* cam = getActiveCamera();
1166
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
1169
bool result = false;
1171
// has occlusion query information
1172
if (node->getAutomaticCulling() & scene::EAC_OCC_QUERY)
1174
result = (Driver->getOcclusionQueryResult(const_cast<ISceneNode*>(node))==0);
1177
// can be seen by a bounding box ?
1178
if (!result && (node->getAutomaticCulling() & scene::EAC_BOX))
1180
core::aabbox3d<f32> tbox = node->getBoundingBox();
1181
node->getAbsoluteTransformation().transformBoxEx(tbox);
1182
result = !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox() ));
1185
// can be seen by a bounding sphere
1186
if (!result && (node->getAutomaticCulling() & scene::EAC_FRUSTUM_SPHERE))
1187
{ // requires bbox diameter
1190
// can be seen by cam pyramid planes ?
1191
if (!result && (node->getAutomaticCulling() & scene::EAC_FRUSTUM_BOX))
1193
SViewFrustum frust = *cam->getViewFrustum();
1195
//transform the frustum to the node's current absolute transformation
1196
core::matrix4 invTrans(node->getAbsoluteTransformation(), core::matrix4::EM4CONST_INVERSE);
1197
//invTrans.makeInverse();
1198
frust.transform(invTrans);
1200
core::vector3df edges[8];
1201
node->getBoundingBox().getEdges(edges);
1203
for (s32 i=0; i<scene::SViewFrustum::VF_PLANE_COUNT; ++i)
1205
bool boxInFrustum=false;
1206
for (u32 j=0; j<8; ++j)
1208
if (frust.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_FRONT)
1223
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
1228
//! registers a node for rendering it at a specific time.
1229
u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDER_PASS pass)
1235
// take camera if it is not already registered
1239
for (u32 i = 0; i != CameraList.size(); ++i)
1241
if (CameraList[i] == node)
1249
CameraList.push_back(node);
1255
// TODO: Point Light culling..
1256
// Lighting model in irrlicht has to be redone..
1257
//if (!isCulled(node))
1259
LightList.push_back(node);
1265
SkyBoxList.push_back(node);
1269
if (!isCulled(node))
1271
SolidNodeList.push_back(node);
1275
case ESNRP_TRANSPARENT:
1276
if (!isCulled(node))
1278
TransparentNodeList.push_back(TransparentNodeEntry(node, camWorldPos));
1282
case ESNRP_TRANSPARENT_EFFECT:
1283
if (!isCulled(node))
1285
TransparentEffectNodeList.push_back(TransparentNodeEntry(node, camWorldPos));
1289
case ESNRP_AUTOMATIC:
1290
if (!isCulled(node))
1292
const u32 count = node->getMaterialCount();
1295
for (u32 i=0; i<count; ++i)
1297
video::IMaterialRenderer* rnd =
1298
Driver->getMaterialRenderer(node->getMaterial(i).MaterialType);
1299
if (rnd && rnd->isTransparent())
1301
// register as transparent node
1302
TransparentNodeEntry e(node, camWorldPos);
1303
TransparentNodeList.push_back(e);
1309
// not transparent, register as solid
1312
SolidNodeList.push_back(node);
1318
if (!isCulled(node))
1320
ShadowNodeList.push_back(node);
1325
case ESNRP_NONE: // ignore this one
1329
#ifdef SCENEMANAGER_DEBUG
1330
s32 index = Parameters.findAttribute ( "calls" );
1331
Parameters.setAttribute ( index, Parameters.getAttributeAsInt ( index ) + 1 );
1335
index = Parameters.findAttribute ( "culled" );
1336
Parameters.setAttribute ( index, Parameters.getAttributeAsInt ( index ) + 1 );
1344
//! This method is called just before the rendering process of the whole scene.
1345
//! draws all scene nodes
1346
void CSceneManager::drawAll()
1352
Parameters.setAttribute ( "culled", 0 );
1353
Parameters.setAttribute ( "calls", 0 );
1354
Parameters.setAttribute ( "drawn_solid", 0 );
1355
Parameters.setAttribute ( "drawn_transparent", 0 );
1356
Parameters.setAttribute ( "drawn_transparent_effect", 0 );
1358
u32 i; // new ISO for scoping problem in some compilers
1360
// reset all transforms
1361
video::IVideoDriver* driver = getVideoDriver();
1364
driver->setMaterial(video::SMaterial());
1365
driver->setTransform ( video::ETS_PROJECTION, core::IdentityMatrix );
1366
driver->setTransform ( video::ETS_VIEW, core::IdentityMatrix );
1367
driver->setTransform ( video::ETS_WORLD, core::IdentityMatrix );
1368
for (i=video::ETS_COUNT-1; i>=video::ETS_TEXTURE_0; --i)
1369
driver->setTransform ( (video::E_TRANSFORMATION_STATE)i, core::IdentityMatrix );
1372
driver->setAllowZWriteOnTransparent(Parameters.getAttributeAsBool( ALLOW_ZWRITE_ON_TRANSPARENT) );
1374
// do animations and other stuff.
1375
OnAnimate(os::Timer::getTime());
1378
First Scene Node for prerendering should be the active camera
1379
consistent Camera is needed for culling
1381
camWorldPos.set(0,0,0);
1384
ActiveCamera->render();
1385
camWorldPos = ActiveCamera->getAbsolutePosition();
1388
// let all nodes register themselves
1389
OnRegisterSceneNode();
1392
LightManager->OnPreRender(LightList);
1394
//render camera scenes
1396
CurrentRendertime = ESNRP_CAMERA;
1397
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0);
1400
LightManager->OnRenderPassPreRender(CurrentRendertime);
1402
for (i=0; i<CameraList.size(); ++i)
1403
CameraList[i]->render();
1405
CameraList.set_used(0);
1408
LightManager->OnRenderPassPostRender(CurrentRendertime);
1411
//render lights scenes
1413
CurrentRendertime = ESNRP_LIGHT;
1414
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0);
1418
LightManager->OnRenderPassPreRender(CurrentRendertime);
1422
// Sort the lights by distance from the camera
1423
core::vector3df camWorldPos(0, 0, 0);
1425
camWorldPos = ActiveCamera->getAbsolutePosition();
1427
core::array<DistanceNodeEntry> SortedLights;
1428
SortedLights.set_used(LightList.size());
1429
for (s32 light = (s32)LightList.size() - 1; light >= 0; --light)
1430
SortedLights[light].setNodeAndDistanceFromPosition(LightList[light], camWorldPos);
1432
SortedLights.set_sorted(false);
1433
SortedLights.sort();
1435
for(s32 light = (s32)LightList.size() - 1; light >= 0; --light)
1436
LightList[light] = SortedLights[light].Node;
1439
Driver->deleteAllDynamicLights();
1441
Driver->setAmbientLight(AmbientLight);
1443
u32 maxLights = LightList.size();
1446
maxLights = core::min_ ( Driver->getMaximalDynamicLightAmount(), maxLights);
1448
for (i=0; i< maxLights; ++i)
1449
LightList[i]->render();
1452
LightManager->OnRenderPassPostRender(CurrentRendertime);
1457
CurrentRendertime = ESNRP_SKY_BOX;
1458
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0);
1462
LightManager->OnRenderPassPreRender(CurrentRendertime);
1463
for (i=0; i<SkyBoxList.size(); ++i)
1465
ISceneNode* node = SkyBoxList[i];
1466
LightManager->OnNodePreRender(node);
1468
LightManager->OnNodePostRender(node);
1473
for (i=0; i<SkyBoxList.size(); ++i)
1474
SkyBoxList[i]->render();
1477
SkyBoxList.set_used(0);
1480
LightManager->OnRenderPassPostRender(CurrentRendertime);
1484
// render default objects
1486
CurrentRendertime = ESNRP_SOLID;
1487
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0);
1489
SolidNodeList.sort(); // sort by textures
1493
LightManager->OnRenderPassPreRender(CurrentRendertime);
1494
for (i=0; i<SolidNodeList.size(); ++i)
1496
ISceneNode* node = SolidNodeList[i].Node;
1497
LightManager->OnNodePreRender(node);
1499
LightManager->OnNodePostRender(node);
1504
for (i=0; i<SolidNodeList.size(); ++i)
1505
SolidNodeList[i].Node->render();
1508
Parameters.setAttribute("drawn_solid", (s32) SolidNodeList.size() );
1509
SolidNodeList.set_used(0);
1512
LightManager->OnRenderPassPostRender(CurrentRendertime);
1517
CurrentRendertime = ESNRP_SHADOW;
1518
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0);
1522
LightManager->OnRenderPassPreRender(CurrentRendertime);
1523
for (i=0; i<ShadowNodeList.size(); ++i)
1525
ISceneNode* node = ShadowNodeList[i];
1526
LightManager->OnNodePreRender(node);
1528
LightManager->OnNodePostRender(node);
1533
for (i=0; i<ShadowNodeList.size(); ++i)
1534
ShadowNodeList[i]->render();
1537
if (!ShadowNodeList.empty())
1538
Driver->drawStencilShadow(true,ShadowColor, ShadowColor,
1539
ShadowColor, ShadowColor);
1541
ShadowNodeList.set_used(0);
1544
LightManager->OnRenderPassPostRender(CurrentRendertime);
1547
// render transparent objects.
1549
CurrentRendertime = ESNRP_TRANSPARENT;
1550
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0);
1552
TransparentNodeList.sort(); // sort by distance from camera
1555
LightManager->OnRenderPassPreRender(CurrentRendertime);
1557
for (i=0; i<TransparentNodeList.size(); ++i)
1559
ISceneNode* node = TransparentNodeList[i].Node;
1560
LightManager->OnNodePreRender(node);
1562
LightManager->OnNodePostRender(node);
1567
for (i=0; i<TransparentNodeList.size(); ++i)
1568
TransparentNodeList[i].Node->render();
1571
Parameters.setAttribute ( "drawn_transparent", (s32) TransparentNodeList.size() );
1572
TransparentNodeList.set_used(0);
1575
LightManager->OnRenderPassPostRender(CurrentRendertime);
1578
// render transparent effect objects.
1580
CurrentRendertime = ESNRP_TRANSPARENT_EFFECT;
1581
Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0);
1583
TransparentEffectNodeList.sort(); // sort by distance from camera
1587
LightManager->OnRenderPassPreRender(CurrentRendertime);
1589
for (i=0; i<TransparentEffectNodeList.size(); ++i)
1591
ISceneNode* node = TransparentEffectNodeList[i].Node;
1592
LightManager->OnNodePreRender(node);
1594
LightManager->OnNodePostRender(node);
1599
for (i=0; i<TransparentEffectNodeList.size(); ++i)
1600
TransparentEffectNodeList[i].Node->render();
1603
Parameters.setAttribute ( "drawn_transparent_effect", (s32) TransparentEffectNodeList.size() );
1604
TransparentEffectNodeList.set_used(0);
1608
LightManager->OnPostRender();
1610
LightList.set_used(0);
1611
clearDeletionList();
1613
CurrentRendertime = ESNRP_NONE;
1616
void CSceneManager::setLightManager(ILightManager* lightManager)
1619
lightManager->grab();
1621
LightManager->drop();
1623
LightManager = lightManager;
1627
//! Sets the color of stencil buffers shadows drawn by the scene manager.
1628
void CSceneManager::setShadowColor(video::SColor color)
1630
ShadowColor = color;
1634
//! Returns the current color of shadows.
1635
video::SColor CSceneManager::getShadowColor() const
1641
//! creates a rotation animator, which rotates the attached scene node around itself.
1642
ISceneNodeAnimator* CSceneManager::createRotationAnimator(const core::vector3df& rotationPerSecond)
1644
ISceneNodeAnimator* anim = new CSceneNodeAnimatorRotation(os::Timer::getTime(),
1651
//! creates a fly circle animator, which lets the attached scene node fly around a center.
1652
ISceneNodeAnimator* CSceneManager::createFlyCircleAnimator(
1653
const core::vector3df& center, f32 radius, f32 speed,
1654
const core::vector3df& direction,
1656
f32 radiusEllipsoid)
1658
const f32 orbitDurationMs = (core::DEGTORAD * 360.f) / speed;
1659
const u32 effectiveTime = os::Timer::getTime() + (u32)(orbitDurationMs * startPosition);
1661
ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyCircle(
1662
effectiveTime, center,
1663
radius, speed, direction,radiusEllipsoid);
1668
//! Creates a fly straight animator, which lets the attached scene node
1669
//! fly or move along a line between two points.
1670
ISceneNodeAnimator* CSceneManager::createFlyStraightAnimator(const core::vector3df& startPoint,
1671
const core::vector3df& endPoint, u32 timeForWay, bool loop,bool pingpong)
1673
ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyStraight(startPoint,
1674
endPoint, timeForWay, loop, os::Timer::getTime(), pingpong);
1680
//! Creates a texture animator, which switches the textures of the target scene
1681
//! node based on a list of textures.
1682
ISceneNodeAnimator* CSceneManager::createTextureAnimator(const core::array<video::ITexture*>& textures,
1683
s32 timePerFrame, bool loop)
1685
ISceneNodeAnimator* anim = new CSceneNodeAnimatorTexture(textures,
1686
timePerFrame, loop, os::Timer::getTime());
1692
//! Creates a scene node animator, which deletes the scene node after
1693
//! some time automaticly.
1694
ISceneNodeAnimator* CSceneManager::createDeleteAnimator(u32 when)
1696
return new CSceneNodeAnimatorDelete(this, os::Timer::getTime() + when);
1700
//! Creates a special scene node animator for doing automatic collision detection
1702
ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnimator(
1703
ITriangleSelector* world, ISceneNode* sceneNode, const core::vector3df& ellipsoidRadius,
1704
const core::vector3df& gravityPerSecond,
1705
const core::vector3df& ellipsoidTranslation, f32 slidingValue)
1707
ISceneNodeAnimatorCollisionResponse* anim = new
1708
CSceneNodeAnimatorCollisionResponse(this, world, sceneNode,
1709
ellipsoidRadius, gravityPerSecond,
1710
ellipsoidTranslation, slidingValue);
1716
//! Creates a follow spline animator.
1717
ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime,
1718
const core::array< core::vector3df >& points,
1719
f32 speed, f32 tightness, bool loop, bool pingpong)
1721
ISceneNodeAnimator* a = new CSceneNodeAnimatorFollowSpline(startTime, points,
1722
speed, tightness, loop, pingpong);
1727
//! Adds an external mesh loader.
1728
void CSceneManager::addExternalMeshLoader(IMeshLoader* externalLoader)
1730
if (!externalLoader)
1733
externalLoader->grab();
1734
MeshLoaderList.push_back(externalLoader);
1738
//! Returns the number of mesh loaders supported by Irrlicht at this time
1739
u32 CSceneManager::getMeshLoaderCount() const
1741
return MeshLoaderList.size();
1745
//! Retrieve the given mesh loader
1746
IMeshLoader* CSceneManager::getMeshLoader(u32 index) const
1748
if (index < MeshLoaderList.size())
1749
return MeshLoaderList[index];
1755
//! Adds an external scene loader.
1756
void CSceneManager::addExternalSceneLoader(ISceneLoader* externalLoader)
1758
if (!externalLoader)
1761
externalLoader->grab();
1762
SceneLoaderList.push_back(externalLoader);
1766
//! Returns the number of scene loaders
1767
u32 CSceneManager::getSceneLoaderCount() const
1769
return SceneLoaderList.size();
1773
//! Retrieve the given scene loader
1774
ISceneLoader* CSceneManager::getSceneLoader(u32 index) const
1776
if (index < SceneLoaderList.size())
1777
return SceneLoaderList[index];
1783
//! Returns a pointer to the scene collision manager.
1784
ISceneCollisionManager* CSceneManager::getSceneCollisionManager()
1786
return CollisionManager;
1790
//! Returns a pointer to the mesh manipulator.
1791
IMeshManipulator* CSceneManager::getMeshManipulator()
1793
return Driver->getMeshManipulator();
1797
//! Creates a simple ITriangleSelector, based on a mesh.
1798
ITriangleSelector* CSceneManager::createTriangleSelector(IMesh* mesh, ISceneNode* node)
1803
return new CTriangleSelector(mesh, node);
1807
//! Creates a simple and updatable ITriangleSelector, based on a the mesh owned by an
1808
//! animated scene node
1809
ITriangleSelector* CSceneManager::createTriangleSelector(IAnimatedMeshSceneNode* node)
1811
if (!node || !node->getMesh())
1814
return new CTriangleSelector(node);
1818
//! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.
1819
ITriangleSelector* CSceneManager::createTriangleSelectorFromBoundingBox(ISceneNode* node)
1824
return new CTriangleBBSelector(node);
1828
//! Creates a simple ITriangleSelector, based on a mesh.
1829
ITriangleSelector* CSceneManager::createOctreeTriangleSelector(IMesh* mesh,
1830
ISceneNode* node, s32 minimalPolysPerNode)
1835
return new COctreeTriangleSelector(mesh, node, minimalPolysPerNode);
1839
//! Creates a meta triangle selector.
1840
IMetaTriangleSelector* CSceneManager::createMetaTriangleSelector()
1842
return new CMetaTriangleSelector();
1846
//! Creates a triangle selector which can select triangles from a terrain scene node
1847
ITriangleSelector* CSceneManager::createTerrainTriangleSelector(
1848
ITerrainSceneNode* node, s32 LOD)
1850
return new CTerrainTriangleSelector(node, LOD);
1855
//! Adds a scene node to the deletion queue.
1856
void CSceneManager::addToDeletionQueue(ISceneNode* node)
1862
DeletionList.push_back(node);
1866
//! clears the deletion list
1867
void CSceneManager::clearDeletionList()
1869
if (DeletionList.empty())
1872
for (u32 i=0; i<DeletionList.size(); ++i)
1874
DeletionList[i]->remove();
1875
DeletionList[i]->drop();
1878
DeletionList.clear();
1882
//! Returns the first scene node with the specified name.
1883
ISceneNode* CSceneManager::getSceneNodeFromName(const char* name, ISceneNode* start)
1886
start = getRootSceneNode();
1888
if (!strcmp(start->getName(),name))
1891
ISceneNode* node = 0;
1893
const ISceneNodeList& list = start->getChildren();
1894
ISceneNodeList::ConstIterator it = list.begin();
1895
for (; it!=list.end(); ++it)
1897
node = getSceneNodeFromName(name, *it);
1906
//! Returns the first scene node with the specified id.
1907
ISceneNode* CSceneManager::getSceneNodeFromId(s32 id, ISceneNode* start)
1910
start = getRootSceneNode();
1912
if (start->getID() == id)
1915
ISceneNode* node = 0;
1917
const ISceneNodeList& list = start->getChildren();
1918
ISceneNodeList::ConstIterator it = list.begin();
1919
for (; it!=list.end(); ++it)
1921
node = getSceneNodeFromId(id, *it);
1930
//! Returns the first scene node with the specified type.
1931
ISceneNode* CSceneManager::getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start)
1934
start = getRootSceneNode();
1936
if (start->getType() == type || ESNT_ANY == type)
1939
ISceneNode* node = 0;
1941
const ISceneNodeList& list = start->getChildren();
1942
ISceneNodeList::ConstIterator it = list.begin();
1943
for (; it!=list.end(); ++it)
1945
node = getSceneNodeFromType(type, *it);
1954
//! returns scene nodes by type.
1955
void CSceneManager::getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array<scene::ISceneNode*>& outNodes, ISceneNode* start)
1958
start = getRootSceneNode();
1960
if (start->getType() == type || ESNT_ANY == type)
1961
outNodes.push_back(start);
1963
const ISceneNodeList& list = start->getChildren();
1964
ISceneNodeList::ConstIterator it = list.begin();
1966
for (; it!=list.end(); ++it)
1968
getSceneNodesFromType(type, outNodes, *it);
1973
//! Posts an input event to the environment. Usually you do not have to
1974
//! use this method, it is used by the internal engine.
1975
bool CSceneManager::postEventFromUser(const SEvent& event)
1978
ICameraSceneNode* cam = getActiveCamera();
1980
ret = cam->OnEvent(event);
1982
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
1987
//! Removes all children of this scene node
1988
void CSceneManager::removeAll()
1990
ISceneNode::removeAll();
1992
// Make sure the driver is reset, might need a more complex method at some point
1994
Driver->setMaterial(video::SMaterial());
1998
//! Clears the whole scene. All scene nodes are removed.
1999
void CSceneManager::clear()
2005
//! Returns interface to the parameters set in this scene.
2006
io::IAttributes* CSceneManager::getParameters()
2012
//! Returns current render pass.
2013
E_SCENE_NODE_RENDER_PASS CSceneManager::getSceneNodeRenderPass() const
2015
return CurrentRendertime;
2019
//! Returns an interface to the mesh cache which is shared beween all existing scene managers.
2020
IMeshCache* CSceneManager::getMeshCache()
2026
//! Creates a new scene manager.
2027
ISceneManager* CSceneManager::createNewSceneManager(bool cloneContent)
2029
CSceneManager* manager = new CSceneManager(Driver, FileSystem, CursorControl, MeshCache, GUIEnvironment);
2032
manager->cloneMembers(this, manager);
2038
//! Returns the default scene node factory which can create all built in scene nodes
2039
ISceneNodeFactory* CSceneManager::getDefaultSceneNodeFactory()
2041
return getSceneNodeFactory(0);
2045
//! Adds a scene node factory to the scene manager.
2046
void CSceneManager::registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd)
2050
factoryToAdd->grab();
2051
SceneNodeFactoryList.push_back(factoryToAdd);
2056
//! Returns amount of registered scene node factories.
2057
u32 CSceneManager::getRegisteredSceneNodeFactoryCount() const
2059
return SceneNodeFactoryList.size();
2063
//! Returns a scene node factory by index
2064
ISceneNodeFactory* CSceneManager::getSceneNodeFactory(u32 index)
2066
if (index < SceneNodeFactoryList.size())
2067
return SceneNodeFactoryList[index];
2073
//! Returns the default scene node animator factory which can create all built-in scene node animators
2074
ISceneNodeAnimatorFactory* CSceneManager::getDefaultSceneNodeAnimatorFactory()
2076
return getSceneNodeAnimatorFactory(0);
2079
//! Adds a scene node animator factory to the scene manager.
2080
void CSceneManager::registerSceneNodeAnimatorFactory(ISceneNodeAnimatorFactory* factoryToAdd)
2084
factoryToAdd->grab();
2085
SceneNodeAnimatorFactoryList.push_back(factoryToAdd);
2090
//! Returns amount of registered scene node animator factories.
2091
u32 CSceneManager::getRegisteredSceneNodeAnimatorFactoryCount() const
2093
return SceneNodeAnimatorFactoryList.size();
2097
//! Returns a scene node animator factory by index
2098
ISceneNodeAnimatorFactory* CSceneManager::getSceneNodeAnimatorFactory(u32 index)
2100
if (index < SceneNodeAnimatorFactoryList.size())
2101
return SceneNodeAnimatorFactoryList[index];
2107
//! Saves the current scene into a file.
2108
//! \param filename: Name of the file .
2109
bool CSceneManager::saveScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer, ISceneNode* node)
2112
io::IWriteFile* file = FileSystem->createAndWriteFile(filename);
2115
ret = saveScene(file, userDataSerializer, node);
2118
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
2123
//! Saves the current scene into a file.
2124
bool CSceneManager::saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer, ISceneNode* node)
2128
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
2132
io::IXMLWriter* writer = FileSystem->createXMLWriter(file);
2135
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
2141
writer->writeXMLHeader();
2142
writeSceneNode(writer, node, userDataSerializer, FileSystem->getFileDir(FileSystem->getAbsolutePath(file->getFileName())).c_str(), true);
2150
bool CSceneManager::loadScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer, ISceneNode* rootNode)
2154
io::IReadFile* file = FileSystem->createAndOpenFile(filename);
2158
os::Printer::log("Unable to open scene file", filename.c_str(), ELL_ERROR);
2159
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
2163
// try scene loaders in reverse order
2164
s32 i = SceneLoaderList.size()-1;
2165
for (; i >= 0 && !ret; --i)
2166
if (SceneLoaderList[i]->isALoadableFileExtension(filename))
2167
ret = SceneLoaderList[i]->loadScene(file, userDataSerializer, rootNode);
2170
os::Printer::log("Could not load scene file, perhaps the format is unsupported: ", filename.c_str(), ELL_ERROR);
2173
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
2178
//! Loads a scene. Note that the current scene is not cleared before.
2179
bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer, ISceneNode* rootNode)
2183
os::Printer::log("Unable to open scene file", ELL_ERROR);
2184
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
2190
// try scene loaders in reverse order
2191
s32 i = SceneLoaderList.size()-1;
2192
for (; i >= 0 && !ret; --i)
2193
if (SceneLoaderList[i]->isALoadableFileFormat(file))
2194
ret = SceneLoaderList[i]->loadScene(file, userDataSerializer, rootNode);
2197
os::Printer::log("Could not load scene file, perhaps the format is unsupported: ", file->getFileName().c_str(), ELL_ERROR);
2199
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
2203
//! writes a scene node
2204
void CSceneManager::writeSceneNode(io::IXMLWriter* writer, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer,
2205
const fschar_t* currentPath, bool init)
2207
if (!writer || !node || node->isDebugObject())
2210
const wchar_t* name;
2211
ISceneNode* tmpNode=node;
2215
name = IRR_XML_FORMAT_SCENE.c_str();
2216
writer->writeElement(name, false);
2221
name = IRR_XML_FORMAT_NODE.c_str();
2222
writer->writeElement(name, false, IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str(),
2223
core::stringw(getSceneNodeTypeName(node->getType())).c_str());
2226
writer->writeLineBreak();
2230
io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
2231
io::SAttributeReadWriteOptions options;
2234
options.Filename=currentPath;
2235
options.Flags|=io::EARWF_USE_RELATIVE_PATHS;
2237
node->serializeAttributes(attr, &options);
2239
if (attr->getAttributeCount() != 0)
2241
attr->write(writer);
2242
writer->writeLineBreak();
2247
if (node->getMaterialCount() && getVideoDriver())
2249
const wchar_t* materialElement = L"materials";
2251
writer->writeElement(materialElement);
2252
writer->writeLineBreak();
2254
for (u32 i=0; i < node->getMaterialCount(); ++i)
2256
io::IAttributes* tmp_attr =
2257
getVideoDriver()->createAttributesFromMaterial(node->getMaterial(i), &options);
2258
tmp_attr->write(writer);
2262
writer->writeClosingTag(materialElement);
2263
writer->writeLineBreak();
2268
if (!node->getAnimators().empty())
2270
const wchar_t* animatorElement = L"animators";
2271
writer->writeElement(animatorElement);
2272
writer->writeLineBreak();
2274
ISceneNodeAnimatorList::ConstIterator it = node->getAnimators().begin();
2275
for (; it != node->getAnimators().end(); ++it)
2278
attr->addString("Type", getAnimatorTypeName((*it)->getType()));
2280
(*it)->serializeAttributes(attr);
2282
attr->write(writer);
2285
writer->writeClosingTag(animatorElement);
2286
writer->writeLineBreak();
2289
// write possible user data
2291
if (userDataSerializer)
2293
io::IAttributes* userData = userDataSerializer->createUserData(node);
2296
const wchar_t* userDataElement = L"userData";
2298
writer->writeLineBreak();
2299
writer->writeElement(userDataElement);
2300
writer->writeLineBreak();
2302
userData->write(writer);
2304
writer->writeClosingTag(userDataElement);
2305
writer->writeLineBreak();
2306
writer->writeLineBreak();
2311
// reset to actual root node
2315
// write children once root node is written
2316
// if parent is not scene manager, we need to write out node first
2317
if (init && (node != this))
2319
writeSceneNode(writer, node, userDataSerializer, currentPath);
2323
ISceneNodeList::ConstIterator it = node->getChildren().begin();
2324
for (; it != node->getChildren().end(); ++it)
2325
writeSceneNode(writer, (*it), userDataSerializer, currentPath);
2330
writer->writeClosingTag(name);
2331
writer->writeLineBreak();
2332
writer->writeLineBreak();
2336
//! Returns a typename from a scene node type or null if not found
2337
const c8* CSceneManager::getSceneNodeTypeName(ESCENE_NODE_TYPE type)
2339
const char* name = 0;
2341
for (s32 i=(s32)SceneNodeFactoryList.size()-1; !name && i>=0; --i)
2342
name = SceneNodeFactoryList[i]->getCreateableSceneNodeTypeName(type);
2347
//! Adds a scene node to the scene by name
2348
ISceneNode* CSceneManager::addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent)
2350
ISceneNode* node = 0;
2352
for (s32 i=(s32)SceneNodeFactoryList.size()-1; i>=0 && !node; --i)
2353
node = SceneNodeFactoryList[i]->addSceneNode(sceneNodeTypeName, parent);
2358
ISceneNodeAnimator* CSceneManager::createSceneNodeAnimator(const char* typeName, ISceneNode* target)
2360
ISceneNodeAnimator *animator = 0;
2362
for (s32 i=(s32)SceneNodeAnimatorFactoryList.size()-1; i>=0 && !animator; --i)
2363
animator = SceneNodeAnimatorFactoryList[i]->createSceneNodeAnimator(typeName, target);
2369
//! Returns a typename from a scene node animator type or null if not found
2370
const c8* CSceneManager::getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type)
2372
const char* name = 0;
2374
for (s32 i=SceneNodeAnimatorFactoryList.size()-1; !name && i >= 0; --i)
2375
name = SceneNodeAnimatorFactoryList[i]->getCreateableSceneNodeAnimatorTypeName(type);
2381
//! Writes attributes of the scene node.
2382
void CSceneManager::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
2384
out->addString ("Name", Name.c_str());
2385
out->addInt ("Id", ID );
2386
out->addColorf ("AmbientLight", AmbientLight);
2388
// fog attributes from video driver
2389
video::SColor color;
2390
video::E_FOG_TYPE fogType;
2391
f32 start, end, density;
2392
bool pixelFog, rangeFog;
2394
Driver->getFog(color, fogType, start, end, density, pixelFog, rangeFog);
2396
out->addEnum("FogType", fogType, video::FogTypeNames);
2397
out->addColorf("FogColor", color);
2398
out->addFloat("FogStart", start);
2399
out->addFloat("FogEnd", end);
2400
out->addFloat("FogDensity", density);
2401
out->addBool("FogPixel", pixelFog);
2402
out->addBool("FogRange", rangeFog);
2405
//! Reads attributes of the scene node.
2406
void CSceneManager::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
2408
Name = in->getAttributeAsString("Name");
2409
ID = in->getAttributeAsInt("Id");
2410
AmbientLight = in->getAttributeAsColorf("AmbientLight");
2413
video::SColor color;
2414
video::E_FOG_TYPE fogType;
2415
f32 start, end, density;
2416
bool pixelFog, rangeFog;
2417
if (in->existsAttribute("FogType"))
2419
fogType = (video::E_FOG_TYPE) in->getAttributeAsEnumeration("FogType", video::FogTypeNames);
2420
color = in->getAttributeAsColorf("FogColor").toSColor();
2421
start = in->getAttributeAsFloat("FogStart");
2422
end = in->getAttributeAsFloat("FogEnd");
2423
density = in->getAttributeAsFloat("FogDensity");
2424
pixelFog = in->getAttributeAsBool("FogPixel");
2425
rangeFog = in->getAttributeAsBool("FogRange");
2426
Driver->setFog(color, fogType, start, end, density, pixelFog, rangeFog);
2429
RelativeTranslation.set(0,0,0);
2430
RelativeRotation.set(0,0,0);
2431
RelativeScale.set(1,1,1);
2433
AutomaticCullingState = scene::EAC_BOX;
2434
DebugDataVisible = scene::EDS_OFF;
2435
IsDebugObject = false;
2437
updateAbsolutePosition();
2441
//! Sets ambient color of the scene
2442
void CSceneManager::setAmbientLight(const video::SColorf &ambientColor)
2444
AmbientLight = ambientColor;
2448
//! Returns ambient color of the scene
2449
const video::SColorf& CSceneManager::getAmbientLight() const
2451
return AmbientLight;
2455
//! Get a skinned mesh, which is not available as header-only code
2456
ISkinnedMesh* CSceneManager::createSkinnedMesh()
2458
#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
2459
return new CSkinnedMesh();
2465
//! Returns a mesh writer implementation if available
2466
IMeshWriter* CSceneManager::createMeshWriter(EMESH_WRITER_TYPE type)
2471
#ifdef _IRR_COMPILE_WITH_IRR_WRITER_
2472
return new CIrrMeshWriter(Driver, FileSystem);
2477
#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_
2478
return new CColladaMeshWriter(this, Driver, FileSystem);
2483
#ifdef _IRR_COMPILE_WITH_STL_WRITER_
2484
return new CSTLMeshWriter(this);
2489
#ifdef _IRR_COMPILE_WITH_OBJ_WRITER_
2490
return new COBJMeshWriter(this, FileSystem);
2496
#ifdef _IRR_COMPILE_WITH_PLY_WRITER_
2497
return new CPLYMeshWriter();
2507
// creates a scenemanager
2508
ISceneManager* createSceneManager(video::IVideoDriver* driver,
2509
io::IFileSystem* fs, gui::ICursorControl* cursorcontrol,
2510
gui::IGUIEnvironment *guiEnvironment)
2512
return new CSceneManager(driver, fs, cursorcontrol, 0, guiEnvironment );
2516
} // end namespace scene
2517
} // end namespace irr