00001
00002
00003
00004
00005 #ifndef __I_SCENE_NODE_H_INCLUDED__
00006 #define __I_SCENE_NODE_H_INCLUDED__
00007
00008 #include "IAttributeExchangingObject.h"
00009 #include "ESceneNodeTypes.h"
00010 #include "ECullingTypes.h"
00011 #include "EDebugSceneTypes.h"
00012 #include "ISceneNodeAnimator.h"
00013 #include "ITriangleSelector.h"
00014 #include "SMaterial.h"
00015 #include "irrString.h"
00016 #include "aabbox3d.h"
00017 #include "matrix4.h"
00018 #include "irrList.h"
00019 #include "IAttributes.h"
00020
00021 namespace irr
00022 {
00023 namespace scene
00024 {
00025 class ISceneManager;
00026
00028 typedef core::list<ISceneNode*> ISceneNodeList;
00030 typedef core::list<ISceneNodeAnimator*> ISceneNodeAnimatorList;
00031
00033
00040 class ISceneNode : virtual public io::IAttributeExchangingObject
00041 {
00042 public:
00043
00045 ISceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id=-1,
00046 const core::vector3df& position = core::vector3df(0,0,0),
00047 const core::vector3df& rotation = core::vector3df(0,0,0),
00048 const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f))
00049 : RelativeTranslation(position), RelativeRotation(rotation), RelativeScale(scale),
00050 Parent(0), SceneManager(mgr), TriangleSelector(0), ID(id),
00051 AutomaticCullingState(EAC_BOX), DebugDataVisible(EDS_OFF),
00052 IsVisible(true), IsDebugObject(false)
00053 {
00054 if (parent)
00055 parent->addChild(this);
00056
00057 updateAbsolutePosition();
00058 }
00059
00060
00062 virtual ~ISceneNode()
00063 {
00064
00065 removeAll();
00066
00067
00068 ISceneNodeAnimatorList::Iterator ait = Animators.begin();
00069 for (; ait != Animators.end(); ++ait)
00070 (*ait)->drop();
00071
00072 if (TriangleSelector)
00073 TriangleSelector->drop();
00074 }
00075
00076
00078
00091 virtual void OnRegisterSceneNode()
00092 {
00093 if (IsVisible)
00094 {
00095 ISceneNodeList::Iterator it = Children.begin();
00096 for (; it != Children.end(); ++it)
00097 (*it)->OnRegisterSceneNode();
00098 }
00099 }
00100
00101
00103
00108 virtual void OnAnimate(u32 timeMs)
00109 {
00110 if (IsVisible)
00111 {
00112
00113
00114 ISceneNodeAnimatorList::Iterator ait = Animators.begin();
00115 while (ait != Animators.end())
00116 {
00117
00118
00119
00120 ISceneNodeAnimator* anim = *ait;
00121 ++ait;
00122 anim->animateNode(this, timeMs);
00123 }
00124
00125
00126 updateAbsolutePosition();
00127
00128
00129
00130 ISceneNodeList::Iterator it = Children.begin();
00131 for (; it != Children.end(); ++it)
00132 (*it)->OnAnimate(timeMs);
00133 }
00134 }
00135
00136
00138 virtual void render() = 0;
00139
00140
00142
00143 virtual const c8* getName() const
00144 {
00145 return Name.c_str();
00146 }
00147
00148
00150
00151 virtual void setName(const c8* name)
00152 {
00153 Name = name;
00154 }
00155
00156
00158
00159 virtual void setName(const core::stringc& name)
00160 {
00161 Name = name;
00162 }
00163
00164
00166
00173 virtual const core::aabbox3d<f32>& getBoundingBox() const = 0;
00174
00175
00177
00178 virtual const core::aabbox3d<f32> getTransformedBoundingBox() const
00179 {
00180 core::aabbox3d<f32> box = getBoundingBox();
00181 AbsoluteTransformation.transformBoxEx(box);
00182 return box;
00183 }
00184
00185
00188 virtual const core::matrix4& getAbsoluteTransformation() const
00189 {
00190 return AbsoluteTransformation;
00191 }
00192
00193
00195
00199 virtual core::matrix4 getRelativeTransformation() const
00200 {
00201 core::matrix4 mat;
00202 mat.setRotationDegrees(RelativeRotation);
00203 mat.setTranslation(RelativeTranslation);
00204
00205 if (RelativeScale != core::vector3df(1.f,1.f,1.f))
00206 {
00207 core::matrix4 smat;
00208 smat.setScale(RelativeScale);
00209 mat *= smat;
00210 }
00211
00212 return mat;
00213 }
00214
00215
00217
00221 virtual bool isVisible() const
00222 {
00223 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00224 return IsVisible;
00225 }
00226
00228
00230 virtual bool isTrulyVisible() const
00231 {
00232 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00233 if(!IsVisible)
00234 return false;
00235
00236 if(!Parent)
00237 return true;
00238
00239 return Parent->isTrulyVisible();
00240 }
00241
00243
00247 virtual void setVisible(bool isVisible)
00248 {
00249 IsVisible = isVisible;
00250 }
00251
00252
00254
00256 virtual s32 getID() const
00257 {
00258 return ID;
00259 }
00260
00261
00263
00265 virtual void setID(s32 id)
00266 {
00267 ID = id;
00268 }
00269
00270
00272
00275 virtual void addChild(ISceneNode* child)
00276 {
00277 if (child && (child != this))
00278 {
00279
00280 if (SceneManager != child->SceneManager)
00281 child->setSceneManager(SceneManager);
00282
00283 child->grab();
00284 child->remove();
00285 Children.push_back(child);
00286 child->Parent = this;
00287 }
00288 }
00289
00290
00292
00297 virtual bool removeChild(ISceneNode* child)
00298 {
00299 ISceneNodeList::Iterator it = Children.begin();
00300 for (; it != Children.end(); ++it)
00301 if ((*it) == child)
00302 {
00303 (*it)->Parent = 0;
00304 (*it)->drop();
00305 Children.erase(it);
00306 return true;
00307 }
00308
00309 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00310 return false;
00311 }
00312
00313
00315
00318 virtual void removeAll()
00319 {
00320 ISceneNodeList::Iterator it = Children.begin();
00321 for (; it != Children.end(); ++it)
00322 {
00323 (*it)->Parent = 0;
00324 (*it)->drop();
00325 }
00326
00327 Children.clear();
00328 }
00329
00330
00332
00334 virtual void remove()
00335 {
00336 if (Parent)
00337 Parent->removeChild(this);
00338 }
00339
00340
00342
00343 virtual void addAnimator(ISceneNodeAnimator* animator)
00344 {
00345 if (animator)
00346 {
00347 Animators.push_back(animator);
00348 animator->grab();
00349 }
00350 }
00351
00352
00354
00355 const core::list<ISceneNodeAnimator*>& getAnimators() const
00356 {
00357 return Animators;
00358 }
00359
00360
00362
00365 virtual void removeAnimator(ISceneNodeAnimator* animator)
00366 {
00367 ISceneNodeAnimatorList::Iterator it = Animators.begin();
00368 for (; it != Animators.end(); ++it)
00369 {
00370 if ((*it) == animator)
00371 {
00372 (*it)->drop();
00373 Animators.erase(it);
00374 return;
00375 }
00376 }
00377 }
00378
00379
00381
00383 virtual void removeAnimators()
00384 {
00385 ISceneNodeAnimatorList::Iterator it = Animators.begin();
00386 for (; it != Animators.end(); ++it)
00387 (*it)->drop();
00388
00389 Animators.clear();
00390 }
00391
00392
00394
00401 virtual video::SMaterial& getMaterial(u32 num)
00402 {
00403 return video::IdentityMaterial;
00404 }
00405
00406
00408
00409 virtual u32 getMaterialCount() const
00410 {
00411 return 0;
00412 }
00413
00414
00416
00420 void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
00421 {
00422 for (u32 i=0; i<getMaterialCount(); ++i)
00423 getMaterial(i).setFlag(flag, newvalue);
00424 }
00425
00426
00428
00431 void setMaterialTexture(u32 textureLayer, video::ITexture* texture)
00432 {
00433 if (textureLayer >= video::MATERIAL_MAX_TEXTURES)
00434 return;
00435
00436 for (u32 i=0; i<getMaterialCount(); ++i)
00437 getMaterial(i).setTexture(textureLayer, texture);
00438 }
00439
00440
00442
00443 void setMaterialType(video::E_MATERIAL_TYPE newType)
00444 {
00445 for (u32 i=0; i<getMaterialCount(); ++i)
00446 getMaterial(i).MaterialType = newType;
00447 }
00448
00449
00451
00455 virtual const core::vector3df& getScale() const
00456 {
00457 return RelativeScale;
00458 }
00459
00460
00462
00463 virtual void setScale(const core::vector3df& scale)
00464 {
00465 RelativeScale = scale;
00466 }
00467
00468
00470
00474 virtual const core::vector3df& getRotation() const
00475 {
00476 return RelativeRotation;
00477 }
00478
00479
00481
00483 virtual void setRotation(const core::vector3df& rotation)
00484 {
00485 RelativeRotation = rotation;
00486 }
00487
00488
00490
00493 virtual const core::vector3df& getPosition() const
00494 {
00495 return RelativeTranslation;
00496 }
00497
00498
00500
00502 virtual void setPosition(const core::vector3df& newpos)
00503 {
00504 RelativeTranslation = newpos;
00505 }
00506
00507
00509
00512 virtual core::vector3df getAbsolutePosition() const
00513 {
00514 return AbsoluteTransformation.getTranslation();
00515 }
00516
00517
00519
00524 void setAutomaticCulling( E_CULLING_TYPE state)
00525 {
00526 AutomaticCullingState = state;
00527 }
00528
00529
00531
00532 E_CULLING_TYPE getAutomaticCulling() const
00533 {
00534 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00535 return AutomaticCullingState;
00536 }
00537
00538
00540
00543 virtual void setDebugDataVisible(s32 state)
00544 {
00545 DebugDataVisible = state;
00546 }
00547
00549
00551 s32 isDebugDataVisible() const
00552 {
00553 return DebugDataVisible;
00554 }
00555
00556
00558
00560 void setIsDebugObject(bool debugObject)
00561 {
00562 IsDebugObject = debugObject;
00563 }
00564
00565
00567
00570 bool isDebugObject() const
00571 {
00572 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
00573 return IsDebugObject;
00574 }
00575
00576
00578
00579 const core::list<ISceneNode*>& getChildren() const
00580 {
00581 return Children;
00582 }
00583
00584
00586
00587 virtual void setParent(ISceneNode* newParent)
00588 {
00589 grab();
00590 remove();
00591
00592 Parent = newParent;
00593
00594 if (Parent)
00595 Parent->addChild(this);
00596
00597 drop();
00598 }
00599
00600
00602
00611 virtual ITriangleSelector* getTriangleSelector() const
00612 {
00613 return TriangleSelector;
00614 }
00615
00616
00618
00626 virtual void setTriangleSelector(ITriangleSelector* selector)
00627 {
00628 if (TriangleSelector != selector)
00629 {
00630 if (TriangleSelector)
00631 TriangleSelector->drop();
00632
00633 TriangleSelector = selector;
00634 if (TriangleSelector)
00635 TriangleSelector->grab();
00636 }
00637 }
00638
00639
00641
00643 virtual void updateAbsolutePosition()
00644 {
00645 if (Parent)
00646 {
00647 AbsoluteTransformation =
00648 Parent->getAbsoluteTransformation() * getRelativeTransformation();
00649 }
00650 else
00651 AbsoluteTransformation = getRelativeTransformation();
00652 }
00653
00654
00656
00657 scene::ISceneNode* getParent() const
00658 {
00659 return Parent;
00660 }
00661
00662
00664
00665 virtual ESCENE_NODE_TYPE getType() const
00666 {
00667 return ESNT_UNKNOWN;
00668 }
00669
00670
00672
00678 virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
00679 {
00680 if (!out)
00681 return;
00682 out->addString ("Name", Name.c_str());
00683 out->addInt ("Id", ID );
00684
00685 out->addVector3d("Position", getPosition() );
00686 out->addVector3d("Rotation", getRotation() );
00687 out->addVector3d("Scale", getScale() );
00688
00689 out->addBool ("Visible", IsVisible );
00690 out->addEnum ("AutomaticCulling", AutomaticCullingState, AutomaticCullingNames);
00691 out->addInt ("DebugDataVisible", DebugDataVisible );
00692 out->addBool ("IsDebugObject", IsDebugObject );
00693 }
00694
00695
00697
00703 virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
00704 {
00705 if (!in)
00706 return;
00707 Name = in->getAttributeAsString("Name");
00708 ID = in->getAttributeAsInt("Id");
00709
00710 setPosition(in->getAttributeAsVector3d("Position"));
00711 setRotation(in->getAttributeAsVector3d("Rotation"));
00712 setScale(in->getAttributeAsVector3d("Scale"));
00713
00714 IsVisible = in->getAttributeAsBool("Visible");
00715 AutomaticCullingState = (scene::E_CULLING_TYPE) in->getAttributeAsEnumeration("AutomaticCulling",
00716 scene::AutomaticCullingNames);
00717
00718 DebugDataVisible = in->getAttributeAsInt("DebugDataVisible");
00719 IsDebugObject = in->getAttributeAsBool("IsDebugObject");
00720
00721 updateAbsolutePosition();
00722 }
00723
00725
00728 virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0)
00729 {
00730 return 0;
00731 }
00732
00734
00735 virtual ISceneManager* getSceneManager(void) const { return SceneManager; }
00736
00737 protected:
00738
00740
00744 void cloneMembers(ISceneNode* toCopyFrom, ISceneManager* newManager)
00745 {
00746 Name = toCopyFrom->Name;
00747 AbsoluteTransformation = toCopyFrom->AbsoluteTransformation;
00748 RelativeTranslation = toCopyFrom->RelativeTranslation;
00749 RelativeRotation = toCopyFrom->RelativeRotation;
00750 RelativeScale = toCopyFrom->RelativeScale;
00751 ID = toCopyFrom->ID;
00752 setTriangleSelector(toCopyFrom->TriangleSelector);
00753 AutomaticCullingState = toCopyFrom->AutomaticCullingState;
00754 DebugDataVisible = toCopyFrom->DebugDataVisible;
00755 IsVisible = toCopyFrom->IsVisible;
00756 IsDebugObject = toCopyFrom->IsDebugObject;
00757
00758 if (newManager)
00759 SceneManager = newManager;
00760 else
00761 SceneManager = toCopyFrom->SceneManager;
00762
00763
00764
00765 ISceneNodeList::Iterator it = toCopyFrom->Children.begin();
00766 for (; it != toCopyFrom->Children.end(); ++it)
00767 (*it)->clone(this, newManager);
00768
00769
00770
00771 ISceneNodeAnimatorList::Iterator ait = toCopyFrom->Animators.begin();
00772 for (; ait != toCopyFrom->Animators.end(); ++ait)
00773 {
00774 ISceneNodeAnimator* anim = (*ait)->createClone(this, SceneManager);
00775 if (anim)
00776 {
00777 addAnimator(anim);
00778 anim->drop();
00779 }
00780 }
00781 }
00782
00785 void setSceneManager(ISceneManager* newManager)
00786 {
00787 SceneManager = newManager;
00788
00789 ISceneNodeList::Iterator it = Children.begin();
00790 for (; it != Children.end(); ++it)
00791 (*it)->setSceneManager(newManager);
00792 }
00793
00795 core::stringc Name;
00796
00798 core::matrix4 AbsoluteTransformation;
00799
00801 core::vector3df RelativeTranslation;
00802
00804 core::vector3df RelativeRotation;
00805
00807 core::vector3df RelativeScale;
00808
00810 ISceneNode* Parent;
00811
00813 core::list<ISceneNode*> Children;
00814
00816 core::list<ISceneNodeAnimator*> Animators;
00817
00819 ISceneManager* SceneManager;
00820
00822 ITriangleSelector* TriangleSelector;
00823
00825 s32 ID;
00826
00828 E_CULLING_TYPE AutomaticCullingState;
00829
00831 s32 DebugDataVisible;
00832
00834 bool IsVisible;
00835
00837 bool IsDebugObject;
00838 };
00839
00840
00841 }
00842 }
00843
00844 #endif
00845