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 //------------------------------------------------------------------------------