Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

SceneNode.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // Lamp : Open source game middleware
00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //------------------------------------------------------------------------------
00019 
00020 /** @file
00021  * シーンノード実装
00022  * @author Junpee
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 // parent_->traverseでは?微妙2通り用意する?
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     // 前回がdisabledでdisabledのままならトラバースしない
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 } // End of namespace Lamp
00174 //------------------------------------------------------------------------------

Generated on Wed Mar 16 10:29:35 2005 for Lamp by doxygen 1.3.2