00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Graphics/SceneNode/SceneNode.h"
00027 #include "Graphics/Scene/Scene.h"
00028 #include "Graphics/Camera/Camera.h"
00029 #include "Graphics/SceneNode/SceneNodeManager.h"
00030 #include "Graphics/Model/Model.h"
00031
00032 namespace Lamp{
00033
00034
00035
00036 SceneNode::SceneNode(const String& name, Scene* scene) :
00037 SceneObject(name, scene), worldMatrix_(Matrix34::unit),
00038 parent_(NULL), enabled_(true), globalEnabled_(true), globalScaled_(false),
00039 globalChanged_(true){
00040 }
00041
00042
00043 SceneNode::~SceneNode(){
00044 }
00045
00046
00047 SceneNode* SceneNode::copy(u_int copyMask) const{
00048 SceneNodeManager* manager = scene_->getSceneNodeManager();
00049 SceneNode* destination = manager->createSceneNode(manager->rename(name_));
00050 copySceneNodeValue(destination, copyMask);
00051 return destination;
00052 }
00053
00054
00055 int SceneNode::recursiveDestroy(SceneNode* sceneNode){
00056 Assert(sceneNode != sceneNode->getScene()->getRootNode());
00057 int result = recursiveDestroyChildren(sceneNode);
00058
00059 SceneNode* parent = sceneNode->getParent();
00060 if(parent != NULL){ parent->removeSceneNode(sceneNode); }
00061
00062 SceneNodeManager* manager = sceneNode->getScene()->getSceneNodeManager();
00063 if(manager->destroy(sceneNode) == 0){ result++; }
00064 return result;
00065 }
00066
00067
00068 int SceneNode::recursiveDestroyChildren(SceneNode* sceneNode){
00069 Assert(sceneNode != NULL);
00070 int result = 0;
00071
00072 for(int i = sceneNode->getSceneLeafCount() - 1; i >= 0; i--){
00073 result += SceneLeaf::recursiveDestroy(sceneNode->getSceneLeaf(i));
00074 }
00075
00076 for(int i = sceneNode->getSceneNodeCount() - 1; i >= 0; i--){
00077 result += recursiveDestroy(sceneNode->getSceneNode(i));
00078 }
00079 return result;
00080 }
00081
00082
00083 void SceneNode::copySceneNodeValue(
00084 SceneNode* destination, u_int copyMask) const{
00085 destination->axis_ = axis_;
00086 destination->setEnabled(enabled_);
00087
00088 int sceneLeafCount = getSceneLeafCount();
00089 for(int i = 0; i < sceneLeafCount; i++){
00090 destination->addSceneLeaf(getSceneLeaf(i)->copy(copyMask));
00091 }
00092
00093 int sceneNodeCount = getSceneNodeCount();
00094 for(int i = 0; i < sceneNodeCount; i++){
00095 destination->addSceneNode(getSceneNode(i)->copy(copyMask));
00096 }
00097 }
00098
00099
00100 void SceneNode::traverse(){
00101 const Vector3& cameraPosition = scene_->getCurrentCamera()->getPosition();
00102 if(parent_ == NULL){
00103 traverse(Matrix34::unit, cameraPosition, true, false, false);
00104 }else{
00105
00106 traverse(parent_->getWorldMatrix(), cameraPosition,
00107 parent_->isGlobalEnabled(), parent_->isGlobalScaled(),
00108 parent_->isGlobalChanged());
00109 }
00110 }
00111
00112
00113 void SceneNode::traverse(const Matrix34& parentMatrix,
00114 const Vector3& cameraPosition, bool parentEnabled, bool parentScaled,
00115 bool parentChanged){
00116 bool preGlobalEnabled = isGlobalEnabled();
00117 bool globalEnabled = (parentEnabled && isEnabled());
00118 setGlobalEnabled(globalEnabled);
00119
00120 if((!preGlobalEnabled) && (!globalEnabled)){ return; }
00121
00122
00123 bool globalChanged = calcMatrix(parentMatrix, parentChanged);
00124 setGlobalChanged(globalChanged);
00125
00126 bool globalScaled = (parentScaled || isScaled());
00127 setGlobalScaled(globalScaled);
00128
00129 int sceneNodeCount = getSceneNodeCount();
00130 for(int i = 0; i < sceneNodeCount; i++){
00131 getSceneNode(i)->traverse(worldMatrix_, cameraPosition,
00132 globalEnabled, globalScaled, globalChanged);
00133 }
00134
00135 int sceneLeafCount = getSceneLeafCount();
00136 for(int i = 0; i < sceneLeafCount; i++){
00137 getSceneLeaf(i)->traverse(worldMatrix_,
00138 globalEnabled, globalScaled, globalChanged);
00139 }
00140 }
00141
00142
00143 bool SceneNode::calcMatrix(const Matrix34& parentMatrix, bool parentChanged){
00144
00145 if(axis_.buildMatrix()){
00146 worldMatrix_ = parentMatrix * getLocalMatrix();
00147 return true;
00148 }
00149
00150 if(parentChanged){
00151
00152 worldMatrix_ = parentMatrix * getLocalMatrix();
00153 return true;
00154 }
00155
00156 Assert((parentMatrix * getLocalMatrix()).epsilonEquals(
00157 worldMatrix_, 0.0001f));
00158 return false;
00159 }
00160
00161
00162 void SceneNode::addSceneLeaf(SceneLeaf* sceneLeaf){
00163 sceneLeaf->setParent(this);
00164 sceneLeafs_.add(sceneLeaf);
00165 }
00166
00167
00168 void SceneNode::removeSceneLeaf(SceneLeaf* sceneLeaf){
00169 sceneLeaf->removeParent(this);
00170 sceneLeafs_.removeByValue(sceneLeaf);
00171 }
00172
00173 }
00174