mirror of
https://github.com/minetest/irrlicht.git
synced 2024-11-11 21:00:35 +01:00
254 lines
20 KiB
HTML
254 lines
20 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||
|
<title>Irrlicht 3D Engine: Tutorial 15: Loading Scenes from .irr Files</title>
|
||
|
|
||
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||
|
<link href="navtree.css" rel="stylesheet" type="text/css"/>
|
||
|
<script type="text/javascript" src="jquery.js"></script>
|
||
|
<script type="text/javascript" src="resize.js"></script>
|
||
|
<script type="text/javascript" src="navtree.js"></script>
|
||
|
<script type="text/javascript">
|
||
|
$(document).ready(initResizable);
|
||
|
</script>
|
||
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||
|
<script type="text/javascript" src="search/search.js"></script>
|
||
|
<script type="text/javascript">
|
||
|
$(document).ready(function() { searchBox.OnSelectItem(0); });
|
||
|
</script>
|
||
|
|
||
|
</head>
|
||
|
<body>
|
||
|
<div id="top"><!-- do not remove this div! -->
|
||
|
|
||
|
|
||
|
<div id="titlearea">
|
||
|
<table cellspacing="0" cellpadding="0">
|
||
|
<tbody>
|
||
|
<tr style="height: 56px;">
|
||
|
|
||
|
<td id="projectlogo"><img alt="Logo" src="irrlichtlogo.png"/></td>
|
||
|
|
||
|
|
||
|
<td style="padding-left: 0.5em;">
|
||
|
<div id="projectname">Irrlicht 3D Engine
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</td>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<td> <div id="MSearchBox" class="MSearchBoxInactive">
|
||
|
<span class="left">
|
||
|
<img id="MSearchSelect" src="search/mag_sel.png"
|
||
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
||
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
||
|
alt=""/>
|
||
|
<input type="text" id="MSearchField" value="Search" accesskey="S"
|
||
|
onfocus="searchBox.OnSearchFieldFocus(true)"
|
||
|
onblur="searchBox.OnSearchFieldFocus(false)"
|
||
|
onkeyup="searchBox.OnSearchFieldChange(event)"/>
|
||
|
</span><span class="right">
|
||
|
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
|
||
|
</span>
|
||
|
</div>
|
||
|
</td>
|
||
|
|
||
|
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</div>
|
||
|
|
||
|
<!-- Generated by Doxygen 1.7.5.1 -->
|
||
|
<script type="text/javascript">
|
||
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
||
|
</script>
|
||
|
<script type="text/javascript" src="dynsections.js"></script>
|
||
|
</div>
|
||
|
<div id="side-nav" class="ui-resizable side-nav-resizable">
|
||
|
<div id="nav-tree">
|
||
|
<div id="nav-tree-contents">
|
||
|
</div>
|
||
|
</div>
|
||
|
<div id="splitbar" style="-moz-user-select:none;"
|
||
|
class="ui-resizable-handle">
|
||
|
</div>
|
||
|
</div>
|
||
|
<script type="text/javascript">
|
||
|
initNavTree('example015.html','');
|
||
|
</script>
|
||
|
<div id="doc-content">
|
||
|
<div class="header">
|
||
|
<div class="headertitle">
|
||
|
<div class="title">Tutorial 15: Loading Scenes from .irr Files </div> </div>
|
||
|
</div>
|
||
|
<div class="contents">
|
||
|
<div class="textblock"><div class="image">
|
||
|
<img src="015shot.jpg" alt="015shot.jpg"/>
|
||
|
</div>
|
||
|
<p>Since version 1.1, Irrlicht is able to save and load the full scene graph into an .irr file, an xml based format. There is an editor available to edit those files, named irrEdit (<a href="http://www.ambiera.com/irredit">http://www.ambiera.com/irredit</a>) which can also be used as world and particle editor. This tutorial shows how to use .irr files.</p>
|
||
|
<p>Lets start: Create an Irrlicht device and setup the window. </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include <<a class="code" href="irrlicht_8h.html" title="Main header file of the irrlicht, the only file needed to include.">irrlicht.h</a>></span>
|
||
|
<span class="preprocessor">#include "<a class="code" href="driver_choice_8h.html">driverChoice.h</a>"</span>
|
||
|
|
||
|
<span class="keyword">using namespace </span>irr;
|
||
|
|
||
|
<span class="preprocessor">#ifdef _MSC_VER</span>
|
||
|
<span class="preprocessor"></span><span class="preprocessor">#pragma comment(lib, "Irrlicht.lib")</span>
|
||
|
<span class="preprocessor"></span><span class="preprocessor">#endif</span>
|
||
|
<span class="preprocessor"></span>
|
||
|
<span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>** argv)
|
||
|
{
|
||
|
<span class="comment">// ask user for driver</span>
|
||
|
<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0" title="An enum for all types of drivers the Irrlicht Engine supports.">video::E_DRIVER_TYPE</a> driverType=driverChoiceConsole();
|
||
|
<span class="keywordflow">if</span> (driverType==<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0ae685cada50f8c100403134d932d0414c" title="No driver, just for counting the elements.">video::EDT_COUNT</a>)
|
||
|
<span class="keywordflow">return</span> 1;
|
||
|
|
||
|
<span class="comment">// create device and exit if creation failed</span>
|
||
|
|
||
|
<a class="code" href="classirr_1_1_irrlicht_device.html" title="The Irrlicht device. You can create it with createDevice() or createDeviceEx().">IrrlichtDevice</a>* device =
|
||
|
<a class="code" href="namespaceirr.html#abaf4d8719cc26b0d30813abf85e47c76" title="Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.">createDevice</a>(driverType, <a class="code" href="classirr_1_1core_1_1dimension2d.html">core::dimension2d<u32></a>(640, 480));
|
||
|
|
||
|
<span class="keywordflow">if</span> (device == 0)
|
||
|
<span class="keywordflow">return</span> 1; <span class="comment">// could not create selected driver.</span>
|
||
|
|
||
|
device-><a class="code" href="classirr_1_1_irrlicht_device.html#a3d7c98d520bf18ce1973c6f1439a7c0f" title="Sets the caption of the window.">setWindowCaption</a>(L<span class="stringliteral">"Load .irr file example"</span>);
|
||
|
|
||
|
<a class="code" href="classirr_1_1video_1_1_i_video_driver.html" title="Interface to driver which is able to perform 2d and 3d graphics functions.">video::IVideoDriver</a>* driver = device-><a class="code" href="classirr_1_1_irrlicht_device.html#ada90707ba5c645d47e000e4e0f87c4c4" title="Provides access to the video driver for drawing 3d and 2d geometry.">getVideoDriver</a>();
|
||
|
<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html" title="The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff.">scene::ISceneManager</a>* smgr = device-><a class="code" href="classirr_1_1_irrlicht_device.html#a891b503ff4d5041296d88f23f97d7b3d" title="Provides access to the scene manager.">getSceneManager</a>();
|
||
|
</pre></div><p>Now load our .irr file. .irr files can store the whole scene graph including animators, materials and particle systems. And there is also the possibility to store arbitrary user data for every scene node in that file. To keep this example simple, we are simply loading the scene here. See the documentation at ISceneManager::loadScene and ISceneManager::saveScene for more information. So to load and display a complicated huge scene, we only need a single call to loadScene(). </p>
|
||
|
<div class="fragment"><pre class="fragment"> <span class="comment">// load the scene</span>
|
||
|
<span class="keywordflow">if</span> (argc>1)
|
||
|
smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#aa7641dd33e84fca7946ed17047349a3e" title="Loads a scene. Note that the current scene is not cleared before.">loadScene</a>(argv[1]);
|
||
|
<span class="keywordflow">else</span>
|
||
|
smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#aa7641dd33e84fca7946ed17047349a3e" title="Loads a scene. Note that the current scene is not cleared before.">loadScene</a>(<span class="stringliteral">"../../media/example.irr"</span>);
|
||
|
</pre></div><p>Now we'll create a camera, and give it a collision response animator that's built from the mesh nodes in the scene we just loaded. </p>
|
||
|
<div class="fragment"><pre class="fragment"> scene::ICameraSceneNode * camera = smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#ac312cbc85161678d00192880f2cdddbb" title="Adds a camera scene node with an animator which provides mouse and keyboard control appropriate for f...">addCameraSceneNodeFPS</a>(0, 50.f, 0.1f);
|
||
|
|
||
|
<span class="comment">// Create a meta triangle selector to hold several triangle selectors.</span>
|
||
|
scene::IMetaTriangleSelector * meta = smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#aee99e59dc55fe9f8c3507df68f84a9ff" title="Creates a meta triangle selector.">createMetaTriangleSelector</a>();
|
||
|
</pre></div><p>Now we will find all the nodes in the scene and create triangle selectors for all suitable nodes. Typically, you would want to make a more informed decision about which nodes to performs collision checks on; you could capture that information in the node name or Id. </p>
|
||
|
<div class="fragment"><pre class="fragment"> core::array<scene::ISceneNode *> nodes;
|
||
|
smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a9afcad318b725b5f95e19c839145d3d6" title="Get scene nodes by type.">getSceneNodesFromType</a>(<a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bdaa61d9ba5a5ec51a33600f83fb8bd71f5" title="Will match with any scene node when checking types.">scene::ESNT_ANY</a>, nodes); <span class="comment">// Find all nodes</span>
|
||
|
|
||
|
<span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0; i < nodes.size(); ++i)
|
||
|
{
|
||
|
scene::ISceneNode * node = nodes[i];
|
||
|
scene::ITriangleSelector * selector = 0;
|
||
|
|
||
|
<span class="keywordflow">switch</span>(node->getType())
|
||
|
{
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bda44d66f5c284aed4d0698d6854b6a72e3" title="simple cube scene node">scene::ESNT_CUBE</a>:
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bda073d7fe9dfd49f24cb13bfae56d8d3b6" title="Animated Mesh Scene Node.">scene::ESNT_ANIMATED_MESH</a>:
|
||
|
<span class="comment">// Because the selector won't animate with the mesh,</span>
|
||
|
<span class="comment">// and is only being used for camera collision, we'll just use an approximate</span>
|
||
|
<span class="comment">// bounding box instead of ((scene::IAnimatedMeshSceneNode*)node)->getMesh(0)</span>
|
||
|
selector = smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#adb717113b4203e92f2bd95c84488059c" title="Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box.">createTriangleSelectorFromBoundingBox</a>(node);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bda25998267ed8640ca0c432df23f1b71fe" title="Mesh Scene Node.">scene::ESNT_MESH</a>:
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bda46ad007c8d7d278a6a3769714c5dacdb" title="Sphere scene node.">scene::ESNT_SPHERE</a>: <span class="comment">// Derived from IMeshSceneNode</span>
|
||
|
selector = smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a266625379b1558e9be1dc062ea4e71f7" title="Creates a simple ITriangleSelector, based on a mesh.">createTriangleSelector</a>(((scene::IMeshSceneNode*)node)->getMesh(), node);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bda699880de1c55e8ed4ae24b0e07df972a" title="Terrain Scene Node.">scene::ESNT_TERRAIN</a>:
|
||
|
selector = smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#af52f8c74e08637b7643d239542371bc5" title="Creates a triangle selector which can select triangles from a terrain scene node.">createTerrainTriangleSelector</a>((scene::ITerrainSceneNode*)node);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bda1cbab0e001b2df07ef2a253434532a52" title="Octree Scene Node.">scene::ESNT_OCTREE</a>:
|
||
|
selector = smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a4ed7d3b34f4d0c70395b6d464fe32b96" title="Creates a Triangle Selector, optimized by an octree.">createOctreeTriangleSelector</a>(((scene::IMeshSceneNode*)node)->getMesh(), node);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
|
||
|
<span class="keywordflow">default</span>:
|
||
|
<span class="comment">// Don't create a selector for this node type</span>
|
||
|
<span class="keywordflow">break</span>;
|
||
|
}
|
||
|
|
||
|
<span class="keywordflow">if</span>(selector)
|
||
|
{
|
||
|
<span class="comment">// Add it to the meta selector, which will take a reference to it</span>
|
||
|
meta->addTriangleSelector(selector);
|
||
|
<span class="comment">// And drop my reference to it, so that the meta selector owns it.</span>
|
||
|
selector->drop();
|
||
|
}
|
||
|
}
|
||
|
</pre></div><p>Now that the mesh scene nodes have had triangle selectors created and added to the meta selector, create a collision response animator from that meta selector. </p>
|
||
|
<div class="fragment"><pre class="fragment"> scene::ISceneNodeAnimator* anim = smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a67b266cc40ebd66b5d21c26a78f002be" title="Creates a special scene node animator for doing automatic collision detection and response...">createCollisionResponseAnimator</a>(
|
||
|
meta, camera, <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(5,5,5),
|
||
|
<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,0,0));
|
||
|
meta->drop(); <span class="comment">// I'm done with the meta selector now</span>
|
||
|
|
||
|
camera->addAnimator(anim);
|
||
|
anim->drop(); <span class="comment">// I'm done with the animator now</span>
|
||
|
|
||
|
<span class="comment">// And set the camera position so that it doesn't start off stuck in the geometry</span>
|
||
|
camera->setPosition(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0.f, 20.f, 0.f));
|
||
|
|
||
|
<span class="comment">// Point the camera at the cube node, by finding the first node of type ESNT_CUBE</span>
|
||
|
scene::ISceneNode * cube = smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a5ab8e8f8cc8456a3ea881c75dfe505bb" title="Get the first scene node with the specified type.">getSceneNodeFromType</a>(<a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bda44d66f5c284aed4d0698d6854b6a72e3" title="simple cube scene node">scene::ESNT_CUBE</a>);
|
||
|
<span class="keywordflow">if</span>(cube)
|
||
|
camera->setTarget(cube->getAbsolutePosition());
|
||
|
</pre></div><p>That's it. Draw everything and finish as usual. </p>
|
||
|
<div class="fragment"><pre class="fragment"> <span class="keywordtype">int</span> lastFPS = -1;
|
||
|
|
||
|
<span class="keywordflow">while</span>(device-><a class="code" href="classirr_1_1_irrlicht_device.html#a0489f8151dc43f6f41503ffb5a160b35" title="Runs the device.">run</a>())
|
||
|
<span class="keywordflow">if</span> (device-><a class="code" href="classirr_1_1_irrlicht_device.html#abd3c88336b739da2694883d5ffd25a70" title="Returns if the window is active.">isWindowActive</a>())
|
||
|
{
|
||
|
driver-><a class="code" href="classirr_1_1video_1_1_i_video_driver.html#a015b8f2f18c260a00a858181be1e9945" title="Applications must call this method before performing any rendering.">beginScene</a>(<span class="keyword">true</span>, <span class="keyword">true</span>, video::SColor(0,200,200,200));
|
||
|
smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a04240262904667c821bd9de5e5fd9b02" title="Draws all the scene nodes.">drawAll</a>();
|
||
|
driver-><a class="code" href="classirr_1_1video_1_1_i_video_driver.html#a75f61a93c5fc9fdf161c044d27bc994e" title="Presents the rendered image to the screen.">endScene</a>();
|
||
|
|
||
|
<span class="keywordtype">int</span> fps = driver-><a class="code" href="classirr_1_1video_1_1_i_video_driver.html#a5b71428402c0b6a3b18b8f2fa408af13" title="Returns current frames per second value.">getFPS</a>();
|
||
|
|
||
|
<span class="keywordflow">if</span> (lastFPS != fps)
|
||
|
{
|
||
|
<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a> str = L<span class="stringliteral">"Load Irrlicht File example - Irrlicht Engine ["</span>;
|
||
|
str += driver-><a class="code" href="classirr_1_1video_1_1_i_video_driver.html#a87ca51832295b2dceaa1e258daf863f1" title="Gets name of this video driver.">getName</a>();
|
||
|
str += <span class="stringliteral">"] FPS:"</span>;
|
||
|
str += fps;
|
||
|
|
||
|
device-><a class="code" href="classirr_1_1_irrlicht_device.html#a3d7c98d520bf18ce1973c6f1439a7c0f" title="Sets the caption of the window.">setWindowCaption</a>(str.c_str());
|
||
|
lastFPS = fps;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
device-><a class="code" href="classirr_1_1_i_reference_counted.html#afb169a857e0d2cdb96b8821cb9bff17a" title="Drops the object. Decrements the reference counter by one.">drop</a>();
|
||
|
|
||
|
<span class="keywordflow">return</span> 0;
|
||
|
}
|
||
|
</pre></div> </div></div>
|
||
|
</div>
|
||
|
<div id="nav-path" class="navpath">
|
||
|
<ul>
|
||
|
<!-- window showing the filter options -->
|
||
|
<div id="MSearchSelectWindow"
|
||
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
||
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
||
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
||
|
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark"> </span>Friends</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark"> </span>Defines</a></div>
|
||
|
|
||
|
<!-- iframe showing the search results (closed by default) -->
|
||
|
<div id="MSearchResultsWindow">
|
||
|
<iframe src="javascript:void(0)" frameborder="0"
|
||
|
name="MSearchResults" id="MSearchResults">
|
||
|
</iframe>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
<li class="footer">
|
||
|
<a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht
|
||
|
Engine</a> Documentation © 2003-2012 by Nikolaus Gebhardt. Generated on Sat Jul 9 2016 18:18:26 for Irrlicht 3D Engine by
|
||
|
<a href="http://www.doxygen.org/index.html" target="_blank">Doxygen</a> 1.7.5.1 </li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|