1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: gfx_SceneHelper.h 4 5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain proprietary 8 information of Nintendo and/or its licensed developers and are protected by 9 national and international copyright laws. They may not be disclosed to third 10 parties or copied or duplicated in any form, in whole or in part, without the 11 prior written consent of Nintendo. 12 13 The content herein is highly confidential and should be handled accordingly. 14 15 $Revision: $ 16 *---------------------------------------------------------------------------*/ 17 18 19 #ifndef NW_GFX_SCENEHELPER_H_ 20 #define NW_GFX_SCENEHELPER_H_ 21 22 #include <nw/gfx/gfx_SceneNode.h> 23 #include <nw/ut/ut_MoveArray.h> 24 25 namespace nw 26 { 27 namespace gfx 28 { 29 30 //! @brief シーンオブジェクトが持つリソースから、シーンの親子関係を各ノードに設定するライブラリクラスです。 31 class SceneHelper 32 { 33 private: 34 SceneHelper(); 35 NW_DISALLOW_COPY_AND_ASSIGN(SceneHelper); 36 37 public: 38 //! @brief シーンツリーの参照構造を解決します。 39 //! 40 //! @tparam TIterator シーンツリーが格納されるコレクションのイテレータです。 41 //! @param[in] begin 解決したいシーンノードのコレクションの先頭です。 42 //! @param[in] end 解決したいシーンノードのコレクションの終端です。 43 //! 44 template<typename TIterator> ResolveReference(TIterator begin,TIterator end)45 static void ResolveReference(TIterator begin, TIterator end) 46 { 47 for (TIterator parent = begin; parent != end; ++parent) 48 { 49 for (TIterator child = begin; child != end; ++child) 50 { 51 NW_NULL_ASSERT(ut::DynamicCast<SceneNode*>(*child)); 52 ResolveReferenceImpl(*parent, *child); 53 } 54 } 55 } 56 57 //! シーンツリーの参照解決の別インターフェースです。 58 template<typename TIterator> ResolveReference(const std::pair<TIterator,TIterator> & range)59 static void ResolveReference(const std::pair<TIterator, TIterator>& range) 60 { 61 ResolveReference<TIterator>(range.first, range.second); 62 } 63 64 //! シーンツリーの参照解決の別インターフェースです。 65 template<typename TNode, int TSize> ResolveReference(TNode (& nodes)[TSize])66 static void ResolveReference(TNode (&nodes)[TSize]) 67 { 68 ResolveReference<TNode*>(nodes, nodes + TSize); 69 } 70 71 //! シーンツリーの参照解決の別インターフェースです。 72 template<typename TNodeArray> ResolveReference(TNodeArray & nodes)73 static void ResolveReference(TNodeArray& nodes) 74 { 75 ResolveReference<TNodeArray::iterator>(nodes.begin(), nodes.end()); 76 } 77 78 //! @brief シーンノードの集合から、親がNULLのノードに対して処理を行います。 79 //! 80 //! @tparam TIterator シーンノードの集合のイテレータです。 81 //! @tparam TFunction 親がNULLのシーンノードに行う処理です。 82 //! @param begin シーンノードのコレクションの先頭です。 83 //! @param end シーンノードのコレクションの終端です。 84 //! @param function シーンノードに行う処理です。 85 //! 86 template <typename TIterator, typename TFunction> 87 static void ForeachRootNodes(TIterator begin,TIterator end,TFunction function)88 ForeachRootNodes(TIterator begin, TIterator end, TFunction function) 89 { 90 for (TIterator iter = begin; iter != end; ++iter) 91 { 92 if ((*iter)->GetParent() == NULL) 93 { 94 function(*iter); 95 } 96 } 97 } 98 99 //---------------------------------------- 100 //! @name 深度計算 101 //@{ 102 103 //! @brief クリップ座標系での深度を計算します。 CalculateDepth(const math::VEC3 & localPosition,const math::MTX34 & worldMatrix,const Camera & camera)104 static float CalculateDepth( 105 const math::VEC3& localPosition, 106 const math::MTX34& worldMatrix, 107 const Camera& camera) 108 { 109 math::VEC3 position; 110 math::VEC3Transform(&position, &worldMatrix, &localPosition); 111 math::VEC3Transform(&position, &camera.ViewMatrix(), &position); 112 const math::MTX44& projection = camera.ProjectionMatrix(); 113 float z = 114 projection.f._20 * position.x + 115 projection.f._21 * position.y + 116 projection.f._22 * position.z + 117 projection.f._23; 118 float w = 119 projection.f._30 * position.x + 120 projection.f._31 * position.y + 121 projection.f._32 * position.z + 122 projection.f._33; 123 // クリップ座標系の Z 深度は 0 ~ -w の範囲になるので、 124 // 0 ~ 1.0 の範囲になるように変換します。 125 return ut::Clamp(-z / w, 0.0f, 1.0f); 126 } 127 128 //! @brief クリップ座標系での深度を計算します。 CalculateDepth(const math::MTX34 & worldMatrix,const Camera & camera)129 static float CalculateDepth( 130 const math::MTX34& worldMatrix, 131 const Camera& camera) 132 { 133 math::VEC3 position(worldMatrix.GetColumn(3)); 134 math::VEC3Transform(&position, &camera.ViewMatrix(), &position); 135 const math::MTX44& projection = camera.ProjectionMatrix(); 136 float z = 137 projection.f._20 * position.x + 138 projection.f._21 * position.y + 139 projection.f._22 * position.z + 140 projection.f._23; 141 float w = 142 projection.f._30 * position.x + 143 projection.f._31 * position.y + 144 projection.f._32 * position.z + 145 projection.f._33; 146 // クリップ座標系の Z 深度は 0 ~ -w の範囲になるので、 147 // 0 ~ 1.0 の範囲になるように変換します。 148 return ut::Clamp(-z / w, 0.0f, 1.0f); 149 } 150 151 //@} 152 153 private: 154 // シーンツリー解釈の内部実装。 155 static void ResolveReferenceImpl(SceneNode* parent, SceneNode* child); 156 }; 157 158 //! @brief シーンノードに子を取り付けるための関数オブジェクトです。 159 class AttachNode 160 { 161 public: 162 //! @brief コンストラクタです。 163 //! 164 //! @param[in] parent 取り付ける親ノードです。 AttachNode(nw::gfx::SceneNode * parent)165 AttachNode(nw::gfx::SceneNode* parent) 166 : m_Parent(parent) 167 {} 168 169 //! @brief 親ノードに子を取り付けます。 170 //! 171 //! @param[in] node 取り付けられるオブジェクトです。 172 template <typename TNode> operator()173 void operator() (TNode* node) 174 { 175 NW_POINTER_ASSERT(m_Parent); 176 m_Parent->AttachChild(node); 177 } 178 179 private: 180 nw::gfx::SceneNode* m_Parent; 181 }; 182 183 } // namespace gfx 184 } // namespace nw 185 186 #endif // NW_GFX_SCENEHELPER_H_ 187