diff --git a/examples/08.SpecialFX/main.cpp b/examples/08.SpecialFX/main.cpp
index 5ac743e9..dcfc1645 100644
--- a/examples/08.SpecialFX/main.cpp
+++ b/examples/08.SpecialFX/main.cpp
@@ -214,6 +214,21 @@ int main()
anode->setPosition(core::vector3df(-50,20,-60));
anode->setAnimationSpeed(15);
+ //volumetric lighting
+ scene::ISceneNode * n = smgr->addVolumeLightSceneNode(NULL, -1,
+ 32, //Sub Divid U
+ 32, //Sub Divid V
+ video::SColor(0, 180, 180, 180), //foot colour
+ video::SColor(0, 0, 0, 0) //tail colour
+ );
+
+ if (n) {
+ n->setScale(core::vector3df(56.0f, 56.0f, 56.0f));
+ n->setPosition(core::vector3df(-120,60,40));
+ video::SMaterial& mat = n->getMaterial(0);
+ mat.setTexture(0, smgr->getVideoDriver()->getTexture("../../media/lightFalloff.png"));
+ }
+
// add shadow
anode->addShadowVolumeSceneNode();
smgr->setShadowColor(video::SColor(150,0,0,0));
diff --git a/include/ISceneManager.h b/include/ISceneManager.h
index d17b32cf..d5790824 100644
--- a/include/ISceneManager.h
+++ b/include/ISceneManager.h
@@ -1,1225 +1,1250 @@
-// 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_MANAGER_H_INCLUDED__
-#define __I_SCENE_MANAGER_H_INCLUDED__
-
-#include "IReferenceCounted.h"
-#include "irrArray.h"
-#include "vector3d.h"
-#include "dimension2d.h"
-#include "SColor.h"
-#include "ETerrainElements.h"
-#include "ESceneNodeTypes.h"
-#include "EMeshWriterEnums.h"
-#include "SceneParameters.h"
-
-namespace irr
-{
- struct SKeyMap;
- struct SEvent;
-
-namespace io
-{
- class IReadFile;
- class IAttributes;
- class IWriteFile;
-} // end namespace io
-
-namespace gui
-{
- class IGUIFont;
- class IGUIEnvironment;
-} // end namespace gui
-
-namespace video
-{
- class IVideoDriver;
- class SMaterial;
- class IImage;
- class ITexture;
-} // end namespace video
-
-namespace scene
-{
- class IMeshWriter;
-
- //! Enumeration for render passes.
- /** A parameter passed to the registerNodeForRendering() method of the ISceneManager,
- specifying when the mode wants to be drawn in relation to the other nodes. */
- enum E_SCENE_NODE_RENDER_PASS
- {
- //! Camera pass. The active view is set up here.
- //! The very first pass.
- ESNRP_CAMERA,
-
- //! In this pass, lights are transformed into camera space and added to the driver
- ESNRP_LIGHT,
-
- //! This is used for sky boxes.
- ESNRP_SKY_BOX,
-
- //! All normal objects can use this for registering themselves.
- //! This value will never be returned by ISceneManager::getSceneNodeRenderPass().
- //! The scene manager will determine by itself if an object is
- //! transparent or solid and register the object as SNRT_TRANSPARENT or
- //! SNRT_SOLD automatically if you call registerNodeForRendering with this
- //! value (which is default). Note that it will register the node only as ONE type.
- //! If your scene node has both solid and transparent material types register
- //! it twice (one time as SNRT_SOLID, the other time as SNRT_TRANSPARENT) and
- //! in the render() method call getSceneNodeRenderPass() to find out the current
- //! render pass and render only the corresponding parts of the node.
- ESNRP_AUTOMATIC,
-
- //! Solid scene nodes or special scene nodes without materials.
- ESNRP_SOLID,
-
- //! Drawn after the transparent nodes, the time for drawing shadow volumes
- ESNRP_SHADOW,
-
- //! Transparent scene nodes, drawn after shadow nodes. They are sorted from back
- //! to front and drawn in that order.
- ESNRP_TRANSPARENT,
-
- //! Never used, value specifing how much parameters there are.
- ESNRP_COUNT
- };
-
- class IMesh;
- class IMeshBuffer;
- class IAnimatedMesh;
- class IMeshCache;
- class ISceneNode;
- class ICameraSceneNode;
- class IAnimatedMeshSceneNode;
- class ISceneNodeAnimator;
- class ISceneNodeAnimatorCollisionResponse;
- class ILightSceneNode;
- class IBillboardSceneNode;
- class ITerrainSceneNode;
- class IMeshSceneNode;
- class IMeshLoader;
- class ISceneCollisionManager;
- class IParticleSystemSceneNode;
- class IDummyTransformationSceneNode;
- class ITriangleSelector;
- class IMetaTriangleSelector;
- class IMeshManipulator;
- class ITextSceneNode;
- class ISceneNodeFactory;
- class ISceneNodeAnimatorFactory;
- class ISceneUserDataSerializer;
-
- namespace quake3
- {
- class SShader;
- } // end namespace quake3
-
- //! The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff.
- /** All Scene nodes can be created only here. There is a always growing list of scene
- nodes for lots of purposes: Indoor rendering scene nodes like the Octree
- (addOctTreeSceneNode()) or the terrain renderer (addTerrainSceneNode()),
- different Camera scene nodes (addCameraSceneNode(), addCameraSceneNodeMaya()),
- scene nodes for Light (addLightSceneNode()), Billboards (addBillboardSceneNode())
- and so on.
- A scene node is a node in the hierachical scene graph. Every scene node may have children,
- which are other scene nodes. Children move relative the their parents position. If the parent of a node is not
- visible, its children won't be visible, too. In this way, it is for example easily possible
- to attach a light to a moving car or to place a walking character on a moving platform
- on a moving ship.
- The SceneManager is also able to load 3d mesh files of different formats. Take a look
- at getMesh() to find out what formats are supported. And if these formats are not enough
- use addExternalMeshLoader() to add new formats to the engine.
- */
- class ISceneManager : public virtual IReferenceCounted
- {
- public:
-
- //! destructor
- virtual ~ISceneManager() {}
-
- //! Returns pointer to an animateable mesh. Loads the file if not loaded already.
- /**
- * If you want to remove a loaded mesh from the cache again, use removeMesh().
- * Currently there are the following mesh formats supported:
- *
- *
- * Format |
- * Description |
- *
- *
- * 3D Studio (.3ds) |
- * Loader for 3D-Studio files which lots of 3D packages are able to export.
- * Only static meshes are currently supported by this importer. |
- *
- *
- * Bliz Basic B3D (.b3d) |
- * Loader for blitz basic files, developed by Mark Sibly, also supports animations. |
- *
- *
- * Cartography shop 4 (.csm) |
- * Cartography Shop is a modeling program for creating architecture and calculating
- * lighting. Irrlicht can directly import .csm files thanks to the IrrCSM library
- * created by Saurav Mohapatra which is now integrated directly in Irrlicht.
- * If you are using this loader, please note that you'll have to set the path
- * of the textures before loading .csm files. You can do this using SceneManager->getParameters()->setParameter(scene::CSM_TEXTURE_PATH,
- * "path/to/your/textures"); |
- *
- *
- * COLLADA (.dae, .xml) |
- * COLLADA is an open Digital Asset Exchange Schema for the interactive 3D industry. There are
- * exporters and importers for this format available for most of the big 3d packages
- * at http://collada.org. Irrlicht can import COLLADA files by using the
- * ISceneManager::getMesh() method. COLLADA files need not contain only one single mesh
- * but multiple meshes and a whole scene setup with lights, cameras and mesh instances,
- * this loader can set up a scene as described by the COLLADA file instead of loading
- * and returning one single mesh. By default, this loader behaves like the other loaders
- * and does not create instances, but it can be switched into this mode by using
- * SceneManager->getParameters()->setParameter(COLLADA_CREATE_SCENE_INSTANCES, true);
- * Created scene nodes will be named as the names of the nodes in the
- * COLLADA file. The returned mesh is just a dummy object in this mode. Meshes included in
- * the scene will be added into the scene manager with the following naming scheme:
- * path/to/file/file.dea#meshname. The loading of such meshes is logged.
- * Currently, this loader is able to create meshes (made of only polygons), lights,
- * and cameras. Materials and animations are currently not supported but this will
- * change with future releases.
- * |
- *
- *
- * Delgine DeleD (.dmf) |
- * DeleD (delgine.com) is a 3D editor and level-editor combined into one and is specifically
- * designed for 3D game-development. With this loader, it is possible to directly load
- * all geometry is as well as textures and lightmaps from .dmf files. To set texture and
- * material paths, see scene::DMF_USE_MATERIALS_DIRS and scene::DMF_TEXTURE_PATH. It is also
- * possible to flip the alpha texture by setting scene::DMF_FLIP_ALPHA_TEXTURES to true and
- * to set the material transparent reference value by setting scene::DMF_ALPHA_CHANNEL_REF to
- * a float between 0 and 1. The loader is
- * based on Salvatore Russo's .dmf loader, I just changed some parts of it. Thanks to
- * Salvatore for his work and for allowing me to use his code in Irrlicht and put it under Irrlicht's
- * license. For newer and more enchanced versions of the loader, take a look at delgine.com.
- * |
- *
- *
- * DirectX (.x) |
- * Platform independent importer (so not D3D-only) for .x files. Most 3D
- * packages can export these natively and there are several tools for them
- * available. (e.g. the Maya exporter included in the DX SDK) .x files can
- * include skeletal animations and Irrlicht is able to play and display them.
- * Currently, Irrlicht only supports uncompressed .x files. |
- *
- *
- * Maya (.obj) |
- * Most 3D software can create .obj files which contain static geometry without
- * material data. The material files .mtl are also supported. This importer
- * for Irrlicht can load them directly. |
- *
- *
- * Milkshape (.ms3d) |
- * .MS3D files contain models and sometimes skeletal animations from the
- * Milkshape 3D modeling and animation software. This importer for Irrlicht
- * can display and/or animate these files. |
- *
- *
- * My3D (.my3d) |
- * .my3D is a flexible 3D file format. The My3DTools contains plug-ins to
- * export .my3D files from several 3D packages. With this built-in importer,
- * Irrlicht can read and display those files directly. This loader was written
- * by Zhuck Dimitry who also created the whole My3DTools package. If you are using this loader, please
- * note that you can set the path of the textures before loading .my3d files.
- * You can do this using SceneManager->getParameters()->setParameter(scene::MY3D_TEXTURE_PATH,
- * "path/to/your/textures"); |
- *
- *
- * OCT (.oct) |
- * The oct file format contains 3D geometry and lightmaps and can be loaded
- * directly by Irrlicht. OCT files
- * can be created by FSRad, Paul Nette's radiosity processor or exported from
- * Blender using OCTTools which can be found in the exporters/OCTTools directory
- * of the SDK. Thanks to Murphy McCauley for creating all this. |
- *
- *
- * OGRE Meshes (.mesh) |
- * Ogre .mesh files contain 3D data for the OGRE 3D engine. Irrlicht can read and
- * display them directly with this importer. To define materials for the mesh,
- * copy a .material file named like the corresponding .mesh file where the .mesh
- * file is. (For example ogrehead.material for ogrehead.mesh). Thanks to Christian Stehno
- * who wrote and contributed this loader. |
- *
- *
- * Pulsar LMTools (.lmts) |
- * LMTools is a set of tools (Windows & Linux) for creating lightmaps.
- * Irrlicht can directly read .lmts files thanks to
- * the importer created by Jonas Petersen. If you are using this loader, please
- * note that you can set the path of the textures before loading .lmts files.
- * You can do this using SceneManager->getParameters()->setParameter(scene::LMTS_TEXTURE_PATH,
- * "path/to/your/textures"); Notes for
- * this version of the loader:
- * - It does not recognice/support user data in the *.lmts files.
- * - The TGAs generated by LMTools don't work in Irrlicht for some reason (the
- * textures are upside down). Opening and resaving them in a graphics app will
- * solve the problem. |
- *
- *
- * Quake 3 levels (.bsp) |
- * Quake 3 is a popular game by IDSoftware, and .pk3 files contain .bsp files
- * and textures/lightmaps describing huge
- * prelighted levels. Irrlicht can read .pk3 and .bsp files directly and thus
- * render Quake 3 levels directly. Written by Nikolaus Gebhardt enhanced by
- * Dean P. Macri with the curved surfaces feature. |
- *
- *
- * Quake 2 models (.md2) |
- * Quake 2 models are characters with morph target animation. Irrlicht can
- * read, display and animate them directly with this importer. |
- *
- *
- *
- * To load and display a mesh quickly, just do this:
- * \code
- * SceneManager->addAnimatedMeshSceneNode(
- * SceneManager->getMesh("yourmesh.3ds"));
- * \endcode
- * If you would like to implement and add your own file format loader to Irrlicht,
- * see addExternalMeshLoader().
- * \param filename: Filename of the mesh to load.
- * \return Returns NULL if failed and the pointer to the mesh if
- * successful.
- * This pointer should not be dropped. See IReferenceCounted::drop() for more information.
- **/
- virtual IAnimatedMesh* getMesh(const c8* filename) = 0;
-
- //! Returns an interface to the mesh cache which is shared beween all existing scene managers.
- /** With this interface, it is possible to manually add new loaded
- meshes (if ISceneManager::getMesh() is not sufficient), to remove them and to iterate
- through already loaded meshes. */
- virtual IMeshCache* getMeshCache() = 0;
-
- //! Returns the video driver.
- /** \return Returns pointer to the video Driver.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual video::IVideoDriver* getVideoDriver() = 0;
-
- //! Returns the active GUIEnvironment
- /** \return Returns pointer to the GUIEnvironment
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual gui::IGUIEnvironment* getGUIEnvironment() = 0;
-
- //! Adds a test scene node for test purposes to the scene.
- /** It is a simple cube of (1,1,1) size.
- \param size: Size of the cube.
- \param parent: Parent of the scene node. Can be NULL if no parent.
- \param id: Id of the node. This id can be used to identify the scene node.
- \param position: Position of the space relative to its parent where the
- scene node will be placed.
- \param rotation: Initital rotation of the scene node.
- \param scale: Initial scale of the scene node.
- \return Returns pointer to the created test scene node.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ISceneNode* addCubeSceneNode(f32 size=10.0f, ISceneNode* parent=0, s32 id=-1,
- const core::vector3df& position = core::vector3df(0,0,0),
- const core::vector3df& rotation = core::vector3df(0,0,0),
- const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0;
-
- //! Adds a sphere scene node for test purposes to the scene.
- /** It is a simple sphere.
- \param radius: Radius of the sphere.
- \param polyCount: Polycount of the sphere.
- \param parent: Parent of the scene node. Can be NULL if no parent.
- \param id: Id of the node. This id can be used to identify the scene node.
- \param position: Position of the space relative to its parent where the
- scene node will be placed.
- \param rotation: Initital rotation of the scene node.
- \param scale: Initial scale of the scene node.
- \return Returns pointer to the created test scene node.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ISceneNode* addSphereSceneNode(f32 radius=5.0f, s32 polyCount=16, ISceneNode* parent=0, s32 id=-1,
- const core::vector3df& position = core::vector3df(0,0,0),
- const core::vector3df& rotation = core::vector3df(0,0,0),
- const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0;
-
- //! Adds a scene node for rendering an animated mesh model.
- /** \param mesh: Pointer to the loaded animated mesh to be displayed.
- \param parent: Parent of the scene node. Can be NULL if no parent.
- \param id: Id of the node. This id can be used to identify the scene node.
- \param position: Position of the space relative to its parent where the
- scene node will be placed.
- \param rotation: Initital rotation of the scene node.
- \param scale: Initial scale of the scene node.
- \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed.
- \return Returns pointer to the created scene node.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual IAnimatedMeshSceneNode* addAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, s32 id=-1,
- const core::vector3df& position = core::vector3df(0,0,0),
- const core::vector3df& rotation = core::vector3df(0,0,0),
- const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f),
- bool alsoAddIfMeshPointerZero=false) = 0;
-
- //! Adds a scene node for rendering a static mesh.
- /** \param mesh: Pointer to the loaded static mesh to be displayed.
- \param parent: Parent of the scene node. Can be NULL if no parent.
- \param id: Id of the node. This id can be used to identify the scene node.
- \param position: Position of the space relative to its parent where the
- scene node will be placed.
- \param rotation: Initital rotation of the scene node.
- \param scale: Initial scale of the scene node.
- \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed.
- \return Returns pointer to the created scene node.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual IMeshSceneNode* addMeshSceneNode(IMesh* mesh, ISceneNode* parent=0, s32 id=-1,
- const core::vector3df& position = core::vector3df(0,0,0),
- const core::vector3df& rotation = core::vector3df(0,0,0),
- const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f),
- bool alsoAddIfMeshPointerZero=false) = 0;
-
- //! Adds a scene node for rendering a animated water surface mesh.
- /** Looks really good when the Material type EMT_TRANSPARENT_REFLECTION
- is used.
- \param waveHeight: Height of the water waves.
- \param waveSpeed: Speed of the water waves.
- \param waveLength: Lenght of a water wave.
- \param mesh: Pointer to the loaded static mesh to be displayed with water waves on it.
- \param parent: Parent of the scene node. Can be NULL if no parent.
- \param id: Id of the node. This id can be used to identify the scene node.
- \param position: Position of the space relative to its parent where the
- scene node will be placed.
- \param rotation: Initital rotation of the scene node.
- \param scale: Initial scale of the scene node.
- \return Returns pointer to the created scene node.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ISceneNode* addWaterSurfaceSceneNode(IMesh* mesh,
- f32 waveHeight=2.0f, f32 waveSpeed=300.0f, f32 waveLength=10.0f,
- ISceneNode* parent=0, s32 id=-1,
- const core::vector3df& position = core::vector3df(0,0,0),
- const core::vector3df& rotation = core::vector3df(0,0,0),
- const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0;
-
-
- //! Adds a scene node for rendering using a octtree to the scene graph.
- /** This a good method for rendering
- scenes with lots of geometry. The Octree is built on the fly from the mesh.
- \param mesh: The mesh containing all geometry from which the octtree will be build.
- If this animated mesh has more than one frames in it, the first frame is taken.
- \param parent: Parent node of the octtree node.
- \param id: id of the node. This id can be used to identify the node.
- \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node.
- If a node gets less polys than this value it will not be split into
- smaller nodes.
- \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed.
- \return Returns the pointer to the OctTree if successful, otherwise 0.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ISceneNode* addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0,
- s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) = 0;
-
- //! Adds a scene node for rendering using a octtree to the scene graph.
- /** This a good method for rendering
- scenes with lots of geometry. The Octree is built on the fly from the mesh, much
- faster then a bsp tree.
- \param mesh: The mesh containing all geometry from which the octtree will be build.
- \param parent: Parent node of the octtree node.
- \param id: id of the node. This id can be used to identify the node.
- \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node.
- If a node gets less polys than this value it will not be split into
- smaller nodes.
- \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed.
- \return Returns the pointer to the octtree if successful, otherwise 0.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ISceneNode* addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent=0,
- s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) = 0;
-
- //! Adds a camera scene node to the scene graph and sets it as active camera.
- /** This camera does not react on user input like for example the one created with
- addCameraSceneNodeFPS(). If you want to move or animate it, use animators or the
- ISceneNode::setPosition(), ICameraSceneNode::setTarget() etc methods.
- \param position: Position of the space relative to its parent where the camera will be placed.
- \param lookat: Position where the camera will look at. Also known as target.
- \param parent: Parent scene node of the camera. Can be null. If the parent moves,
- the camera will move too.
- \param id: id of the camera. This id can be used to identify the camera.
- \return Returns pointer to interface to camera if successful, otherwise 0.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ICameraSceneNode* addCameraSceneNode(ISceneNode* parent = 0,
- const core::vector3df& position = core::vector3df(0,0,0),
- const core::vector3df& lookat = core::vector3df(0,0,100), s32 id=-1) = 0;
-
- //! Adds a maya style user controlled camera scene node to the scene graph.
- /** The maya camera is able to be controlled with the mouse similar
- like in the 3D Software Maya by Alias Wavefront.
- \param parent: Parent scene node of the camera. Can be null.
- \param rotateSpeed: Rotation speed of the camera.
- \param zoomSpeed: Zoom speed of the camera.
- \param translationSpeed: TranslationSpeed of the camera.
- \param id: id of the camera. This id can be used to identify the camera.
- \return Returns a pointer to the interface of the camera if successful, otherwise 0.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent = 0,
- f32 rotateSpeed = -1500.0f, f32 zoomSpeed = 200.0f, f32 translationSpeed = 1500.0f, s32 id=-1) = 0;
-
- //! Adds a camera scene node which is able to be controlled with the mouse and keys like in most first person shooters (FPS).
- /** Look with the mouse, move with cursor keys. If you do not like the default
- key layout, you may want to specify your own. For example to make the camera
- be controlled by the cursor keys AND the keys W,A,S, and D, do something
- like this:
- \code
- SKeyMap keyMap[8];
- keyMap[0].Action = EKA_MOVE_FORWARD;
- keyMap[0].KeyCode = KEY_UP;
- keyMap[1].Action = EKA_MOVE_FORWARD;
- keyMap[1].KeyCode = KEY_KEY_W;
-
- keyMap[2].Action = EKA_MOVE_BACKWARD;
- keyMap[2].KeyCode = KEY_DOWN;
- keyMap[3].Action = EKA_MOVE_BACKWARD;
- keyMap[3].KeyCode = KEY_KEY_S;
-
- keyMap[4].Action = EKA_STRAFE_LEFT;
- keyMap[4].KeyCode = KEY_LEFT;
- keyMap[5].Action = EKA_STRAFE_LEFT;
- keyMap[5].KeyCode = KEY_KEY_A;
-
- keyMap[6].Action = EKA_STRAFE_RIGHT;
- keyMap[6].KeyCode = KEY_RIGHT;
- keyMap[7].Action = EKA_STRAFE_RIGHT;
- keyMap[7].KeyCode = KEY_KEY_D;
-
- camera = sceneManager->addCameraSceneNodeFPS(0, 100, 500, -1, keyMap, 8);
- \endcode
- \param parent: Parent scene node of the camera. Can be null.
- \param rotateSpeed: Speed with which the camera is rotated. This can be done
- only with the mouse.
- \param moveSpeed: Speed with which the camera is moved. Movement is done with
- the cursor keys.
- \param id: id of the camera. This id can be used to identify the camera.
- \param keyMapArray: Optional pointer to an array of a keymap, specifying what
- keys should be used to move the camera. If this is null, the default keymap
- is used. You can define actions more then one time in the array, to bind
- multiple keys to the same action.
- \param keyMapSize: Amount of items in the keymap array.
- \param noVerticalMovement: Setting this to true makes the camera only move within a
- horizontal plane, and disables vertical movement as known from most ego shooters. Default
- is 'false', with which it is possible to fly around in space, if no gravity is there.
- \param jumpSpeed: Speed with which the camera is moved when jumping.
- \return Returns a pointer to the interface of the camera if successful, otherwise 0.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ICameraSceneNode* addCameraSceneNodeFPS(ISceneNode* parent = 0,
- f32 rotateSpeed = 100.0f, f32 moveSpeed = 500.0f, s32 id=-1,
- SKeyMap* keyMapArray=0, s32 keyMapSize=0, bool noVerticalMovement=false,
- f32 jumpSpeed = 0.f) = 0;
-
- //! Adds a dynamic light scene node to the scene graph.
- /** The light will cast dynamic light on all
- other scene nodes in the scene, which have the material flag video::MTF_LIGHTING
- turned on. (This is the default setting in most scene nodes).
- \param parent: Parent scene node of the light. Can be null. If the parent moves,
- the light will move too.
- \param position: Position of the space relative to its parent where the light will be placed.
- \param color: Diffuse color of the light. Ambient or Specular colors can be set manually with
- the ILightSceneNode::getLightData() method.
- \param radius: Radius of the light.
- \param id: id of the node. This id can be used to identify the node.
- \return Returns pointer to the interface of the light if successful, otherwise NULL.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ILightSceneNode* addLightSceneNode(ISceneNode* parent = 0,
- const core::vector3df& position = core::vector3df(0,0,0),
- video::SColorf color = video::SColorf(1.0f, 1.0f, 1.0f),
- f32 radius=100.0f, s32 id=-1) = 0;
-
- //! Adds a billboard scene node to the scene graph.
- /** A billboard is like a 3d sprite: A 2d element,
- which always looks to the camera. It is usually used for things like explosions, fire,
- lensflares and things like that.
- \param parent: Parent scene node of the billboard. Can be null. If the parent moves,
- the billboard will move too.
- \param position: Position of the space relative to its parent where the billboard will be placed.
- \param size: Size of the billboard. This size is 2 dimensional because a billboard only has
- width and height.
- \param id: An id of the node. This id can be used to identify the node.
- \param shade_top: vertex color top
- \param shade_down: vertex color down
- \return Returns pointer to the billboard if successful, otherwise NULL.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual IBillboardSceneNode* addBillboardSceneNode(ISceneNode* parent = 0,
- const core::dimension2d& size = core::dimension2d(10.0f, 10.0f),
- const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1,
- video::SColor shade_top = 0xFFFFFFFF, video::SColor shade_down = 0xFFFFFFFF) = 0;
-
- //! Adds a skybox scene node to the scene graph.
- /** A skybox is a big cube with 6 textures on it and
- is drawn around the camera position.
- \param top: Texture for the top plane of the box.
- \param bottom: Texture for the bottom plane of the box.
- \param left: Texture for the left plane of the box.
- \param right: Texture for the right plane of the box.
- \param front: Texture for the front plane of the box.
- \param back: Texture for the back plane of the box.
- \param parent: Parent scene node of the skybox. A skybox usually has no parent,
- so this should be null. Note: If a parent is set to the skybox, the box will not
- change how it is drawn.
- \param id: An id of the node. This id can be used to identify the node.
- \return Returns a pointer to the sky box if successful, otherwise NULL.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ISceneNode* addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom,
- video::ITexture* left, video::ITexture* right, video::ITexture* front,
- video::ITexture* back, ISceneNode* parent = 0, s32 id=-1) = 0;
-
- //! Adds a skydome scene node to the scene graph.
- /** A skydome is a large (half-) sphere with a panoramic texture
- on the inside and is drawn around the camera position.
- \param texture: Texture for the dome.
- \param horiRes: Number of vertices of a horizontal layer of the sphere.
- \param vertRes: Number of vertices of a vertical layer of the sphere.
- \param texturePercentage: How much of the height of the texture is used. Should be between 0 and 1.
- \param spherePercentage: How much of the sphere is drawn. Value should be between 0 and 2, where 1 is an exact half-sphere and 2 is a full sphere.
- \param parent: Parent scene node of the dome. A dome usually has no parent,
- so this should be null. Note: If a parent is set, the dome will not
- change how it is drawn.
- \param id: An id of the node. This id can be used to identify the node.
- \return Returns a pointer to the sky dome if successful, otherwise NULL.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ISceneNode* addSkyDomeSceneNode(video::ITexture* texture,
- u32 horiRes, u32 vertRes, f64 texturePercentage, f64 spherePercentage,
- ISceneNode* parent = 0, s32 id=-1) = 0;
-
- //! Adds a particle system scene node to the scene graph.
- /** \param withDefaultEmitter: Creates a default working point emitter
- which emitts some particles. Set this to true to see a particle system
- in action. If set to false, you'll have to set the emitter you want by
- calling IParticleSystemSceneNode::setEmitter().
- \param parent: Parent of the scene node. Can be NULL if no parent.
- \param id: Id of the node. This id can be used to identify the scene node.
- \param position: Position of the space relative to its parent where the
- scene node will be placed.
- \param rotation: Initital rotation of the scene node.
- \param scale: Initial scale of the scene node.
- \return Returns pointer to the created scene node.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual IParticleSystemSceneNode* addParticleSystemSceneNode(
- bool withDefaultEmitter=true, ISceneNode* parent=0, s32 id=-1,
- const core::vector3df& position = core::vector3df(0,0,0),
- const core::vector3df& rotation = core::vector3df(0,0,0),
- const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0;
-
- //! Adds a terrain scene node to the scene graph.
- /** This node implements is a simple terrain renderer which uses
- a technique known as geo mip mapping
- for reducing the detail of triangle blocks which are far away.
- The code for the TerrainSceneNode is based on the terrain
- renderer by Soconne and the GeoMipMapSceneNode developed by
- Spintz. They made their code available for Irrlicht and allowed
- it to be distributed under this licence. I only modified some
- parts. A lot of thanks go to them.
-
- This scene node is capable of loading terrains and updating
- the indices at runtime to enable viewing very large terrains
- very quickly. It uses a CLOD (Continuous Level of Detail)
- algorithm which updates the indices for each patch based on
- a LOD (Level of Detail) which is determined based on a patch's
- distance from the camera.
-
- The patch size of the terrain must always be a size of ( 2^N+1, i.e. 8+1(9), 16+1(17), etc. ).
- The MaxLOD available is directly dependent on the patch size of the terrain. LOD 0 contains all
- of the indices to draw all the triangles at the max detail for a patch. As each LOD goes up by 1
- the step taken, in generating indices increases by - 2^LOD, so for LOD 1, the step taken is 2, for
- LOD 2, the step taken is 4, LOD 3 - 8, etc. The step can be no larger than the size of the patch,
- so having a LOD of 8, with a patch size of 17, is asking the algoritm to generate indices every
- 2^8 ( 256 ) vertices, which is not possible with a patch size of 17. The maximum LOD for a patch
- size of 17 is 2^4 ( 16 ). So, with a MaxLOD of 5, you'll have LOD 0 ( full detail ), LOD 1 ( every
- 2 vertices ), LOD 2 ( every 4 vertices ), LOD 3 ( every 8 vertices ) and LOD 4 ( every 16 vertices ).
- \param heightMapFileName: The name of the file on disk, to read vertex data from. This should
- be a gray scale bitmap.
- \param parent: Parent of the scene node. Can be 0 if no parent.
- \param id: Id of the node. This id can be used to identify the scene node.
- \param position: The absolute position of this node.
- \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED )
- \param scale: The scale factor for the terrain. If you're using a heightmap of size 129x129 and would like
- your terrain to be 12900x12900 in game units, then use a scale factor of ( core::vector ( 100.0f, 100.0f, 100.0f ).
- If you use a Y scaling factor of 0.0f, then your terrain will be flat.
- \param vertexColor: The default color of all the vertices. If no texture is associated
- with the scene node, then all vertices will be this color. Defaults to white.
- \param maxLOD: The maximum LOD (level of detail) for the node. Only change if you
- know what you are doing, this might lead to strange behaviour.
- \param patchSize: patch size of the terrain. Only change if you
- know what you are doing, this might lead to strange behaviour.
- \param smoothFactor: The number of times the vertices are smoothed.
- \param addAlsoIfHeightmapEmpty: Add terrain node even with empty heightmap.
- \return Returns pointer to the created scene node. Can be null if the
- terrain could not be created, for example because the heightmap could not be loaded.
- The returned pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ITerrainSceneNode* addTerrainSceneNode(
- const c8* heightMapFileName,
- ISceneNode* parent=0, s32 id=-1,
- const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f),
- const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f),
- const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f),
- video::SColor vertexColor = video::SColor(255,255,255,255),
- s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17, s32 smoothFactor=0,
- bool addAlsoIfHeightmapEmpty = false) = 0;
-
- //! Adds a terrain scene node to the scene graph.
- /** Just like the other addTerrainSceneNode() method, but takes an IReadFile
- pointer as parameter for the heightmap. For more informations take a look
- at the other function.
- \param heightMapFile: The file handle to read vertex data from. This should
- be a gray scale bitmap.
- \param parent: Parent of the scene node. Can be 0 if no parent.
- \param id: Id of the node. This id can be used to identify the scene node.
- \param position: The absolute position of this node.
- \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED )
- \param scale: The scale factor for the terrain. If you're using a heightmap of size 129x129 and would like
- your terrain to be 12900x12900 in game units, then use a scale factor of ( core::vector ( 100.0f, 100.0f, 100.0f ).
- If you use a Y scaling factor of 0.0f, then your terrain will be flat.
- \param vertexColor: The default color of all the vertices. If no texture is associated
- with the scene node, then all vertices will be this color. Defaults to white.
- \param maxLOD: The maximum LOD (level of detail) for the node. Only change if you
- know what you are doing, this might lead to strange behaviour.
- \param patchSize: patch size of the terrain. Only change if you
- know what you are doing, this might lead to strange behaviour.
- \param smoothFactor: The number of times the vertices are smoothed.
- \param addAlsoIfHeightmapEmpty: Add terrain node even with empty heightmap.
- \return Returns pointer to the created scene node. Can be null if the
- terrain could not be created, for example because the heightmap could not be loaded.
- The returned pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ITerrainSceneNode* addTerrainSceneNode(
- io::IReadFile* heightMapFile,
- ISceneNode* parent=0, s32 id=-1,
- const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f),
- const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f),
- const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f),
- video::SColor vertexColor = video::SColor(255,255,255,255),
- s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17, s32 smoothFactor=0,
- bool addAlsoIfHeightmapEmpty = false) = 0;
-
- //! Adds a quake3 scene node to the scene graph.
- /** A Quake3 Scene renders multiple meshes for a specific HighLanguage Shader (Quake3 Style )
- \return Returns a pointer to the quake3 scene node if successful, otherwise NULL.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ISceneNode* addQuake3SceneNode(IMeshBuffer* meshBuffer, const quake3::SShader * shader,
- ISceneNode* parent=0, s32 id=-1
- ) = 0;
-
-
- //! Adds an empty scene node to the scene graph.
- /** Can be used for doing advanced transformations
- or structuring the scene graph.
- \return Returns pointer to the created scene node.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual ISceneNode* addEmptySceneNode(ISceneNode* parent=0, s32 id=-1) = 0;
-
- //! Adds a dummy transformation scene node to the scene graph.
- /** This scene node does not render itself, and does not respond to set/getPosition,
- set/getRotation and set/getScale. Its just a simple scene node that takes a
- matrix as relative transformation, making it possible to insert any transformation
- anywhere into the scene graph.
- \return Returns pointer to the created scene node.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual IDummyTransformationSceneNode* addDummyTransformationSceneNode(
- ISceneNode* parent=0, s32 id=-1) = 0;
-
- //! Adds a text scene node, which is able to display 2d text at a position in three dimensional space
- virtual ITextSceneNode* addTextSceneNode(gui::IGUIFont* font, const wchar_t* text,
- video::SColor color=video::SColor(100,255,255,255),
- ISceneNode* parent = 0, const core::vector3df& position = core::vector3df(0,0,0),
- s32 id=-1) = 0;
-
- //! Adds a text scene node, which uses billboards
- virtual ITextSceneNode* addBillboardTextSceneNode( gui::IGUIFont* font, const wchar_t* text,
- ISceneNode* parent = 0,
- const core::dimension2d& size = core::dimension2d(10.0f, 10.0f),
- const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1,
- video::SColor shade_top = 0xFFFFFFFF, video::SColor shade_down = 0xFFFFFFFF) = 0;
-
- //! Adds a Hill Plane mesh to the mesh pool.
- /** The mesh is generated on the fly
- and looks like a plane with some hills on it. It is uses mostly for quick
- tests of the engine only. You can specify how many hills there should be
- on the plane and how high they should be. Also you must specify a name for
- the mesh, because the mesh is added to the mesh pool, and can be retrieved
- again using ISceneManager::getMesh() with the name as parameter.
- \param name: The name of this mesh which must be specified in order
- to be able to retrieve the mesh later with ISceneManager::getMesh().
- \param tileSize: Size of a tile of the mesh. (10.0f, 10.0f) would be a
- good value to start, for example.
- \param tileCount: Specifies how much tiles there will be. If you specifiy
- for example that a tile has the size (10.0f, 10.0f) and the tileCount is
- (10,10), than you get a field of 100 tiles which has the dimension 100.0fx100.0f.
- \param material: Material of the hill mesh.
- \param hillHeight: Height of the hills. If you specify a negative value
- you will get holes instead of hills. If the height is 0, no hills will be
- created.
- \param countHills: Amount of hills on the plane. There will be countHills.X
- hills along the X axis and countHills.Y along the Y axis. So in total there
- will be countHills.X * countHills.Y hills.
- \param textureRepeatCount: Defines how often the texture will be repeated in
- x and y direction.
- \return Returns null if the creation failed. The reason could be that you
- specified some invalid parameters or that a mesh with that name already
- exists. If successful, a pointer to the mesh is returned.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual IAnimatedMesh* addHillPlaneMesh(const c8* name,
- const core::dimension2d& tileSize, const core::dimension2d& tileCount,
- video::SMaterial* material = 0, f32 hillHeight = 0.0f,
- const core::dimension2d& countHills = core::dimension2d(0.0f, 0.0f),
- const core::dimension2d& textureRepeatCount = core::dimension2d(1.0f, 1.0f)) = 0;
-
- //! Adds a static terrain mesh to the mesh pool.
- /** The mesh is generated on the fly
- from a texture file and a height map file. Both files may be huge
- (8000x8000 pixels would be no problem) because the generator splits the
- files into smaller textures if necessary.
- You must specify a name for the mesh, because the mesh is added to the mesh pool,
- and can be retrieved again using ISceneManager::getMesh() with the name as parameter.
- \param meshname: The name of this mesh which must be specified in order
- to be able to retrieve the mesh later with ISceneManager::getMesh().
- \param texture: Texture for the terrain. Please note that this is not a
- hardware texture as usual (ITexture), but an IImage software texture.
- You can load this texture with IVideoDriver::createImageFromFile().
- \param heightmap: A grayscaled heightmap image. Like the texture,
- it can be created with IVideoDriver::createImageFromFile(). The amount
- of triangles created depends on the size of this texture, so use a small
- heightmap to increase rendering speed.
- \param stretchSize: Parameter defining how big a is pixel on the heightmap.
- \param maxHeight: Defines how height a white pixel on the heighmap is.
- \param defaultVertexBlockSize: Defines the initial dimension between vertices.
- \return Returns null if the creation failed. The reason could be that you
- specified some invalid parameters, that a mesh with that name already
- exists, or that a texture could not be found. If successful, a pointer to the mesh is returned.
- This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
- virtual IAnimatedMesh* addTerrainMesh(const c8* meshname,
- video::IImage* texture, video::IImage* heightmap,
- const core::dimension2d& stretchSize = core::dimension2d(10.0f,10.0f),
- f32 maxHeight=200.0f,
- const core::dimension2d& defaultVertexBlockSize = core::dimension2d(64,64)) = 0;
-
- //! add a static arrow mesh to the meshpool
- virtual IAnimatedMesh* addArrowMesh(const c8* name,
- video::SColor vtxColor0=0xFFFFFFFF,
- video::SColor vtxColor1=0xFFFFFFFF,
- u32 tesselationCylinder=4, u32 tesselationCone=8,
- f32 height=1.f, f32 cylinderHeight=0.6f,
- f32 width0=0.05f, f32 width1=0.3f) = 0;
-
- //! add a static sphere mesh to the meshpool
- virtual IAnimatedMesh* addSphereMesh(const c8* name,
- f32 radius=5.f, u32 polyCountX = 16,
- u32 polyCountY = 16) = 0;
-
- //! Returns the root scene node.
- /** This is the scene node which is parent
- of all scene nodes. The root scene node is a special scene node which
- only exists to manage all scene nodes. It will not be rendered and cannot
- be removed from the scene.
- \return Returns a pointer to the root scene node. */
- virtual ISceneNode* getRootSceneNode() = 0;
-
- //! Returns the first scene node with the specified id.
- /** \param id: The id to search for
- \param start: Scene node to start from. All children of this scene
- node are searched. If null is specified, the root scene node is
- taken.
- \return Returns pointer to the first scene node with this id,
- and null if no scene node could be found. */
- virtual ISceneNode* getSceneNodeFromId(s32 id, ISceneNode* start=0) = 0;
-
- //! Returns the first scene node with the specified name.
- /** \param name: The name to search for
- \param start: Scene node to start from. All children of this scene
- node are searched. If null is specified, the root scene node is
- taken.
- \return Returns pointer to the first scene node with this id,
- and null if no scene node could be found. */
- virtual ISceneNode* getSceneNodeFromName(const c8* name, ISceneNode* start=0) = 0;
-
- //! Returns the first scene node with the specified type.
- /** \param type: The type to search for
- \param start: Scene node to start from. All children of this scene
- node are searched. If null is specified, the root scene node is
- taken.
- \return Returns pointer to the first scene node with this type,
- and null if no scene node could be found. */
- virtual ISceneNode* getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start=0) = 0;
-
- //! returns scene nodes by type.
- /** \param type: Type of scene node to find.
- \param outNodes: array to be filled with results.
- \param start: Scene node to start from. All children of this scene
- node are searched. If null is specified, the root scene node is
- taken. */
- virtual void getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array& outNodes, ISceneNode* start=0) = 0;
-
- //! Returns the current active camera.
- /** \return The active camera is returned. Note that this can be NULL, if there
- was no camera created yet. */
- virtual ICameraSceneNode* getActiveCamera() = 0;
-
- //! Sets the currently active camera.
- /** The previous active camera will be deactivated.
- \param camera: The new camera which should be active. */
- virtual void setActiveCamera(ICameraSceneNode* camera) = 0;
-
- //! Sets the color of stencil buffers shadows drawn by the scene manager.
- virtual void setShadowColor(video::SColor color = video::SColor(150,0,0,0)) = 0;
-
- //! Returns the current color of shadows.
- virtual video::SColor getShadowColor() const = 0;
-
- //! Registers a node for rendering it at a specific time.
- /** This method should only be used by SceneNodes when they get a
- ISceneNode::OnRegisterSceneNode() call.
- \param node: Node to register for drawing. Usually scene nodes would set 'this'
- as parameter here because they want to be drawn.
- \param pass: Specifies when the mode wants to be drawn in relation to the other nodes.
- For example, if the node is a shadow, it usually wants to be drawn after all other nodes
- and will use ESNRP_SHADOW for this. See E_SCENE_NODE_RENDER_PASS for details.
- \return scene will be rendered ( passed culling ) */
- virtual u32 registerNodeForRendering(ISceneNode* node,
- E_SCENE_NODE_RENDER_PASS pass = ESNRP_AUTOMATIC) = 0;
-
- //! Draws all the scene nodes.
- /** This can only be invoked between
- IVideoDriver::beginScene() and IVideoDriver::endScene(). Please note that
- the scene is not only drawn when calling this, but also animated
- by existing scene node animators, culling of scene nodes is done, etc. */
- virtual void drawAll() = 0;
-
- //! Creates a rotation animator, which rotates the attached scene node around itself.
- /** \param rotationPerSecond: Specifies the speed of the animation
- \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
- and the animator will animate it.
- If you no longer need the animator, you should call ISceneNodeAnimator::drop().
- See IReferenceCounted::drop() for more information. */
- virtual ISceneNodeAnimator* createRotationAnimator(const core::vector3df& rotationPerSecond) = 0;
-
- //! Creates a fly circle animator, which lets the attached scene node fly around a center.
- /** \param center: Center of the circle.
- \param radius: Radius of the circle.
- \param speed: Specifies the speed of the flight.
- \param direction: Specifies the upvector used for alignment of the mesh.
- \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
- and the animator will animate it.
- If you no longer need the animator, you should call ISceneNodeAnimator::drop().
- See IReferenceCounted::drop() for more information. */
- virtual ISceneNodeAnimator* createFlyCircleAnimator(const core::vector3df& center,
- f32 radius, f32 speed=0.001f, const core::vector3df& direction= core::vector3df ( 0.f, 1.f, 0.f ) ) = 0;
-
- //! Creates a fly straight animator, which lets the attached scene node fly or move along a line between two points.
- /** \param startPoint: Start point of the line.
- \param endPoint: End point of the line.
- \param timeForWay: Time in milli seconds how long the node should need to
- move from the start point to the end point.
- \param loop: If set to false, the node stops when the end point is reached.
- If loop is true, the node begins again at the start.
- \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
- and the animator will animate it.
- If you no longer need the animator, you should call ISceneNodeAnimator::drop().
- See IReferenceCounted::drop() for more information. */
- virtual ISceneNodeAnimator* createFlyStraightAnimator(const core::vector3df& startPoint,
- const core::vector3df& endPoint, u32 timeForWay, bool loop=false) = 0;
-
- //! Creates a texture animator, which switches the textures of the target scene node based on a list of textures.
- /** \param textures: List of textures to use.
- \param timePerFrame: Time in milliseconds, how long any texture in the list
- should be visible.
- \param loop: If set to to false, the last texture remains set, and the animation
- stops. If set to true, the animation restarts with the first texture.
- \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
- and the animator will animate it.
- If you no longer need the animator, you should call ISceneNodeAnimator::drop().
- See IReferenceCounted::drop() for more information. */
- virtual ISceneNodeAnimator* createTextureAnimator(const core::array& textures,
- s32 timePerFrame, bool loop=true) = 0;
-
- //! Creates a scene node animator, which deletes the scene node after some time automatically.
- /** \param timeMs: Time in milliseconds, after when the node will be deleted.
- \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
- and the animator will animate it.
- If you no longer need the animator, you should call ISceneNodeAnimator::drop().
- See IReferenceCounted::drop() for more information. */
- virtual ISceneNodeAnimator* createDeleteAnimator(u32 timeMs) = 0;
-
- //! Creates a special scene node animator for doing automatic collision detection and response.
- /** See ISceneNodeAnimatorCollisionResponse for details.
- \param world: Triangle selector holding all triangles of the world with which
- the scene node may collide. You can create a triangle selector with
- ISceneManager::createTriangleSelector();
- \param sceneNode: SceneNode which should be manipulated. After you added this animator
- to the scene node, the scene node will not be able to move through walls and is
- affected by gravity.
- \param ellipsoidRadius: Radius of the ellipsoid with which collision detection and
- response is done. If you have got a scene node, and you are unsure about
- how big the radius should be, you could use the following code to determine
- it:
- \code
- const core::aabbox& box = yourSceneNode->getBoundingBox();
- core::vector3df radius = box.MaxEdge - box.getCenter();
- \endcode
- \param gravityPerSecond: Sets the gravity of the environment. A good example value would be
- core::vector3df(0,-100.0f,0) for letting gravity affect all object to
- fall down. For bigger gravity, make increase the length of the vector.
- You can disable gravity by setting it to core::vector3df(0,0,0).
- \param ellipsoidTranslation: By default, the ellipsoid for collision detection is created around
- the center of the scene node, which means that the ellipsoid surrounds
- it completely. If this is not what you want, you may specify a translation
- for the ellipsoid.
- \param slidingValue: DOCUMENTATION NEEDED.
- \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
- and the animator will cause it to do collision detection and response.
- If you no longer need the animator, you should call ISceneNodeAnimator::drop().
- See IReferenceCounted::drop() for more information. */
- virtual ISceneNodeAnimatorCollisionResponse* createCollisionResponseAnimator(
- ITriangleSelector* world, ISceneNode* sceneNode,
- const core::vector3df& ellipsoidRadius = core::vector3df(30,60,30),
- const core::vector3df& gravityPerSecond = core::vector3df(0,-100.0f,0),
- const core::vector3df& ellipsoidTranslation = core::vector3df(0,0,0),
- f32 slidingValue = 0.0005f) = 0;
-
- //! Creates a follow spline animator.
- /** The animator modifies the position of
- the attached scene node to make it follow a hermite spline.
- The code of the is based on a scene node
- Matthias Gall sent in. Thanks! I adapted the code just a little bit. Matthias
- wrote:
- Uses a subset of hermite splines: either cardinal splines (tightness != 0.5) or catmull-rom-splines (tightness == 0.5)
- but this is just my understanding of this stuff, I'm not a mathematician, so this might be wrong ;) */
- virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime,
- const core::array< core::vector3df >& points,
- f32 speed = 1.0f, f32 tightness = 0.5f) = 0;
-
- //! Creates a simple ITriangleSelector, based on a mesh.
- /** Triangle selectors
- can be used for doing collision detection. Don't use this selector
- for a huge amount of triangles like in Quake3 maps.
- Instead, use for example ISceneManager::createOctTreeTriangleSelector().
- Please note that the created triangle selector is not automaticly attached
- to the scene node. You will have to call ISceneNode::setTriangleSelector()
- for this. To create and attach a triangle selector is done like this:
- \code
- ITriangleSelector* s = sceneManager->createTriangleSelector(yourMesh,
- yourSceneNode);
- yourSceneNode->setTriangleSelector(s);
- s->drop();
- \endcode
- \param mesh: Mesh of which the triangles are taken.
- \param node: Scene node of which visibility and transformation is used.
- \return Returns the selector, or null if not successful.
- If you no longer need the selector, you should call ITriangleSelector::drop().
- See IReferenceCounted::drop() for more information. */
- virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node) = 0;
-
- //! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.
- /** Triangle selectors
- can be used for doing collision detection. Every time when triangles are
- queried, the triangle selector gets the bounding box of the scene node,
- an creates new triangles. In this way, it works good with animated scene nodes.
- \param node: Scene node of which the bounding box, visibility and transformation is used.
- \return Returns the selector, or null if not successful.
- If you no longer need the selector, you should call ITriangleSelector::drop().
- See IReferenceCounted::drop() for more information. */
- virtual ITriangleSelector* createTriangleSelectorFromBoundingBox(ISceneNode* node) = 0;
-
- //! Creates a Triangle Selector, optimized by an octtree.
- /** Triangle selectors
- can be used for doing collision detection. This triangle selector is
- optimized for huge amounts of triangle, it organizes them in an octtree.
- Please note that the created triangle selector is not automaticly attached
- to the scene node. You will have to call ISceneNode::setTriangleSelector()
- for this. To create and attach a triangle selector is done like this:
- \code
- ITriangleSelector* s = sceneManager->createOctTreeTriangleSelector(yourMesh,
- yourSceneNode);
- yourSceneNode->setTriangleSelector(s);
- s->drop();
- \endcode
- For more informations and examples on this, take a look at the collision
- tutorial in the SDK.
- \param mesh: Mesh of which the triangles are taken.
- \param node: Scene node of which visibility and transformation is used.
- \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node.
- If a node gets less polys the this value, it will not be splitted into
- smaller nodes.
- \return Returns the selector, or null if not successful.
- If you no longer need the selector, you should call ITriangleSelector::drop().
- See IReferenceCounted::drop() for more information. */
- virtual ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh,
- ISceneNode* node, s32 minimalPolysPerNode=32) = 0;
-
- //! Creates a meta triangle selector.
- /** A meta triangle selector is nothing more than a
- collection of one or more triangle selectors providing together
- the interface of one triangle selector. In this way,
- collision tests can be done with different triangle soups in one pass.
- \return Returns the selector, or null if not successful.
- If you no longer need the selector, you should call ITriangleSelector::drop().
- See IReferenceCounted::drop() for more information. */
- virtual IMetaTriangleSelector* createMetaTriangleSelector() = 0;
-
- //! Creates a triangle selector which can select triangles from a terrain scene node.
- /** \param node: Pointer to the created terrain scene node
- \param LOD: Level of detail, 0 for highest detail. */
- virtual ITriangleSelector* createTerrainTriangleSelector(
- ITerrainSceneNode* node, s32 LOD=0) = 0;
-
- //! Adds an external mesh loader for extending the engine with new file formats.
- /** If you want the engine to be extended with
- file formats it currently is not able to load (e.g. .cob), just implement
- the IMeshLoader interface in your loading class and add it with this method.
- Using this method it is also possible to override built-in mesh loaders with
- newer or updated versions without the need of recompiling the engine.
- \param externalLoader: Implementation of a new mesh loader. */
- virtual void addExternalMeshLoader(IMeshLoader* externalLoader) = 0;
-
- //! Returns a pointer to the scene collision manager.
- virtual ISceneCollisionManager* getSceneCollisionManager() = 0;
-
- //! Returns a pointer to the mesh manipulator.
- virtual IMeshManipulator* getMeshManipulator() = 0;
-
- //! Adds a scene node to the deletion queue.
- /** The scene node is immediatly
- deleted when it's secure. Which means when the scene node does not
- execute animators and things like that. This method is for example
- used for deleting scene nodes by their scene node animators. In
- most other cases, a ISceneNode::remove() call is enough, using this
- deletion queue is not necessary.
- See ISceneManager::createDeleteAnimator() for details.
- \param node: Node to detete. */
- virtual void addToDeletionQueue(ISceneNode* node) = 0;
-
- //! Posts an input event to the environment.
- /** Usually you do not have to
- use this method, it is used by the internal engine. */
- virtual bool postEventFromUser(const SEvent& event) = 0;
-
- //! Clears the whole scene.
- /** All scene nodes are removed. */
- virtual void clear() = 0;
-
- //! Returns interface to the parameters set in this scene.
- /** String parameters can be used by plugins and mesh loaders.
- For example the CMS and LMTS loader want a parameter named 'CSM_TexturePath'
- and 'LMTS_TexturePath' set to the path were attached textures can be found. See
- CSM_TEXTURE_PATH, LMTS_TEXTURE_PATH, MY3D_TEXTURE_PATH,
- COLLADA_CREATE_SCENE_INSTANCES, DMF_TEXTURE_PATH and DMF_USE_MATERIALS_DIRS*/
- virtual io::IAttributes* getParameters() = 0;
-
- //! Returns current render pass.
- /** All scene nodes are being rendered in a specific order.
- First lights, cameras, sky boxes, solid geometry, and then transparent
- stuff. During the rendering process, scene nodes may want to know what the scene
- manager is rendering currently, because for example they registered for rendering
- twice, once for transparent geometry and once for solid. When knowing what rendering
- pass currently is active they can render the correct part of their geometry. */
- virtual E_SCENE_NODE_RENDER_PASS getSceneNodeRenderPass() const = 0;
-
- //! Returns the default scene node factory which can create all built in scene nodes
- virtual ISceneNodeFactory* getDefaultSceneNodeFactory() = 0;
-
- //! Adds a scene node factory to the scene manager.
- /** Use this to extend the scene manager with new scene node types which it should be
- able to create automaticly, for example when loading data from xml files. */
- virtual void registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd) = 0;
-
- //! Returns amount of registered scene node factories.
- virtual u32 getRegisteredSceneNodeFactoryCount() const = 0;
-
- //! Returns a scene node factory by index
- virtual ISceneNodeFactory* getSceneNodeFactory(u32 index) = 0;
-
- //! Returns the default scene node animator factory which can create all built-in scene node animators
- virtual ISceneNodeAnimatorFactory* getDefaultSceneNodeAnimatorFactory() = 0;
-
- //! Adds a scene node animator factory to the scene manager.
- /** Use this to extend the scene manager with new scene node animator types which it should be
- able to create automaticly, for example when loading data from xml files. */
- virtual void registerSceneNodeAnimatorFactory(ISceneNodeAnimatorFactory* factoryToAdd) = 0;
-
- //! Returns amount of registered scene node animator factories.
- virtual u32 getRegisteredSceneNodeAnimatorFactoryCount() const = 0;
-
- //! Returns a scene node animator factory by index
- virtual ISceneNodeAnimatorFactory* getSceneNodeAnimatorFactory(u32 index) = 0;
-
- //! Returns a typename from a scene node type or null if not found
- virtual const c8* getSceneNodeTypeName(ESCENE_NODE_TYPE type) = 0;
-
- //! Adds a scene node to the scene by name
- virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent) = 0;
-
- //! Creates a new scene manager.
- /** This can be used to easily draw and/or store two independent scenes at the same time.
- The mesh cache will be shared between all existing scene managers, which means if you load
- a mesh in the original scene manager using for example getMesh(), the mesh will be available
- in all other scene managers too, without loading.
- The original/main scene manager will still be there and accessible via IrrlichtDevice::getSceneManager().
- If you need input event in this new scene manager, for example for FPS cameras, you'll need
- to forward input to this manually: Just implement an IEventReceiver and call
- yourNewSceneManager->postEventFromUser(), and return true so that the original scene manager
- doesn't get the event. Otherwise, all input will go automaticly to the main scene manager.
- If you no longer need the new scene manager, you should call ISceneManager::drop().
- See IReferenceCounted::drop() for more information. */
- virtual ISceneManager* createNewSceneManager(bool cloneContent=false) = 0;
-
- //! Saves the current scene into a file.
- /** Scene nodes with the option isDebugObject set to true are not being saved.
- The scene is usually written to an .irr file, an xml based format. .irr files can
- Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org).
- To load .irr files again, see ISceneManager::loadScene().
- \param filename: Name of the file.
- \param userDataSerializer: If you want to save some user data for every scene node into the
- file, implement the ISceneUserDataSerializer interface and provide it as parameter here.
- Otherwise, simply specify 0 as this parameter.
- \return Returns true if successful. */
- virtual bool saveScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer=0) = 0;
-
- //! Saves the current scene into a file.
- /** Scene nodes with the option isDebugObject set to true are not being saved.
- The scene is usually written to an .irr file, an xml based format. .irr files can
- Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org).
- To load .irr files again, see ISceneManager::loadScene().
- \param file: File where the scene is saved into.
- \param userDataSerializer: If you want to save some user data for every scene node into the
- file, implement the ISceneUserDataSerializer interface and provide it as parameter here.
- Otherwise, simply specify 0 as this parameter.
- \return Returns true if successful. */
- virtual bool saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer=0) = 0;
-
- //! Loads a scene. Note that the current scene is not cleared before.
- /** The scene is usually load from an .irr file, an xml based format. .irr files can
- Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org) or
- saved directly by the engine using ISceneManager::saveScene().
- \param filename: Name of the file.
- \param userDataSerializer: If you want to load user data possibily saved in that file for
- some scene nodes in the file, implement the ISceneUserDataSerializer interface and provide it as parameter here.
- Otherwise, simply specify 0 as this parameter.
- \return Returns true if successful. */
- virtual bool loadScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer=0) = 0;
-
- //! Loads a scene. Note that the current scene is not cleared before.
- /** The scene is usually load from an .irr file, an xml based format. .irr files can
- Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org) or
- saved directly by the engine using ISceneManager::saveScene().
- \param file: File where the scene is going to be saved into.
- \param userDataSerializer: If you want to load user data possibily saved in that file for
- some scene nodes in the file, implement the ISceneUserDataSerializer interface and provide it as parameter here.
- Otherwise, simply specify 0 as this parameter.
- \return Returns true if successful. */
- virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0) = 0;
-
- //! Returns a mesh writer implementation if available
- /** Note: You need to drop() the pointer after use again, see IReferenceCounted::drop()
- for details. */
- virtual IMeshWriter* createMeshWriter(EMESH_WRITER_TYPE type) = 0;
-
- //! Sets ambient color of the scene
- virtual void setAmbientLight(const video::SColorf &ambientColor) = 0;
-
- //! Returns ambient color of the scene
- virtual const video::SColorf& getAmbientLight() const = 0;
-
- };
-
-
-} // end namespace scene
-} // end namespace irr
-
-#endif
-
+// 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_MANAGER_H_INCLUDED__
+#define __I_SCENE_MANAGER_H_INCLUDED__
+
+#include "IReferenceCounted.h"
+#include "irrArray.h"
+#include "vector3d.h"
+#include "dimension2d.h"
+#include "SColor.h"
+#include "ETerrainElements.h"
+#include "ESceneNodeTypes.h"
+#include "EMeshWriterEnums.h"
+#include "SceneParameters.h"
+
+namespace irr
+{
+ struct SKeyMap;
+ struct SEvent;
+
+namespace io
+{
+ class IReadFile;
+ class IAttributes;
+ class IWriteFile;
+} // end namespace io
+
+namespace gui
+{
+ class IGUIFont;
+ class IGUIEnvironment;
+} // end namespace gui
+
+namespace video
+{
+ class IVideoDriver;
+ class SMaterial;
+ class IImage;
+ class ITexture;
+} // end namespace video
+
+namespace scene
+{
+ class IMeshWriter;
+
+ //! Enumeration for render passes.
+ /** A parameter passed to the registerNodeForRendering() method of the ISceneManager,
+ specifying when the mode wants to be drawn in relation to the other nodes. */
+ enum E_SCENE_NODE_RENDER_PASS
+ {
+ //! Camera pass. The active view is set up here.
+ //! The very first pass.
+ ESNRP_CAMERA,
+
+ //! In this pass, lights are transformed into camera space and added to the driver
+ ESNRP_LIGHT,
+
+ //! This is used for sky boxes.
+ ESNRP_SKY_BOX,
+
+ //! All normal objects can use this for registering themselves.
+ //! This value will never be returned by ISceneManager::getSceneNodeRenderPass().
+ //! The scene manager will determine by itself if an object is
+ //! transparent or solid and register the object as SNRT_TRANSPARENT or
+ //! SNRT_SOLD automatically if you call registerNodeForRendering with this
+ //! value (which is default). Note that it will register the node only as ONE type.
+ //! If your scene node has both solid and transparent material types register
+ //! it twice (one time as SNRT_SOLID, the other time as SNRT_TRANSPARENT) and
+ //! in the render() method call getSceneNodeRenderPass() to find out the current
+ //! render pass and render only the corresponding parts of the node.
+ ESNRP_AUTOMATIC,
+
+ //! Solid scene nodes or special scene nodes without materials.
+ ESNRP_SOLID,
+
+ //! Drawn after the transparent nodes, the time for drawing shadow volumes
+ ESNRP_SHADOW,
+
+ //! Transparent scene nodes, drawn after shadow nodes. They are sorted from back
+ //! to front and drawn in that order.
+ ESNRP_TRANSPARENT,
+
+ //! Never used, value specifing how much parameters there are.
+ ESNRP_COUNT
+ };
+
+ class IMesh;
+ class IMeshBuffer;
+ class IAnimatedMesh;
+ class IMeshCache;
+ class ISceneNode;
+ class ICameraSceneNode;
+ class IAnimatedMeshSceneNode;
+ class ISceneNodeAnimator;
+ class ISceneNodeAnimatorCollisionResponse;
+ class ILightSceneNode;
+ class IBillboardSceneNode;
+ class ITerrainSceneNode;
+ class IMeshSceneNode;
+ class IMeshLoader;
+ class ISceneCollisionManager;
+ class IParticleSystemSceneNode;
+ class IDummyTransformationSceneNode;
+ class ITriangleSelector;
+ class IMetaTriangleSelector;
+ class IMeshManipulator;
+ class ITextSceneNode;
+ class ISceneNodeFactory;
+ class ISceneNodeAnimatorFactory;
+ class ISceneUserDataSerializer;
+
+ namespace quake3
+ {
+ class SShader;
+ } // end namespace quake3
+
+ //! The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff.
+ /** All Scene nodes can be created only here. There is a always growing list of scene
+ nodes for lots of purposes: Indoor rendering scene nodes like the Octree
+ (addOctTreeSceneNode()) or the terrain renderer (addTerrainSceneNode()),
+ different Camera scene nodes (addCameraSceneNode(), addCameraSceneNodeMaya()),
+ scene nodes for Light (addLightSceneNode()), Billboards (addBillboardSceneNode())
+ and so on.
+ A scene node is a node in the hierachical scene graph. Every scene node may have children,
+ which are other scene nodes. Children move relative the their parents position. If the parent of a node is not
+ visible, its children won't be visible, too. In this way, it is for example easily possible
+ to attach a light to a moving car or to place a walking character on a moving platform
+ on a moving ship.
+ The SceneManager is also able to load 3d mesh files of different formats. Take a look
+ at getMesh() to find out what formats are supported. And if these formats are not enough
+ use addExternalMeshLoader() to add new formats to the engine.
+ */
+ class ISceneManager : public virtual IReferenceCounted
+ {
+ public:
+
+ //! destructor
+ virtual ~ISceneManager() {}
+
+ //! Returns pointer to an animateable mesh. Loads the file if not loaded already.
+ /**
+ * If you want to remove a loaded mesh from the cache again, use removeMesh().
+ * Currently there are the following mesh formats supported:
+ *
+ *
+ * Format |
+ * Description |
+ *
+ *
+ * 3D Studio (.3ds) |
+ * Loader for 3D-Studio files which lots of 3D packages are able to export.
+ * Only static meshes are currently supported by this importer. |
+ *
+ *
+ * Bliz Basic B3D (.b3d) |
+ * Loader for blitz basic files, developed by Mark Sibly, also supports animations. |
+ *
+ *
+ * Cartography shop 4 (.csm) |
+ * Cartography Shop is a modeling program for creating architecture and calculating
+ * lighting. Irrlicht can directly import .csm files thanks to the IrrCSM library
+ * created by Saurav Mohapatra which is now integrated directly in Irrlicht.
+ * If you are using this loader, please note that you'll have to set the path
+ * of the textures before loading .csm files. You can do this using SceneManager->getParameters()->setParameter(scene::CSM_TEXTURE_PATH,
+ * "path/to/your/textures"); |
+ *
+ *
+ * COLLADA (.dae, .xml) |
+ * COLLADA is an open Digital Asset Exchange Schema for the interactive 3D industry. There are
+ * exporters and importers for this format available for most of the big 3d packages
+ * at http://collada.org. Irrlicht can import COLLADA files by using the
+ * ISceneManager::getMesh() method. COLLADA files need not contain only one single mesh
+ * but multiple meshes and a whole scene setup with lights, cameras and mesh instances,
+ * this loader can set up a scene as described by the COLLADA file instead of loading
+ * and returning one single mesh. By default, this loader behaves like the other loaders
+ * and does not create instances, but it can be switched into this mode by using
+ * SceneManager->getParameters()->setParameter(COLLADA_CREATE_SCENE_INSTANCES, true);
+ * Created scene nodes will be named as the names of the nodes in the
+ * COLLADA file. The returned mesh is just a dummy object in this mode. Meshes included in
+ * the scene will be added into the scene manager with the following naming scheme:
+ * path/to/file/file.dea#meshname. The loading of such meshes is logged.
+ * Currently, this loader is able to create meshes (made of only polygons), lights,
+ * and cameras. Materials and animations are currently not supported but this will
+ * change with future releases.
+ * |
+ *
+ *
+ * Delgine DeleD (.dmf) |
+ * DeleD (delgine.com) is a 3D editor and level-editor combined into one and is specifically
+ * designed for 3D game-development. With this loader, it is possible to directly load
+ * all geometry is as well as textures and lightmaps from .dmf files. To set texture and
+ * material paths, see scene::DMF_USE_MATERIALS_DIRS and scene::DMF_TEXTURE_PATH. It is also
+ * possible to flip the alpha texture by setting scene::DMF_FLIP_ALPHA_TEXTURES to true and
+ * to set the material transparent reference value by setting scene::DMF_ALPHA_CHANNEL_REF to
+ * a float between 0 and 1. The loader is
+ * based on Salvatore Russo's .dmf loader, I just changed some parts of it. Thanks to
+ * Salvatore for his work and for allowing me to use his code in Irrlicht and put it under Irrlicht's
+ * license. For newer and more enchanced versions of the loader, take a look at delgine.com.
+ * |
+ *
+ *
+ * DirectX (.x) |
+ * Platform independent importer (so not D3D-only) for .x files. Most 3D
+ * packages can export these natively and there are several tools for them
+ * available. (e.g. the Maya exporter included in the DX SDK) .x files can
+ * include skeletal animations and Irrlicht is able to play and display them.
+ * Currently, Irrlicht only supports uncompressed .x files. |
+ *
+ *
+ * Maya (.obj) |
+ * Most 3D software can create .obj files which contain static geometry without
+ * material data. The material files .mtl are also supported. This importer
+ * for Irrlicht can load them directly. |
+ *
+ *
+ * Milkshape (.ms3d) |
+ * .MS3D files contain models and sometimes skeletal animations from the
+ * Milkshape 3D modeling and animation software. This importer for Irrlicht
+ * can display and/or animate these files. |
+ *
+ *
+ * My3D (.my3d) |
+ * .my3D is a flexible 3D file format. The My3DTools contains plug-ins to
+ * export .my3D files from several 3D packages. With this built-in importer,
+ * Irrlicht can read and display those files directly. This loader was written
+ * by Zhuck Dimitry who also created the whole My3DTools package. If you are using this loader, please
+ * note that you can set the path of the textures before loading .my3d files.
+ * You can do this using SceneManager->getParameters()->setParameter(scene::MY3D_TEXTURE_PATH,
+ * "path/to/your/textures"); |
+ *
+ *
+ * OCT (.oct) |
+ * The oct file format contains 3D geometry and lightmaps and can be loaded
+ * directly by Irrlicht. OCT files
+ * can be created by FSRad, Paul Nette's radiosity processor or exported from
+ * Blender using OCTTools which can be found in the exporters/OCTTools directory
+ * of the SDK. Thanks to Murphy McCauley for creating all this. |
+ *
+ *
+ * OGRE Meshes (.mesh) |
+ * Ogre .mesh files contain 3D data for the OGRE 3D engine. Irrlicht can read and
+ * display them directly with this importer. To define materials for the mesh,
+ * copy a .material file named like the corresponding .mesh file where the .mesh
+ * file is. (For example ogrehead.material for ogrehead.mesh). Thanks to Christian Stehno
+ * who wrote and contributed this loader. |
+ *
+ *
+ * Pulsar LMTools (.lmts) |
+ * LMTools is a set of tools (Windows & Linux) for creating lightmaps.
+ * Irrlicht can directly read .lmts files thanks to
+ * the importer created by Jonas Petersen. If you are using this loader, please
+ * note that you can set the path of the textures before loading .lmts files.
+ * You can do this using SceneManager->getParameters()->setParameter(scene::LMTS_TEXTURE_PATH,
+ * "path/to/your/textures"); Notes for
+ * this version of the loader:
+ * - It does not recognice/support user data in the *.lmts files.
+ * - The TGAs generated by LMTools don't work in Irrlicht for some reason (the
+ * textures are upside down). Opening and resaving them in a graphics app will
+ * solve the problem. |
+ *
+ *
+ * Quake 3 levels (.bsp) |
+ * Quake 3 is a popular game by IDSoftware, and .pk3 files contain .bsp files
+ * and textures/lightmaps describing huge
+ * prelighted levels. Irrlicht can read .pk3 and .bsp files directly and thus
+ * render Quake 3 levels directly. Written by Nikolaus Gebhardt enhanced by
+ * Dean P. Macri with the curved surfaces feature. |
+ *
+ *
+ * Quake 2 models (.md2) |
+ * Quake 2 models are characters with morph target animation. Irrlicht can
+ * read, display and animate them directly with this importer. |
+ *
+ *
+ *
+ * To load and display a mesh quickly, just do this:
+ * \code
+ * SceneManager->addAnimatedMeshSceneNode(
+ * SceneManager->getMesh("yourmesh.3ds"));
+ * \endcode
+ * If you would like to implement and add your own file format loader to Irrlicht,
+ * see addExternalMeshLoader().
+ * \param filename: Filename of the mesh to load.
+ * \return Returns NULL if failed and the pointer to the mesh if
+ * successful.
+ * This pointer should not be dropped. See IReferenceCounted::drop() for more information.
+ **/
+ virtual IAnimatedMesh* getMesh(const c8* filename) = 0;
+
+ //! Returns an interface to the mesh cache which is shared beween all existing scene managers.
+ /** With this interface, it is possible to manually add new loaded
+ meshes (if ISceneManager::getMesh() is not sufficient), to remove them and to iterate
+ through already loaded meshes. */
+ virtual IMeshCache* getMeshCache() = 0;
+
+ //! Returns the video driver.
+ /** \return Returns pointer to the video Driver.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual video::IVideoDriver* getVideoDriver() = 0;
+
+ //! Returns the active GUIEnvironment
+ /** \return Returns pointer to the GUIEnvironment
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual gui::IGUIEnvironment* getGUIEnvironment() = 0;
+
+ //! adds Volume Lighting Scene Node.
+ //! the returned pointer must not be dropped.
+ // Example Useage:
+ // scene::ISceneNode * n = smgr->addVolumeLightSceneNode(NULL, -1,
+ // 32, //Sub Divid U
+ // 32, //Sub Divid V
+ // video::SColor(0, 180, 180, 180), //foot colour
+ // video::SColor(0, 0, 0, 0) //tail colour
+ // );
+ // if (n) {
+ // n->setScale(core::vector3df(46.0f, 45.0f, 46.0f));
+ // n->setPosition(core::vector3df(0,0,0));
+ // video::SMaterial& mat = n->getMaterial(0);
+ // mat.setTexture(0, smgr->getVideoDriver()->getTexture("lightFalloff.png"));
+ // }
+ //
+ virtual ISceneNode* addVolumeLightSceneNode(ISceneNode* parent=0, s32 id=-1,
+ const s32 subdivU = 32, const s32 subdivV = 32,
+ const video::SColor foot = video::SColor(51, 0, 230, 180),
+ const video::SColor tail = video::SColor(0, 0, 0, 0),
+ const core::vector3df& position = core::vector3df(0,0,0),
+ const core::vector3df& rotation = core::vector3df(0,0,0),
+ const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0;
+
+
+ //! Adds a test scene node for test purposes to the scene.
+ /** It is a simple cube of (1,1,1) size.
+ \param size: Size of the cube.
+ \param parent: Parent of the scene node. Can be NULL if no parent.
+ \param id: Id of the node. This id can be used to identify the scene node.
+ \param position: Position of the space relative to its parent where the
+ scene node will be placed.
+ \param rotation: Initital rotation of the scene node.
+ \param scale: Initial scale of the scene node.
+ \return Returns pointer to the created test scene node.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ISceneNode* addCubeSceneNode(f32 size=10.0f, ISceneNode* parent=0, s32 id=-1,
+ const core::vector3df& position = core::vector3df(0,0,0),
+ const core::vector3df& rotation = core::vector3df(0,0,0),
+ const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0;
+
+ //! Adds a sphere scene node for test purposes to the scene.
+ /** It is a simple sphere.
+ \param radius: Radius of the sphere.
+ \param polyCount: Polycount of the sphere.
+ \param parent: Parent of the scene node. Can be NULL if no parent.
+ \param id: Id of the node. This id can be used to identify the scene node.
+ \param position: Position of the space relative to its parent where the
+ scene node will be placed.
+ \param rotation: Initital rotation of the scene node.
+ \param scale: Initial scale of the scene node.
+ \return Returns pointer to the created test scene node.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ISceneNode* addSphereSceneNode(f32 radius=5.0f, s32 polyCount=16, ISceneNode* parent=0, s32 id=-1,
+ const core::vector3df& position = core::vector3df(0,0,0),
+ const core::vector3df& rotation = core::vector3df(0,0,0),
+ const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0;
+
+ //! Adds a scene node for rendering an animated mesh model.
+ /** \param mesh: Pointer to the loaded animated mesh to be displayed.
+ \param parent: Parent of the scene node. Can be NULL if no parent.
+ \param id: Id of the node. This id can be used to identify the scene node.
+ \param position: Position of the space relative to its parent where the
+ scene node will be placed.
+ \param rotation: Initital rotation of the scene node.
+ \param scale: Initial scale of the scene node.
+ \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed.
+ \return Returns pointer to the created scene node.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual IAnimatedMeshSceneNode* addAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, s32 id=-1,
+ const core::vector3df& position = core::vector3df(0,0,0),
+ const core::vector3df& rotation = core::vector3df(0,0,0),
+ const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f),
+ bool alsoAddIfMeshPointerZero=false) = 0;
+
+ //! Adds a scene node for rendering a static mesh.
+ /** \param mesh: Pointer to the loaded static mesh to be displayed.
+ \param parent: Parent of the scene node. Can be NULL if no parent.
+ \param id: Id of the node. This id can be used to identify the scene node.
+ \param position: Position of the space relative to its parent where the
+ scene node will be placed.
+ \param rotation: Initital rotation of the scene node.
+ \param scale: Initial scale of the scene node.
+ \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed.
+ \return Returns pointer to the created scene node.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual IMeshSceneNode* addMeshSceneNode(IMesh* mesh, ISceneNode* parent=0, s32 id=-1,
+ const core::vector3df& position = core::vector3df(0,0,0),
+ const core::vector3df& rotation = core::vector3df(0,0,0),
+ const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f),
+ bool alsoAddIfMeshPointerZero=false) = 0;
+
+ //! Adds a scene node for rendering a animated water surface mesh.
+ /** Looks really good when the Material type EMT_TRANSPARENT_REFLECTION
+ is used.
+ \param waveHeight: Height of the water waves.
+ \param waveSpeed: Speed of the water waves.
+ \param waveLength: Lenght of a water wave.
+ \param mesh: Pointer to the loaded static mesh to be displayed with water waves on it.
+ \param parent: Parent of the scene node. Can be NULL if no parent.
+ \param id: Id of the node. This id can be used to identify the scene node.
+ \param position: Position of the space relative to its parent where the
+ scene node will be placed.
+ \param rotation: Initital rotation of the scene node.
+ \param scale: Initial scale of the scene node.
+ \return Returns pointer to the created scene node.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ISceneNode* addWaterSurfaceSceneNode(IMesh* mesh,
+ f32 waveHeight=2.0f, f32 waveSpeed=300.0f, f32 waveLength=10.0f,
+ ISceneNode* parent=0, s32 id=-1,
+ const core::vector3df& position = core::vector3df(0,0,0),
+ const core::vector3df& rotation = core::vector3df(0,0,0),
+ const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0;
+
+
+ //! Adds a scene node for rendering using a octtree to the scene graph.
+ /** This a good method for rendering
+ scenes with lots of geometry. The Octree is built on the fly from the mesh.
+ \param mesh: The mesh containing all geometry from which the octtree will be build.
+ If this animated mesh has more than one frames in it, the first frame is taken.
+ \param parent: Parent node of the octtree node.
+ \param id: id of the node. This id can be used to identify the node.
+ \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node.
+ If a node gets less polys than this value it will not be split into
+ smaller nodes.
+ \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed.
+ \return Returns the pointer to the OctTree if successful, otherwise 0.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ISceneNode* addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0,
+ s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) = 0;
+
+ //! Adds a scene node for rendering using a octtree to the scene graph.
+ /** This a good method for rendering
+ scenes with lots of geometry. The Octree is built on the fly from the mesh, much
+ faster then a bsp tree.
+ \param mesh: The mesh containing all geometry from which the octtree will be build.
+ \param parent: Parent node of the octtree node.
+ \param id: id of the node. This id can be used to identify the node.
+ \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node.
+ If a node gets less polys than this value it will not be split into
+ smaller nodes.
+ \param alsoAddIfMeshPointerZero: Add the scene node even if a 0 pointer is passed.
+ \return Returns the pointer to the octtree if successful, otherwise 0.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ISceneNode* addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent=0,
+ s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) = 0;
+
+ //! Adds a camera scene node to the scene graph and sets it as active camera.
+ /** This camera does not react on user input like for example the one created with
+ addCameraSceneNodeFPS(). If you want to move or animate it, use animators or the
+ ISceneNode::setPosition(), ICameraSceneNode::setTarget() etc methods.
+ \param position: Position of the space relative to its parent where the camera will be placed.
+ \param lookat: Position where the camera will look at. Also known as target.
+ \param parent: Parent scene node of the camera. Can be null. If the parent moves,
+ the camera will move too.
+ \param id: id of the camera. This id can be used to identify the camera.
+ \return Returns pointer to interface to camera if successful, otherwise 0.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ICameraSceneNode* addCameraSceneNode(ISceneNode* parent = 0,
+ const core::vector3df& position = core::vector3df(0,0,0),
+ const core::vector3df& lookat = core::vector3df(0,0,100), s32 id=-1) = 0;
+
+ //! Adds a maya style user controlled camera scene node to the scene graph.
+ /** The maya camera is able to be controlled with the mouse similar
+ like in the 3D Software Maya by Alias Wavefront.
+ \param parent: Parent scene node of the camera. Can be null.
+ \param rotateSpeed: Rotation speed of the camera.
+ \param zoomSpeed: Zoom speed of the camera.
+ \param translationSpeed: TranslationSpeed of the camera.
+ \param id: id of the camera. This id can be used to identify the camera.
+ \return Returns a pointer to the interface of the camera if successful, otherwise 0.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent = 0,
+ f32 rotateSpeed = -1500.0f, f32 zoomSpeed = 200.0f, f32 translationSpeed = 1500.0f, s32 id=-1) = 0;
+
+ //! Adds a camera scene node which is able to be controlled with the mouse and keys like in most first person shooters (FPS).
+ /** Look with the mouse, move with cursor keys. If you do not like the default
+ key layout, you may want to specify your own. For example to make the camera
+ be controlled by the cursor keys AND the keys W,A,S, and D, do something
+ like this:
+ \code
+ SKeyMap keyMap[8];
+ keyMap[0].Action = EKA_MOVE_FORWARD;
+ keyMap[0].KeyCode = KEY_UP;
+ keyMap[1].Action = EKA_MOVE_FORWARD;
+ keyMap[1].KeyCode = KEY_KEY_W;
+
+ keyMap[2].Action = EKA_MOVE_BACKWARD;
+ keyMap[2].KeyCode = KEY_DOWN;
+ keyMap[3].Action = EKA_MOVE_BACKWARD;
+ keyMap[3].KeyCode = KEY_KEY_S;
+
+ keyMap[4].Action = EKA_STRAFE_LEFT;
+ keyMap[4].KeyCode = KEY_LEFT;
+ keyMap[5].Action = EKA_STRAFE_LEFT;
+ keyMap[5].KeyCode = KEY_KEY_A;
+
+ keyMap[6].Action = EKA_STRAFE_RIGHT;
+ keyMap[6].KeyCode = KEY_RIGHT;
+ keyMap[7].Action = EKA_STRAFE_RIGHT;
+ keyMap[7].KeyCode = KEY_KEY_D;
+
+ camera = sceneManager->addCameraSceneNodeFPS(0, 100, 500, -1, keyMap, 8);
+ \endcode
+ \param parent: Parent scene node of the camera. Can be null.
+ \param rotateSpeed: Speed with which the camera is rotated. This can be done
+ only with the mouse.
+ \param moveSpeed: Speed with which the camera is moved. Movement is done with
+ the cursor keys.
+ \param id: id of the camera. This id can be used to identify the camera.
+ \param keyMapArray: Optional pointer to an array of a keymap, specifying what
+ keys should be used to move the camera. If this is null, the default keymap
+ is used. You can define actions more then one time in the array, to bind
+ multiple keys to the same action.
+ \param keyMapSize: Amount of items in the keymap array.
+ \param noVerticalMovement: Setting this to true makes the camera only move within a
+ horizontal plane, and disables vertical movement as known from most ego shooters. Default
+ is 'false', with which it is possible to fly around in space, if no gravity is there.
+ \param jumpSpeed: Speed with which the camera is moved when jumping.
+ \return Returns a pointer to the interface of the camera if successful, otherwise 0.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ICameraSceneNode* addCameraSceneNodeFPS(ISceneNode* parent = 0,
+ f32 rotateSpeed = 100.0f, f32 moveSpeed = 500.0f, s32 id=-1,
+ SKeyMap* keyMapArray=0, s32 keyMapSize=0, bool noVerticalMovement=false,
+ f32 jumpSpeed = 0.f) = 0;
+
+ //! Adds a dynamic light scene node to the scene graph.
+ /** The light will cast dynamic light on all
+ other scene nodes in the scene, which have the material flag video::MTF_LIGHTING
+ turned on. (This is the default setting in most scene nodes).
+ \param parent: Parent scene node of the light. Can be null. If the parent moves,
+ the light will move too.
+ \param position: Position of the space relative to its parent where the light will be placed.
+ \param color: Diffuse color of the light. Ambient or Specular colors can be set manually with
+ the ILightSceneNode::getLightData() method.
+ \param radius: Radius of the light.
+ \param id: id of the node. This id can be used to identify the node.
+ \return Returns pointer to the interface of the light if successful, otherwise NULL.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ILightSceneNode* addLightSceneNode(ISceneNode* parent = 0,
+ const core::vector3df& position = core::vector3df(0,0,0),
+ video::SColorf color = video::SColorf(1.0f, 1.0f, 1.0f),
+ f32 radius=100.0f, s32 id=-1) = 0;
+
+ //! Adds a billboard scene node to the scene graph.
+ /** A billboard is like a 3d sprite: A 2d element,
+ which always looks to the camera. It is usually used for things like explosions, fire,
+ lensflares and things like that.
+ \param parent: Parent scene node of the billboard. Can be null. If the parent moves,
+ the billboard will move too.
+ \param position: Position of the space relative to its parent where the billboard will be placed.
+ \param size: Size of the billboard. This size is 2 dimensional because a billboard only has
+ width and height.
+ \param id: An id of the node. This id can be used to identify the node.
+ \param shade_top: vertex color top
+ \param shade_down: vertex color down
+ \return Returns pointer to the billboard if successful, otherwise NULL.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual IBillboardSceneNode* addBillboardSceneNode(ISceneNode* parent = 0,
+ const core::dimension2d& size = core::dimension2d(10.0f, 10.0f),
+ const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1,
+ video::SColor shade_top = 0xFFFFFFFF, video::SColor shade_down = 0xFFFFFFFF) = 0;
+
+ //! Adds a skybox scene node to the scene graph.
+ /** A skybox is a big cube with 6 textures on it and
+ is drawn around the camera position.
+ \param top: Texture for the top plane of the box.
+ \param bottom: Texture for the bottom plane of the box.
+ \param left: Texture for the left plane of the box.
+ \param right: Texture for the right plane of the box.
+ \param front: Texture for the front plane of the box.
+ \param back: Texture for the back plane of the box.
+ \param parent: Parent scene node of the skybox. A skybox usually has no parent,
+ so this should be null. Note: If a parent is set to the skybox, the box will not
+ change how it is drawn.
+ \param id: An id of the node. This id can be used to identify the node.
+ \return Returns a pointer to the sky box if successful, otherwise NULL.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ISceneNode* addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom,
+ video::ITexture* left, video::ITexture* right, video::ITexture* front,
+ video::ITexture* back, ISceneNode* parent = 0, s32 id=-1) = 0;
+
+ //! Adds a skydome scene node to the scene graph.
+ /** A skydome is a large (half-) sphere with a panoramic texture
+ on the inside and is drawn around the camera position.
+ \param texture: Texture for the dome.
+ \param horiRes: Number of vertices of a horizontal layer of the sphere.
+ \param vertRes: Number of vertices of a vertical layer of the sphere.
+ \param texturePercentage: How much of the height of the texture is used. Should be between 0 and 1.
+ \param spherePercentage: How much of the sphere is drawn. Value should be between 0 and 2, where 1 is an exact half-sphere and 2 is a full sphere.
+ \param parent: Parent scene node of the dome. A dome usually has no parent,
+ so this should be null. Note: If a parent is set, the dome will not
+ change how it is drawn.
+ \param id: An id of the node. This id can be used to identify the node.
+ \return Returns a pointer to the sky dome if successful, otherwise NULL.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ISceneNode* addSkyDomeSceneNode(video::ITexture* texture,
+ u32 horiRes, u32 vertRes, f64 texturePercentage, f64 spherePercentage,
+ ISceneNode* parent = 0, s32 id=-1) = 0;
+
+ //! Adds a particle system scene node to the scene graph.
+ /** \param withDefaultEmitter: Creates a default working point emitter
+ which emitts some particles. Set this to true to see a particle system
+ in action. If set to false, you'll have to set the emitter you want by
+ calling IParticleSystemSceneNode::setEmitter().
+ \param parent: Parent of the scene node. Can be NULL if no parent.
+ \param id: Id of the node. This id can be used to identify the scene node.
+ \param position: Position of the space relative to its parent where the
+ scene node will be placed.
+ \param rotation: Initital rotation of the scene node.
+ \param scale: Initial scale of the scene node.
+ \return Returns pointer to the created scene node.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual IParticleSystemSceneNode* addParticleSystemSceneNode(
+ bool withDefaultEmitter=true, ISceneNode* parent=0, s32 id=-1,
+ const core::vector3df& position = core::vector3df(0,0,0),
+ const core::vector3df& rotation = core::vector3df(0,0,0),
+ const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) = 0;
+
+ //! Adds a terrain scene node to the scene graph.
+ /** This node implements is a simple terrain renderer which uses
+ a technique known as geo mip mapping
+ for reducing the detail of triangle blocks which are far away.
+ The code for the TerrainSceneNode is based on the terrain
+ renderer by Soconne and the GeoMipMapSceneNode developed by
+ Spintz. They made their code available for Irrlicht and allowed
+ it to be distributed under this licence. I only modified some
+ parts. A lot of thanks go to them.
+
+ This scene node is capable of loading terrains and updating
+ the indices at runtime to enable viewing very large terrains
+ very quickly. It uses a CLOD (Continuous Level of Detail)
+ algorithm which updates the indices for each patch based on
+ a LOD (Level of Detail) which is determined based on a patch's
+ distance from the camera.
+
+ The patch size of the terrain must always be a size of ( 2^N+1, i.e. 8+1(9), 16+1(17), etc. ).
+ The MaxLOD available is directly dependent on the patch size of the terrain. LOD 0 contains all
+ of the indices to draw all the triangles at the max detail for a patch. As each LOD goes up by 1
+ the step taken, in generating indices increases by - 2^LOD, so for LOD 1, the step taken is 2, for
+ LOD 2, the step taken is 4, LOD 3 - 8, etc. The step can be no larger than the size of the patch,
+ so having a LOD of 8, with a patch size of 17, is asking the algoritm to generate indices every
+ 2^8 ( 256 ) vertices, which is not possible with a patch size of 17. The maximum LOD for a patch
+ size of 17 is 2^4 ( 16 ). So, with a MaxLOD of 5, you'll have LOD 0 ( full detail ), LOD 1 ( every
+ 2 vertices ), LOD 2 ( every 4 vertices ), LOD 3 ( every 8 vertices ) and LOD 4 ( every 16 vertices ).
+ \param heightMapFileName: The name of the file on disk, to read vertex data from. This should
+ be a gray scale bitmap.
+ \param parent: Parent of the scene node. Can be 0 if no parent.
+ \param id: Id of the node. This id can be used to identify the scene node.
+ \param position: The absolute position of this node.
+ \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED )
+ \param scale: The scale factor for the terrain. If you're using a heightmap of size 129x129 and would like
+ your terrain to be 12900x12900 in game units, then use a scale factor of ( core::vector ( 100.0f, 100.0f, 100.0f ).
+ If you use a Y scaling factor of 0.0f, then your terrain will be flat.
+ \param vertexColor: The default color of all the vertices. If no texture is associated
+ with the scene node, then all vertices will be this color. Defaults to white.
+ \param maxLOD: The maximum LOD (level of detail) for the node. Only change if you
+ know what you are doing, this might lead to strange behaviour.
+ \param patchSize: patch size of the terrain. Only change if you
+ know what you are doing, this might lead to strange behaviour.
+ \param smoothFactor: The number of times the vertices are smoothed.
+ \param addAlsoIfHeightmapEmpty: Add terrain node even with empty heightmap.
+ \return Returns pointer to the created scene node. Can be null if the
+ terrain could not be created, for example because the heightmap could not be loaded.
+ The returned pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ITerrainSceneNode* addTerrainSceneNode(
+ const c8* heightMapFileName,
+ ISceneNode* parent=0, s32 id=-1,
+ const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f),
+ const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f),
+ const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f),
+ video::SColor vertexColor = video::SColor(255,255,255,255),
+ s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17, s32 smoothFactor=0,
+ bool addAlsoIfHeightmapEmpty = false) = 0;
+
+ //! Adds a terrain scene node to the scene graph.
+ /** Just like the other addTerrainSceneNode() method, but takes an IReadFile
+ pointer as parameter for the heightmap. For more informations take a look
+ at the other function.
+ \param heightMapFile: The file handle to read vertex data from. This should
+ be a gray scale bitmap.
+ \param parent: Parent of the scene node. Can be 0 if no parent.
+ \param id: Id of the node. This id can be used to identify the scene node.
+ \param position: The absolute position of this node.
+ \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED )
+ \param scale: The scale factor for the terrain. If you're using a heightmap of size 129x129 and would like
+ your terrain to be 12900x12900 in game units, then use a scale factor of ( core::vector ( 100.0f, 100.0f, 100.0f ).
+ If you use a Y scaling factor of 0.0f, then your terrain will be flat.
+ \param vertexColor: The default color of all the vertices. If no texture is associated
+ with the scene node, then all vertices will be this color. Defaults to white.
+ \param maxLOD: The maximum LOD (level of detail) for the node. Only change if you
+ know what you are doing, this might lead to strange behaviour.
+ \param patchSize: patch size of the terrain. Only change if you
+ know what you are doing, this might lead to strange behaviour.
+ \param smoothFactor: The number of times the vertices are smoothed.
+ \param addAlsoIfHeightmapEmpty: Add terrain node even with empty heightmap.
+ \return Returns pointer to the created scene node. Can be null if the
+ terrain could not be created, for example because the heightmap could not be loaded.
+ The returned pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ITerrainSceneNode* addTerrainSceneNode(
+ io::IReadFile* heightMapFile,
+ ISceneNode* parent=0, s32 id=-1,
+ const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f),
+ const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f),
+ const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f),
+ video::SColor vertexColor = video::SColor(255,255,255,255),
+ s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17, s32 smoothFactor=0,
+ bool addAlsoIfHeightmapEmpty = false) = 0;
+
+ //! Adds a quake3 scene node to the scene graph.
+ /** A Quake3 Scene renders multiple meshes for a specific HighLanguage Shader (Quake3 Style )
+ \return Returns a pointer to the quake3 scene node if successful, otherwise NULL.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ISceneNode* addQuake3SceneNode(IMeshBuffer* meshBuffer, const quake3::SShader * shader,
+ ISceneNode* parent=0, s32 id=-1
+ ) = 0;
+
+
+ //! Adds an empty scene node to the scene graph.
+ /** Can be used for doing advanced transformations
+ or structuring the scene graph.
+ \return Returns pointer to the created scene node.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ISceneNode* addEmptySceneNode(ISceneNode* parent=0, s32 id=-1) = 0;
+
+ //! Adds a dummy transformation scene node to the scene graph.
+ /** This scene node does not render itself, and does not respond to set/getPosition,
+ set/getRotation and set/getScale. Its just a simple scene node that takes a
+ matrix as relative transformation, making it possible to insert any transformation
+ anywhere into the scene graph.
+ \return Returns pointer to the created scene node.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual IDummyTransformationSceneNode* addDummyTransformationSceneNode(
+ ISceneNode* parent=0, s32 id=-1) = 0;
+
+ //! Adds a text scene node, which is able to display 2d text at a position in three dimensional space
+ virtual ITextSceneNode* addTextSceneNode(gui::IGUIFont* font, const wchar_t* text,
+ video::SColor color=video::SColor(100,255,255,255),
+ ISceneNode* parent = 0, const core::vector3df& position = core::vector3df(0,0,0),
+ s32 id=-1) = 0;
+
+ //! Adds a text scene node, which uses billboards
+ virtual ITextSceneNode* addBillboardTextSceneNode( gui::IGUIFont* font, const wchar_t* text,
+ ISceneNode* parent = 0,
+ const core::dimension2d& size = core::dimension2d(10.0f, 10.0f),
+ const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1,
+ video::SColor shade_top = 0xFFFFFFFF, video::SColor shade_down = 0xFFFFFFFF) = 0;
+
+ //! Adds a Hill Plane mesh to the mesh pool.
+ /** The mesh is generated on the fly
+ and looks like a plane with some hills on it. It is uses mostly for quick
+ tests of the engine only. You can specify how many hills there should be
+ on the plane and how high they should be. Also you must specify a name for
+ the mesh, because the mesh is added to the mesh pool, and can be retrieved
+ again using ISceneManager::getMesh() with the name as parameter.
+ \param name: The name of this mesh which must be specified in order
+ to be able to retrieve the mesh later with ISceneManager::getMesh().
+ \param tileSize: Size of a tile of the mesh. (10.0f, 10.0f) would be a
+ good value to start, for example.
+ \param tileCount: Specifies how much tiles there will be. If you specifiy
+ for example that a tile has the size (10.0f, 10.0f) and the tileCount is
+ (10,10), than you get a field of 100 tiles which has the dimension 100.0fx100.0f.
+ \param material: Material of the hill mesh.
+ \param hillHeight: Height of the hills. If you specify a negative value
+ you will get holes instead of hills. If the height is 0, no hills will be
+ created.
+ \param countHills: Amount of hills on the plane. There will be countHills.X
+ hills along the X axis and countHills.Y along the Y axis. So in total there
+ will be countHills.X * countHills.Y hills.
+ \param textureRepeatCount: Defines how often the texture will be repeated in
+ x and y direction.
+ \return Returns null if the creation failed. The reason could be that you
+ specified some invalid parameters or that a mesh with that name already
+ exists. If successful, a pointer to the mesh is returned.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual IAnimatedMesh* addHillPlaneMesh(const c8* name,
+ const core::dimension2d& tileSize, const core::dimension2d& tileCount,
+ video::SMaterial* material = 0, f32 hillHeight = 0.0f,
+ const core::dimension2d& countHills = core::dimension2d(0.0f, 0.0f),
+ const core::dimension2d& textureRepeatCount = core::dimension2d(1.0f, 1.0f)) = 0;
+
+ //! Adds a static terrain mesh to the mesh pool.
+ /** The mesh is generated on the fly
+ from a texture file and a height map file. Both files may be huge
+ (8000x8000 pixels would be no problem) because the generator splits the
+ files into smaller textures if necessary.
+ You must specify a name for the mesh, because the mesh is added to the mesh pool,
+ and can be retrieved again using ISceneManager::getMesh() with the name as parameter.
+ \param meshname: The name of this mesh which must be specified in order
+ to be able to retrieve the mesh later with ISceneManager::getMesh().
+ \param texture: Texture for the terrain. Please note that this is not a
+ hardware texture as usual (ITexture), but an IImage software texture.
+ You can load this texture with IVideoDriver::createImageFromFile().
+ \param heightmap: A grayscaled heightmap image. Like the texture,
+ it can be created with IVideoDriver::createImageFromFile(). The amount
+ of triangles created depends on the size of this texture, so use a small
+ heightmap to increase rendering speed.
+ \param stretchSize: Parameter defining how big a is pixel on the heightmap.
+ \param maxHeight: Defines how height a white pixel on the heighmap is.
+ \param defaultVertexBlockSize: Defines the initial dimension between vertices.
+ \return Returns null if the creation failed. The reason could be that you
+ specified some invalid parameters, that a mesh with that name already
+ exists, or that a texture could not be found. If successful, a pointer to the mesh is returned.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual IAnimatedMesh* addTerrainMesh(const c8* meshname,
+ video::IImage* texture, video::IImage* heightmap,
+ const core::dimension2d& stretchSize = core::dimension2d(10.0f,10.0f),
+ f32 maxHeight=200.0f,
+ const core::dimension2d& defaultVertexBlockSize = core::dimension2d(64,64)) = 0;
+
+ //! add a static arrow mesh to the meshpool
+ virtual IAnimatedMesh* addArrowMesh(const c8* name,
+ video::SColor vtxColor0=0xFFFFFFFF,
+ video::SColor vtxColor1=0xFFFFFFFF,
+ u32 tesselationCylinder=4, u32 tesselationCone=8,
+ f32 height=1.f, f32 cylinderHeight=0.6f,
+ f32 width0=0.05f, f32 width1=0.3f) = 0;
+
+ //! add a static sphere mesh to the meshpool
+ virtual IAnimatedMesh* addSphereMesh(const c8* name,
+ f32 radius=5.f, u32 polyCountX = 16,
+ u32 polyCountY = 16) = 0;
+
+ //! Returns the root scene node.
+ /** This is the scene node which is parent
+ of all scene nodes. The root scene node is a special scene node which
+ only exists to manage all scene nodes. It will not be rendered and cannot
+ be removed from the scene.
+ \return Returns a pointer to the root scene node. */
+ virtual ISceneNode* getRootSceneNode() = 0;
+
+ //! Returns the first scene node with the specified id.
+ /** \param id: The id to search for
+ \param start: Scene node to start from. All children of this scene
+ node are searched. If null is specified, the root scene node is
+ taken.
+ \return Returns pointer to the first scene node with this id,
+ and null if no scene node could be found. */
+ virtual ISceneNode* getSceneNodeFromId(s32 id, ISceneNode* start=0) = 0;
+
+ //! Returns the first scene node with the specified name.
+ /** \param name: The name to search for
+ \param start: Scene node to start from. All children of this scene
+ node are searched. If null is specified, the root scene node is
+ taken.
+ \return Returns pointer to the first scene node with this id,
+ and null if no scene node could be found. */
+ virtual ISceneNode* getSceneNodeFromName(const c8* name, ISceneNode* start=0) = 0;
+
+ //! Returns the first scene node with the specified type.
+ /** \param type: The type to search for
+ \param start: Scene node to start from. All children of this scene
+ node are searched. If null is specified, the root scene node is
+ taken.
+ \return Returns pointer to the first scene node with this type,
+ and null if no scene node could be found. */
+ virtual ISceneNode* getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start=0) = 0;
+
+ //! returns scene nodes by type.
+ /** \param type: Type of scene node to find.
+ \param outNodes: array to be filled with results.
+ \param start: Scene node to start from. All children of this scene
+ node are searched. If null is specified, the root scene node is
+ taken. */
+ virtual void getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array& outNodes, ISceneNode* start=0) = 0;
+
+ //! Returns the current active camera.
+ /** \return The active camera is returned. Note that this can be NULL, if there
+ was no camera created yet. */
+ virtual ICameraSceneNode* getActiveCamera() = 0;
+
+ //! Sets the currently active camera.
+ /** The previous active camera will be deactivated.
+ \param camera: The new camera which should be active. */
+ virtual void setActiveCamera(ICameraSceneNode* camera) = 0;
+
+ //! Sets the color of stencil buffers shadows drawn by the scene manager.
+ virtual void setShadowColor(video::SColor color = video::SColor(150,0,0,0)) = 0;
+
+ //! Returns the current color of shadows.
+ virtual video::SColor getShadowColor() const = 0;
+
+ //! Registers a node for rendering it at a specific time.
+ /** This method should only be used by SceneNodes when they get a
+ ISceneNode::OnRegisterSceneNode() call.
+ \param node: Node to register for drawing. Usually scene nodes would set 'this'
+ as parameter here because they want to be drawn.
+ \param pass: Specifies when the mode wants to be drawn in relation to the other nodes.
+ For example, if the node is a shadow, it usually wants to be drawn after all other nodes
+ and will use ESNRP_SHADOW for this. See E_SCENE_NODE_RENDER_PASS for details.
+ \return scene will be rendered ( passed culling ) */
+ virtual u32 registerNodeForRendering(ISceneNode* node,
+ E_SCENE_NODE_RENDER_PASS pass = ESNRP_AUTOMATIC) = 0;
+
+ //! Draws all the scene nodes.
+ /** This can only be invoked between
+ IVideoDriver::beginScene() and IVideoDriver::endScene(). Please note that
+ the scene is not only drawn when calling this, but also animated
+ by existing scene node animators, culling of scene nodes is done, etc. */
+ virtual void drawAll() = 0;
+
+ //! Creates a rotation animator, which rotates the attached scene node around itself.
+ /** \param rotationPerSecond: Specifies the speed of the animation
+ \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
+ and the animator will animate it.
+ If you no longer need the animator, you should call ISceneNodeAnimator::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual ISceneNodeAnimator* createRotationAnimator(const core::vector3df& rotationPerSecond) = 0;
+
+ //! Creates a fly circle animator, which lets the attached scene node fly around a center.
+ /** \param center: Center of the circle.
+ \param radius: Radius of the circle.
+ \param speed: Specifies the speed of the flight.
+ \param direction: Specifies the upvector used for alignment of the mesh.
+ \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
+ and the animator will animate it.
+ If you no longer need the animator, you should call ISceneNodeAnimator::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual ISceneNodeAnimator* createFlyCircleAnimator(const core::vector3df& center,
+ f32 radius, f32 speed=0.001f, const core::vector3df& direction= core::vector3df ( 0.f, 1.f, 0.f ) ) = 0;
+
+ //! Creates a fly straight animator, which lets the attached scene node fly or move along a line between two points.
+ /** \param startPoint: Start point of the line.
+ \param endPoint: End point of the line.
+ \param timeForWay: Time in milli seconds how long the node should need to
+ move from the start point to the end point.
+ \param loop: If set to false, the node stops when the end point is reached.
+ If loop is true, the node begins again at the start.
+ \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
+ and the animator will animate it.
+ If you no longer need the animator, you should call ISceneNodeAnimator::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual ISceneNodeAnimator* createFlyStraightAnimator(const core::vector3df& startPoint,
+ const core::vector3df& endPoint, u32 timeForWay, bool loop=false) = 0;
+
+ //! Creates a texture animator, which switches the textures of the target scene node based on a list of textures.
+ /** \param textures: List of textures to use.
+ \param timePerFrame: Time in milliseconds, how long any texture in the list
+ should be visible.
+ \param loop: If set to to false, the last texture remains set, and the animation
+ stops. If set to true, the animation restarts with the first texture.
+ \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
+ and the animator will animate it.
+ If you no longer need the animator, you should call ISceneNodeAnimator::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual ISceneNodeAnimator* createTextureAnimator(const core::array& textures,
+ s32 timePerFrame, bool loop=true) = 0;
+
+ //! Creates a scene node animator, which deletes the scene node after some time automatically.
+ /** \param timeMs: Time in milliseconds, after when the node will be deleted.
+ \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
+ and the animator will animate it.
+ If you no longer need the animator, you should call ISceneNodeAnimator::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual ISceneNodeAnimator* createDeleteAnimator(u32 timeMs) = 0;
+
+ //! Creates a special scene node animator for doing automatic collision detection and response.
+ /** See ISceneNodeAnimatorCollisionResponse for details.
+ \param world: Triangle selector holding all triangles of the world with which
+ the scene node may collide. You can create a triangle selector with
+ ISceneManager::createTriangleSelector();
+ \param sceneNode: SceneNode which should be manipulated. After you added this animator
+ to the scene node, the scene node will not be able to move through walls and is
+ affected by gravity.
+ \param ellipsoidRadius: Radius of the ellipsoid with which collision detection and
+ response is done. If you have got a scene node, and you are unsure about
+ how big the radius should be, you could use the following code to determine
+ it:
+ \code
+ const core::aabbox& box = yourSceneNode->getBoundingBox();
+ core::vector3df radius = box.MaxEdge - box.getCenter();
+ \endcode
+ \param gravityPerSecond: Sets the gravity of the environment. A good example value would be
+ core::vector3df(0,-100.0f,0) for letting gravity affect all object to
+ fall down. For bigger gravity, make increase the length of the vector.
+ You can disable gravity by setting it to core::vector3df(0,0,0).
+ \param ellipsoidTranslation: By default, the ellipsoid for collision detection is created around
+ the center of the scene node, which means that the ellipsoid surrounds
+ it completely. If this is not what you want, you may specify a translation
+ for the ellipsoid.
+ \param slidingValue: DOCUMENTATION NEEDED.
+ \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
+ and the animator will cause it to do collision detection and response.
+ If you no longer need the animator, you should call ISceneNodeAnimator::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual ISceneNodeAnimatorCollisionResponse* createCollisionResponseAnimator(
+ ITriangleSelector* world, ISceneNode* sceneNode,
+ const core::vector3df& ellipsoidRadius = core::vector3df(30,60,30),
+ const core::vector3df& gravityPerSecond = core::vector3df(0,-100.0f,0),
+ const core::vector3df& ellipsoidTranslation = core::vector3df(0,0,0),
+ f32 slidingValue = 0.0005f) = 0;
+
+ //! Creates a follow spline animator.
+ /** The animator modifies the position of
+ the attached scene node to make it follow a hermite spline.
+ The code of the is based on a scene node
+ Matthias Gall sent in. Thanks! I adapted the code just a little bit. Matthias
+ wrote:
+ Uses a subset of hermite splines: either cardinal splines (tightness != 0.5) or catmull-rom-splines (tightness == 0.5)
+ but this is just my understanding of this stuff, I'm not a mathematician, so this might be wrong ;) */
+ virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime,
+ const core::array< core::vector3df >& points,
+ f32 speed = 1.0f, f32 tightness = 0.5f) = 0;
+
+ //! Creates a simple ITriangleSelector, based on a mesh.
+ /** Triangle selectors
+ can be used for doing collision detection. Don't use this selector
+ for a huge amount of triangles like in Quake3 maps.
+ Instead, use for example ISceneManager::createOctTreeTriangleSelector().
+ Please note that the created triangle selector is not automaticly attached
+ to the scene node. You will have to call ISceneNode::setTriangleSelector()
+ for this. To create and attach a triangle selector is done like this:
+ \code
+ ITriangleSelector* s = sceneManager->createTriangleSelector(yourMesh,
+ yourSceneNode);
+ yourSceneNode->setTriangleSelector(s);
+ s->drop();
+ \endcode
+ \param mesh: Mesh of which the triangles are taken.
+ \param node: Scene node of which visibility and transformation is used.
+ \return Returns the selector, or null if not successful.
+ If you no longer need the selector, you should call ITriangleSelector::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node) = 0;
+
+ //! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.
+ /** Triangle selectors
+ can be used for doing collision detection. Every time when triangles are
+ queried, the triangle selector gets the bounding box of the scene node,
+ an creates new triangles. In this way, it works good with animated scene nodes.
+ \param node: Scene node of which the bounding box, visibility and transformation is used.
+ \return Returns the selector, or null if not successful.
+ If you no longer need the selector, you should call ITriangleSelector::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual ITriangleSelector* createTriangleSelectorFromBoundingBox(ISceneNode* node) = 0;
+
+ //! Creates a Triangle Selector, optimized by an octtree.
+ /** Triangle selectors
+ can be used for doing collision detection. This triangle selector is
+ optimized for huge amounts of triangle, it organizes them in an octtree.
+ Please note that the created triangle selector is not automaticly attached
+ to the scene node. You will have to call ISceneNode::setTriangleSelector()
+ for this. To create and attach a triangle selector is done like this:
+ \code
+ ITriangleSelector* s = sceneManager->createOctTreeTriangleSelector(yourMesh,
+ yourSceneNode);
+ yourSceneNode->setTriangleSelector(s);
+ s->drop();
+ \endcode
+ For more informations and examples on this, take a look at the collision
+ tutorial in the SDK.
+ \param mesh: Mesh of which the triangles are taken.
+ \param node: Scene node of which visibility and transformation is used.
+ \param minimalPolysPerNode: Specifies the minimal polygons contained a octree node.
+ If a node gets less polys the this value, it will not be splitted into
+ smaller nodes.
+ \return Returns the selector, or null if not successful.
+ If you no longer need the selector, you should call ITriangleSelector::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh,
+ ISceneNode* node, s32 minimalPolysPerNode=32) = 0;
+
+ //! Creates a meta triangle selector.
+ /** A meta triangle selector is nothing more than a
+ collection of one or more triangle selectors providing together
+ the interface of one triangle selector. In this way,
+ collision tests can be done with different triangle soups in one pass.
+ \return Returns the selector, or null if not successful.
+ If you no longer need the selector, you should call ITriangleSelector::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual IMetaTriangleSelector* createMetaTriangleSelector() = 0;
+
+ //! Creates a triangle selector which can select triangles from a terrain scene node.
+ /** \param node: Pointer to the created terrain scene node
+ \param LOD: Level of detail, 0 for highest detail. */
+ virtual ITriangleSelector* createTerrainTriangleSelector(
+ ITerrainSceneNode* node, s32 LOD=0) = 0;
+
+ //! Adds an external mesh loader for extending the engine with new file formats.
+ /** If you want the engine to be extended with
+ file formats it currently is not able to load (e.g. .cob), just implement
+ the IMeshLoader interface in your loading class and add it with this method.
+ Using this method it is also possible to override built-in mesh loaders with
+ newer or updated versions without the need of recompiling the engine.
+ \param externalLoader: Implementation of a new mesh loader. */
+ virtual void addExternalMeshLoader(IMeshLoader* externalLoader) = 0;
+
+ //! Returns a pointer to the scene collision manager.
+ virtual ISceneCollisionManager* getSceneCollisionManager() = 0;
+
+ //! Returns a pointer to the mesh manipulator.
+ virtual IMeshManipulator* getMeshManipulator() = 0;
+
+ //! Adds a scene node to the deletion queue.
+ /** The scene node is immediatly
+ deleted when it's secure. Which means when the scene node does not
+ execute animators and things like that. This method is for example
+ used for deleting scene nodes by their scene node animators. In
+ most other cases, a ISceneNode::remove() call is enough, using this
+ deletion queue is not necessary.
+ See ISceneManager::createDeleteAnimator() for details.
+ \param node: Node to detete. */
+ virtual void addToDeletionQueue(ISceneNode* node) = 0;
+
+ //! Posts an input event to the environment.
+ /** Usually you do not have to
+ use this method, it is used by the internal engine. */
+ virtual bool postEventFromUser(const SEvent& event) = 0;
+
+ //! Clears the whole scene.
+ /** All scene nodes are removed. */
+ virtual void clear() = 0;
+
+ //! Returns interface to the parameters set in this scene.
+ /** String parameters can be used by plugins and mesh loaders.
+ For example the CMS and LMTS loader want a parameter named 'CSM_TexturePath'
+ and 'LMTS_TexturePath' set to the path were attached textures can be found. See
+ CSM_TEXTURE_PATH, LMTS_TEXTURE_PATH, MY3D_TEXTURE_PATH,
+ COLLADA_CREATE_SCENE_INSTANCES, DMF_TEXTURE_PATH and DMF_USE_MATERIALS_DIRS*/
+ virtual io::IAttributes* getParameters() = 0;
+
+ //! Returns current render pass.
+ /** All scene nodes are being rendered in a specific order.
+ First lights, cameras, sky boxes, solid geometry, and then transparent
+ stuff. During the rendering process, scene nodes may want to know what the scene
+ manager is rendering currently, because for example they registered for rendering
+ twice, once for transparent geometry and once for solid. When knowing what rendering
+ pass currently is active they can render the correct part of their geometry. */
+ virtual E_SCENE_NODE_RENDER_PASS getSceneNodeRenderPass() const = 0;
+
+ //! Returns the default scene node factory which can create all built in scene nodes
+ virtual ISceneNodeFactory* getDefaultSceneNodeFactory() = 0;
+
+ //! Adds a scene node factory to the scene manager.
+ /** Use this to extend the scene manager with new scene node types which it should be
+ able to create automaticly, for example when loading data from xml files. */
+ virtual void registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd) = 0;
+
+ //! Returns amount of registered scene node factories.
+ virtual u32 getRegisteredSceneNodeFactoryCount() const = 0;
+
+ //! Returns a scene node factory by index
+ virtual ISceneNodeFactory* getSceneNodeFactory(u32 index) = 0;
+
+ //! Returns the default scene node animator factory which can create all built-in scene node animators
+ virtual ISceneNodeAnimatorFactory* getDefaultSceneNodeAnimatorFactory() = 0;
+
+ //! Adds a scene node animator factory to the scene manager.
+ /** Use this to extend the scene manager with new scene node animator types which it should be
+ able to create automaticly, for example when loading data from xml files. */
+ virtual void registerSceneNodeAnimatorFactory(ISceneNodeAnimatorFactory* factoryToAdd) = 0;
+
+ //! Returns amount of registered scene node animator factories.
+ virtual u32 getRegisteredSceneNodeAnimatorFactoryCount() const = 0;
+
+ //! Returns a scene node animator factory by index
+ virtual ISceneNodeAnimatorFactory* getSceneNodeAnimatorFactory(u32 index) = 0;
+
+ //! Returns a typename from a scene node type or null if not found
+ virtual const c8* getSceneNodeTypeName(ESCENE_NODE_TYPE type) = 0;
+
+ //! Adds a scene node to the scene by name
+ virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent) = 0;
+
+ //! Creates a new scene manager.
+ /** This can be used to easily draw and/or store two independent scenes at the same time.
+ The mesh cache will be shared between all existing scene managers, which means if you load
+ a mesh in the original scene manager using for example getMesh(), the mesh will be available
+ in all other scene managers too, without loading.
+ The original/main scene manager will still be there and accessible via IrrlichtDevice::getSceneManager().
+ If you need input event in this new scene manager, for example for FPS cameras, you'll need
+ to forward input to this manually: Just implement an IEventReceiver and call
+ yourNewSceneManager->postEventFromUser(), and return true so that the original scene manager
+ doesn't get the event. Otherwise, all input will go automaticly to the main scene manager.
+ If you no longer need the new scene manager, you should call ISceneManager::drop().
+ See IReferenceCounted::drop() for more information. */
+ virtual ISceneManager* createNewSceneManager(bool cloneContent=false) = 0;
+
+ //! Saves the current scene into a file.
+ /** Scene nodes with the option isDebugObject set to true are not being saved.
+ The scene is usually written to an .irr file, an xml based format. .irr files can
+ Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org).
+ To load .irr files again, see ISceneManager::loadScene().
+ \param filename: Name of the file.
+ \param userDataSerializer: If you want to save some user data for every scene node into the
+ file, implement the ISceneUserDataSerializer interface and provide it as parameter here.
+ Otherwise, simply specify 0 as this parameter.
+ \return Returns true if successful. */
+ virtual bool saveScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer=0) = 0;
+
+ //! Saves the current scene into a file.
+ /** Scene nodes with the option isDebugObject set to true are not being saved.
+ The scene is usually written to an .irr file, an xml based format. .irr files can
+ Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org).
+ To load .irr files again, see ISceneManager::loadScene().
+ \param file: File where the scene is saved into.
+ \param userDataSerializer: If you want to save some user data for every scene node into the
+ file, implement the ISceneUserDataSerializer interface and provide it as parameter here.
+ Otherwise, simply specify 0 as this parameter.
+ \return Returns true if successful. */
+ virtual bool saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer=0) = 0;
+
+ //! Loads a scene. Note that the current scene is not cleared before.
+ /** The scene is usually load from an .irr file, an xml based format. .irr files can
+ Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org) or
+ saved directly by the engine using ISceneManager::saveScene().
+ \param filename: Name of the file.
+ \param userDataSerializer: If you want to load user data possibily saved in that file for
+ some scene nodes in the file, implement the ISceneUserDataSerializer interface and provide it as parameter here.
+ Otherwise, simply specify 0 as this parameter.
+ \return Returns true if successful. */
+ virtual bool loadScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer=0) = 0;
+
+ //! Loads a scene. Note that the current scene is not cleared before.
+ /** The scene is usually load from an .irr file, an xml based format. .irr files can
+ Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org) or
+ saved directly by the engine using ISceneManager::saveScene().
+ \param file: File where the scene is going to be saved into.
+ \param userDataSerializer: If you want to load user data possibily saved in that file for
+ some scene nodes in the file, implement the ISceneUserDataSerializer interface and provide it as parameter here.
+ Otherwise, simply specify 0 as this parameter.
+ \return Returns true if successful. */
+ virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0) = 0;
+
+ //! Returns a mesh writer implementation if available
+ /** Note: You need to drop() the pointer after use again, see IReferenceCounted::drop()
+ for details. */
+ virtual IMeshWriter* createMeshWriter(EMESH_WRITER_TYPE type) = 0;
+
+ //! Sets ambient color of the scene
+ virtual void setAmbientLight(const video::SColorf &ambientColor) = 0;
+
+ //! Returns ambient color of the scene
+ virtual const video::SColorf& getAmbientLight() const = 0;
+
+ };
+
+
+} // end namespace scene
+} // end namespace irr
+
+#endif
+
diff --git a/media/lightFalloff.png b/media/lightFalloff.png
new file mode 100644
index 00000000..21b2142a
Binary files /dev/null and b/media/lightFalloff.png differ
diff --git a/source/Irrlicht/CSceneManager.cpp b/source/Irrlicht/CSceneManager.cpp
index 91961634..ba646b92 100644
--- a/source/Irrlicht/CSceneManager.cpp
+++ b/source/Irrlicht/CSceneManager.cpp
@@ -1,2211 +1,2228 @@
-// 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
-
-#include "IrrCompileConfig.h"
-#include "CSceneManager.h"
-#include "IVideoDriver.h"
-#include "IFileSystem.h"
-#include "SAnimatedMesh.h"
-#include "CMeshCache.h"
-#include "IWriteFile.h"
-#include "IXMLWriter.h"
-#include "ISceneUserDataSerializer.h"
-#include "IGUIEnvironment.h"
-#include "IMaterialRenderer.h"
-
-#include "os.h"
-
-#include "CGeometryCreator.h"
-
-#ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_
-#include "CIrrMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_BSP_LOADER_
-#include "CBSPMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_MD2_LOADER_
-#include "CMD2MeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
-#include "CMS3DMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
-#include "C3DSMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_X_LOADER_
-#include "CXMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
-#include "COCTLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_CSM_LOADER_
-#include "CCSMLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
-#include "CLMTSMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
-#include "CMY3DMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
-#include "CColladaFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_DMF_LOADER_
-#include "CDMFLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
-#include "COgreMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
-#include "COBJMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_MD3_LOADER_
-#include "CMD3MeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
-#include "CB3DMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_STL_LOADER_
-#include "CSTLMeshFileLoader.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_
-#include "CColladaMeshWriter.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_IRR_WRITER_
-#include "CIrrMeshWriter.h"
-#endif
-
-#ifdef _IRR_COMPILE_WITH_STL_WRITER_
-#include "CSTLMeshWriter.h"
-#endif
-
-#include "CCubeSceneNode.h"
-#include "CSphereSceneNode.h"
-#include "CAnimatedMeshSceneNode.h"
-#include "COctTreeSceneNode.h"
-#include "CCameraSceneNode.h"
-#include "CCameraMayaSceneNode.h"
-#include "CCameraFPSSceneNode.h"
-#include "CLightSceneNode.h"
-#include "CBillboardSceneNode.h"
-#include "CMeshSceneNode.h"
-#include "CSkyBoxSceneNode.h"
-#include "CSkyDomeSceneNode.h"
-#include "CParticleSystemSceneNode.h"
-#include "CDummyTransformationSceneNode.h"
-#include "CWaterSurfaceSceneNode.h"
-#include "CTerrainSceneNode.h"
-#include "CEmptySceneNode.h"
-#include "CTextSceneNode.h"
-#include "CDefaultSceneNodeFactory.h"
-
-#include "CSceneCollisionManager.h"
-#include "CMeshManipulator.h"
-#include "CTriangleSelector.h"
-#include "COctTreeTriangleSelector.h"
-#include "CTriangleBBSelector.h"
-#include "CMetaTriangleSelector.h"
-#include "CTerrainTriangleSelector.h"
-
-#include "CSceneNodeAnimatorRotation.h"
-#include "CSceneNodeAnimatorFlyCircle.h"
-#include "CSceneNodeAnimatorFlyStraight.h"
-#include "CSceneNodeAnimatorTexture.h"
-#include "CSceneNodeAnimatorCollisionResponse.h"
-#include "CSceneNodeAnimatorDelete.h"
-#include "CSceneNodeAnimatorFollowSpline.h"
-#include "CDefaultSceneNodeAnimatorFactory.h"
-
-#include "CQuake3ShaderSceneNode.h"
-
-//! Enable debug features
-#define SCENEMANAGER_DEBUG
-
-namespace irr
-{
-namespace scene
-{
-
-//! 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")
-{
- #ifdef _DEBUG
- ISceneManager::setDebugName("CSceneManager ISceneManager");
- ISceneNode::setDebugName("CSceneManager ISceneNode");
- #endif
-
- if (Driver)
- Driver->grab();
-
- if (FileSystem)
- FileSystem->grab();
-
- if (CursorControl)
- CursorControl->grab();
-
- if ( GUIEnvironment )
- GUIEnvironment->grab();
-
- // create mesh cache if not there already
- if (!MeshCache)
- MeshCache = new CMeshCache();
- else
- MeshCache->grab();
-
- // create collision manager
- CollisionManager = new CSceneCollisionManager(this, Driver);
-
- // create manipulator
- MeshManipulator = new CMeshManipulator();
-
- // add file format loaders
-
- #ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_
- MeshLoaderList.push_back(new CIrrMeshFileLoader(Driver, this, FileSystem));
- #endif
- #ifdef _IRR_COMPILE_WITH_BSP_LOADER_
- MeshLoaderList.push_back(new CBSPMeshFileLoader(FileSystem, Driver, this));
- #endif
- #ifdef _IRR_COMPILE_WITH_MD2_LOADER_
- MeshLoaderList.push_back(new CMD2MeshFileLoader());
- #endif
- #ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
- MeshLoaderList.push_back(new CMS3DMeshFileLoader(Driver));
- #endif
- #ifdef _IRR_COMPILE_WITH_3DS_LOADER_
- MeshLoaderList.push_back(new C3DSMeshFileLoader(MeshManipulator,FileSystem, Driver));
- #endif
- #ifdef _IRR_COMPILE_WITH_X_LOADER_
- MeshLoaderList.push_back(new CXMeshFileLoader(this));
- #endif
- #ifdef _IRR_COMPILE_WITH_OCT_LOADER_
- MeshLoaderList.push_back(new COCTLoader(Driver));
- #endif
- #ifdef _IRR_COMPILE_WITH_CSM_LOADER_
- MeshLoaderList.push_back(new CCSMLoader(this, FileSystem));
- #endif
- #ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
- MeshLoaderList.push_back(new CLMTSMeshFileLoader(FileSystem, Driver, &Parameters));
- #endif
- #ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
- MeshLoaderList.push_back(new CMY3DMeshFileLoader(FileSystem, Driver, this));
- #endif
- #ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
- MeshLoaderList.push_back(new CColladaFileLoader(Driver, this, FileSystem));
- #endif
- #ifdef _IRR_COMPILE_WITH_DMF_LOADER_
- MeshLoaderList.push_back(new CDMFLoader(Driver, this));
- #endif
- #ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
- MeshLoaderList.push_back(new COgreMeshFileLoader(MeshManipulator, FileSystem, Driver));
- #endif
- #ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
- MeshLoaderList.push_back(new COBJMeshFileLoader(FileSystem, Driver));
- #endif
- #ifdef _IRR_COMPILE_WITH_MD3_LOADER_
- MeshLoaderList.push_back(new CMD3MeshFileLoader(FileSystem, Driver));
- #endif
- #ifdef _IRR_COMPILE_WITH_B3D_LOADER_
- MeshLoaderList.push_back(new CB3DMeshFileLoader(this));
- #endif
- #ifdef _IRR_COMPILE_WITH_STL_LOADER_
- MeshLoaderList.push_back(new CSTLMeshFileLoader());
- #endif
-
- // factories
- ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this);
- registerSceneNodeFactory(factory);
- factory->drop();
-
- ISceneNodeAnimatorFactory* animatorFactory = new CDefaultSceneNodeAnimatorFactory(this);
- registerSceneNodeAnimatorFactory(animatorFactory);
- animatorFactory->drop();
-}
-
-
-
-//! destructor
-CSceneManager::~CSceneManager()
-{
- clearDeletionList();
-
- if (Driver)
- Driver->drop();
-
- if (FileSystem)
- FileSystem->drop();
-
- if (CursorControl)
- CursorControl->drop();
-
- if (CollisionManager)
- CollisionManager->drop();
-
- if (MeshManipulator)
- MeshManipulator->drop();
-
- if ( GUIEnvironment )
- GUIEnvironment->drop ();
-
- u32 i;
-
- for (i=0; idrop();
-
- if (ActiveCamera)
- ActiveCamera->drop();
-
- if (MeshCache)
- MeshCache->drop();
-
- for (i=0; idrop();
-
- for (i=0; idrop();
-}
-
-
-//! gets an animateable mesh. loads it if needed. returned pointer must not be dropped.
-IAnimatedMesh* CSceneManager::getMesh(const c8* filename)
-{
- IAnimatedMesh* msh = MeshCache->getMeshByFilename(filename);
- if (msh)
- return msh;
-
- io::IReadFile* file = FileSystem->createAndOpenFile(filename);
- if (!file)
- {
- os::Printer::log("Could not load mesh, because file could not be opened.", filename, ELL_ERROR);
- return 0;
- }
-
- core::stringc name = filename;
- name.make_lower();
- s32 count = MeshLoaderList.size();
- for (s32 i=count-1; i>=0; --i)
- {
- if (MeshLoaderList[i]->isALoadableFileExtension(name.c_str()))
- {
- // reset file to avoid side effects of previous calls to createMesh
- file->seek(0);
- msh = MeshLoaderList[i]->createMesh(file);
- if (msh)
- {
- MeshCache->addMesh(filename, msh);
- msh->drop();
- break;
- }
- }
- }
-
- file->drop();
-
- if (!msh)
- os::Printer::log("Could not load mesh, file format seems to be unsupported", filename, ELL_ERROR);
- else
- os::Printer::log("Loaded mesh", filename, ELL_INFORMATION);
-
- return msh;
-}
-
-
-//! returns the video driver
-video::IVideoDriver* CSceneManager::getVideoDriver()
-{
- return Driver;
-}
-
-//! returns the GUI Environment
-gui::IGUIEnvironment* CSceneManager::getGUIEnvironment ()
-{
- return GUIEnvironment;
-}
-
-
-//! Adds a text scene node, which is able to display
-//! 2d text at a position in three dimensional space
-ITextSceneNode* CSceneManager::addTextSceneNode(gui::IGUIFont* font,
- const wchar_t* text, video::SColor color, ISceneNode* parent,
- const core::vector3df& position, s32 id)
-{
- if (!font)
- return 0;
-
- if (!parent)
- parent = this;
-
- ITextSceneNode* t = new CTextSceneNode(parent, this, id, font,
- getSceneCollisionManager(), position, text, color);
- t->drop();
-
- return t;
-}
-
-//! Adds a text scene node, which uses billboards
-ITextSceneNode* CSceneManager::addBillboardTextSceneNode(gui::IGUIFont* font,
- const wchar_t* text, ISceneNode* parent,
- const core::dimension2d& size,
- const core::vector3df& position, s32 id,
- video::SColor shade_top, video::SColor shade_down)
-{
- if (!font)
- return 0;
-
- if (!parent)
- parent = this;
-
- ITextSceneNode* node = new CBillboardTextSceneNode(parent, this, id, font, text, position, size,
- shade_top, shade_down);
- node->drop();
-
- return node;
-
-}
-
-
-//! Adds a scene node, which can render a quake3 shader
-ISceneNode* CSceneManager::addQuake3SceneNode( IMeshBuffer* meshBuffer,
- const quake3::SShader * shader,
- ISceneNode* parent,
- s32 id
- )
-
-{
- if ( 0 == shader )
- return 0;
-
- if (!parent)
- parent = this;
-
- CQuake3ShaderSceneNode* node = new CQuake3ShaderSceneNode ( parent, this, id, FileSystem, meshBuffer, shader );
- node->drop();
-
- return node;
-
-}
-
-
-//! adds a test scene node for test purposes to the scene. It is a simple cube of (1,1,1) size.
-//! the returned pointer must not be dropped.
-ISceneNode* CSceneManager::addCubeSceneNode(f32 size, ISceneNode* parent, s32 id,
- const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
-{
- if (!parent)
- parent = this;
-
- ISceneNode* node = new CCubeSceneNode(size, parent, this, id, position, rotation, scale);
- node->drop();
-
- return node;
-}
-
-//! Adds a sphere scene node for test purposes to the scene.
-ISceneNode* CSceneManager::addSphereSceneNode(f32 radius, s32 polyCount, ISceneNode* parent, s32 id,
- const core::vector3df& position,
- const core::vector3df& rotation,
- const core::vector3df& scale)
-{
- if (!parent)
- parent = this;
-
- ISceneNode* node = new CSphereSceneNode(radius, polyCount, polyCount, parent, this, id, position, rotation, scale);
- node->drop();
-
- return node;
-}
-
-
-//! adds a scene node for rendering a static mesh
-//! the returned pointer must not be dropped.
-IMeshSceneNode* CSceneManager::addMeshSceneNode(IMesh* mesh, ISceneNode* parent, s32 id,
- const core::vector3df& position, const core::vector3df& rotation,
- const core::vector3df& scale, bool alsoAddIfMeshPointerZero)
-{
- if (!alsoAddIfMeshPointerZero && !mesh)
- return 0;
-
- if (!parent)
- parent = this;
-
- IMeshSceneNode* node = new CMeshSceneNode(mesh, parent, this, id, position, rotation, scale);
- node->drop();
-
- return node;
-}
-
-
-//! Adds a scene node for rendering a animated water surface mesh.
-ISceneNode* CSceneManager::addWaterSurfaceSceneNode(IMesh* mesh, f32 waveHeight, f32 waveSpeed, f32 waveLength,
- ISceneNode* parent, s32 id, const core::vector3df& position,
- const core::vector3df& rotation, const core::vector3df& scale)
-{
- if (!mesh)
- return 0;
-
- if (!parent)
- parent = this;
-
- ISceneNode* node = new CWaterSurfaceSceneNode(waveHeight, waveSpeed, waveLength,
- mesh, parent, this, id, position, rotation, scale);
-
- node->drop();
-
- return node;
-}
-
-
-
-//! adds a scene node for rendering an animated mesh model
-IAnimatedMeshSceneNode* CSceneManager::addAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, s32 id,
- const core::vector3df& position, const core::vector3df& rotation,
- const core::vector3df& scale, bool alsoAddIfMeshPointerZero)
-{
- if (!alsoAddIfMeshPointerZero && !mesh)
- return 0;
-
- if (!parent)
- parent = this;
-
- IAnimatedMeshSceneNode* node =
- new CAnimatedMeshSceneNode(mesh, parent, this, id, position, rotation, scale);
- node->drop();
-
- return node;
-}
-
-
-//! Adds a scene node for rendering using a octtree to the scene graph. This a good method for rendering
-//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much
-//! faster then a bsp tree.
-ISceneNode* CSceneManager::addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent,
- s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero)
-{
- if (!alsoAddIfMeshPointerZero && (!mesh || !mesh->getFrameCount()))
- return 0;
-
- return addOctTreeSceneNode(mesh ? mesh->getMesh(0) : 0,
- parent, id, minimalPolysPerNode,
- alsoAddIfMeshPointerZero);
-}
-
-
-
-//! Adss a scene node for rendering using a octtree. This a good method for rendering
-//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much
-//! faster then a bsp tree.
-ISceneNode* CSceneManager::addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent,
- s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero)
-{
- if (!alsoAddIfMeshPointerZero && !mesh)
- return 0;
-
- if (!parent)
- parent = this;
-
- COctTreeSceneNode* node = new COctTreeSceneNode(parent, this, id, minimalPolysPerNode);
-
- if (mesh)
- node->createTree(mesh);
-
- node->drop();
-
- return node;
-}
-
-
-//! Adds a camera scene node to the tree and sets it as active camera.
-//! \param position: Position of the space relative to its parent where the camera will be placed.
-//! \param lookat: Position where the camera will look at. Also known as target.
-//! \param parent: Parent scene node of the camera. Can be null. If the parent moves,
-//! the camera will move too.
-//! \return Returns pointer to interface to camera
-ICameraSceneNode* CSceneManager::addCameraSceneNode(ISceneNode* parent,
- const core::vector3df& position, const core::vector3df& lookat, s32 id)
-{
- if (!parent)
- parent = this;
-
- ICameraSceneNode* node = new CCameraSceneNode(parent, this, id, position, lookat);
- node->drop();
-
- setActiveCamera(node);
-
- return node;
-}
-
-
-
-//! Adds a camera scene node which is able to be controlle with the mouse similar
-//! like in the 3D Software Maya by Alias Wavefront.
-//! The returned pointer must not be dropped.
-ICameraSceneNode* CSceneManager::addCameraSceneNodeMaya(ISceneNode* parent,
- f32 rotateSpeed, f32 zoomSpeed, f32 translationSpeed, s32 id)
-{
- if (!parent)
- parent = this;
-
- ICameraSceneNode* node = new CCameraMayaSceneNode(parent, this, id, rotateSpeed,
- zoomSpeed, translationSpeed);
- node->drop();
-
- setActiveCamera(node);
-
- return node;
-}
-
-
-
-//! Adds a camera scene node which is able to be controled with the mouse and keys
-//! like in most first person shooters (FPS):
-ICameraSceneNode* CSceneManager::addCameraSceneNodeFPS(ISceneNode* parent,
- f32 rotateSpeed, f32 moveSpeed, s32 id,
- SKeyMap* keyMapArray, s32 keyMapSize, bool noVerticalMovement,f32 jumpSpeed)
-{
- if (!parent)
- parent = this;
-
- ICameraSceneNode* node = new CCameraFPSSceneNode(parent, this, CursorControl,
- id, rotateSpeed, moveSpeed, jumpSpeed, keyMapArray, keyMapSize, noVerticalMovement);
- node->drop();
-
- setActiveCamera(node);
-
- return node;
-}
-
-
-
-//! Adds a dynamic light scene node. The light will cast dynamic light on all
-//! other scene nodes in the scene, which have the material flag video::MTF_LIGHTING
-//! turned on. (This is the default setting in most scene nodes).
-ILightSceneNode* CSceneManager::addLightSceneNode(ISceneNode* parent,
- const core::vector3df& position, video::SColorf color, f32 range, s32 id)
-{
- if (!parent)
- parent = this;
-
- ILightSceneNode* node = new CLightSceneNode(parent, this, id, position, color, range);
- node->drop();
-
- return node;
-}
-
-
-
-//! Adds a billboard scene node to the scene. A billboard is like a 3d sprite: A 2d element,
-//! which always looks to the camera. It is usually used for things like explosions, fire,
-//! lensflares and things like that.
-IBillboardSceneNode* CSceneManager::addBillboardSceneNode(ISceneNode* parent,
- const core::dimension2d& size, const core::vector3df& position, s32 id,
- video::SColor shade_top, video::SColor shade_down
- )
-{
- if (!parent)
- parent = this;
-
- IBillboardSceneNode* node = new CBillboardSceneNode(parent, this, id, position, size,
- shade_top, shade_down);
- node->drop();
-
- return node;
-}
-
-
-
-//! Adds a skybox scene node. A skybox is a big cube with 6 textures on it and
-//! is drawn around the camera position.
-ISceneNode* CSceneManager::addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom,
- video::ITexture* left, video::ITexture* right, video::ITexture* front,
- video::ITexture* back, ISceneNode* parent, s32 id)
-{
- if (!parent)
- parent = this;
-
- ISceneNode* node = new CSkyBoxSceneNode(top, bottom, left, right,
- front, back, parent, this, id);
-
- node->drop();
- return node;
-}
-
-
-//! Adds a skydome scene node. A skydome is a large (half-) sphere with a
-//! panoramic texture on it and is drawn around the camera position.
-ISceneNode* CSceneManager::addSkyDomeSceneNode(video::ITexture* texture,
- u32 horiRes, u32 vertRes, f64 texturePercentage,
- f64 spherePercentage, ISceneNode* parent, s32 id)
-{
- if (!parent)
- parent = this;
-
- ISceneNode* node = new CSkyDomeSceneNode(texture, horiRes, vertRes,
- texturePercentage, spherePercentage, parent, this, id);
-
- node->drop();
- return node;
-}
-
-
-//! Adds a particle system scene node.
-IParticleSystemSceneNode* CSceneManager::addParticleSystemSceneNode(
- bool withDefaultEmitter, ISceneNode* parent, s32 id,
- const core::vector3df& position, const core::vector3df& rotation,
- const core::vector3df& scale)
-{
- if (!parent)
- parent = this;
-
- IParticleSystemSceneNode* node = new CParticleSystemSceneNode(withDefaultEmitter,
- parent, this, id, position, rotation, scale);
- node->drop();
-
- return node;
-}
-
-
-//! Adds a terrain scene node to the scene graph.
-ITerrainSceneNode* CSceneManager::addTerrainSceneNode(
- const char* heightMapFileName,
- ISceneNode* parent, s32 id,
- const core::vector3df& position,
- const core::vector3df& rotation,
- const core::vector3df& scale,
- video::SColor vertexColor,
- s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, s32 smoothFactor,
- bool addAlsoIfHeightmapEmpty)
-{
- io::IReadFile* file = FileSystem->createAndOpenFile(heightMapFileName);
-
- if(!file && !addAlsoIfHeightmapEmpty)
- {
- os::Printer::log("Could not load terrain, because file could not be opened.",
- heightMapFileName, ELL_ERROR);
- return 0;
- }
-
- ITerrainSceneNode* terrain = addTerrainSceneNode(file, parent, id,
- position, rotation, scale, vertexColor, maxLOD, patchSize,
- smoothFactor, addAlsoIfHeightmapEmpty);
-
- if (file)
- file->drop();
-
- return terrain;
-}
-
-//! Adds a terrain scene node to the scene graph.
-ITerrainSceneNode* CSceneManager::addTerrainSceneNode(
- io::IReadFile* heightMapFile,
- ISceneNode* parent, s32 id,
- const core::vector3df& position,
- const core::vector3df& rotation,
- const core::vector3df& scale,
- video::SColor vertexColor,
- s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize,
- s32 smoothFactor,
- bool addAlsoIfHeightmapEmpty)
-{
- if (!parent)
- parent = this;
-
- if (!heightMapFile && !addAlsoIfHeightmapEmpty)
- {
- os::Printer::log("Could not load terrain, because file could not be opened.", ELL_ERROR);
- return 0;
- }
-
- CTerrainSceneNode* node = new CTerrainSceneNode(parent, this, FileSystem, id,
- maxLOD, patchSize, position, rotation, scale);
-
- if (!node->loadHeightMap(heightMapFile, vertexColor, smoothFactor))
- {
- if (!addAlsoIfHeightmapEmpty)
- {
- node->remove();
- node->drop();
- return 0;
- }
- }
-
- node->drop();
- return node;
-}
-
-
-//! Adds an empty scene node.
-ISceneNode* CSceneManager::addEmptySceneNode(ISceneNode* parent, s32 id)
-{
- if (!parent)
- parent = this;
-
- ISceneNode* node = new CEmptySceneNode(parent, this, id);
- node->drop();
-
- return node;
-}
-
-
-//! Adds a dummy transformation scene node to the scene graph.
-IDummyTransformationSceneNode* CSceneManager::addDummyTransformationSceneNode(
- ISceneNode* parent, s32 id)
-{
- if (!parent)
- parent = this;
-
- IDummyTransformationSceneNode* node = new CDummyTransformationSceneNode(
- parent, this, id);
- node->drop();
-
- return node;
-}
-
-//! Adds a Hill Plane mesh to the mesh pool. The mesh is generated on the fly
-//! and looks like a plane with some hills on it. It is uses mostly for quick
-//! tests of the engine only. You can specify how many hills there should be
-//! on the plane and how high they should be. Also you must specify a name for
-//! the mesh, because the mesh is added to the mesh pool, and can be retrieved
-//! again using ISceneManager::getMesh with the name as parameter.
-IAnimatedMesh* CSceneManager::addHillPlaneMesh(const c8* name,
- const core::dimension2d& tileSize,
- const core::dimension2d& tileCount,
- video::SMaterial* material, f32 hillHeight,
- const core::dimension2d& countHills,
- const core::dimension2d& textureRepeatCount)
-{
- if (!name || MeshCache->isMeshLoaded(name))
- return 0;
-
- IMesh* mesh = CGeometryCreator::createHillPlaneMesh(tileSize,
- tileCount, material, hillHeight, countHills,
- textureRepeatCount);
- if (!mesh)
- return 0;
-
- SAnimatedMesh* animatedMesh = new SAnimatedMesh();
- if (!animatedMesh)
- return 0;
-
- animatedMesh->addMesh(mesh);
- animatedMesh->recalculateBoundingBox();
- mesh->drop();
-
- MeshCache->addMesh(name, animatedMesh);
- animatedMesh->drop();
-
- return animatedMesh;
-}
-
-
-//! Adds a terrain mesh to the mesh pool.
-IAnimatedMesh* CSceneManager::addTerrainMesh(const c8* name,
- video::IImage* texture, video::IImage* heightmap,
- const core::dimension2d& stretchSize,
- f32 maxHeight,
- const core::dimension2d& defaultVertexBlockSize)
-{
- if (!name || MeshCache->isMeshLoaded(name))
- return 0;
-
- IMesh* mesh = CGeometryCreator::createTerrainMesh(texture, heightmap,
- stretchSize, maxHeight, getVideoDriver(),
- defaultVertexBlockSize);
- if (!mesh)
- return 0;
-
- SAnimatedMesh* animatedMesh = new SAnimatedMesh();
- if (!animatedMesh)
- return 0;
-
- animatedMesh->addMesh(mesh);
- animatedMesh->recalculateBoundingBox();
- mesh->drop();
-
- MeshCache->addMesh(name, animatedMesh);
- animatedMesh->drop();
-
- return animatedMesh;
-}
-
-//! Adds an arrow mesh to the mesh pool.
-IAnimatedMesh* CSceneManager::addArrowMesh(const c8* name,
- video::SColor vtxColor0, video::SColor vtxColor1,
- u32 tesselationCylinder, u32 tesselationCone, f32 height,
- f32 cylinderHeight, f32 width0,f32 width1)
-{
- if (!name || MeshCache->isMeshLoaded(name))
- return 0;
-
- IMesh* mesh = CGeometryCreator::createArrowMesh( tesselationCylinder,
- tesselationCone, height, cylinderHeight, width0,width1,
- vtxColor0, vtxColor1);
- if (!mesh)
- return 0;
-
- SAnimatedMesh* animatedMesh = new SAnimatedMesh();
- if (!animatedMesh)
- return 0;
-
- animatedMesh->addMesh(mesh);
- animatedMesh->recalculateBoundingBox();
- mesh->drop();
-
- MeshCache->addMesh(name, animatedMesh);
- animatedMesh->drop();
-
- return animatedMesh;
-}
-
-
-
-//! Adds a static sphere mesh to the mesh pool.
-IAnimatedMesh* CSceneManager::addSphereMesh(const c8* name,
- f32 radius, u32 polyCountX, u32 polyCountY)
-{
- if (!name || MeshCache->isMeshLoaded(name))
- return 0;
-
- IMesh* mesh = CGeometryCreator::createSphereMesh( radius, polyCountX, polyCountY);
- if (!mesh)
- return 0;
-
- SAnimatedMesh* animatedMesh = new SAnimatedMesh();
- if (!animatedMesh)
- return 0;
-
- animatedMesh->addMesh(mesh);
- animatedMesh->recalculateBoundingBox();
- mesh->drop();
-
- MeshCache->addMesh(name, animatedMesh);
- animatedMesh->drop();
-
- return animatedMesh;
-}
-
-
-
-//! Returns the root scene node. This is the scene node wich is parent
-//! of all scene nodes. The root scene node is a special scene node which
-//! only exists to manage all scene nodes. It is not rendered and cannot
-//! be removed from the scene.
-//! \return Returns a pointer to the root scene node.
-ISceneNode* CSceneManager::getRootSceneNode()
-{
- return this;
-}
-
-
-
-//! Returns the current active camera.
-//! \return The active camera is returned. Note that this can be NULL, if there
-//! was no camera created yet.
-ICameraSceneNode* CSceneManager::getActiveCamera()
-{
- return ActiveCamera;
-}
-
-
-
-//! Sets the active camera. The previous active camera will be deactivated.
-//! \param camera: The new camera which should be active.
-void CSceneManager::setActiveCamera(ICameraSceneNode* camera)
-{
- if (ActiveCamera)
- ActiveCamera->drop();
-
- ActiveCamera = camera;
-
- if (ActiveCamera)
- ActiveCamera->grab();
-}
-
-
-
-
-//! renders the node.
-void CSceneManager::render()
-{
-}
-
-
-//! returns the axis aligned bounding box of this node
-const core::aabbox3d& CSceneManager::getBoundingBox() const
-{
- _IRR_DEBUG_BREAK_IF(true) // Bounding Box of Scene Manager wanted.
-
- // should never be used.
- return *((core::aabbox3d*)0);
-}
-
-
-
-//! returns if node is culled
-bool CSceneManager::isCulled(const ISceneNode* node)
-{
- const ICameraSceneNode* cam = getActiveCamera();
- if (!cam)
- return false;
-
- switch ( node->getAutomaticCulling() )
- {
- // can be seen by a bounding box ?
- case scene::EAC_BOX:
- {
- core::aabbox3d tbox = node->getBoundingBox();
- node->getAbsoluteTransformation().transformBox(tbox);
- return !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox() ));
- }
-
- // can be seen by a bounding sphere
- case scene::EAC_FRUSTUM_SPHERE:
- { // requires bbox diameter
- }
- break;
-
- // can be seen by cam pyramid planes ?
- case scene::EAC_FRUSTUM_BOX:
- {
- SViewFrustum frust = *cam->getViewFrustum();
-
- //transform the frustum to the node's current absolute transformation
- core::matrix4 invTrans(node->getAbsoluteTransformation());
- invTrans.makeInverse();
- frust.transform(invTrans);
-
- core::vector3df edges[8];
- node->getBoundingBox().getEdges(edges);
-
- for (s32 i=0; igetMaterialCount();
-
- taken = 0;
- for (u32 i=0; igetMaterialRenderer(node->getMaterial(i).MaterialType);
- if (rnd && rnd->isTransparent())
- {
- // register as transparent node
- TransparentNodeEntry e(node, camWorldPos);
- TransparentNodeList.push_back(e);
- taken = 1;
- break;
- }
- }
-
- // not transparent, register as solid
- if ( 0 == taken )
- {
- SolidNodeList.push_back( node );
- taken = 1;
- }
- }
- break;
- case ESNRP_SHADOW:
- if (!isCulled(node))
- {
- ShadowNodeList.push_back(node);
- taken = 1;
- }
- break;
-
- case ESNRP_COUNT: // ignore this one
- break;
- }
-
-#ifdef SCENEMANAGER_DEBUG
- s32 index = Parameters.findAttribute ( "calls" );
- Parameters.setAttribute ( index, Parameters.getAttributeAsInt ( index ) + 1 );
-
- if ( 0 == taken )
- {
- index = Parameters.findAttribute ( "culled" );
- Parameters.setAttribute ( index, Parameters.getAttributeAsInt ( index ) + 1 );
- }
-#endif
-
- return taken;
-}
-
-//! This method is called just before the rendering process of the whole scene.
-//! draws all scene nodes
-void CSceneManager::drawAll()
-{
- if (!Driver)
- return;
-
- // reset attributes
- Parameters.setAttribute ( "culled", 0 );
- Parameters.setAttribute ( "calls", 0 );
- Parameters.setAttribute ( "drawn", 0 );
-
- // reset all transforms
- video::IVideoDriver* driver = getVideoDriver();
- if ( driver )
- {
- driver->setTransform ( video::ETS_PROJECTION, core::IdentityMatrix );
- driver->setTransform ( video::ETS_VIEW, core::IdentityMatrix );
- driver->setTransform ( video::ETS_WORLD, core::IdentityMatrix );
- driver->setTransform ( video::ETS_TEXTURE_0, core::IdentityMatrix );
- driver->setTransform ( video::ETS_TEXTURE_1, core::IdentityMatrix );
- driver->setTransform ( video::ETS_TEXTURE_2, core::IdentityMatrix );
- driver->setTransform ( video::ETS_TEXTURE_3, core::IdentityMatrix );
- }
-
- // do animations and other stuff.
- OnAnimate(os::Timer::getTime());
-
- /*!
- First Scene Node for prerendering should be the active camera
- consistent Camera is needed for culling
- */
- camWorldPos.set(0,0,0);
- if ( ActiveCamera )
- {
- ActiveCamera->OnRegisterSceneNode();
- camWorldPos = ActiveCamera->getAbsolutePosition();
- }
-
- // let all nodes register themselves
- OnRegisterSceneNode();
-
- u32 i; // new ISO for scoping problem in some compilers
-
- //render camera scenes
- {
- CurrentRendertime = ESNRP_CAMERA;
- for (i=0; irender();
-
- CameraList.set_used(0);
- }
-
- //render lights scenes
- {
- CurrentRendertime = ESNRP_LIGHT;
-
- Driver->deleteAllDynamicLights();
-
- Driver->setAmbientLight(AmbientLight);
-
- LightList.sort (); // on distance to camera
-
- u32 maxLights = core::min_ ( Driver->getMaximalDynamicLightAmount (), LightList.size () );
- for (i=0; i< maxLights; ++i)
- LightList[i].node->render();
-
- LightList.set_used(0);
- }
-
- // render skyboxes
- {
- CurrentRendertime = ESNRP_SKY_BOX;
-
- for (i=0; irender();
-
- SkyBoxList.set_used(0);
- }
-
-
- // render default objects
- {
- CurrentRendertime = ESNRP_SOLID;
- SolidNodeList.sort(); // sort by textures
-
- for (i=0; irender();
-
- Parameters.setAttribute ( "drawn", (s32) SolidNodeList.size () );
-
- SolidNodeList.set_used(0);
- }
-
- // render shadows
- {
- CurrentRendertime = ESNRP_SHADOW;
- for (i=0; irender();
-
- if (!ShadowNodeList.empty())
- Driver->drawStencilShadow(true,ShadowColor, ShadowColor,
- ShadowColor, ShadowColor);
-
- ShadowNodeList.set_used(0);
- }
-
- // render transparent objects.
- {
- CurrentRendertime = ESNRP_TRANSPARENT;
- TransparentNodeList.sort(); // sort by distance from camera
-
- for (i=0; irender();
-
- TransparentNodeList.set_used(0);
- }
-
-
- clearDeletionList();
-
- CurrentRendertime = ESNRP_COUNT;
-}
-
-
-//! Sets the color of stencil buffers shadows drawn by the scene manager.
-void CSceneManager::setShadowColor(video::SColor color)
-{
- ShadowColor = color;
-}
-
-
-//! Returns the current color of shadows.
-video::SColor CSceneManager::getShadowColor() const
-{
- return ShadowColor;
-}
-
-
-
-//! creates a rotation animator, which rotates the attached scene node around itself.
-ISceneNodeAnimator* CSceneManager::createRotationAnimator(const core::vector3df& rotationPerSecond)
-{
- ISceneNodeAnimator* anim = new CSceneNodeAnimatorRotation(os::Timer::getTime(),
- rotationPerSecond);
-
- return anim;
-}
-
-
-
-//! creates a fly circle animator, which lets the attached scene node fly around a center.
-ISceneNodeAnimator* CSceneManager::createFlyCircleAnimator(
- const core::vector3df& normal, f32 radius, f32 speed,
- const core::vector3df& direction)
-{
- ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyCircle(os::Timer::getTime(), normal,
- radius, speed, direction);
- return anim;
-}
-
-
-//! Creates a fly straight animator, which lets the attached scene node
-//! fly or move along a line between two points.
-ISceneNodeAnimator* CSceneManager::createFlyStraightAnimator(const core::vector3df& startPoint,
- const core::vector3df& endPoint, u32 timeForWay, bool loop)
-{
- ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyStraight(startPoint,
- endPoint, timeForWay, loop, os::Timer::getTime());
-
- return anim;
-}
-
-
-//! Creates a texture animator, which switches the textures of the target scene
-//! node based on a list of textures.
-ISceneNodeAnimator* CSceneManager::createTextureAnimator(const core::array& textures,
- s32 timePerFrame, bool loop)
-{
- ISceneNodeAnimator* anim = new CSceneNodeAnimatorTexture(textures,
- timePerFrame, loop, os::Timer::getTime());
-
- return anim;
-}
-
-
-//! Creates a scene node animator, which deletes the scene node after
-//! some time automaticly.
-ISceneNodeAnimator* CSceneManager::createDeleteAnimator(u32 when)
-{
- return new CSceneNodeAnimatorDelete(this, os::Timer::getTime() + when);
-}
-
-
-
-
-//! Creates a special scene node animator for doing automatic collision detection
-//! and response.
-ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnimator(
- ITriangleSelector* world, ISceneNode* sceneNode, const core::vector3df& ellipsoidRadius,
- const core::vector3df& gravityPerSecond,
- const core::vector3df& ellipsoidTranslation, f32 slidingValue)
-{
- ISceneNodeAnimatorCollisionResponse* anim = new
- CSceneNodeAnimatorCollisionResponse(this, world, sceneNode,
- ellipsoidRadius, gravityPerSecond,
- ellipsoidTranslation, slidingValue);
-
- return anim;
-}
-
-
-//! Creates a follow spline animator.
-ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime,
- const core::array< core::vector3df >& points,
- f32 speed, f32 tightness)
-{
- ISceneNodeAnimator* a = new CSceneNodeAnimatorFollowSpline(startTime, points,
- speed, tightness);
- return a;
-}
-
-
-
-//! Adds an external mesh loader.
-void CSceneManager::addExternalMeshLoader(IMeshLoader* externalLoader)
-{
- if (!externalLoader)
- return;
-
- externalLoader->grab();
- MeshLoaderList.push_back(externalLoader);
-}
-
-
-
-//! Returns a pointer to the scene collision manager.
-ISceneCollisionManager* CSceneManager::getSceneCollisionManager()
-{
- return CollisionManager;
-}
-
-
-//! Returns a pointer to the mesh manipulator.
-IMeshManipulator* CSceneManager::getMeshManipulator()
-{
- return MeshManipulator;
-}
-
-
-//! Creates a simple ITriangleSelector, based on a mesh.
-ITriangleSelector* CSceneManager::createTriangleSelector(IMesh* mesh, ISceneNode* node)
-{
- if (!mesh || !node)
- return 0;
-
- return new CTriangleSelector(mesh, node);
-}
-
-
-//! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.
-ITriangleSelector* CSceneManager::createTriangleSelectorFromBoundingBox(ISceneNode* node)
-{
- if (!node)
- return 0;
-
- return new CTriangleBBSelector(node);
-}
-
-
-//! Creates a simple ITriangleSelector, based on a mesh.
-ITriangleSelector* CSceneManager::createOctTreeTriangleSelector(IMesh* mesh,
- ISceneNode* node,
- s32 minimalPolysPerNode)
-{
- if (!mesh || !node)
- return 0;
-
- return new COctTreeTriangleSelector(mesh, node, minimalPolysPerNode);
-}
-
-
-
-//! Creates a meta triangle selector.
-IMetaTriangleSelector* CSceneManager::createMetaTriangleSelector()
-{
- return new CMetaTriangleSelector();
-}
-
-
-
-//! Creates a triangle selector which can select triangles from a terrain scene node
-ITriangleSelector* CSceneManager::createTerrainTriangleSelector(
- ITerrainSceneNode* node, s32 LOD)
-{
- return new CTerrainTriangleSelector(node, LOD);
-}
-
-
-
-//! Adds a scene node to the deletion queue.
-void CSceneManager::addToDeletionQueue(ISceneNode* node)
-{
- if (!node)
- return;
-
- node->grab();
- DeletionList.push_back(node);
-}
-
-
-//! clears the deletion list
-void CSceneManager::clearDeletionList()
-{
- if (DeletionList.empty())
- return;
-
- for (s32 i=0; i<(s32)DeletionList.size(); ++i)
- {
- DeletionList[i]->remove();
- DeletionList[i]->drop();
- }
-
- DeletionList.clear();
-}
-
-
-//! Returns the first scene node with the specified name.
-ISceneNode* CSceneManager::getSceneNodeFromName(const char* name, ISceneNode* start)
-{
- if (start == 0)
- start = getRootSceneNode();
-
- if (!strcmp(start->getName(),name))
- return start;
-
- ISceneNode* node = 0;
-
- const core::list& list = start->getChildren();
- core::list::ConstIterator it = list.begin();
- for (; it!=list.end(); ++it)
- {
- node = getSceneNodeFromName(name, *it);
- if (node)
- return node;
- }
-
- return 0;
-}
-
-
-//! Returns the first scene node with the specified id.
-ISceneNode* CSceneManager::getSceneNodeFromId(s32 id, ISceneNode* start)
-{
- if (start == 0)
- start = getRootSceneNode();
-
- if (start->getID() == id)
- return start;
-
- ISceneNode* node = 0;
-
- const core::list& list = start->getChildren();
- core::list::ConstIterator it = list.begin();
- for (; it!=list.end(); ++it)
- {
- node = getSceneNodeFromId(id, *it);
- if (node)
- return node;
- }
-
- return 0;
-}
-
-
-//! Returns the first scene node with the specified type.
-ISceneNode* CSceneManager::getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start)
-{
- if (start == 0)
- start = getRootSceneNode();
-
- if (start->getType() == type)
- return start;
-
- ISceneNode* node = 0;
-
- const core::list& list = start->getChildren();
- core::list::ConstIterator it = list.begin();
- for (; it!=list.end(); ++it)
- {
- node = getSceneNodeFromType(type, *it);
- if (node)
- return node;
- }
-
- return 0;
-}
-
-//! returns scene nodes by type.
-void CSceneManager::getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array& outNodes, ISceneNode* start)
-{
- if (start == 0)
- start = getRootSceneNode();
-
- if (start->getType() == type)
- outNodes.push_back(start);
-
- const core::list& list = start->getChildren();
- core::list::ConstIterator it = list.begin();
-
- for (; it!=list.end(); ++it)
- {
- getSceneNodesFromType(type, outNodes, *it);
- }
-}
-
-
-//! Posts an input event to the environment. Usually you do not have to
-//! use this method, it is used by the internal engine.
-bool CSceneManager::postEventFromUser(const SEvent& event)
-{
- bool ret = false;
- ICameraSceneNode* cam = getActiveCamera();
- if (cam)
- ret = cam->OnEvent(event);
-
- _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
- return ret;
-}
-
-
-//! Removes all children of this scene node
-void CSceneManager::removeAll()
-{
- ISceneNode::removeAll();
- setActiveCamera(0);
-}
-
-
-//! Clears the whole scene. All scene nodes are removed.
-void CSceneManager::clear()
-{
- removeAll();
-}
-
-
-//! Returns interface to the parameters set in this scene.
-io::IAttributes* CSceneManager::getParameters()
-{
- return &Parameters;
-}
-
-
-//! Returns current render pass.
-E_SCENE_NODE_RENDER_PASS CSceneManager::getSceneNodeRenderPass() const
-{
- return CurrentRendertime;
-}
-
-
-
-//! Returns an interface to the mesh cache which is shared beween all existing scene managers.
-IMeshCache* CSceneManager::getMeshCache()
-{
- return MeshCache;
-}
-
-
-//! Creates a new scene manager.
-ISceneManager* CSceneManager::createNewSceneManager(bool cloneContent)
-{
- CSceneManager* manager = new CSceneManager(Driver, FileSystem, CursorControl, MeshCache);
-
- if (cloneContent)
- manager->cloneMembers(this, manager);
-
- return manager;
-}
-
-
-//! Returns the default scene node factory which can create all built in scene nodes
-ISceneNodeFactory* CSceneManager::getDefaultSceneNodeFactory()
-{
- return getSceneNodeFactory(0);
-}
-
-
-//! Adds a scene node factory to the scene manager.
-void CSceneManager::registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd)
-{
- if (factoryToAdd)
- {
- factoryToAdd->grab();
- SceneNodeFactoryList.push_back(factoryToAdd);
- }
-}
-
-
-//! Returns amount of registered scene node factories.
-u32 CSceneManager::getRegisteredSceneNodeFactoryCount() const
-{
- return SceneNodeFactoryList.size();
-}
-
-
-//! Returns a scene node factory by index
-ISceneNodeFactory* CSceneManager::getSceneNodeFactory(u32 index)
-{
- if (indexgrab();
- SceneNodeAnimatorFactoryList.push_back(factoryToAdd);
- }
-}
-
-
-//! Returns amount of registered scene node animator factories.
-u32 CSceneManager::getRegisteredSceneNodeAnimatorFactoryCount() const
-{
- return SceneNodeAnimatorFactoryList.size();
-}
-
-
-//! Returns a scene node animator factory by index
-ISceneNodeAnimatorFactory* CSceneManager::getSceneNodeAnimatorFactory(u32 index)
-{
- if (indexcreateAndWriteFile(filename);
- if (!file)
- return false;
-
- bool ret = saveScene(file, userDataSerializer);
- file->drop();
- return ret;
-}
-
-
-//! Saves the current scene into a file.
-bool CSceneManager::saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer)
-{
- if (!file)
- return false;
-
- io::IXMLWriter* writer = FileSystem->createXMLWriter(file);
- if (!writer)
- return false;
-
- writer->writeXMLHeader();
- writeSceneNode(writer, this, userDataSerializer);
- writer->drop();
-
- return true;
-}
-
-
-//! Loads a scene. Note that the current scene is not cleared before.
-//! \param filename: Name of the file .
-bool CSceneManager::loadScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer)
-{
- io::IReadFile* read = FileSystem->createAndOpenFile(filename);
- if (!read)
- {
- os::Printer::log("Unable to open scene file", filename, ELL_ERROR);
- return false;
- }
-
- bool ret = loadScene(read, userDataSerializer);
- read->drop();
-
- return ret;
-}
-
-
-//! Loads a scene. Note that the current scene is not cleared before.
-bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer)
-{
- if (!file)
- {
- os::Printer::log("Unable to open scene file", ELL_ERROR);
- return false;
- }
-
- io::IXMLReader* reader = FileSystem->createXMLReader(file);
- if (!reader)
- {
- os::Printer::log("Scene is not a valid XML file", file->getFileName(), ELL_ERROR);
- return false;
- }
-
- // for mesh loading, set collada loading attributes
-
- bool oldColladaSingleMesh = getParameters()->getAttributeAsBool(COLLADA_CREATE_SCENE_INSTANCES);
- getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, false);
-
- // read file
-
- while(reader->read())
- {
- readSceneNode(reader, 0, userDataSerializer);
- }
-
- // restore old collada parameters
-
- getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, oldColladaSingleMesh);
-
- // finish up
-
- reader->drop();
- return true;
-
-}
-
-
-//! reads a scene node
-void CSceneManager::readSceneNode(io::IXMLReader* reader, ISceneNode* parent, ISceneUserDataSerializer* userDataSerializer)
-{
- if (!reader)
- return;
-
- scene::ISceneNode* node = 0;
-
- if ((!parent && IRR_XML_FORMAT_SCENE==reader->getNodeName()) ||
- ( parent && IRR_XML_FORMAT_NODE==reader->getNodeName()))
- {
- if (parent)
- {
- // find node type and create it
- core::stringc attrName = reader->getAttributeValue(IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str());
-
- for (int i=(int)SceneNodeFactoryList.size()-1; i>=0 && !node; --i)
- node = SceneNodeFactoryList[i]->addSceneNode(attrName.c_str(), parent);
-
- if (!node)
- os::Printer::log("Could not create scene node of unknown type", attrName.c_str());
- }
- else
- node = this; // root
- }
-
- // read attributes
- while(reader->read())
- {
- bool endreached = false;
-
- switch (reader->getNodeType())
- {
- case io::EXN_ELEMENT_END:
- if ((IRR_XML_FORMAT_NODE==reader->getNodeName()) ||
- (IRR_XML_FORMAT_SCENE==reader->getNodeName()))
- {
- endreached = true;
- }
- break;
- case io::EXN_ELEMENT:
- if (core::stringw(L"attributes")==reader->getNodeName())
- {
- // read attributes
- io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
- attr->read(reader, true);
-
- if (node)
- node->deserializeAttributes(attr);
-
- attr->drop();
- }
- else
- if (core::stringw(L"materials")==reader->getNodeName())
- readMaterials(reader, node);
- else
- if (core::stringw(L"animators")==reader->getNodeName())
- readAnimators(reader, node);
- else
- if (core::stringw(L"userData")==reader->getNodeName())
- readUserData(reader, node, userDataSerializer);
- else
- if ((IRR_XML_FORMAT_NODE==reader->getNodeName()) ||
- (IRR_XML_FORMAT_SCENE==reader->getNodeName()))
- {
- readSceneNode(reader, node, userDataSerializer);
- }
- else
- {
- os::Printer::log("Found unknown element in irrlicht scene file",
- core::stringc(reader->getNodeName()).c_str());
- }
- break;
- default:
- break;
- }
-
- if (endreached)
- break;
- }
-}
-
-
-//! reads materials of a node
-void CSceneManager::readMaterials(io::IXMLReader* reader, ISceneNode* node)
-{
- u32 nr = 0;
-
- while(reader->read())
- {
- const wchar_t* name = reader->getNodeName();
-
- switch(reader->getNodeType())
- {
- case io::EXN_ELEMENT_END:
- if (core::stringw(L"materials")==name)
- return;
- break;
- case io::EXN_ELEMENT:
- if (core::stringw(L"attributes")==name)
- {
- // read materials from attribute list
- io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
- attr->read(reader);
-
- if (node && node->getMaterialCount() > nr)
- {
- getVideoDriver()->fillMaterialStructureFromAttributes(
- node->getMaterial(nr), attr);
- }
-
- attr->drop();
- ++nr;
- }
- break;
- default:
- break;
- }
- }
-}
-
-
-//! reads animators of a node
-void CSceneManager::readAnimators(io::IXMLReader* reader, ISceneNode* node)
-{
- while(reader->read())
- {
- const wchar_t* name = reader->getNodeName();
-
- switch(reader->getNodeType())
- {
- case io::EXN_ELEMENT_END:
- if (core::stringw(L"animators")==name)
- return;
- break;
- case io::EXN_ELEMENT:
- if (core::stringw(L"attributes")==name)
- {
- // read animator data from attribute list
- io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
- attr->read(reader);
-
- if (node)
- {
- core::stringc typeName = attr->getAttributeAsString("Type");
- ISceneNodeAnimator* anim = 0;
-
- for (int i=0; i<(int)SceneNodeAnimatorFactoryList.size() && !anim; ++i)
- anim = SceneNodeAnimatorFactoryList[i]->createSceneNodeAnimator(typeName.c_str(), node);
-
- if (anim)
- {
- anim->deserializeAttributes(attr);
- anim->drop();
- }
- }
-
- attr->drop();
- }
- break;
- default:
- break;
- }
- }
-}
-
-
-//! reads user data of a node
-void CSceneManager::readUserData(io::IXMLReader* reader, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer)
-{
- while(reader->read())
- {
- const wchar_t* name = reader->getNodeName();
-
- switch(reader->getNodeType())
- {
- case io::EXN_ELEMENT_END:
- if (core::stringw(L"userData")==name)
- return;
- break;
- case io::EXN_ELEMENT:
- if (core::stringw(L"attributes")==name)
- {
- // read user data from attribute list
- io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
- attr->read(reader);
-
- if (node && userDataSerializer)
- {
- userDataSerializer->OnReadUserData(node, attr);
- }
-
- attr->drop();
- }
- break;
- default:
- break;
- }
- }
-}
-
-
-//! writes a scene node
-void CSceneManager::writeSceneNode(io::IXMLWriter* writer, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer)
-{
- if (!writer || !node || node->isDebugObject())
- return;
-
- const wchar_t* name;
-
- if (node == this)
- {
- name = IRR_XML_FORMAT_SCENE.c_str();
- writer->writeElement(name, false);
- }
- else
- {
- name = IRR_XML_FORMAT_NODE.c_str();
- writer->writeElement(name, false, IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str(),
- core::stringw(getSceneNodeTypeName(node->getType())).c_str());
- }
-
- writer->writeLineBreak();
- writer->writeLineBreak();
-
- // write properties
-
- io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
- node->serializeAttributes(attr);
-
- if (attr->getAttributeCount() != 0)
- {
- attr->write(writer);
- writer->writeLineBreak();
- }
-
- // write materials
-
- if (node->getMaterialCount() && getVideoDriver())
- {
- const wchar_t* materialElement = L"materials";
-
- writer->writeElement(materialElement);
- writer->writeLineBreak();
-
- for (u32 i=0; i < node->getMaterialCount(); ++i)
- {
- io::IAttributes* tmp_attr =
- getVideoDriver()->createAttributesFromMaterial(node->getMaterial(i));
- tmp_attr->write(writer);
- tmp_attr->drop();
- }
-
- writer->writeClosingTag(materialElement);
- writer->writeLineBreak();
- }
-
- // write animators
-
- if (!node->getAnimators().empty())
- {
- const wchar_t* animatorElement = L"animators";
- writer->writeElement(animatorElement);
- writer->writeLineBreak();
-
- core::list::ConstIterator it = node->getAnimators().begin();
- for (; it != node->getAnimators().end(); ++it)
- {
- attr->clear();
- attr->addString("Type", getAnimatorTypeName((*it)->getType()));
-
- (*it)->serializeAttributes(attr);
-
- attr->write(writer);
- }
-
- writer->writeClosingTag(animatorElement);
- writer->writeLineBreak();
- }
-
- // write possible user data
-
- if ( userDataSerializer )
- {
- io::IAttributes* userData = userDataSerializer->createUserData(node);
- if (userData)
- {
- const wchar_t* userDataElement = L"userData";
-
- writer->writeLineBreak();
- writer->writeElement(userDataElement);
- writer->writeLineBreak();
-
- userData->write(writer);
-
- writer->writeClosingTag(userDataElement);
- writer->writeLineBreak();
- writer->writeLineBreak();
-
- userData->drop();
- }
- }
-
- // write children
-
- core::list::ConstIterator it = node->getChildren().begin();
- for (; it != node->getChildren().end(); ++it)
- writeSceneNode(writer, (*it), userDataSerializer);
-
- attr->drop();
-
- writer->writeClosingTag(name);
- writer->writeLineBreak();
- writer->writeLineBreak();
-}
-
-
-//! Returns a typename from a scene node type or null if not found
-const c8* CSceneManager::getSceneNodeTypeName(ESCENE_NODE_TYPE type)
-{
- const char* name = 0;
-
- for (int i=(int)SceneNodeFactoryList.size()-1; !name && i>=0; --i)
- name = SceneNodeFactoryList[i]->getCreateableSceneNodeTypeName(type);
-
- return name;
-}
-
-//! Adds a scene node to the scene by name
-ISceneNode* CSceneManager::addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent)
-{
- ISceneNode* node = 0;
-
- for (int i=(int)SceneNodeFactoryList.size()-1; i>=0 && !node; --i)
- node = SceneNodeFactoryList[i]->addSceneNode(sceneNodeTypeName, parent);
-
- return node;
-}
-
-
-//! Returns a typename from a scene node animator type or null if not found
-const c8* CSceneManager::getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) const
-{
- const char* name = 0;
-
- for (u32 i=0; !name && igetCreateableSceneNodeAnimatorTypeName(type);
-
- return name;
-}
-
-
-//! Writes attributes of the scene node.
-void CSceneManager::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
-{
- out->addString ("Name", Name.c_str());
- out->addInt ("Id", ID );
- out->addColorf ("AmbientLight", AmbientLight);
-}
-
-//! Reads attributes of the scene node.
-void CSceneManager::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
-{
- Name = in->getAttributeAsString("Name");
- ID = in->getAttributeAsInt("Id");
- AmbientLight = in->getAttributeAsColorf("AmbientLight");
-
- RelativeTranslation.set(0,0,0);
- RelativeRotation.set(0,0,0);
- RelativeScale.set(1,1,1);
- IsVisible = true;
- AutomaticCullingState = scene::EAC_BOX;
- DebugDataVisible = scene::EDS_OFF;
- IsDebugObject = false;
-
- updateAbsolutePosition();
-}
-
-
-//! Sets ambient color of the scene
-void CSceneManager::setAmbientLight(const video::SColorf &ambientColor)
-{
- AmbientLight = ambientColor;
-}
-
-
-//! Returns ambient color of the scene
-const video::SColorf& CSceneManager::getAmbientLight() const
-{
- return AmbientLight;
-}
-
-
-//! Returns a mesh writer implementation if available
-IMeshWriter* CSceneManager::createMeshWriter(EMESH_WRITER_TYPE type)
-{
- switch(type)
- {
- case EMWT_IRR_MESH:
-#ifdef _IRR_COMPILE_WITH_IRR_WRITER_
- return new CIrrMeshWriter(Driver, FileSystem);
-#else
- return 0;
-#endif
- case EMWT_COLLADA:
-#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_
- return new CColladaMeshWriter(Driver, FileSystem);
-#else
- return 0;
-#endif
- case EMWT_STL:
-#ifdef _IRR_COMPILE_WITH_STL_WRITER_
- return new CSTLMeshWriter(this);
-#else
- return 0;
-#endif
- }
-
- return 0;
-}
-
-
-// creates a scenemanager
-ISceneManager* createSceneManager(video::IVideoDriver* driver,
- io::IFileSystem* fs, gui::ICursorControl* cursorcontrol,
- gui::IGUIEnvironment *guiEnvironment)
-{
- return new CSceneManager(driver, fs, cursorcontrol, 0, guiEnvironment );
-}
-
-
-} // end namespace scene
-} // end namespace irr
-
+// 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
+
+#include "IrrCompileConfig.h"
+#include "CSceneManager.h"
+#include "IVideoDriver.h"
+#include "IFileSystem.h"
+#include "SAnimatedMesh.h"
+#include "CMeshCache.h"
+#include "IWriteFile.h"
+#include "IXMLWriter.h"
+#include "ISceneUserDataSerializer.h"
+#include "IGUIEnvironment.h"
+#include "IMaterialRenderer.h"
+
+#include "os.h"
+
+#include "CGeometryCreator.h"
+
+#ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_
+#include "CIrrMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_BSP_LOADER_
+#include "CBSPMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_MD2_LOADER_
+#include "CMD2MeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
+#include "CMS3DMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
+#include "C3DSMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_X_LOADER_
+#include "CXMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
+#include "COCTLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_CSM_LOADER_
+#include "CCSMLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
+#include "CLMTSMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
+#include "CMY3DMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
+#include "CColladaFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_DMF_LOADER_
+#include "CDMFLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
+#include "COgreMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
+#include "COBJMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_MD3_LOADER_
+#include "CMD3MeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
+#include "CB3DMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_STL_LOADER_
+#include "CSTLMeshFileLoader.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_
+#include "CColladaMeshWriter.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_IRR_WRITER_
+#include "CIrrMeshWriter.h"
+#endif
+
+#ifdef _IRR_COMPILE_WITH_STL_WRITER_
+#include "CSTLMeshWriter.h"
+#endif
+
+#include "CCubeSceneNode.h"
+#include "CSphereSceneNode.h"
+#include "CAnimatedMeshSceneNode.h"
+#include "COctTreeSceneNode.h"
+#include "CCameraSceneNode.h"
+#include "CCameraMayaSceneNode.h"
+#include "CCameraFPSSceneNode.h"
+#include "CLightSceneNode.h"
+#include "CBillboardSceneNode.h"
+#include "CMeshSceneNode.h"
+#include "CSkyBoxSceneNode.h"
+#include "CSkyDomeSceneNode.h"
+#include "CParticleSystemSceneNode.h"
+#include "CDummyTransformationSceneNode.h"
+#include "CWaterSurfaceSceneNode.h"
+#include "CTerrainSceneNode.h"
+#include "CEmptySceneNode.h"
+#include "CTextSceneNode.h"
+#include "CDefaultSceneNodeFactory.h"
+
+#include "CSceneCollisionManager.h"
+#include "CMeshManipulator.h"
+#include "CTriangleSelector.h"
+#include "COctTreeTriangleSelector.h"
+#include "CTriangleBBSelector.h"
+#include "CMetaTriangleSelector.h"
+#include "CTerrainTriangleSelector.h"
+
+#include "CSceneNodeAnimatorRotation.h"
+#include "CSceneNodeAnimatorFlyCircle.h"
+#include "CSceneNodeAnimatorFlyStraight.h"
+#include "CSceneNodeAnimatorTexture.h"
+#include "CSceneNodeAnimatorCollisionResponse.h"
+#include "CSceneNodeAnimatorDelete.h"
+#include "CSceneNodeAnimatorFollowSpline.h"
+#include "CDefaultSceneNodeAnimatorFactory.h"
+
+#include "CQuake3ShaderSceneNode.h"
+#include "CVolumeLightSceneNode.h"
+
+//! Enable debug features
+#define SCENEMANAGER_DEBUG
+
+namespace irr
+{
+namespace scene
+{
+
+//! 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")
+{
+ #ifdef _DEBUG
+ ISceneManager::setDebugName("CSceneManager ISceneManager");
+ ISceneNode::setDebugName("CSceneManager ISceneNode");
+ #endif
+
+ if (Driver)
+ Driver->grab();
+
+ if (FileSystem)
+ FileSystem->grab();
+
+ if (CursorControl)
+ CursorControl->grab();
+
+ if ( GUIEnvironment )
+ GUIEnvironment->grab();
+
+ // create mesh cache if not there already
+ if (!MeshCache)
+ MeshCache = new CMeshCache();
+ else
+ MeshCache->grab();
+
+ // create collision manager
+ CollisionManager = new CSceneCollisionManager(this, Driver);
+
+ // create manipulator
+ MeshManipulator = new CMeshManipulator();
+
+ // add file format loaders
+
+ #ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_
+ MeshLoaderList.push_back(new CIrrMeshFileLoader(Driver, this, FileSystem));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_BSP_LOADER_
+ MeshLoaderList.push_back(new CBSPMeshFileLoader(FileSystem, Driver, this));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_MD2_LOADER_
+ MeshLoaderList.push_back(new CMD2MeshFileLoader());
+ #endif
+ #ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
+ MeshLoaderList.push_back(new CMS3DMeshFileLoader(Driver));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_3DS_LOADER_
+ MeshLoaderList.push_back(new C3DSMeshFileLoader(MeshManipulator,FileSystem, Driver));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_X_LOADER_
+ MeshLoaderList.push_back(new CXMeshFileLoader(this));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_OCT_LOADER_
+ MeshLoaderList.push_back(new COCTLoader(Driver));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_CSM_LOADER_
+ MeshLoaderList.push_back(new CCSMLoader(this, FileSystem));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
+ MeshLoaderList.push_back(new CLMTSMeshFileLoader(FileSystem, Driver, &Parameters));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
+ MeshLoaderList.push_back(new CMY3DMeshFileLoader(FileSystem, Driver, this));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
+ MeshLoaderList.push_back(new CColladaFileLoader(Driver, this, FileSystem));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_DMF_LOADER_
+ MeshLoaderList.push_back(new CDMFLoader(Driver, this));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
+ MeshLoaderList.push_back(new COgreMeshFileLoader(MeshManipulator, FileSystem, Driver));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
+ MeshLoaderList.push_back(new COBJMeshFileLoader(FileSystem, Driver));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_MD3_LOADER_
+ MeshLoaderList.push_back(new CMD3MeshFileLoader(FileSystem, Driver));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_B3D_LOADER_
+ MeshLoaderList.push_back(new CB3DMeshFileLoader(this));
+ #endif
+ #ifdef _IRR_COMPILE_WITH_STL_LOADER_
+ MeshLoaderList.push_back(new CSTLMeshFileLoader());
+ #endif
+
+ // factories
+ ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this);
+ registerSceneNodeFactory(factory);
+ factory->drop();
+
+ ISceneNodeAnimatorFactory* animatorFactory = new CDefaultSceneNodeAnimatorFactory(this);
+ registerSceneNodeAnimatorFactory(animatorFactory);
+ animatorFactory->drop();
+}
+
+
+
+//! destructor
+CSceneManager::~CSceneManager()
+{
+ clearDeletionList();
+
+ if (Driver)
+ Driver->drop();
+
+ if (FileSystem)
+ FileSystem->drop();
+
+ if (CursorControl)
+ CursorControl->drop();
+
+ if (CollisionManager)
+ CollisionManager->drop();
+
+ if (MeshManipulator)
+ MeshManipulator->drop();
+
+ if ( GUIEnvironment )
+ GUIEnvironment->drop ();
+
+ u32 i;
+
+ for (i=0; idrop();
+
+ if (ActiveCamera)
+ ActiveCamera->drop();
+
+ if (MeshCache)
+ MeshCache->drop();
+
+ for (i=0; idrop();
+
+ for (i=0; idrop();
+}
+
+
+//! gets an animateable mesh. loads it if needed. returned pointer must not be dropped.
+IAnimatedMesh* CSceneManager::getMesh(const c8* filename)
+{
+ IAnimatedMesh* msh = MeshCache->getMeshByFilename(filename);
+ if (msh)
+ return msh;
+
+ io::IReadFile* file = FileSystem->createAndOpenFile(filename);
+ if (!file)
+ {
+ os::Printer::log("Could not load mesh, because file could not be opened.", filename, ELL_ERROR);
+ return 0;
+ }
+
+ core::stringc name = filename;
+ name.make_lower();
+ s32 count = MeshLoaderList.size();
+ for (s32 i=count-1; i>=0; --i)
+ {
+ if (MeshLoaderList[i]->isALoadableFileExtension(name.c_str()))
+ {
+ // reset file to avoid side effects of previous calls to createMesh
+ file->seek(0);
+ msh = MeshLoaderList[i]->createMesh(file);
+ if (msh)
+ {
+ MeshCache->addMesh(filename, msh);
+ msh->drop();
+ break;
+ }
+ }
+ }
+
+ file->drop();
+
+ if (!msh)
+ os::Printer::log("Could not load mesh, file format seems to be unsupported", filename, ELL_ERROR);
+ else
+ os::Printer::log("Loaded mesh", filename, ELL_INFORMATION);
+
+ return msh;
+}
+
+
+//! returns the video driver
+video::IVideoDriver* CSceneManager::getVideoDriver()
+{
+ return Driver;
+}
+
+//! returns the GUI Environment
+gui::IGUIEnvironment* CSceneManager::getGUIEnvironment ()
+{
+ return GUIEnvironment;
+}
+
+
+//! Adds a text scene node, which is able to display
+//! 2d text at a position in three dimensional space
+ITextSceneNode* CSceneManager::addTextSceneNode(gui::IGUIFont* font,
+ const wchar_t* text, video::SColor color, ISceneNode* parent,
+ const core::vector3df& position, s32 id)
+{
+ if (!font)
+ return 0;
+
+ if (!parent)
+ parent = this;
+
+ ITextSceneNode* t = new CTextSceneNode(parent, this, id, font,
+ getSceneCollisionManager(), position, text, color);
+ t->drop();
+
+ return t;
+}
+
+//! Adds a text scene node, which uses billboards
+ITextSceneNode* CSceneManager::addBillboardTextSceneNode(gui::IGUIFont* font,
+ const wchar_t* text, ISceneNode* parent,
+ const core::dimension2d& size,
+ const core::vector3df& position, s32 id,
+ video::SColor shade_top, video::SColor shade_down)
+{
+ if (!font)
+ return 0;
+
+ if (!parent)
+ parent = this;
+
+ ITextSceneNode* node = new CBillboardTextSceneNode(parent, this, id, font, text, position, size,
+ shade_top, shade_down);
+ node->drop();
+
+ return node;
+
+}
+
+
+//! Adds a scene node, which can render a quake3 shader
+ISceneNode* CSceneManager::addQuake3SceneNode( IMeshBuffer* meshBuffer,
+ const quake3::SShader * shader,
+ ISceneNode* parent,
+ s32 id
+ )
+
+{
+ if ( 0 == shader )
+ return 0;
+
+ if (!parent)
+ parent = this;
+
+ CQuake3ShaderSceneNode* node = new CQuake3ShaderSceneNode ( parent, this, id, FileSystem, meshBuffer, shader );
+ node->drop();
+
+ return node;
+
+}
+
+//! adds Volume Lighting Scene Node.
+//! the returned pointer must not be dropped.
+ISceneNode* CSceneManager::addVolumeLightSceneNode(ISceneNode* parent, s32 id,
+ const s32 subdivU, const s32 subdivV,
+ const video::SColor foot,
+ const video::SColor tail,
+ const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
+{
+ if (!parent)
+ parent = this;
+
+ ISceneNode* node = new CVolumeLightSceneNode(parent, this, id, subdivU, subdivV, foot, tail, position, rotation, scale);
+ node->drop();
+
+ return node;
+}
+
+//! adds a test scene node for test purposes to the scene. It is a simple cube of (1,1,1) size.
+//! the returned pointer must not be dropped.
+ISceneNode* CSceneManager::addCubeSceneNode(f32 size, ISceneNode* parent, s32 id,
+ const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
+{
+ if (!parent)
+ parent = this;
+
+ ISceneNode* node = new CCubeSceneNode(size, parent, this, id, position, rotation, scale);
+ node->drop();
+
+ return node;
+}
+
+//! Adds a sphere scene node for test purposes to the scene.
+ISceneNode* CSceneManager::addSphereSceneNode(f32 radius, s32 polyCount, ISceneNode* parent, s32 id,
+ const core::vector3df& position,
+ const core::vector3df& rotation,
+ const core::vector3df& scale)
+{
+ if (!parent)
+ parent = this;
+
+ ISceneNode* node = new CSphereSceneNode(radius, polyCount, polyCount, parent, this, id, position, rotation, scale);
+ node->drop();
+
+ return node;
+}
+
+
+//! adds a scene node for rendering a static mesh
+//! the returned pointer must not be dropped.
+IMeshSceneNode* CSceneManager::addMeshSceneNode(IMesh* mesh, ISceneNode* parent, s32 id,
+ const core::vector3df& position, const core::vector3df& rotation,
+ const core::vector3df& scale, bool alsoAddIfMeshPointerZero)
+{
+ if (!alsoAddIfMeshPointerZero && !mesh)
+ return 0;
+
+ if (!parent)
+ parent = this;
+
+ IMeshSceneNode* node = new CMeshSceneNode(mesh, parent, this, id, position, rotation, scale);
+ node->drop();
+
+ return node;
+}
+
+
+//! Adds a scene node for rendering a animated water surface mesh.
+ISceneNode* CSceneManager::addWaterSurfaceSceneNode(IMesh* mesh, f32 waveHeight, f32 waveSpeed, f32 waveLength,
+ ISceneNode* parent, s32 id, const core::vector3df& position,
+ const core::vector3df& rotation, const core::vector3df& scale)
+{
+ if (!mesh)
+ return 0;
+
+ if (!parent)
+ parent = this;
+
+ ISceneNode* node = new CWaterSurfaceSceneNode(waveHeight, waveSpeed, waveLength,
+ mesh, parent, this, id, position, rotation, scale);
+
+ node->drop();
+
+ return node;
+}
+
+
+
+//! adds a scene node for rendering an animated mesh model
+IAnimatedMeshSceneNode* CSceneManager::addAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, s32 id,
+ const core::vector3df& position, const core::vector3df& rotation,
+ const core::vector3df& scale, bool alsoAddIfMeshPointerZero)
+{
+ if (!alsoAddIfMeshPointerZero && !mesh)
+ return 0;
+
+ if (!parent)
+ parent = this;
+
+ IAnimatedMeshSceneNode* node =
+ new CAnimatedMeshSceneNode(mesh, parent, this, id, position, rotation, scale);
+ node->drop();
+
+ return node;
+}
+
+
+//! Adds a scene node for rendering using a octtree to the scene graph. This a good method for rendering
+//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much
+//! faster then a bsp tree.
+ISceneNode* CSceneManager::addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent,
+ s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero)
+{
+ if (!alsoAddIfMeshPointerZero && (!mesh || !mesh->getFrameCount()))
+ return 0;
+
+ return addOctTreeSceneNode(mesh ? mesh->getMesh(0) : 0,
+ parent, id, minimalPolysPerNode,
+ alsoAddIfMeshPointerZero);
+}
+
+
+
+//! Adss a scene node for rendering using a octtree. This a good method for rendering
+//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much
+//! faster then a bsp tree.
+ISceneNode* CSceneManager::addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent,
+ s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero)
+{
+ if (!alsoAddIfMeshPointerZero && !mesh)
+ return 0;
+
+ if (!parent)
+ parent = this;
+
+ COctTreeSceneNode* node = new COctTreeSceneNode(parent, this, id, minimalPolysPerNode);
+
+ if (mesh)
+ node->createTree(mesh);
+
+ node->drop();
+
+ return node;
+}
+
+
+//! Adds a camera scene node to the tree and sets it as active camera.
+//! \param position: Position of the space relative to its parent where the camera will be placed.
+//! \param lookat: Position where the camera will look at. Also known as target.
+//! \param parent: Parent scene node of the camera. Can be null. If the parent moves,
+//! the camera will move too.
+//! \return Returns pointer to interface to camera
+ICameraSceneNode* CSceneManager::addCameraSceneNode(ISceneNode* parent,
+ const core::vector3df& position, const core::vector3df& lookat, s32 id)
+{
+ if (!parent)
+ parent = this;
+
+ ICameraSceneNode* node = new CCameraSceneNode(parent, this, id, position, lookat);
+ node->drop();
+
+ setActiveCamera(node);
+
+ return node;
+}
+
+
+
+//! Adds a camera scene node which is able to be controlle with the mouse similar
+//! like in the 3D Software Maya by Alias Wavefront.
+//! The returned pointer must not be dropped.
+ICameraSceneNode* CSceneManager::addCameraSceneNodeMaya(ISceneNode* parent,
+ f32 rotateSpeed, f32 zoomSpeed, f32 translationSpeed, s32 id)
+{
+ if (!parent)
+ parent = this;
+
+ ICameraSceneNode* node = new CCameraMayaSceneNode(parent, this, id, rotateSpeed,
+ zoomSpeed, translationSpeed);
+ node->drop();
+
+ setActiveCamera(node);
+
+ return node;
+}
+
+
+
+//! Adds a camera scene node which is able to be controled with the mouse and keys
+//! like in most first person shooters (FPS):
+ICameraSceneNode* CSceneManager::addCameraSceneNodeFPS(ISceneNode* parent,
+ f32 rotateSpeed, f32 moveSpeed, s32 id,
+ SKeyMap* keyMapArray, s32 keyMapSize, bool noVerticalMovement,f32 jumpSpeed)
+{
+ if (!parent)
+ parent = this;
+
+ ICameraSceneNode* node = new CCameraFPSSceneNode(parent, this, CursorControl,
+ id, rotateSpeed, moveSpeed, jumpSpeed, keyMapArray, keyMapSize, noVerticalMovement);
+ node->drop();
+
+ setActiveCamera(node);
+
+ return node;
+}
+
+
+
+//! Adds a dynamic light scene node. The light will cast dynamic light on all
+//! other scene nodes in the scene, which have the material flag video::MTF_LIGHTING
+//! turned on. (This is the default setting in most scene nodes).
+ILightSceneNode* CSceneManager::addLightSceneNode(ISceneNode* parent,
+ const core::vector3df& position, video::SColorf color, f32 range, s32 id)
+{
+ if (!parent)
+ parent = this;
+
+ ILightSceneNode* node = new CLightSceneNode(parent, this, id, position, color, range);
+ node->drop();
+
+ return node;
+}
+
+
+
+//! Adds a billboard scene node to the scene. A billboard is like a 3d sprite: A 2d element,
+//! which always looks to the camera. It is usually used for things like explosions, fire,
+//! lensflares and things like that.
+IBillboardSceneNode* CSceneManager::addBillboardSceneNode(ISceneNode* parent,
+ const core::dimension2d& size, const core::vector3df& position, s32 id,
+ video::SColor shade_top, video::SColor shade_down
+ )
+{
+ if (!parent)
+ parent = this;
+
+ IBillboardSceneNode* node = new CBillboardSceneNode(parent, this, id, position, size,
+ shade_top, shade_down);
+ node->drop();
+
+ return node;
+}
+
+
+
+//! Adds a skybox scene node. A skybox is a big cube with 6 textures on it and
+//! is drawn around the camera position.
+ISceneNode* CSceneManager::addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom,
+ video::ITexture* left, video::ITexture* right, video::ITexture* front,
+ video::ITexture* back, ISceneNode* parent, s32 id)
+{
+ if (!parent)
+ parent = this;
+
+ ISceneNode* node = new CSkyBoxSceneNode(top, bottom, left, right,
+ front, back, parent, this, id);
+
+ node->drop();
+ return node;
+}
+
+
+//! Adds a skydome scene node. A skydome is a large (half-) sphere with a
+//! panoramic texture on it and is drawn around the camera position.
+ISceneNode* CSceneManager::addSkyDomeSceneNode(video::ITexture* texture,
+ u32 horiRes, u32 vertRes, f64 texturePercentage,
+ f64 spherePercentage, ISceneNode* parent, s32 id)
+{
+ if (!parent)
+ parent = this;
+
+ ISceneNode* node = new CSkyDomeSceneNode(texture, horiRes, vertRes,
+ texturePercentage, spherePercentage, parent, this, id);
+
+ node->drop();
+ return node;
+}
+
+
+//! Adds a particle system scene node.
+IParticleSystemSceneNode* CSceneManager::addParticleSystemSceneNode(
+ bool withDefaultEmitter, ISceneNode* parent, s32 id,
+ const core::vector3df& position, const core::vector3df& rotation,
+ const core::vector3df& scale)
+{
+ if (!parent)
+ parent = this;
+
+ IParticleSystemSceneNode* node = new CParticleSystemSceneNode(withDefaultEmitter,
+ parent, this, id, position, rotation, scale);
+ node->drop();
+
+ return node;
+}
+
+
+//! Adds a terrain scene node to the scene graph.
+ITerrainSceneNode* CSceneManager::addTerrainSceneNode(
+ const char* heightMapFileName,
+ ISceneNode* parent, s32 id,
+ const core::vector3df& position,
+ const core::vector3df& rotation,
+ const core::vector3df& scale,
+ video::SColor vertexColor,
+ s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, s32 smoothFactor,
+ bool addAlsoIfHeightmapEmpty)
+{
+ io::IReadFile* file = FileSystem->createAndOpenFile(heightMapFileName);
+
+ if(!file && !addAlsoIfHeightmapEmpty)
+ {
+ os::Printer::log("Could not load terrain, because file could not be opened.",
+ heightMapFileName, ELL_ERROR);
+ return 0;
+ }
+
+ ITerrainSceneNode* terrain = addTerrainSceneNode(file, parent, id,
+ position, rotation, scale, vertexColor, maxLOD, patchSize,
+ smoothFactor, addAlsoIfHeightmapEmpty);
+
+ if (file)
+ file->drop();
+
+ return terrain;
+}
+
+//! Adds a terrain scene node to the scene graph.
+ITerrainSceneNode* CSceneManager::addTerrainSceneNode(
+ io::IReadFile* heightMapFile,
+ ISceneNode* parent, s32 id,
+ const core::vector3df& position,
+ const core::vector3df& rotation,
+ const core::vector3df& scale,
+ video::SColor vertexColor,
+ s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize,
+ s32 smoothFactor,
+ bool addAlsoIfHeightmapEmpty)
+{
+ if (!parent)
+ parent = this;
+
+ if (!heightMapFile && !addAlsoIfHeightmapEmpty)
+ {
+ os::Printer::log("Could not load terrain, because file could not be opened.", ELL_ERROR);
+ return 0;
+ }
+
+ CTerrainSceneNode* node = new CTerrainSceneNode(parent, this, FileSystem, id,
+ maxLOD, patchSize, position, rotation, scale);
+
+ if (!node->loadHeightMap(heightMapFile, vertexColor, smoothFactor))
+ {
+ if (!addAlsoIfHeightmapEmpty)
+ {
+ node->remove();
+ node->drop();
+ return 0;
+ }
+ }
+
+ node->drop();
+ return node;
+}
+
+
+//! Adds an empty scene node.
+ISceneNode* CSceneManager::addEmptySceneNode(ISceneNode* parent, s32 id)
+{
+ if (!parent)
+ parent = this;
+
+ ISceneNode* node = new CEmptySceneNode(parent, this, id);
+ node->drop();
+
+ return node;
+}
+
+
+//! Adds a dummy transformation scene node to the scene graph.
+IDummyTransformationSceneNode* CSceneManager::addDummyTransformationSceneNode(
+ ISceneNode* parent, s32 id)
+{
+ if (!parent)
+ parent = this;
+
+ IDummyTransformationSceneNode* node = new CDummyTransformationSceneNode(
+ parent, this, id);
+ node->drop();
+
+ return node;
+}
+
+//! Adds a Hill Plane mesh to the mesh pool. The mesh is generated on the fly
+//! and looks like a plane with some hills on it. It is uses mostly for quick
+//! tests of the engine only. You can specify how many hills there should be
+//! on the plane and how high they should be. Also you must specify a name for
+//! the mesh, because the mesh is added to the mesh pool, and can be retrieved
+//! again using ISceneManager::getMesh with the name as parameter.
+IAnimatedMesh* CSceneManager::addHillPlaneMesh(const c8* name,
+ const core::dimension2d& tileSize,
+ const core::dimension2d& tileCount,
+ video::SMaterial* material, f32 hillHeight,
+ const core::dimension2d& countHills,
+ const core::dimension2d& textureRepeatCount)
+{
+ if (!name || MeshCache->isMeshLoaded(name))
+ return 0;
+
+ IMesh* mesh = CGeometryCreator::createHillPlaneMesh(tileSize,
+ tileCount, material, hillHeight, countHills,
+ textureRepeatCount);
+ if (!mesh)
+ return 0;
+
+ SAnimatedMesh* animatedMesh = new SAnimatedMesh();
+ if (!animatedMesh)
+ return 0;
+
+ animatedMesh->addMesh(mesh);
+ animatedMesh->recalculateBoundingBox();
+ mesh->drop();
+
+ MeshCache->addMesh(name, animatedMesh);
+ animatedMesh->drop();
+
+ return animatedMesh;
+}
+
+
+//! Adds a terrain mesh to the mesh pool.
+IAnimatedMesh* CSceneManager::addTerrainMesh(const c8* name,
+ video::IImage* texture, video::IImage* heightmap,
+ const core::dimension2d& stretchSize,
+ f32 maxHeight,
+ const core::dimension2d& defaultVertexBlockSize)
+{
+ if (!name || MeshCache->isMeshLoaded(name))
+ return 0;
+
+ IMesh* mesh = CGeometryCreator::createTerrainMesh(texture, heightmap,
+ stretchSize, maxHeight, getVideoDriver(),
+ defaultVertexBlockSize);
+ if (!mesh)
+ return 0;
+
+ SAnimatedMesh* animatedMesh = new SAnimatedMesh();
+ if (!animatedMesh)
+ return 0;
+
+ animatedMesh->addMesh(mesh);
+ animatedMesh->recalculateBoundingBox();
+ mesh->drop();
+
+ MeshCache->addMesh(name, animatedMesh);
+ animatedMesh->drop();
+
+ return animatedMesh;
+}
+
+//! Adds an arrow mesh to the mesh pool.
+IAnimatedMesh* CSceneManager::addArrowMesh(const c8* name,
+ video::SColor vtxColor0, video::SColor vtxColor1,
+ u32 tesselationCylinder, u32 tesselationCone, f32 height,
+ f32 cylinderHeight, f32 width0,f32 width1)
+{
+ if (!name || MeshCache->isMeshLoaded(name))
+ return 0;
+
+ IMesh* mesh = CGeometryCreator::createArrowMesh( tesselationCylinder,
+ tesselationCone, height, cylinderHeight, width0,width1,
+ vtxColor0, vtxColor1);
+ if (!mesh)
+ return 0;
+
+ SAnimatedMesh* animatedMesh = new SAnimatedMesh();
+ if (!animatedMesh)
+ return 0;
+
+ animatedMesh->addMesh(mesh);
+ animatedMesh->recalculateBoundingBox();
+ mesh->drop();
+
+ MeshCache->addMesh(name, animatedMesh);
+ animatedMesh->drop();
+
+ return animatedMesh;
+}
+
+
+
+//! Adds a static sphere mesh to the mesh pool.
+IAnimatedMesh* CSceneManager::addSphereMesh(const c8* name,
+ f32 radius, u32 polyCountX, u32 polyCountY)
+{
+ if (!name || MeshCache->isMeshLoaded(name))
+ return 0;
+
+ IMesh* mesh = CGeometryCreator::createSphereMesh( radius, polyCountX, polyCountY);
+ if (!mesh)
+ return 0;
+
+ SAnimatedMesh* animatedMesh = new SAnimatedMesh();
+ if (!animatedMesh)
+ return 0;
+
+ animatedMesh->addMesh(mesh);
+ animatedMesh->recalculateBoundingBox();
+ mesh->drop();
+
+ MeshCache->addMesh(name, animatedMesh);
+ animatedMesh->drop();
+
+ return animatedMesh;
+}
+
+
+
+//! Returns the root scene node. This is the scene node wich is parent
+//! of all scene nodes. The root scene node is a special scene node which
+//! only exists to manage all scene nodes. It is not rendered and cannot
+//! be removed from the scene.
+//! \return Returns a pointer to the root scene node.
+ISceneNode* CSceneManager::getRootSceneNode()
+{
+ return this;
+}
+
+
+
+//! Returns the current active camera.
+//! \return The active camera is returned. Note that this can be NULL, if there
+//! was no camera created yet.
+ICameraSceneNode* CSceneManager::getActiveCamera()
+{
+ return ActiveCamera;
+}
+
+
+
+//! Sets the active camera. The previous active camera will be deactivated.
+//! \param camera: The new camera which should be active.
+void CSceneManager::setActiveCamera(ICameraSceneNode* camera)
+{
+ if (ActiveCamera)
+ ActiveCamera->drop();
+
+ ActiveCamera = camera;
+
+ if (ActiveCamera)
+ ActiveCamera->grab();
+}
+
+
+
+
+//! renders the node.
+void CSceneManager::render()
+{
+}
+
+
+//! returns the axis aligned bounding box of this node
+const core::aabbox3d& CSceneManager::getBoundingBox() const
+{
+ _IRR_DEBUG_BREAK_IF(true) // Bounding Box of Scene Manager wanted.
+
+ // should never be used.
+ return *((core::aabbox3d*)0);
+}
+
+
+
+//! returns if node is culled
+bool CSceneManager::isCulled(const ISceneNode* node)
+{
+ const ICameraSceneNode* cam = getActiveCamera();
+ if (!cam)
+ return false;
+
+ switch ( node->getAutomaticCulling() )
+ {
+ // can be seen by a bounding box ?
+ case scene::EAC_BOX:
+ {
+ core::aabbox3d tbox = node->getBoundingBox();
+ node->getAbsoluteTransformation().transformBox(tbox);
+ return !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox() ));
+ }
+
+ // can be seen by a bounding sphere
+ case scene::EAC_FRUSTUM_SPHERE:
+ { // requires bbox diameter
+ }
+ break;
+
+ // can be seen by cam pyramid planes ?
+ case scene::EAC_FRUSTUM_BOX:
+ {
+ SViewFrustum frust = *cam->getViewFrustum();
+
+ //transform the frustum to the node's current absolute transformation
+ core::matrix4 invTrans(node->getAbsoluteTransformation());
+ invTrans.makeInverse();
+ frust.transform(invTrans);
+
+ core::vector3df edges[8];
+ node->getBoundingBox().getEdges(edges);
+
+ for (s32 i=0; igetMaterialCount();
+
+ taken = 0;
+ for (u32 i=0; igetMaterialRenderer(node->getMaterial(i).MaterialType);
+ if (rnd && rnd->isTransparent())
+ {
+ // register as transparent node
+ TransparentNodeEntry e(node, camWorldPos);
+ TransparentNodeList.push_back(e);
+ taken = 1;
+ break;
+ }
+ }
+
+ // not transparent, register as solid
+ if ( 0 == taken )
+ {
+ SolidNodeList.push_back( node );
+ taken = 1;
+ }
+ }
+ break;
+ case ESNRP_SHADOW:
+ if (!isCulled(node))
+ {
+ ShadowNodeList.push_back(node);
+ taken = 1;
+ }
+ break;
+
+ case ESNRP_COUNT: // ignore this one
+ break;
+ }
+
+#ifdef SCENEMANAGER_DEBUG
+ s32 index = Parameters.findAttribute ( "calls" );
+ Parameters.setAttribute ( index, Parameters.getAttributeAsInt ( index ) + 1 );
+
+ if ( 0 == taken )
+ {
+ index = Parameters.findAttribute ( "culled" );
+ Parameters.setAttribute ( index, Parameters.getAttributeAsInt ( index ) + 1 );
+ }
+#endif
+
+ return taken;
+}
+
+//! This method is called just before the rendering process of the whole scene.
+//! draws all scene nodes
+void CSceneManager::drawAll()
+{
+ if (!Driver)
+ return;
+
+ // reset attributes
+ Parameters.setAttribute ( "culled", 0 );
+ Parameters.setAttribute ( "calls", 0 );
+ Parameters.setAttribute ( "drawn", 0 );
+
+ // reset all transforms
+ video::IVideoDriver* driver = getVideoDriver();
+ if ( driver )
+ {
+ driver->setTransform ( video::ETS_PROJECTION, core::IdentityMatrix );
+ driver->setTransform ( video::ETS_VIEW, core::IdentityMatrix );
+ driver->setTransform ( video::ETS_WORLD, core::IdentityMatrix );
+ driver->setTransform ( video::ETS_TEXTURE_0, core::IdentityMatrix );
+ driver->setTransform ( video::ETS_TEXTURE_1, core::IdentityMatrix );
+ driver->setTransform ( video::ETS_TEXTURE_2, core::IdentityMatrix );
+ driver->setTransform ( video::ETS_TEXTURE_3, core::IdentityMatrix );
+ }
+
+ // do animations and other stuff.
+ OnAnimate(os::Timer::getTime());
+
+ /*!
+ First Scene Node for prerendering should be the active camera
+ consistent Camera is needed for culling
+ */
+ camWorldPos.set(0,0,0);
+ if ( ActiveCamera )
+ {
+ ActiveCamera->OnRegisterSceneNode();
+ camWorldPos = ActiveCamera->getAbsolutePosition();
+ }
+
+ // let all nodes register themselves
+ OnRegisterSceneNode();
+
+ u32 i; // new ISO for scoping problem in some compilers
+
+ //render camera scenes
+ {
+ CurrentRendertime = ESNRP_CAMERA;
+ for (i=0; irender();
+
+ CameraList.set_used(0);
+ }
+
+ //render lights scenes
+ {
+ CurrentRendertime = ESNRP_LIGHT;
+
+ Driver->deleteAllDynamicLights();
+
+ Driver->setAmbientLight(AmbientLight);
+
+ LightList.sort (); // on distance to camera
+
+ u32 maxLights = core::min_ ( Driver->getMaximalDynamicLightAmount (), LightList.size () );
+ for (i=0; i< maxLights; ++i)
+ LightList[i].node->render();
+
+ LightList.set_used(0);
+ }
+
+ // render skyboxes
+ {
+ CurrentRendertime = ESNRP_SKY_BOX;
+
+ for (i=0; irender();
+
+ SkyBoxList.set_used(0);
+ }
+
+
+ // render default objects
+ {
+ CurrentRendertime = ESNRP_SOLID;
+ SolidNodeList.sort(); // sort by textures
+
+ for (i=0; irender();
+
+ Parameters.setAttribute ( "drawn", (s32) SolidNodeList.size () );
+
+ SolidNodeList.set_used(0);
+ }
+
+ // render shadows
+ {
+ CurrentRendertime = ESNRP_SHADOW;
+ for (i=0; irender();
+
+ if (!ShadowNodeList.empty())
+ Driver->drawStencilShadow(true,ShadowColor, ShadowColor,
+ ShadowColor, ShadowColor);
+
+ ShadowNodeList.set_used(0);
+ }
+
+ // render transparent objects.
+ {
+ CurrentRendertime = ESNRP_TRANSPARENT;
+ TransparentNodeList.sort(); // sort by distance from camera
+
+ for (i=0; irender();
+
+ TransparentNodeList.set_used(0);
+ }
+
+
+ clearDeletionList();
+
+ CurrentRendertime = ESNRP_COUNT;
+}
+
+
+//! Sets the color of stencil buffers shadows drawn by the scene manager.
+void CSceneManager::setShadowColor(video::SColor color)
+{
+ ShadowColor = color;
+}
+
+
+//! Returns the current color of shadows.
+video::SColor CSceneManager::getShadowColor() const
+{
+ return ShadowColor;
+}
+
+
+
+//! creates a rotation animator, which rotates the attached scene node around itself.
+ISceneNodeAnimator* CSceneManager::createRotationAnimator(const core::vector3df& rotationPerSecond)
+{
+ ISceneNodeAnimator* anim = new CSceneNodeAnimatorRotation(os::Timer::getTime(),
+ rotationPerSecond);
+
+ return anim;
+}
+
+
+
+//! creates a fly circle animator, which lets the attached scene node fly around a center.
+ISceneNodeAnimator* CSceneManager::createFlyCircleAnimator(
+ const core::vector3df& normal, f32 radius, f32 speed,
+ const core::vector3df& direction)
+{
+ ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyCircle(os::Timer::getTime(), normal,
+ radius, speed, direction);
+ return anim;
+}
+
+
+//! Creates a fly straight animator, which lets the attached scene node
+//! fly or move along a line between two points.
+ISceneNodeAnimator* CSceneManager::createFlyStraightAnimator(const core::vector3df& startPoint,
+ const core::vector3df& endPoint, u32 timeForWay, bool loop)
+{
+ ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyStraight(startPoint,
+ endPoint, timeForWay, loop, os::Timer::getTime());
+
+ return anim;
+}
+
+
+//! Creates a texture animator, which switches the textures of the target scene
+//! node based on a list of textures.
+ISceneNodeAnimator* CSceneManager::createTextureAnimator(const core::array& textures,
+ s32 timePerFrame, bool loop)
+{
+ ISceneNodeAnimator* anim = new CSceneNodeAnimatorTexture(textures,
+ timePerFrame, loop, os::Timer::getTime());
+
+ return anim;
+}
+
+
+//! Creates a scene node animator, which deletes the scene node after
+//! some time automaticly.
+ISceneNodeAnimator* CSceneManager::createDeleteAnimator(u32 when)
+{
+ return new CSceneNodeAnimatorDelete(this, os::Timer::getTime() + when);
+}
+
+
+
+
+//! Creates a special scene node animator for doing automatic collision detection
+//! and response.
+ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnimator(
+ ITriangleSelector* world, ISceneNode* sceneNode, const core::vector3df& ellipsoidRadius,
+ const core::vector3df& gravityPerSecond,
+ const core::vector3df& ellipsoidTranslation, f32 slidingValue)
+{
+ ISceneNodeAnimatorCollisionResponse* anim = new
+ CSceneNodeAnimatorCollisionResponse(this, world, sceneNode,
+ ellipsoidRadius, gravityPerSecond,
+ ellipsoidTranslation, slidingValue);
+
+ return anim;
+}
+
+
+//! Creates a follow spline animator.
+ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime,
+ const core::array< core::vector3df >& points,
+ f32 speed, f32 tightness)
+{
+ ISceneNodeAnimator* a = new CSceneNodeAnimatorFollowSpline(startTime, points,
+ speed, tightness);
+ return a;
+}
+
+
+
+//! Adds an external mesh loader.
+void CSceneManager::addExternalMeshLoader(IMeshLoader* externalLoader)
+{
+ if (!externalLoader)
+ return;
+
+ externalLoader->grab();
+ MeshLoaderList.push_back(externalLoader);
+}
+
+
+
+//! Returns a pointer to the scene collision manager.
+ISceneCollisionManager* CSceneManager::getSceneCollisionManager()
+{
+ return CollisionManager;
+}
+
+
+//! Returns a pointer to the mesh manipulator.
+IMeshManipulator* CSceneManager::getMeshManipulator()
+{
+ return MeshManipulator;
+}
+
+
+//! Creates a simple ITriangleSelector, based on a mesh.
+ITriangleSelector* CSceneManager::createTriangleSelector(IMesh* mesh, ISceneNode* node)
+{
+ if (!mesh || !node)
+ return 0;
+
+ return new CTriangleSelector(mesh, node);
+}
+
+
+//! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.
+ITriangleSelector* CSceneManager::createTriangleSelectorFromBoundingBox(ISceneNode* node)
+{
+ if (!node)
+ return 0;
+
+ return new CTriangleBBSelector(node);
+}
+
+
+//! Creates a simple ITriangleSelector, based on a mesh.
+ITriangleSelector* CSceneManager::createOctTreeTriangleSelector(IMesh* mesh,
+ ISceneNode* node,
+ s32 minimalPolysPerNode)
+{
+ if (!mesh || !node)
+ return 0;
+
+ return new COctTreeTriangleSelector(mesh, node, minimalPolysPerNode);
+}
+
+
+
+//! Creates a meta triangle selector.
+IMetaTriangleSelector* CSceneManager::createMetaTriangleSelector()
+{
+ return new CMetaTriangleSelector();
+}
+
+
+
+//! Creates a triangle selector which can select triangles from a terrain scene node
+ITriangleSelector* CSceneManager::createTerrainTriangleSelector(
+ ITerrainSceneNode* node, s32 LOD)
+{
+ return new CTerrainTriangleSelector(node, LOD);
+}
+
+
+
+//! Adds a scene node to the deletion queue.
+void CSceneManager::addToDeletionQueue(ISceneNode* node)
+{
+ if (!node)
+ return;
+
+ node->grab();
+ DeletionList.push_back(node);
+}
+
+
+//! clears the deletion list
+void CSceneManager::clearDeletionList()
+{
+ if (DeletionList.empty())
+ return;
+
+ for (s32 i=0; i<(s32)DeletionList.size(); ++i)
+ {
+ DeletionList[i]->remove();
+ DeletionList[i]->drop();
+ }
+
+ DeletionList.clear();
+}
+
+
+//! Returns the first scene node with the specified name.
+ISceneNode* CSceneManager::getSceneNodeFromName(const char* name, ISceneNode* start)
+{
+ if (start == 0)
+ start = getRootSceneNode();
+
+ if (!strcmp(start->getName(),name))
+ return start;
+
+ ISceneNode* node = 0;
+
+ const core::list& list = start->getChildren();
+ core::list::ConstIterator it = list.begin();
+ for (; it!=list.end(); ++it)
+ {
+ node = getSceneNodeFromName(name, *it);
+ if (node)
+ return node;
+ }
+
+ return 0;
+}
+
+
+//! Returns the first scene node with the specified id.
+ISceneNode* CSceneManager::getSceneNodeFromId(s32 id, ISceneNode* start)
+{
+ if (start == 0)
+ start = getRootSceneNode();
+
+ if (start->getID() == id)
+ return start;
+
+ ISceneNode* node = 0;
+
+ const core::list& list = start->getChildren();
+ core::list::ConstIterator it = list.begin();
+ for (; it!=list.end(); ++it)
+ {
+ node = getSceneNodeFromId(id, *it);
+ if (node)
+ return node;
+ }
+
+ return 0;
+}
+
+
+//! Returns the first scene node with the specified type.
+ISceneNode* CSceneManager::getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start)
+{
+ if (start == 0)
+ start = getRootSceneNode();
+
+ if (start->getType() == type)
+ return start;
+
+ ISceneNode* node = 0;
+
+ const core::list& list = start->getChildren();
+ core::list::ConstIterator it = list.begin();
+ for (; it!=list.end(); ++it)
+ {
+ node = getSceneNodeFromType(type, *it);
+ if (node)
+ return node;
+ }
+
+ return 0;
+}
+
+//! returns scene nodes by type.
+void CSceneManager::getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array& outNodes, ISceneNode* start)
+{
+ if (start == 0)
+ start = getRootSceneNode();
+
+ if (start->getType() == type)
+ outNodes.push_back(start);
+
+ const core::list& list = start->getChildren();
+ core::list::ConstIterator it = list.begin();
+
+ for (; it!=list.end(); ++it)
+ {
+ getSceneNodesFromType(type, outNodes, *it);
+ }
+}
+
+
+//! Posts an input event to the environment. Usually you do not have to
+//! use this method, it is used by the internal engine.
+bool CSceneManager::postEventFromUser(const SEvent& event)
+{
+ bool ret = false;
+ ICameraSceneNode* cam = getActiveCamera();
+ if (cam)
+ ret = cam->OnEvent(event);
+
+ _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
+ return ret;
+}
+
+
+//! Removes all children of this scene node
+void CSceneManager::removeAll()
+{
+ ISceneNode::removeAll();
+ setActiveCamera(0);
+}
+
+
+//! Clears the whole scene. All scene nodes are removed.
+void CSceneManager::clear()
+{
+ removeAll();
+}
+
+
+//! Returns interface to the parameters set in this scene.
+io::IAttributes* CSceneManager::getParameters()
+{
+ return &Parameters;
+}
+
+
+//! Returns current render pass.
+E_SCENE_NODE_RENDER_PASS CSceneManager::getSceneNodeRenderPass() const
+{
+ return CurrentRendertime;
+}
+
+
+
+//! Returns an interface to the mesh cache which is shared beween all existing scene managers.
+IMeshCache* CSceneManager::getMeshCache()
+{
+ return MeshCache;
+}
+
+
+//! Creates a new scene manager.
+ISceneManager* CSceneManager::createNewSceneManager(bool cloneContent)
+{
+ CSceneManager* manager = new CSceneManager(Driver, FileSystem, CursorControl, MeshCache);
+
+ if (cloneContent)
+ manager->cloneMembers(this, manager);
+
+ return manager;
+}
+
+
+//! Returns the default scene node factory which can create all built in scene nodes
+ISceneNodeFactory* CSceneManager::getDefaultSceneNodeFactory()
+{
+ return getSceneNodeFactory(0);
+}
+
+
+//! Adds a scene node factory to the scene manager.
+void CSceneManager::registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd)
+{
+ if (factoryToAdd)
+ {
+ factoryToAdd->grab();
+ SceneNodeFactoryList.push_back(factoryToAdd);
+ }
+}
+
+
+//! Returns amount of registered scene node factories.
+u32 CSceneManager::getRegisteredSceneNodeFactoryCount() const
+{
+ return SceneNodeFactoryList.size();
+}
+
+
+//! Returns a scene node factory by index
+ISceneNodeFactory* CSceneManager::getSceneNodeFactory(u32 index)
+{
+ if (indexgrab();
+ SceneNodeAnimatorFactoryList.push_back(factoryToAdd);
+ }
+}
+
+
+//! Returns amount of registered scene node animator factories.
+u32 CSceneManager::getRegisteredSceneNodeAnimatorFactoryCount() const
+{
+ return SceneNodeAnimatorFactoryList.size();
+}
+
+
+//! Returns a scene node animator factory by index
+ISceneNodeAnimatorFactory* CSceneManager::getSceneNodeAnimatorFactory(u32 index)
+{
+ if (indexcreateAndWriteFile(filename);
+ if (!file)
+ return false;
+
+ bool ret = saveScene(file, userDataSerializer);
+ file->drop();
+ return ret;
+}
+
+
+//! Saves the current scene into a file.
+bool CSceneManager::saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer)
+{
+ if (!file)
+ return false;
+
+ io::IXMLWriter* writer = FileSystem->createXMLWriter(file);
+ if (!writer)
+ return false;
+
+ writer->writeXMLHeader();
+ writeSceneNode(writer, this, userDataSerializer);
+ writer->drop();
+
+ return true;
+}
+
+
+//! Loads a scene. Note that the current scene is not cleared before.
+//! \param filename: Name of the file .
+bool CSceneManager::loadScene(const c8* filename, ISceneUserDataSerializer* userDataSerializer)
+{
+ io::IReadFile* read = FileSystem->createAndOpenFile(filename);
+ if (!read)
+ {
+ os::Printer::log("Unable to open scene file", filename, ELL_ERROR);
+ return false;
+ }
+
+ bool ret = loadScene(read, userDataSerializer);
+ read->drop();
+
+ return ret;
+}
+
+
+//! Loads a scene. Note that the current scene is not cleared before.
+bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer)
+{
+ if (!file)
+ {
+ os::Printer::log("Unable to open scene file", ELL_ERROR);
+ return false;
+ }
+
+ io::IXMLReader* reader = FileSystem->createXMLReader(file);
+ if (!reader)
+ {
+ os::Printer::log("Scene is not a valid XML file", file->getFileName(), ELL_ERROR);
+ return false;
+ }
+
+ // for mesh loading, set collada loading attributes
+
+ bool oldColladaSingleMesh = getParameters()->getAttributeAsBool(COLLADA_CREATE_SCENE_INSTANCES);
+ getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, false);
+
+ // read file
+
+ while(reader->read())
+ {
+ readSceneNode(reader, 0, userDataSerializer);
+ }
+
+ // restore old collada parameters
+
+ getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, oldColladaSingleMesh);
+
+ // finish up
+
+ reader->drop();
+ return true;
+
+}
+
+
+//! reads a scene node
+void CSceneManager::readSceneNode(io::IXMLReader* reader, ISceneNode* parent, ISceneUserDataSerializer* userDataSerializer)
+{
+ if (!reader)
+ return;
+
+ scene::ISceneNode* node = 0;
+
+ if ((!parent && IRR_XML_FORMAT_SCENE==reader->getNodeName()) ||
+ ( parent && IRR_XML_FORMAT_NODE==reader->getNodeName()))
+ {
+ if (parent)
+ {
+ // find node type and create it
+ core::stringc attrName = reader->getAttributeValue(IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str());
+
+ for (int i=(int)SceneNodeFactoryList.size()-1; i>=0 && !node; --i)
+ node = SceneNodeFactoryList[i]->addSceneNode(attrName.c_str(), parent);
+
+ if (!node)
+ os::Printer::log("Could not create scene node of unknown type", attrName.c_str());
+ }
+ else
+ node = this; // root
+ }
+
+ // read attributes
+ while(reader->read())
+ {
+ bool endreached = false;
+
+ switch (reader->getNodeType())
+ {
+ case io::EXN_ELEMENT_END:
+ if ((IRR_XML_FORMAT_NODE==reader->getNodeName()) ||
+ (IRR_XML_FORMAT_SCENE==reader->getNodeName()))
+ {
+ endreached = true;
+ }
+ break;
+ case io::EXN_ELEMENT:
+ if (core::stringw(L"attributes")==reader->getNodeName())
+ {
+ // read attributes
+ io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
+ attr->read(reader, true);
+
+ if (node)
+ node->deserializeAttributes(attr);
+
+ attr->drop();
+ }
+ else
+ if (core::stringw(L"materials")==reader->getNodeName())
+ readMaterials(reader, node);
+ else
+ if (core::stringw(L"animators")==reader->getNodeName())
+ readAnimators(reader, node);
+ else
+ if (core::stringw(L"userData")==reader->getNodeName())
+ readUserData(reader, node, userDataSerializer);
+ else
+ if ((IRR_XML_FORMAT_NODE==reader->getNodeName()) ||
+ (IRR_XML_FORMAT_SCENE==reader->getNodeName()))
+ {
+ readSceneNode(reader, node, userDataSerializer);
+ }
+ else
+ {
+ os::Printer::log("Found unknown element in irrlicht scene file",
+ core::stringc(reader->getNodeName()).c_str());
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (endreached)
+ break;
+ }
+}
+
+
+//! reads materials of a node
+void CSceneManager::readMaterials(io::IXMLReader* reader, ISceneNode* node)
+{
+ u32 nr = 0;
+
+ while(reader->read())
+ {
+ const wchar_t* name = reader->getNodeName();
+
+ switch(reader->getNodeType())
+ {
+ case io::EXN_ELEMENT_END:
+ if (core::stringw(L"materials")==name)
+ return;
+ break;
+ case io::EXN_ELEMENT:
+ if (core::stringw(L"attributes")==name)
+ {
+ // read materials from attribute list
+ io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
+ attr->read(reader);
+
+ if (node && node->getMaterialCount() > nr)
+ {
+ getVideoDriver()->fillMaterialStructureFromAttributes(
+ node->getMaterial(nr), attr);
+ }
+
+ attr->drop();
+ ++nr;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+//! reads animators of a node
+void CSceneManager::readAnimators(io::IXMLReader* reader, ISceneNode* node)
+{
+ while(reader->read())
+ {
+ const wchar_t* name = reader->getNodeName();
+
+ switch(reader->getNodeType())
+ {
+ case io::EXN_ELEMENT_END:
+ if (core::stringw(L"animators")==name)
+ return;
+ break;
+ case io::EXN_ELEMENT:
+ if (core::stringw(L"attributes")==name)
+ {
+ // read animator data from attribute list
+ io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
+ attr->read(reader);
+
+ if (node)
+ {
+ core::stringc typeName = attr->getAttributeAsString("Type");
+ ISceneNodeAnimator* anim = 0;
+
+ for (int i=0; i<(int)SceneNodeAnimatorFactoryList.size() && !anim; ++i)
+ anim = SceneNodeAnimatorFactoryList[i]->createSceneNodeAnimator(typeName.c_str(), node);
+
+ if (anim)
+ {
+ anim->deserializeAttributes(attr);
+ anim->drop();
+ }
+ }
+
+ attr->drop();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+//! reads user data of a node
+void CSceneManager::readUserData(io::IXMLReader* reader, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer)
+{
+ while(reader->read())
+ {
+ const wchar_t* name = reader->getNodeName();
+
+ switch(reader->getNodeType())
+ {
+ case io::EXN_ELEMENT_END:
+ if (core::stringw(L"userData")==name)
+ return;
+ break;
+ case io::EXN_ELEMENT:
+ if (core::stringw(L"attributes")==name)
+ {
+ // read user data from attribute list
+ io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
+ attr->read(reader);
+
+ if (node && userDataSerializer)
+ {
+ userDataSerializer->OnReadUserData(node, attr);
+ }
+
+ attr->drop();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+//! writes a scene node
+void CSceneManager::writeSceneNode(io::IXMLWriter* writer, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer)
+{
+ if (!writer || !node || node->isDebugObject())
+ return;
+
+ const wchar_t* name;
+
+ if (node == this)
+ {
+ name = IRR_XML_FORMAT_SCENE.c_str();
+ writer->writeElement(name, false);
+ }
+ else
+ {
+ name = IRR_XML_FORMAT_NODE.c_str();
+ writer->writeElement(name, false, IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str(),
+ core::stringw(getSceneNodeTypeName(node->getType())).c_str());
+ }
+
+ writer->writeLineBreak();
+ writer->writeLineBreak();
+
+ // write properties
+
+ io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver);
+ node->serializeAttributes(attr);
+
+ if (attr->getAttributeCount() != 0)
+ {
+ attr->write(writer);
+ writer->writeLineBreak();
+ }
+
+ // write materials
+
+ if (node->getMaterialCount() && getVideoDriver())
+ {
+ const wchar_t* materialElement = L"materials";
+
+ writer->writeElement(materialElement);
+ writer->writeLineBreak();
+
+ for (u32 i=0; i < node->getMaterialCount(); ++i)
+ {
+ io::IAttributes* tmp_attr =
+ getVideoDriver()->createAttributesFromMaterial(node->getMaterial(i));
+ tmp_attr->write(writer);
+ tmp_attr->drop();
+ }
+
+ writer->writeClosingTag(materialElement);
+ writer->writeLineBreak();
+ }
+
+ // write animators
+
+ if (!node->getAnimators().empty())
+ {
+ const wchar_t* animatorElement = L"animators";
+ writer->writeElement(animatorElement);
+ writer->writeLineBreak();
+
+ core::list::ConstIterator it = node->getAnimators().begin();
+ for (; it != node->getAnimators().end(); ++it)
+ {
+ attr->clear();
+ attr->addString("Type", getAnimatorTypeName((*it)->getType()));
+
+ (*it)->serializeAttributes(attr);
+
+ attr->write(writer);
+ }
+
+ writer->writeClosingTag(animatorElement);
+ writer->writeLineBreak();
+ }
+
+ // write possible user data
+
+ if ( userDataSerializer )
+ {
+ io::IAttributes* userData = userDataSerializer->createUserData(node);
+ if (userData)
+ {
+ const wchar_t* userDataElement = L"userData";
+
+ writer->writeLineBreak();
+ writer->writeElement(userDataElement);
+ writer->writeLineBreak();
+
+ userData->write(writer);
+
+ writer->writeClosingTag(userDataElement);
+ writer->writeLineBreak();
+ writer->writeLineBreak();
+
+ userData->drop();
+ }
+ }
+
+ // write children
+
+ core::list::ConstIterator it = node->getChildren().begin();
+ for (; it != node->getChildren().end(); ++it)
+ writeSceneNode(writer, (*it), userDataSerializer);
+
+ attr->drop();
+
+ writer->writeClosingTag(name);
+ writer->writeLineBreak();
+ writer->writeLineBreak();
+}
+
+
+//! Returns a typename from a scene node type or null if not found
+const c8* CSceneManager::getSceneNodeTypeName(ESCENE_NODE_TYPE type)
+{
+ const char* name = 0;
+
+ for (int i=(int)SceneNodeFactoryList.size()-1; !name && i>=0; --i)
+ name = SceneNodeFactoryList[i]->getCreateableSceneNodeTypeName(type);
+
+ return name;
+}
+
+//! Adds a scene node to the scene by name
+ISceneNode* CSceneManager::addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent)
+{
+ ISceneNode* node = 0;
+
+ for (int i=(int)SceneNodeFactoryList.size()-1; i>=0 && !node; --i)
+ node = SceneNodeFactoryList[i]->addSceneNode(sceneNodeTypeName, parent);
+
+ return node;
+}
+
+
+//! Returns a typename from a scene node animator type or null if not found
+const c8* CSceneManager::getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) const
+{
+ const char* name = 0;
+
+ for (u32 i=0; !name && igetCreateableSceneNodeAnimatorTypeName(type);
+
+ return name;
+}
+
+
+//! Writes attributes of the scene node.
+void CSceneManager::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
+{
+ out->addString ("Name", Name.c_str());
+ out->addInt ("Id", ID );
+ out->addColorf ("AmbientLight", AmbientLight);
+}
+
+//! Reads attributes of the scene node.
+void CSceneManager::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
+{
+ Name = in->getAttributeAsString("Name");
+ ID = in->getAttributeAsInt("Id");
+ AmbientLight = in->getAttributeAsColorf("AmbientLight");
+
+ RelativeTranslation.set(0,0,0);
+ RelativeRotation.set(0,0,0);
+ RelativeScale.set(1,1,1);
+ IsVisible = true;
+ AutomaticCullingState = scene::EAC_BOX;
+ DebugDataVisible = scene::EDS_OFF;
+ IsDebugObject = false;
+
+ updateAbsolutePosition();
+}
+
+
+//! Sets ambient color of the scene
+void CSceneManager::setAmbientLight(const video::SColorf &ambientColor)
+{
+ AmbientLight = ambientColor;
+}
+
+
+//! Returns ambient color of the scene
+const video::SColorf& CSceneManager::getAmbientLight() const
+{
+ return AmbientLight;
+}
+
+
+//! Returns a mesh writer implementation if available
+IMeshWriter* CSceneManager::createMeshWriter(EMESH_WRITER_TYPE type)
+{
+ switch(type)
+ {
+ case EMWT_IRR_MESH:
+#ifdef _IRR_COMPILE_WITH_IRR_WRITER_
+ return new CIrrMeshWriter(Driver, FileSystem);
+#else
+ return 0;
+#endif
+ case EMWT_COLLADA:
+#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_
+ return new CColladaMeshWriter(Driver, FileSystem);
+#else
+ return 0;
+#endif
+ case EMWT_STL:
+#ifdef _IRR_COMPILE_WITH_STL_WRITER_
+ return new CSTLMeshWriter(this);
+#else
+ return 0;
+#endif
+ }
+
+ return 0;
+}
+
+
+// creates a scenemanager
+ISceneManager* createSceneManager(video::IVideoDriver* driver,
+ io::IFileSystem* fs, gui::ICursorControl* cursorcontrol,
+ gui::IGUIEnvironment *guiEnvironment)
+{
+ return new CSceneManager(driver, fs, cursorcontrol, 0, guiEnvironment );
+}
+
+
+} // end namespace scene
+} // end namespace irr
+
diff --git a/source/Irrlicht/CSceneManager.h b/source/Irrlicht/CSceneManager.h
index 3449e91d..79741072 100644
--- a/source/Irrlicht/CSceneManager.h
+++ b/source/Irrlicht/CSceneManager.h
@@ -50,6 +50,14 @@ namespace scene
virtual gui::IGUIEnvironment* getGUIEnvironment();
+ //! adds Volume Lighting Scene Node.
+ //! the returned pointer must not be dropped.
+ virtual ISceneNode* addVolumeLightSceneNode(ISceneNode* parent=0, s32 id=-1,
+ const s32 subdivU = 32, const s32 subdivV = 32,
+ const video::SColor foot = video::SColor(51, 0, 230, 180),
+ const video::SColor tail = video::SColor(0, 0, 0, 0),
+ const core::vector3df& position = core::vector3df(0,0,0), const core::vector3df& rotation = core::vector3df(0,0,0), const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f));
+
//! adds a cube scene node to the scene. It is a simple cube of (1,1,1) size.
//! the returned pointer must not be dropped.
virtual ISceneNode* addCubeSceneNode(f32 size=10.0f, ISceneNode* parent=0, s32 id=-1,
diff --git a/source/Irrlicht/CVolumeLightSceneNode.cpp b/source/Irrlicht/CVolumeLightSceneNode.cpp
new file mode 100644
index 00000000..2dc7a29d
--- /dev/null
+++ b/source/Irrlicht/CVolumeLightSceneNode.cpp
@@ -0,0 +1,301 @@
+// 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
+//
+// created by Dean Wadsworth aka Varmint Dec 31 2007
+
+#include "CVolumeLightSceneNode.h"
+#include "IVideoDriver.h"
+#include "ISceneManager.h"
+#include "S3DVertex.h"
+#include "os.h"
+
+namespace irr
+{
+namespace scene
+{
+
+//! constructor
+CVolumeLightSceneNode::CVolumeLightSceneNode(ISceneNode* parent, ISceneManager* mgr,
+ s32 id, const s32 subdivU, const s32 subdivV,
+ const video::SColor foot,
+ const video::SColor tail,
+ const core::vector3df& position,
+ const core::vector3df& rotation, const core::vector3df& scale)
+ : ISceneNode(parent, mgr, id, position, rotation, scale)
+{
+ #ifdef _DEBUG
+ setDebugName("CVolumeLightSceneNode");
+ #endif
+
+ video::IVideoDriver* driver = SceneManager->getVideoDriver();
+
+ lightDimensions = core::vector3df(1.0f, 1.2f, 1.0f);
+
+ mlpDistance = 8.0f;
+
+ mSubdivideU = subdivU;
+ mSubdivideV = subdivV;
+
+ //test light
+ mfootColour = foot;
+ mtailColour = tail;
+
+ Buffer = NULL;
+
+ constructLight();
+}
+
+
+//! destructor
+CVolumeLightSceneNode::~CVolumeLightSceneNode()
+{
+ if (Buffer)
+ Buffer->drop();
+}
+
+void CVolumeLightSceneNode::addToBuffer(video::S3DVertex v)
+{
+ s32 tnidx = Buffer->Vertices.linear_reverse_search(v);
+ bool alreadyIn = (tnidx != -1);
+ u16 nidx = (u16)tnidx;
+ if (!alreadyIn) {
+ nidx = Buffer->Vertices.size();
+ Buffer->Indices.push_back(nidx);
+ Buffer->Vertices.push_back(v);
+ } else
+ Buffer->Indices.push_back(nidx);
+
+}
+
+void CVolumeLightSceneNode::constructLight()
+{
+ core::vector3df lightPoint = core::vector3df(0, -(mlpDistance*lightDimensions.Y), 0);
+ f32 ax = lightDimensions.X / 2.0f; // X Axis
+ f32 az = lightDimensions.Z / 2.0f; // Z Axis
+
+ if (Buffer)
+ Buffer->drop();
+ Buffer = new SMeshBuffer();
+
+ //draw the bottom foot.. the glowing region
+ addToBuffer(video::S3DVertex(-ax, 0, az, 0,0,0, mfootColour, 0, 1));
+ addToBuffer(video::S3DVertex(ax , 0, az, 0,0,0, mfootColour, 1, 1));
+ addToBuffer(video::S3DVertex(ax , 0,-az, 0,0,0, mfootColour, 1, 0));
+
+ addToBuffer(video::S3DVertex(ax , 0,-az, 0,0,0, mfootColour, 1, 0));
+ addToBuffer(video::S3DVertex(-ax, 0,-az, 0,0,0, mfootColour, 0, 0));
+ addToBuffer(video::S3DVertex(-ax, 0, az, 0,0,0, mfootColour, 0, 1));
+
+ // Slices in X/U space
+ for(s32 i = 0; i <= mSubdivideU; i++) {
+ f32 k = ((f32)i) / mSubdivideU; // use for the texture coord
+ f32 bx = ((lightDimensions.X / (f32)mSubdivideU) * i) - ax;
+ //printf("bx: %f\n", bx);
+
+ // These are the two endpoints for a slice at the foot
+ core::vector3df end1(bx, 0.0f, -az);
+ core::vector3df end2(bx, 0.0f, az);
+
+ end1 -= lightPoint; // get a vector from point to lightsource
+ end1.normalize(); // normalize vector
+ end1 *= lightDimensions.Y; // multiply it out by shootlength
+
+ end1.X += bx; // Add the original point location to the vector
+ end1.Z -= az;
+
+ // Do it again for the other point.
+ end2 -= lightPoint;
+ end2.normalize();
+ end2 *= lightDimensions.Y;
+
+ end2.X += bx;
+ end2.Z += az;
+
+
+ addToBuffer(video::S3DVertex(bx , 0, az, 0,0,0, mfootColour, k, 1));
+ addToBuffer(video::S3DVertex(bx , 0, -az, 0,0,0, mfootColour, k, 0));
+ addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, mtailColour, k, 1));
+
+ addToBuffer(video::S3DVertex(bx , 0, -az, 0,0,0, mfootColour, k, 0));
+ addToBuffer(video::S3DVertex(end1.X , end1.Y, end1.Z, 0,0,0, mtailColour, k, 0));
+ addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, mtailColour, k, 1));
+
+ //back side
+ addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, mtailColour, k, 1));
+ addToBuffer(video::S3DVertex(-bx , 0, -az, 0,0,0, mfootColour, k, 1));
+ addToBuffer(video::S3DVertex(-bx , 0, az, 0,0,0, mfootColour, k, 0));
+
+ addToBuffer(video::S3DVertex(-bx , 0, az, 0,0,0, mfootColour, k, 0));
+ addToBuffer(video::S3DVertex(-end1.X , end1.Y, -end1.Z, 0,0,0, mtailColour, k, 0));
+ addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, mtailColour, k, 1));
+
+ }
+
+ // Slices in Z/V space
+ for(s32 i = 0; i <= mSubdivideV; i++) {
+ f32 k = ((f32)i) / mSubdivideV; // use for the texture coord
+ f32 bz = ((lightDimensions.Z / (f32)mSubdivideV) * i) - az;
+
+ // These are the two endpoints for a slice at the foot
+ core::vector3df end1(-ax, 0.0f, bz);
+ core::vector3df end2(ax, 0.0f, bz);
+
+ end1 -= lightPoint; // get a vector from point to lightsource
+ end1.normalize(); // normalize vector
+ end1 *= lightDimensions.Y; // multiply it out by shootlength
+
+ end1.X -= ax; // Add the original point location to the vector
+ end1.Z += bz;
+
+ // Do it again for the other point.
+ end2 -= lightPoint;
+ end2.normalize();
+ end2 *= lightDimensions.Y;
+
+ end2.X += ax;
+ end2.Z += bz;
+
+ addToBuffer(video::S3DVertex(-ax , 0, bz, 0,0,0, mfootColour, 0, k));
+ addToBuffer(video::S3DVertex(ax , 0, bz, 0,0,0, mfootColour, 1, k));
+ addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, mtailColour, 1, k));
+
+ addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, mtailColour, 1, k));
+ addToBuffer(video::S3DVertex(end1.X , end1.Y, end1.Z, 0,0,0, mtailColour, 0, k));
+ addToBuffer(video::S3DVertex(-ax , 0, bz, 0,0,0, mfootColour, 0, k));
+
+ //back side
+ addToBuffer(video::S3DVertex(ax , 0, -bz, 0,0,0, mfootColour, 0, k));
+ addToBuffer(video::S3DVertex(-ax , 0, -bz, 0,0,0, mfootColour, 1, k));
+ addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, mtailColour, 1, k));
+
+ addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, mtailColour, 1, k));
+ addToBuffer(video::S3DVertex(-end1.X , end1.Y, -end1.Z, 0,0,0, mtailColour, 0, k));
+ addToBuffer(video::S3DVertex(ax , 0, -bz, 0,0,0, mfootColour, 0, k));
+
+ }
+
+ Buffer->BoundingBox.reset(0,0,0);
+
+ Buffer->recalculateBoundingBox();
+
+ Buffer->Material.MaterialType = video::EMT_ONETEXTURE_BLEND;
+ Buffer->Material.MaterialTypeParam = pack_texureBlendFunc( video::EBF_SRC_COLOR, video::EBF_SRC_ALPHA, video::EMFN_MODULATE_1X );
+
+ Buffer->Material.Lighting = false;
+ Buffer->Material.ZWriteEnable = false;
+}
+
+//! renders the node.
+void CVolumeLightSceneNode::render()
+{
+ video::IVideoDriver* driver = SceneManager->getVideoDriver();
+ driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
+
+ driver->setMaterial(Buffer->Material);
+ driver->drawVertexPrimitiveList(
+ Buffer->getVertices(), Buffer->getVertexCount(),
+ Buffer->getIndices(), Buffer->getIndexCount() / 3 ,
+ Buffer->getVertexType(), EPT_TRIANGLES);
+}
+
+
+//! returns the axis aligned bounding box of this node
+const core::aabbox3d& CVolumeLightSceneNode::getBoundingBox() const
+{
+ return Buffer->BoundingBox;
+}
+
+
+void CVolumeLightSceneNode::OnRegisterSceneNode()
+{
+ if (IsVisible) {
+ //lie to sceneManager
+ Buffer->Material.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
+ Buffer->Material.MaterialTypeParam = 0.01f;
+ SceneManager->registerNodeForRendering(this, ESNRP_AUTOMATIC);
+
+ //restore state
+ Buffer->Material.MaterialType = video::EMT_ONETEXTURE_BLEND;
+ Buffer->Material.MaterialTypeParam = pack_texureBlendFunc( video::EBF_SRC_COLOR, video::EBF_SRC_ALPHA, video::EMFN_MODULATE_1X );
+ }
+ ISceneNode::OnRegisterSceneNode();
+}
+
+
+//! returns the material based on the zero based index i. To get the amount
+//! of materials used by this scene node, use getMaterialCount().
+//! This function is needed for inserting the node into the scene hirachy on a
+//! optimal position for minimizing renderstate changes, but can also be used
+//! to directly modify the material of a scene node.
+video::SMaterial& CVolumeLightSceneNode::getMaterial(u32 i)
+{
+ return Buffer->Material;
+}
+
+
+//! returns amount of materials used by this scene node.
+u32 CVolumeLightSceneNode::getMaterialCount() const
+{
+ return 1;
+}
+
+
+//! Writes attributes of the scene node.
+void CVolumeLightSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
+{
+ ISceneNode::serializeAttributes(out, options);
+
+ out->addFloat("lpDistance", mlpDistance);
+ out->addInt("subDivideU", mSubdivideU);
+ out->addInt("subDivideV", mSubdivideV);
+
+ out->addColor("footColour", mfootColour);
+ out->addColor("tailColour", mtailColour);
+
+ out->addVector3d("lightDimension", lightDimensions);
+}
+
+
+//! Reads attributes of the scene node.
+void CVolumeLightSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
+{
+ mlpDistance = in->getAttributeAsFloat("lpDistance");
+ mlpDistance = core::max_(mlpDistance, 8.0f);
+
+ mSubdivideU = in->getAttributeAsInt("subDivideU");
+ mSubdivideU = core::max_(mSubdivideU, 1);
+
+ mSubdivideV = in->getAttributeAsInt("subDivideV");
+ mSubdivideV = core::max_(mSubdivideV, 1);
+
+ mfootColour = in->getAttributeAsColor("footColour");
+ mtailColour = in->getAttributeAsColor("tailColour");
+
+ lightDimensions = in->getAttributeAsVector3d("lightDimension");
+
+ constructLight();
+
+ ISceneNode::deserializeAttributes(in, options);
+}
+
+
+//! Creates a clone of this scene node and its children.
+ISceneNode* CVolumeLightSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
+{
+ if (!newParent) newParent = Parent;
+ if (!newManager) newManager = SceneManager;
+
+ CVolumeLightSceneNode* nb = new CVolumeLightSceneNode(newParent,
+ newManager, ID, mSubdivideU, mSubdivideV, mfootColour, mtailColour, RelativeTranslation);
+
+ nb->cloneMembers(this, newManager);
+ nb->Buffer->Material = Buffer->Material;
+
+ nb->drop();
+ return nb;
+}
+
+
+} // end namespace scene
+} // end namespace irr
diff --git a/source/Irrlicht/CVolumeLightSceneNode.h b/source/Irrlicht/CVolumeLightSceneNode.h
new file mode 100644
index 00000000..e8da5d0b
--- /dev/null
+++ b/source/Irrlicht/CVolumeLightSceneNode.h
@@ -0,0 +1,98 @@
+// 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
+//
+// created by Dean Wadsworth aka Varmint Dec 31 2007
+
+#ifndef __VOLUME_LIGHT_SCENE_NODE_H_INCLUDED__
+#define __VOLUME_LIGHT_SCENE_NODE_H_INCLUDED__
+
+#include "ISceneNode.h"
+#include "SMeshBuffer.h"
+
+namespace irr
+{
+namespace scene
+{
+ class CVolumeLightSceneNode : public ISceneNode
+ {
+ public:
+
+ //! constructor
+ CVolumeLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
+ const s32 subdivU = 32, const s32 subdivV = 32,
+ const video::SColor foot = video::SColor(51, 0, 230, 180),
+ const video::SColor tail = video::SColor(0, 0, 0, 0),
+ const core::vector3df& position = core::vector3df(0,0,0),
+ const core::vector3df& rotation = core::vector3df(0,0,0),
+ const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f));
+
+ //! destructor
+ virtual ~CVolumeLightSceneNode();
+
+ virtual void OnRegisterSceneNode();
+
+ //! renders the node.
+ virtual void render();
+
+ //! returns the axis aligned bounding box of this node
+ virtual const core::aabbox3d& getBoundingBox() const;
+
+ //! returns the material based on the zero based index i. To get the amount
+ //! of materials used by this scene node, use getMaterialCount().
+ //! This function is needed for inserting the node into the scene hirachy on a
+ //! optimal position for minimizing renderstate changes, but can also be used
+ //! to directly modify the material of a scene node.
+ virtual video::SMaterial& getMaterial(u32 i);
+
+ //! returns amount of materials used by this scene node.
+ virtual u32 getMaterialCount() const;
+
+ //! Returns type of the scene node
+ virtual ESCENE_NODE_TYPE getType() const { return ESNT_CUBE; }
+
+ //! Writes attributes of the scene node.
+ virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const;
+
+ //! Reads attributes of the scene node.
+ virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0);
+
+ //! Creates a clone of this scene node and its children.
+ virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0);
+
+ void setSubDivideU (const s32 inU) { mSubdivideU = inU; }
+ void setSubDivideV (const s32 inV) { mSubdivideV = inV; }
+
+ s32 getSubDivideU () const { return mSubdivideU; }
+ s32 getSubDivideV () const { return mSubdivideV; }
+
+ void setFootColour(const video::SColor inColouf) { mfootColour = inColouf; }
+ void setTailColour(const video::SColor inColouf) { mtailColour = inColouf; }
+
+ video::SColor getFootColour () const { return mfootColour; }
+ video::SColor getTailColour () const { return mtailColour; }
+
+ private:
+ void addToBuffer(video::S3DVertex v);
+ void constructLight();
+
+ SMeshBuffer * Buffer;
+
+ f32 mlpDistance; // Distance to hypothetical lightsource point -- affects fov angle
+
+ s32 mSubdivideU; // Number of subdivisions in U and V space.
+ s32 mSubdivideV; // Controls the number of "slices" in the volume.
+ // NOTE : Total number of polygons = 2 + ((mSubdiveU + 1) + (mSubdivideV + 1)) * 2
+ // Each slice being a quad plus the rectangular plane at the bottom.
+
+ video::SColor mfootColour; // Color at the source
+ video::SColor mtailColour; // Color at the end.
+
+ core::vector3df lightDimensions; // lightDimensions.Y Distance of shooting -- Length of beams
+ // lightDimensions.X and lightDimensions.Z determine the size/dimension of the plane
+ };
+
+} // end namespace scene
+} // end namespace irr
+
+#endif
diff --git a/source/Irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj b/source/Irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj
index 545b3eb0..a319dcb3 100644
--- a/source/Irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj
+++ b/source/Irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj
@@ -36,6 +36,8 @@
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
+ 090FBC820D31085E0076D847 /* CVolumeLightSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 090FBC800D31085E0076D847 /* CVolumeLightSceneNode.cpp */; };
+ 090FBC830D31085E0076D847 /* CVolumeLightSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 090FBC810D31085E0076D847 /* CVolumeLightSceneNode.h */; };
0910B9DE0D1F5D4100D46B04 /* CBurningShader_Raster_Reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0910B9D90D1F5D4100D46B04 /* CBurningShader_Raster_Reference.cpp */; };
0910B9DF0D1F5D4100D46B04 /* CGUITable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0910B9DA0D1F5D4100D46B04 /* CGUITable.cpp */; };
0910B9E00D1F5D4100D46B04 /* CGUITable.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910B9DB0D1F5D4100D46B04 /* CGUITable.h */; };
@@ -721,6 +723,8 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 090FBC800D31085E0076D847 /* CVolumeLightSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CVolumeLightSceneNode.cpp; sourceTree = ""; };
+ 090FBC810D31085E0076D847 /* CVolumeLightSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CVolumeLightSceneNode.h; sourceTree = ""; };
0910B9D90D1F5D4100D46B04 /* CBurningShader_Raster_Reference.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CBurningShader_Raster_Reference.cpp; sourceTree = ""; };
0910B9DA0D1F5D4100D46B04 /* CGUITable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUITable.cpp; sourceTree = ""; };
0910B9DB0D1F5D4100D46B04 /* CGUITable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUITable.h; sourceTree = ""; };
@@ -1155,7 +1159,7 @@
4C53E18D0A484C2C0014E966 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = uncompr.c; sourceTree = ""; };
4C53E1920A484C2C0014E966 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = zutil.c; sourceTree = ""; };
4C53E24D0A4850120014E966 /* libIrrlicht.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIrrlicht.a; sourceTree = BUILT_PRODUCTS_DIR; };
- 4C53E2520A4850550014E966 /* Quake3Map_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Quake3Map_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4C53E2520A4850550014E966 /* Quake3Map.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Quake3Map.app; sourceTree = BUILT_PRODUCTS_DIR; };
4C53E26D0A4850D60014E966 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; };
4C53E26E0A4850D60014E966 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; };
4C53E38E0A4855BA0014E966 /* DemoApp-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = "DemoApp-Info.plist"; sourceTree = ""; };
@@ -1219,18 +1223,18 @@
4C53E76F0A485CD90014E966 /* wrrle.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = wrrle.c; sourceTree = ""; };
4C53E7700A485CD90014E966 /* wrtarga.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = wrtarga.c; sourceTree = ""; };
4C6DC9B60A48715A0017A6E5 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = inflate.c; sourceTree = ""; };
- 4CA25B980A485D9800B4E469 /* CustomSceneNode_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CustomSceneNode_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25B9A0A485D9800B4E469 /* MeshViewer_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeshViewer_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25B9C0A485D9800B4E469 /* RenderToTexture_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RenderToTexture_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25B9E0A485D9800B4E469 /* UserInterface_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UserInterface_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25BA00A485D9800B4E469 /* PerPixelLighting_dbg.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = PerPixelLighting_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25BA20A485D9800B4E469 /* Demo_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25BA40A485D9800B4E469 /* Movement_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Movement_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25BA60A485D9800B4E469 /* Shaders_dbg.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Shaders_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25BA80A485D9800B4E469 /* SpecialFx_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpecialFx_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25BAA0A485D9800B4E469 /* TerrainRendering_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TerrainRendering_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25BAC0A485D9800B4E469 /* 2DGraphics_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2DGraphics_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4CA25BAE0A485D9800B4E469 /* Collision_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Collision_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25B980A485D9800B4E469 /* CustomSceneNode.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CustomSceneNode.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25B9A0A485D9800B4E469 /* MeshViewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeshViewer.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25B9C0A485D9800B4E469 /* RenderToTexture.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RenderToTexture.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25B9E0A485D9800B4E469 /* UserInterface.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UserInterface.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25BA00A485D9800B4E469 /* PerPixelLighting.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PerPixelLighting.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25BA20A485D9800B4E469 /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25BA40A485D9800B4E469 /* Movement.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Movement.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25BA60A485D9800B4E469 /* Shaders.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Shaders.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25BA80A485D9800B4E469 /* SpecialFx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpecialFx.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25BAA0A485D9800B4E469 /* TerrainRendering.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TerrainRendering.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25BAC0A485D9800B4E469 /* 2DGraphics.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2DGraphics.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4CA25BAE0A485D9800B4E469 /* Collision.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Collision.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CC36B0D0A6B61DB0076C4B2 /* CSphereSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSphereSceneNode.cpp; sourceTree = ""; };
4CC36B0E0A6B61DB0076C4B2 /* CSphereSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSphereSceneNode.h; sourceTree = ""; };
4CFA7BDC0A88735900B03626 /* CImageLoaderBMP.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CImageLoaderBMP.cpp; sourceTree = ""; };
@@ -2042,6 +2046,8 @@
4C53DFCB0A484C240014E966 /* CTerrainSceneNode.h */,
4C53DFCE0A484C240014E966 /* CTextSceneNode.cpp */,
4C53DFCF0A484C240014E966 /* CTextSceneNode.h */,
+ 090FBC800D31085E0076D847 /* CVolumeLightSceneNode.cpp */,
+ 090FBC810D31085E0076D847 /* CVolumeLightSceneNode.h */,
4C53DFF00A484C250014E966 /* CWaterSurfaceSceneNode.cpp */,
4C53DFF10A484C250014E966 /* CWaterSurfaceSceneNode.h */,
);
@@ -2588,19 +2594,19 @@
isa = PBXGroup;
children = (
4C53E24D0A4850120014E966 /* libIrrlicht.a */,
- 4C53E2520A4850550014E966 /* Quake3Map_dbg.app */,
- 4CA25B980A485D9800B4E469 /* CustomSceneNode_dbg.app */,
- 4CA25BA40A485D9800B4E469 /* Movement_dbg.app */,
- 4CA25B9E0A485D9800B4E469 /* UserInterface_dbg.app */,
- 4CA25BAC0A485D9800B4E469 /* 2DGraphics_dbg.app */,
- 4CA25BAE0A485D9800B4E469 /* Collision_dbg.app */,
- 4CA25BA80A485D9800B4E469 /* SpecialFx_dbg.app */,
- 4CA25B9A0A485D9800B4E469 /* MeshViewer_dbg.app */,
- 4CA25BA60A485D9800B4E469 /* Shaders_dbg.app */,
- 4CA25BA00A485D9800B4E469 /* PerPixelLighting_dbg.app */,
- 4CA25B9C0A485D9800B4E469 /* RenderToTexture_dbg.app */,
- 4CA25BAA0A485D9800B4E469 /* TerrainRendering_dbg.app */,
- 4CA25BA20A485D9800B4E469 /* Demo_dbg.app */,
+ 4C53E2520A4850550014E966 /* Quake3Map.app */,
+ 4CA25B980A485D9800B4E469 /* CustomSceneNode.app */,
+ 4CA25BA40A485D9800B4E469 /* Movement.app */,
+ 4CA25B9E0A485D9800B4E469 /* UserInterface.app */,
+ 4CA25BAC0A485D9800B4E469 /* 2DGraphics.app */,
+ 4CA25BAE0A485D9800B4E469 /* Collision.app */,
+ 4CA25BA80A485D9800B4E469 /* SpecialFx.app */,
+ 4CA25B9A0A485D9800B4E469 /* MeshViewer.app */,
+ 4CA25BA60A485D9800B4E469 /* Shaders.app */,
+ 4CA25BA00A485D9800B4E469 /* PerPixelLighting.app */,
+ 4CA25B9C0A485D9800B4E469 /* RenderToTexture.app */,
+ 4CA25BAA0A485D9800B4E469 /* TerrainRendering.app */,
+ 4CA25BA20A485D9800B4E469 /* Demo.app */,
09F6493E0D2CE03E001E0599 /* LoadIrrFile.app */,
09F649650D2CE206001E0599 /* Quake3Shader.app */,
09F649030D2CDED9001E0599 /* HelloWorld.app */,
@@ -2753,6 +2759,7 @@
0910BA480D1F64B300D46B04 /* SSharedMeshBuffer.h in Headers */,
0910BA490D1F64B300D46B04 /* SSkinMeshBuffer.h in Headers */,
0910BA4A0D1F64B300D46B04 /* SViewFrustum.h in Headers */,
+ 090FBC830D31085E0076D847 /* CVolumeLightSceneNode.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2828,7 +2835,7 @@
);
name = 2DGraphics;
productName = DemoApp;
- productReference = 4CA25BAC0A485D9800B4E469 /* 2DGraphics_dbg.app */;
+ productReference = 4CA25BAC0A485D9800B4E469 /* 2DGraphics.app */;
productType = "com.apple.product-type.application";
};
B81CFE82097FDDE20057C06F /* Collision */ = {
@@ -2846,7 +2853,7 @@
);
name = Collision;
productName = DemoApp;
- productReference = 4CA25BAE0A485D9800B4E469 /* Collision_dbg.app */;
+ productReference = 4CA25BAE0A485D9800B4E469 /* Collision.app */;
productType = "com.apple.product-type.application";
};
B81CFEA4097FDE900057C06F /* PerPixelLightning */ = {
@@ -2864,7 +2871,7 @@
);
name = PerPixelLightning;
productName = DemoApp;
- productReference = 4CA25BA00A485D9800B4E469 /* PerPixelLighting_dbg.app */;
+ productReference = 4CA25BA00A485D9800B4E469 /* PerPixelLighting.app */;
productType = "com.apple.product-type.application";
};
B81CFEC2097FDF020057C06F /* TerrainRendering */ = {
@@ -2882,7 +2889,7 @@
);
name = TerrainRendering;
productName = DemoApp;
- productReference = 4CA25BAA0A485D9800B4E469 /* TerrainRendering_dbg.app */;
+ productReference = 4CA25BAA0A485D9800B4E469 /* TerrainRendering.app */;
productType = "com.apple.product-type.application";
};
B81CFEE8097FE05F0057C06F /* SpecialFx */ = {
@@ -2900,7 +2907,7 @@
);
name = SpecialFx;
productName = DemoApp;
- productReference = 4CA25BA80A485D9800B4E469 /* SpecialFx_dbg.app */;
+ productReference = 4CA25BA80A485D9800B4E469 /* SpecialFx.app */;
productType = "com.apple.product-type.application";
};
B81CFF07097FE13E0057C06F /* UserInterface */ = {
@@ -2918,7 +2925,7 @@
);
name = UserInterface;
productName = DemoApp;
- productReference = 4CA25B9E0A485D9800B4E469 /* UserInterface_dbg.app */;
+ productReference = 4CA25B9E0A485D9800B4E469 /* UserInterface.app */;
productType = "com.apple.product-type.application";
};
B81CFF1E097FE1E00057C06F /* CustomSceneNode */ = {
@@ -2936,7 +2943,7 @@
);
name = CustomSceneNode;
productName = DemoApp;
- productReference = 4CA25B980A485D9800B4E469 /* CustomSceneNode_dbg.app */;
+ productReference = 4CA25B980A485D9800B4E469 /* CustomSceneNode.app */;
productType = "com.apple.product-type.application";
};
B81CFF33097FE25F0057C06F /* Quake3Map */ = {
@@ -2954,7 +2961,7 @@
);
name = Quake3Map;
productName = DemoApp;
- productReference = 4C53E2520A4850550014E966 /* Quake3Map_dbg.app */;
+ productReference = 4C53E2520A4850550014E966 /* Quake3Map.app */;
productType = "com.apple.product-type.application";
};
B81CFF4A097FE3050057C06F /* Shaders */ = {
@@ -2972,7 +2979,7 @@
);
name = Shaders;
productName = DemoApp;
- productReference = 4CA25BA60A485D9800B4E469 /* Shaders_dbg.app */;
+ productReference = 4CA25BA60A485D9800B4E469 /* Shaders.app */;
productType = "com.apple.product-type.application";
};
B81CFF78097FE3DC0057C06F /* Movement */ = {
@@ -2990,7 +2997,7 @@
);
name = Movement;
productName = DemoApp;
- productReference = 4CA25BA40A485D9800B4E469 /* Movement_dbg.app */;
+ productReference = 4CA25BA40A485D9800B4E469 /* Movement.app */;
productType = "com.apple.product-type.application";
};
B81CFF91097FE45E0057C06F /* MeshViewer */ = {
@@ -3008,7 +3015,7 @@
);
name = MeshViewer;
productName = DemoApp;
- productReference = 4CA25B9A0A485D9800B4E469 /* MeshViewer_dbg.app */;
+ productReference = 4CA25B9A0A485D9800B4E469 /* MeshViewer.app */;
productType = "com.apple.product-type.application";
};
B81CFFAF097FE5F80057C06F /* RenderToTexture */ = {
@@ -3026,7 +3033,7 @@
);
name = RenderToTexture;
productName = DemoApp;
- productReference = 4CA25B9C0A485D9800B4E469 /* RenderToTexture_dbg.app */;
+ productReference = 4CA25B9C0A485D9800B4E469 /* RenderToTexture.app */;
productType = "com.apple.product-type.application";
};
B8DEF35C0950229200FDEA7E /* Demo */ = {
@@ -3044,7 +3051,7 @@
);
name = Demo;
productName = DemoApp;
- productReference = 4CA25BA20A485D9800B4E469 /* Demo_dbg.app */;
+ productReference = 4CA25BA20A485D9800B4E469 /* Demo.app */;
productType = "com.apple.product-type.application";
};
D2AAC07D0554694100DB518D /* libIrrlicht.a */ = {
@@ -3663,6 +3670,7 @@
0910B9DE0D1F5D4100D46B04 /* CBurningShader_Raster_Reference.cpp in Sources */,
0910B9DF0D1F5D4100D46B04 /* CGUITable.cpp in Sources */,
0910B9E10D1F5D4100D46B04 /* CImageLoaderWAL.cpp in Sources */,
+ 090FBC820D31085E0076D847 /* CVolumeLightSceneNode.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};