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