Line data Source code
1 : // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 : // This file is part of the "Irrlicht Engine".
3 : // For conditions of distribution and use, see copyright notice in irrlicht.h
4 :
5 : #ifndef __I_SCENE_NODE_H_INCLUDED__
6 : #define __I_SCENE_NODE_H_INCLUDED__
7 :
8 : #include "IAttributeExchangingObject.h"
9 : #include "ESceneNodeTypes.h"
10 : #include "ECullingTypes.h"
11 : #include "EDebugSceneTypes.h"
12 : #include "ISceneNodeAnimator.h"
13 : #include "ITriangleSelector.h"
14 : #include "SMaterial.h"
15 : #include "irrString.h"
16 : #include "aabbox3d.h"
17 : #include "matrix4.h"
18 : #include "irrList.h"
19 : #include "IAttributes.h"
20 :
21 : namespace irr
22 : {
23 : namespace scene
24 : {
25 : class ISceneManager;
26 :
27 : //! Typedef for list of scene nodes
28 : typedef core::list<ISceneNode*> ISceneNodeList;
29 : //! Typedef for list of scene node animators
30 : typedef core::list<ISceneNodeAnimator*> ISceneNodeAnimatorList;
31 :
32 : //! Scene node interface.
33 : /** A scene node is a node in the hierarchical scene graph. Every scene
34 : node may have children, which are also scene nodes. Children move
35 : relative to their parent's position. If the parent of a node is not
36 : visible, its children won't be visible either. In this way, it is for
37 : example easily possible to attach a light to a moving car, or to place
38 : a walking character on a moving platform on a moving ship.
39 : */
40 : class ISceneNode : virtual public io::IAttributeExchangingObject
41 : {
42 : public:
43 :
44 : //! Constructor
45 256 : ISceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id=-1,
46 : const core::vector3df& position = core::vector3df(0,0,0),
47 : const core::vector3df& rotation = core::vector3df(0,0,0),
48 : const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f))
49 : : RelativeTranslation(position), RelativeRotation(rotation), RelativeScale(scale),
50 : Parent(0), SceneManager(mgr), TriangleSelector(0), ID(id),
51 : AutomaticCullingState(EAC_BOX), DebugDataVisible(EDS_OFF),
52 256 : IsVisible(true), IsDebugObject(false)
53 : {
54 256 : if (parent)
55 256 : parent->addChild(this);
56 :
57 256 : updateAbsolutePosition();
58 256 : }
59 :
60 :
61 : //! Destructor
62 260 : virtual ~ISceneNode()
63 520 : {
64 : // delete all children
65 260 : removeAll();
66 :
67 : // delete all animators
68 260 : ISceneNodeAnimatorList::Iterator ait = Animators.begin();
69 260 : for (; ait != Animators.end(); ++ait)
70 0 : (*ait)->drop();
71 :
72 260 : if (TriangleSelector)
73 0 : TriangleSelector->drop();
74 260 : }
75 :
76 :
77 : //! This method is called just before the rendering process of the whole scene.
78 : /** Nodes may register themselves in the render pipeline during this call,
79 : precalculate the geometry which should be renderered, and prevent their
80 : children from being able to register themselves if they are clipped by simply
81 : not calling their OnRegisterSceneNode method.
82 : If you are implementing your own scene node, you should overwrite this method
83 : with an implementation code looking like this:
84 : \code
85 : if (IsVisible)
86 : SceneManager->registerNodeForRendering(this);
87 :
88 : ISceneNode::OnRegisterSceneNode();
89 : \endcode
90 : */
91 125042 : virtual void OnRegisterSceneNode()
92 : {
93 125042 : if (IsVisible)
94 : {
95 125042 : ISceneNodeList::Iterator it = Children.begin();
96 419156 : for (; it != Children.end(); ++it)
97 147057 : (*it)->OnRegisterSceneNode();
98 : }
99 125042 : }
100 :
101 :
102 : //! OnAnimate() is called just before rendering the whole scene.
103 : /** Nodes may calculate or store animations here, and may do other useful things,
104 : depending on what they are. Also, OnAnimate() should be called for all
105 : child scene nodes here. This method will be called once per frame, independent
106 : of whether the scene node is visible or not.
107 : \param timeMs Current time in milliseconds. */
108 63133 : virtual void OnAnimate(u32 timeMs)
109 : {
110 63133 : if (IsVisible)
111 : {
112 : // animate this node with all animators
113 :
114 63133 : ISceneNodeAnimatorList::Iterator ait = Animators.begin();
115 63133 : while (ait != Animators.end())
116 : {
117 : // continue to the next node before calling animateNode()
118 : // so that the animator may remove itself from the scene
119 : // node without the iterator becoming invalid
120 0 : ISceneNodeAnimator* anim = *ait;
121 0 : ++ait;
122 0 : anim->animateNode(this, timeMs);
123 : }
124 :
125 : // update absolute position
126 63133 : updateAbsolutePosition();
127 :
128 : // perform the post render process on all children
129 :
130 63133 : ISceneNodeList::Iterator it = Children.begin();
131 202085 : for (; it != Children.end(); ++it)
132 69476 : (*it)->OnAnimate(timeMs);
133 : }
134 63133 : }
135 :
136 :
137 : //! Renders the node.
138 : virtual void render() = 0;
139 :
140 :
141 : //! Returns the name of the node.
142 : /** \return Name as character string. */
143 0 : virtual const c8* getName() const
144 : {
145 0 : return Name.c_str();
146 : }
147 :
148 :
149 : //! Sets the name of the node.
150 : /** \param name New name of the scene node. */
151 0 : virtual void setName(const c8* name)
152 : {
153 0 : Name = name;
154 0 : }
155 :
156 :
157 : //! Sets the name of the node.
158 : /** \param name New name of the scene node. */
159 0 : virtual void setName(const core::stringc& name)
160 : {
161 0 : Name = name;
162 0 : }
163 :
164 :
165 : //! Get the axis aligned, not transformed bounding box of this node.
166 : /** This means that if this node is an animated 3d character,
167 : moving in a room, the bounding box will always be around the
168 : origin. To get the box in real world coordinates, just
169 : transform it with the matrix you receive with
170 : getAbsoluteTransformation() or simply use
171 : getTransformedBoundingBox(), which does the same.
172 : \return The non-transformed bounding box. */
173 : virtual const core::aabbox3d<f32>& getBoundingBox() const = 0;
174 :
175 :
176 : //! Get the axis aligned, transformed and animated absolute bounding box of this node.
177 : /** \return The transformed bounding box. */
178 0 : virtual const core::aabbox3d<f32> getTransformedBoundingBox() const
179 : {
180 0 : core::aabbox3d<f32> box = getBoundingBox();
181 0 : AbsoluteTransformation.transformBoxEx(box);
182 0 : return box;
183 : }
184 :
185 :
186 : //! Get the absolute transformation of the node. Is recalculated every OnAnimate()-call.
187 : /** NOTE: For speed reasons the absolute transformation is not
188 : automatically recalculated on each change of the relative
189 : transformation or by a transformation change of an parent. Instead the
190 : update usually happens once per frame in OnAnimate. You can enforce
191 : an update with updateAbsolutePosition().
192 : \return The absolute transformation matrix. */
193 453367 : virtual const core::matrix4& getAbsoluteTransformation() const
194 : {
195 453367 : return AbsoluteTransformation;
196 : }
197 :
198 :
199 : //! Returns the relative transformation of the scene node.
200 : /** The relative transformation is stored internally as 3
201 : vectors: translation, rotation and scale. To get the relative
202 : transformation matrix, it is calculated from these values.
203 : \return The relative transformation matrix. */
204 361526 : virtual core::matrix4 getRelativeTransformation() const
205 : {
206 361526 : core::matrix4 mat;
207 361526 : mat.setRotationDegrees(RelativeRotation);
208 361526 : mat.setTranslation(RelativeTranslation);
209 :
210 361526 : if (RelativeScale != core::vector3df(1.f,1.f,1.f))
211 : {
212 118632 : core::matrix4 smat;
213 118632 : smat.setScale(RelativeScale);
214 118632 : mat *= smat;
215 : }
216 :
217 361526 : return mat;
218 : }
219 :
220 :
221 : //! Returns whether the node should be visible (if all of its parents are visible).
222 : /** This is only an option set by the user, but has nothing to
223 : do with geometry culling
224 : \return The requested visibility of the node, true means
225 : visible (if all parents are also visible). */
226 0 : virtual bool isVisible() const
227 : {
228 : _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
229 0 : return IsVisible;
230 : }
231 :
232 : //! Check whether the node is truly visible, taking into accounts its parents' visibility
233 : /** \return true if the node and all its parents are visible,
234 : false if this or any parent node is invisible. */
235 0 : virtual bool isTrulyVisible() const
236 : {
237 : _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
238 0 : if(!IsVisible)
239 0 : return false;
240 :
241 0 : if(!Parent)
242 0 : return true;
243 :
244 0 : return Parent->isTrulyVisible();
245 : }
246 :
247 : //! Sets if the node should be visible or not.
248 : /** All children of this node won't be visible either, when set
249 : to false. Invisible nodes are not valid candidates for selection by
250 : collision manager bounding box methods.
251 : \param isVisible If the node shall be visible. */
252 27423 : virtual void setVisible(bool isVisible)
253 : {
254 27423 : IsVisible = isVisible;
255 27423 : }
256 :
257 :
258 : //! Get the id of the scene node.
259 : /** This id can be used to identify the node.
260 : \return The id. */
261 0 : virtual s32 getID() const
262 : {
263 0 : return ID;
264 : }
265 :
266 :
267 : //! Sets the id of the scene node.
268 : /** This id can be used to identify the node.
269 : \param id The new id. */
270 0 : virtual void setID(s32 id)
271 : {
272 0 : ID = id;
273 0 : }
274 :
275 :
276 : //! Adds a child to this scene node.
277 : /** If the scene node already has a parent it is first removed
278 : from the other parent.
279 : \param child A pointer to the new child. */
280 778 : virtual void addChild(ISceneNode* child)
281 : {
282 778 : if (child && (child != this))
283 : {
284 : // Change scene manager?
285 778 : if (SceneManager != child->SceneManager)
286 0 : child->setSceneManager(SceneManager);
287 :
288 778 : child->grab();
289 778 : child->remove(); // remove from old parent
290 778 : Children.push_back(child);
291 778 : child->Parent = this;
292 : }
293 778 : }
294 :
295 :
296 : //! Removes a child from this scene node.
297 : /** If found in the children list, the child pointer is also
298 : dropped and might be deleted if no other grab exists.
299 : \param child A pointer to the child which shall be removed.
300 : \return True if the child was removed, and false if not,
301 : e.g. because it couldn't be found in the children list. */
302 863 : virtual bool removeChild(ISceneNode* child)
303 : {
304 863 : ISceneNodeList::Iterator it = Children.begin();
305 44697 : for (; it != Children.end(); ++it)
306 22413 : if ((*it) == child)
307 : {
308 496 : (*it)->Parent = 0;
309 496 : (*it)->drop();
310 496 : Children.erase(it);
311 496 : return true;
312 : }
313 :
314 : _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
315 367 : return false;
316 : }
317 :
318 :
319 : //! Removes all children of this scene node
320 : /** The scene nodes found in the children list are also dropped
321 : and might be deleted if no other grab exists on them.
322 : */
323 260 : virtual void removeAll()
324 : {
325 260 : ISceneNodeList::Iterator it = Children.begin();
326 312 : for (; it != Children.end(); ++it)
327 : {
328 26 : (*it)->Parent = 0;
329 26 : (*it)->drop();
330 : }
331 :
332 260 : Children.clear();
333 260 : }
334 :
335 :
336 : //! Removes this scene node from the scene
337 : /** If no other grab exists for this node, it will be deleted.
338 : */
339 1514 : virtual void remove()
340 : {
341 1514 : if (Parent)
342 889 : Parent->removeChild(this);
343 1514 : }
344 :
345 :
346 : //! Adds an animator which should animate this node.
347 : /** \param animator A pointer to the new animator. */
348 0 : virtual void addAnimator(ISceneNodeAnimator* animator)
349 : {
350 0 : if (animator)
351 : {
352 0 : Animators.push_back(animator);
353 0 : animator->grab();
354 : }
355 0 : }
356 :
357 :
358 : //! Get a list of all scene node animators.
359 : /** \return The list of animators attached to this node. */
360 : const core::list<ISceneNodeAnimator*>& getAnimators() const
361 : {
362 : return Animators;
363 : }
364 :
365 :
366 : //! Removes an animator from this scene node.
367 : /** If the animator is found, it is also dropped and might be
368 : deleted if not other grab exists for it.
369 : \param animator A pointer to the animator to be deleted. */
370 0 : virtual void removeAnimator(ISceneNodeAnimator* animator)
371 : {
372 0 : ISceneNodeAnimatorList::Iterator it = Animators.begin();
373 0 : for (; it != Animators.end(); ++it)
374 : {
375 0 : if ((*it) == animator)
376 : {
377 0 : (*it)->drop();
378 0 : Animators.erase(it);
379 0 : return;
380 : }
381 : }
382 : }
383 :
384 :
385 : //! Removes all animators from this scene node.
386 : /** The animators might also be deleted if no other grab exists
387 : for them. */
388 4 : virtual void removeAnimators()
389 : {
390 4 : ISceneNodeAnimatorList::Iterator it = Animators.begin();
391 4 : for (; it != Animators.end(); ++it)
392 0 : (*it)->drop();
393 :
394 4 : Animators.clear();
395 4 : }
396 :
397 :
398 : //! Returns the material based on the zero based index i.
399 : /** To get the amount of materials used by this scene node, use
400 : getMaterialCount(). This function is needed for inserting the
401 : node into the scene hierarchy at an optimal position for
402 : minimizing renderstate changes, but can also be used to
403 : directly modify the material of a scene node.
404 : \param num Zero based index. The maximal value is getMaterialCount() - 1.
405 : \return The material at that index. */
406 0 : virtual video::SMaterial& getMaterial(u32 num)
407 : {
408 0 : return video::IdentityMaterial;
409 : }
410 :
411 :
412 : //! Get amount of materials used by this scene node.
413 : /** \return Current amount of materials of this scene node. */
414 5830 : virtual u32 getMaterialCount() const
415 : {
416 5830 : return 0;
417 : }
418 :
419 :
420 : //! Sets all material flags at once to a new value.
421 : /** Useful, for example, if you want the whole mesh to be
422 : affected by light.
423 : \param flag Which flag of all materials to be set.
424 : \param newvalue New value of that flag. */
425 165 : void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
426 : {
427 668 : for (u32 i=0; i<getMaterialCount(); ++i)
428 503 : getMaterial(i).setFlag(flag, newvalue);
429 165 : }
430 :
431 :
432 : //! Sets the texture of the specified layer in all materials of this scene node to the new texture.
433 : /** \param textureLayer Layer of texture to be set. Must be a
434 : value smaller than MATERIAL_MAX_TEXTURES.
435 : \param texture New texture to be used. */
436 0 : void setMaterialTexture(u32 textureLayer, video::ITexture* texture)
437 : {
438 0 : if (textureLayer >= video::MATERIAL_MAX_TEXTURES)
439 0 : return;
440 :
441 0 : for (u32 i=0; i<getMaterialCount(); ++i)
442 0 : getMaterial(i).setTexture(textureLayer, texture);
443 : }
444 :
445 :
446 : //! Sets the material type of all materials in this scene node to a new material type.
447 : /** \param newType New type of material to be set. */
448 26 : void setMaterialType(video::E_MATERIAL_TYPE newType)
449 : {
450 78 : for (u32 i=0; i<getMaterialCount(); ++i)
451 52 : getMaterial(i).MaterialType = newType;
452 26 : }
453 :
454 :
455 : //! Gets the scale of the scene node relative to its parent.
456 : /** This is the scale of this node relative to its parent.
457 : If you want the absolute scale, use
458 : getAbsoluteTransformation().getScale()
459 : \return The scale of the scene node. */
460 0 : virtual const core::vector3df& getScale() const
461 : {
462 0 : return RelativeScale;
463 : }
464 :
465 :
466 : //! Sets the relative scale of the scene node.
467 : /** \param scale New scale of the node, relative to its parent. */
468 144014 : virtual void setScale(const core::vector3df& scale)
469 : {
470 144014 : RelativeScale = scale;
471 144014 : }
472 :
473 :
474 : //! Gets the rotation of the node relative to its parent.
475 : /** Note that this is the relative rotation of the node.
476 : If you want the absolute rotation, use
477 : getAbsoluteTransformation().getRotation()
478 : \return Current relative rotation of the scene node. */
479 28707 : virtual const core::vector3df& getRotation() const
480 : {
481 28707 : return RelativeRotation;
482 : }
483 :
484 :
485 : //! Sets the rotation of the node relative to its parent.
486 : /** This only modifies the relative rotation of the node.
487 : \param rotation New rotation of the node in degrees. */
488 176127 : virtual void setRotation(const core::vector3df& rotation)
489 : {
490 176127 : RelativeRotation = rotation;
491 176127 : }
492 :
493 :
494 : //! Gets the position of the node relative to its parent.
495 : /** Note that the position is relative to the parent. If you want
496 : the position in world coordinates, use getAbsolutePosition() instead.
497 : \return The current position of the node relative to the parent. */
498 2332 : virtual const core::vector3df& getPosition() const
499 : {
500 2332 : return RelativeTranslation;
501 : }
502 :
503 :
504 : //! Sets the position of the node relative to its parent.
505 : /** Note that the position is relative to the parent.
506 : \param newpos New relative position of the scene node. */
507 178459 : virtual void setPosition(const core::vector3df& newpos)
508 : {
509 178459 : RelativeTranslation = newpos;
510 178459 : }
511 :
512 :
513 : //! Gets the absolute position of the node in world coordinates.
514 : /** If you want the position of the node relative to its parent,
515 : use getPosition() instead.
516 : NOTE: For speed reasons the absolute position is not
517 : automatically recalculated on each change of the relative
518 : position or by a position change of an parent. Instead the
519 : update usually happens once per frame in OnAnimate. You can enforce
520 : an update with updateAbsolutePosition().
521 : \return The current absolute position of the scene node (updated on last call of updateAbsolutePosition). */
522 18647 : virtual core::vector3df getAbsolutePosition() const
523 : {
524 18647 : return AbsoluteTransformation.getTranslation();
525 : }
526 :
527 :
528 : //! Enables or disables automatic culling based on the bounding box.
529 : /** Automatic culling is enabled by default. Note that not
530 : all SceneNodes support culling and that some nodes always cull
531 : their geometry because it is their only reason for existence,
532 : for example the OctreeSceneNode.
533 : \param state The culling state to be used. */
534 252 : void setAutomaticCulling( u32 state)
535 : {
536 252 : AutomaticCullingState = state;
537 252 : }
538 :
539 :
540 : //! Gets the automatic culling state.
541 : /** \return The automatic culling state. */
542 : u32 getAutomaticCulling() const
543 : {
544 : return AutomaticCullingState;
545 : }
546 :
547 :
548 : //! Sets if debug data like bounding boxes should be drawn.
549 : /** A bitwise OR of the types from @ref irr::scene::E_DEBUG_SCENE_TYPE.
550 : Please note that not all scene nodes support all debug data types.
551 : \param state The debug data visibility state to be used. */
552 0 : virtual void setDebugDataVisible(u32 state)
553 : {
554 0 : DebugDataVisible = state;
555 0 : }
556 :
557 : //! Returns if debug data like bounding boxes are drawn.
558 : /** \return A bitwise OR of the debug data values from
559 : @ref irr::scene::E_DEBUG_SCENE_TYPE that are currently visible. */
560 : u32 isDebugDataVisible() const
561 : {
562 : return DebugDataVisible;
563 : }
564 :
565 :
566 : //! Sets if this scene node is a debug object.
567 : /** Debug objects have some special properties, for example they can be easily
568 : excluded from collision detection or from serialization, etc. */
569 : void setIsDebugObject(bool debugObject)
570 : {
571 : IsDebugObject = debugObject;
572 : }
573 :
574 :
575 : //! Returns if this scene node is a debug object.
576 : /** Debug objects have some special properties, for example they can be easily
577 : excluded from collision detection or from serialization, etc.
578 : \return If this node is a debug object, true is returned. */
579 : bool isDebugObject() const
580 : {
581 : _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
582 : return IsDebugObject;
583 : }
584 :
585 :
586 : //! Returns a const reference to the list of all children.
587 : /** \return The list of all children of this node. */
588 : const core::list<ISceneNode*>& getChildren() const
589 : {
590 : return Children;
591 : }
592 :
593 :
594 : //! Changes the parent of the scene node.
595 : /** \param newParent The new parent to be used. */
596 393 : virtual void setParent(ISceneNode* newParent)
597 : {
598 393 : grab();
599 393 : remove();
600 :
601 393 : Parent = newParent;
602 :
603 393 : if (Parent)
604 393 : Parent->addChild(this);
605 :
606 393 : drop();
607 393 : }
608 :
609 :
610 : //! Returns the triangle selector attached to this scene node.
611 : /** The Selector can be used by the engine for doing collision
612 : detection. You can create a TriangleSelector with
613 : ISceneManager::createTriangleSelector() or
614 : ISceneManager::createOctreeTriangleSelector and set it with
615 : ISceneNode::setTriangleSelector(). If a scene node got no triangle
616 : selector, but collision tests should be done with it, a triangle
617 : selector is created using the bounding box of the scene node.
618 : \return A pointer to the TriangleSelector or 0, if there
619 : is none. */
620 0 : virtual ITriangleSelector* getTriangleSelector() const
621 : {
622 0 : return TriangleSelector;
623 : }
624 :
625 :
626 : //! Sets the triangle selector of the scene node.
627 : /** The Selector can be used by the engine for doing collision
628 : detection. You can create a TriangleSelector with
629 : ISceneManager::createTriangleSelector() or
630 : ISceneManager::createOctreeTriangleSelector(). Some nodes may
631 : create their own selector by default, so it would be good to
632 : check if there is already a selector in this node by calling
633 : ISceneNode::getTriangleSelector().
634 : \param selector New triangle selector for this scene node. */
635 0 : virtual void setTriangleSelector(ITriangleSelector* selector)
636 : {
637 0 : if (TriangleSelector != selector)
638 : {
639 0 : if (TriangleSelector)
640 0 : TriangleSelector->drop();
641 :
642 0 : TriangleSelector = selector;
643 0 : if (TriangleSelector)
644 0 : TriangleSelector->grab();
645 : }
646 0 : }
647 :
648 :
649 : //! Updates the absolute position based on the relative and the parents position
650 : /** Note: This does not recursively update the parents absolute positions, so if you have a deeper
651 : hierarchy you might want to update the parents first.*/
652 361284 : virtual void updateAbsolutePosition()
653 : {
654 361284 : if (Parent)
655 : {
656 358782 : AbsoluteTransformation =
657 717564 : Parent->getAbsoluteTransformation() * getRelativeTransformation();
658 : }
659 : else
660 2502 : AbsoluteTransformation = getRelativeTransformation();
661 361284 : }
662 :
663 :
664 : //! Returns the parent of this scene node
665 : /** \return A pointer to the parent. */
666 : scene::ISceneNode* getParent() const
667 : {
668 : return Parent;
669 : }
670 :
671 :
672 : //! Returns type of the scene node
673 : /** \return The type of this node. */
674 0 : virtual ESCENE_NODE_TYPE getType() const
675 : {
676 0 : return ESNT_UNKNOWN;
677 : }
678 :
679 :
680 : //! Writes attributes of the scene node.
681 : /** Implement this to expose the attributes of your scene node
682 : for scripting languages, editors, debuggers or xml
683 : serialization purposes.
684 : \param out The attribute container to write into.
685 : \param options Additional options which might influence the
686 : serialization. */
687 0 : virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
688 : {
689 0 : if (!out)
690 0 : return;
691 0 : out->addString ("Name", Name.c_str());
692 0 : out->addInt ("Id", ID );
693 :
694 0 : out->addVector3d("Position", getPosition() );
695 0 : out->addVector3d("Rotation", getRotation() );
696 0 : out->addVector3d("Scale", getScale() );
697 :
698 0 : out->addBool ("Visible", IsVisible );
699 0 : out->addInt ("AutomaticCulling", AutomaticCullingState);
700 0 : out->addInt ("DebugDataVisible", DebugDataVisible );
701 0 : out->addBool ("IsDebugObject", IsDebugObject );
702 : }
703 :
704 :
705 : //! Reads attributes of the scene node.
706 : /** Implement this to set the attributes of your scene node for
707 : scripting languages, editors, debuggers or xml deserialization
708 : purposes.
709 : \param in The attribute container to read from.
710 : \param options Additional options which might influence the
711 : deserialization. */
712 0 : virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
713 : {
714 0 : if (!in)
715 0 : return;
716 0 : Name = in->getAttributeAsString("Name");
717 0 : ID = in->getAttributeAsInt("Id");
718 :
719 0 : setPosition(in->getAttributeAsVector3d("Position"));
720 0 : setRotation(in->getAttributeAsVector3d("Rotation"));
721 0 : setScale(in->getAttributeAsVector3d("Scale"));
722 :
723 0 : IsVisible = in->getAttributeAsBool("Visible");
724 : s32 tmpState = in->getAttributeAsEnumeration("AutomaticCulling",
725 0 : scene::AutomaticCullingNames);
726 0 : if (tmpState != -1)
727 0 : AutomaticCullingState = (u32)tmpState;
728 : else
729 0 : AutomaticCullingState = in->getAttributeAsInt("AutomaticCulling");
730 :
731 0 : DebugDataVisible = in->getAttributeAsInt("DebugDataVisible");
732 0 : IsDebugObject = in->getAttributeAsBool("IsDebugObject");
733 :
734 0 : updateAbsolutePosition();
735 : }
736 :
737 : //! Creates a clone of this scene node and its children.
738 : /** \param newParent An optional new parent.
739 : \param newManager An optional new scene manager.
740 : \return The newly created clone of this node. */
741 0 : virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0)
742 : {
743 0 : return 0; // to be implemented by derived classes
744 : }
745 :
746 : //! Retrieve the scene manager for this node.
747 : /** \return The node's scene manager. */
748 0 : virtual ISceneManager* getSceneManager(void) const { return SceneManager; }
749 :
750 : protected:
751 :
752 : //! A clone function for the ISceneNode members.
753 : /** This method can be used by clone() implementations of
754 : derived classes
755 : \param toCopyFrom The node from which the values are copied
756 : \param newManager The new scene manager. */
757 : void cloneMembers(ISceneNode* toCopyFrom, ISceneManager* newManager)
758 : {
759 : Name = toCopyFrom->Name;
760 : AbsoluteTransformation = toCopyFrom->AbsoluteTransformation;
761 : RelativeTranslation = toCopyFrom->RelativeTranslation;
762 : RelativeRotation = toCopyFrom->RelativeRotation;
763 : RelativeScale = toCopyFrom->RelativeScale;
764 : ID = toCopyFrom->ID;
765 : setTriangleSelector(toCopyFrom->TriangleSelector);
766 : AutomaticCullingState = toCopyFrom->AutomaticCullingState;
767 : DebugDataVisible = toCopyFrom->DebugDataVisible;
768 : IsVisible = toCopyFrom->IsVisible;
769 : IsDebugObject = toCopyFrom->IsDebugObject;
770 :
771 : if (newManager)
772 : SceneManager = newManager;
773 : else
774 : SceneManager = toCopyFrom->SceneManager;
775 :
776 : // clone children
777 :
778 : ISceneNodeList::Iterator it = toCopyFrom->Children.begin();
779 : for (; it != toCopyFrom->Children.end(); ++it)
780 : (*it)->clone(this, newManager);
781 :
782 : // clone animators
783 :
784 : ISceneNodeAnimatorList::Iterator ait = toCopyFrom->Animators.begin();
785 : for (; ait != toCopyFrom->Animators.end(); ++ait)
786 : {
787 : ISceneNodeAnimator* anim = (*ait)->createClone(this, SceneManager);
788 : if (anim)
789 : {
790 : addAnimator(anim);
791 : anim->drop();
792 : }
793 : }
794 : }
795 :
796 : //! Sets the new scene manager for this node and all children.
797 : //! Called by addChild when moving nodes between scene managers
798 0 : void setSceneManager(ISceneManager* newManager)
799 : {
800 0 : SceneManager = newManager;
801 :
802 0 : ISceneNodeList::Iterator it = Children.begin();
803 0 : for (; it != Children.end(); ++it)
804 0 : (*it)->setSceneManager(newManager);
805 0 : }
806 :
807 : //! Name of the scene node.
808 : core::stringc Name;
809 :
810 : //! Absolute transformation of the node.
811 : core::matrix4 AbsoluteTransformation;
812 :
813 : //! Relative translation of the scene node.
814 : core::vector3df RelativeTranslation;
815 :
816 : //! Relative rotation of the scene node.
817 : core::vector3df RelativeRotation;
818 :
819 : //! Relative scale of the scene node.
820 : core::vector3df RelativeScale;
821 :
822 : //! Pointer to the parent
823 : ISceneNode* Parent;
824 :
825 : //! List of all children of this node
826 : core::list<ISceneNode*> Children;
827 :
828 : //! List of all animator nodes
829 : core::list<ISceneNodeAnimator*> Animators;
830 :
831 : //! Pointer to the scene manager
832 : ISceneManager* SceneManager;
833 :
834 : //! Pointer to the triangle selector
835 : ITriangleSelector* TriangleSelector;
836 :
837 : //! ID of the node.
838 : s32 ID;
839 :
840 : //! Automatic culling state
841 : u32 AutomaticCullingState;
842 :
843 : //! Flag if debug data should be drawn, such as Bounding Boxes.
844 : u32 DebugDataVisible;
845 :
846 : //! Is the node visible?
847 : bool IsVisible;
848 :
849 : //! Is debug object?
850 : bool IsDebugObject;
851 : };
852 :
853 :
854 : } // end namespace scene
855 : } // end namespace irr
856 :
857 : #endif
858 :
|