1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: gfx_SceneUpdateHelper.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 #ifndef NW_GFX_SCENEUPDATEHELPER_H_ 19 #define NW_GFX_SCENEUPDATEHELPER_H_ 20 21 #include <nw/gfx/gfx_SceneContext.h> 22 #include <nw/gfx/gfx_SkeletalModel.h> 23 #include <nw/gfx/gfx_BillboardUpdater.h> 24 #include <nw/gfx/gfx_RenderQueue.h> 25 26 namespace nw 27 { 28 namespace gfx 29 { 30 31 //--------------------------------------------------------------------------- 32 //! @brief シーン更新の手助けをするライブラリクラスです。 33 //--------------------------------------------------------------------------- 34 class SceneUpdateHelper 35 { 36 public: 37 //--------------------------------------------------------------------------- 38 //! @brief カメラの視界に基づいてシーンを更新し、描画キューを構築する関数オブジェクトです。 39 //! 40 //! @tparam EnqueueModelMesh モデルをレンダーキューに積むための関数オブジェクトの型です。 41 //! @tparam EnqueueSkeletalModelFunctor スケルタルモデルをレンダーキューに積むための関数オブジェクトの型です。 42 //! @tparam IsVisibleModel 表示するモデルを識別するための関数オブジェクトの型です。 43 //--------------------------------------------------------------------------- 44 template< 45 typename EnqueueModelMesh, 46 typename EnqueueSkeletalModelMesh, 47 typename IsVisibleModel> 48 class SubmitViewFunctor : public std::unary_function<Model*, void> 49 { 50 public: 51 //! @brief コンストラクタです。 52 //! 53 //! @param[in] skeletonUpdater 54 //! @param[in] billboardUpdater 55 //! @param[in] renderQueue 描画対象となる要素を集めたキューです。 56 //! @param[in] camera カメラです。 57 //! @param[in] layerId 描画要素のソート時に最優先に区分される ID です。レイヤーやビューポートの描画を制御するのに用います。 58 //! @param[in] particleLayerId パーティクル描画用の layerId です。 59 //! @param[in] isVisibleModel 表示するモデルを識別するための関数オブジェクトです。 60 //! SubmitViewFunctor(SkeletonUpdater * skeletonUpdater,BillboardUpdater * billboardUpdater,RenderQueue * renderQueue,const Camera * camera,u8 layerId,u8 particleLayerId,IsVisibleModel * isVisibleModel)61 SubmitViewFunctor( 62 SkeletonUpdater* skeletonUpdater, 63 BillboardUpdater* billboardUpdater, 64 RenderQueue* renderQueue, 65 const Camera* camera, 66 u8 layerId, 67 u8 particleLayerId, 68 IsVisibleModel* isVisibleModel) 69 : m_SkeletonUpdater(skeletonUpdater), 70 m_BillboardUpdater(billboardUpdater), 71 m_RenderQueue(renderQueue), 72 m_Camera(camera), 73 m_LayerId(layerId), 74 m_ParticleLayerId(particleLayerId), 75 m_IsVisibleModel(isVisibleModel) {} 76 77 //! @brief カメラの視界に基づいてシーンを更新し、描画キューを構築します。 78 //! 79 //! @param[in] model 描画対象となるモデルです。 80 //! operator()81 void operator() (Model* model) 82 { 83 // スケルタルモデルの更新を行います。 84 SkeletalModel* skeletalModel = ut::DynamicCast<SkeletalModel*>(model); 85 86 if (skeletalModel) 87 { 88 Skeleton* skeleton = skeletalModel->GetSkeleton(); 89 // 必ず Skeleton の更新フラグを false に設定します。 90 skeleton->SetUpdated(false); 91 } 92 93 if (!m_IsVisibleModel->IsVisible(model)) { return; } 94 95 if (skeletalModel) 96 { 97 if (!skeletalModel->IsSharingSkeleton()) 98 { 99 this->m_SkeletonUpdater->UpdateView( 100 skeletalModel->GetSkeleton(), 101 *this->m_BillboardUpdater, 102 *this->m_Camera); 103 } 104 105 const Skeleton* skeleton = skeletalModel->GetSkeleton(); 106 ResSkeleton resSkeleton = skeleton->GetResSkeleton(); 107 108 bool isModelCoordinate = 109 ut::CheckFlag(resSkeleton.GetFlags(), ResSkeletonData::FLAG_MODEL_COORDINATE); 110 model->UpdateModelViewMatrixAndNormalMatrix(this->m_Camera->ViewMatrix(), isModelCoordinate); 111 112 u8 meshLayerId = m_LayerId | model->GetLayerId(); 113 114 // ZSort 用の深度を計算して、レンダーキューにメッシュを積みます。 115 gfx::ResMeshArray meshs = skeletalModel->GetResMeshes(); 116 std::for_each( 117 meshs.begin(), 118 meshs.end(), 119 EnqueueSkeletalModelMesh(this->m_RenderQueue, skeletalModel, meshLayerId, *this->m_Camera)); 120 } 121 else 122 { 123 model->UpdateModelViewMatrixAndNormalMatrix(this->m_Camera->ViewMatrix(), false); 124 125 u8 meshLayerId = 126 ut::IsTypeOf<ParticleModel>(model) 127 ? this->m_ParticleLayerId 128 : this->m_LayerId; 129 meshLayerId |= model->GetLayerId(); 130 131 // ZSort 用の深度を計算して、レンダーキューにメッシュを積みます。 132 gfx::ResMeshArray meshs = model->GetResMeshes(); 133 std::for_each( 134 meshs.begin(), 135 meshs.end(), 136 EnqueueModelMesh(this->m_RenderQueue, model, meshLayerId, *this->m_Camera)); 137 } 138 } 139 140 private: 141 SkeletonUpdater* m_SkeletonUpdater; 142 BillboardUpdater* m_BillboardUpdater; 143 RenderQueue* m_RenderQueue; 144 const Camera* m_Camera; 145 u8 m_LayerId; 146 u8 m_ParticleLayerId; 147 IsVisibleModel* m_IsVisibleModel; 148 }; 149 150 //! @brief カメラの視界に基づいてシーンを更新し、描画キューを構築します。 151 //! 152 //! @tparam IsVisibleModelFunctor 表示するモデルを識別するための関数オブジェクトの型です。 153 //! @param[in] skeletonUpdater スケルトンアップデータです。 154 //! @param[in] billboardUpdater ビルボードアップデータです。 155 //! @param[in] renderQueue 描画対象となる要素を集めたキューです。 156 //! @param[in] sceneContext シーンコンテキストです。 157 //! @param[in] camera カメラです。 158 //! @param[in] layerId 描画要素のソート時に最優先に区分される ID です。レイヤーやビューポートの描画を制御するのに用います。 159 //! @param[in] particleLayerId パーティクル描画用の layerId です。 160 //! @param[in] isVisibleModel 表示するモデルを識別するための関数オブジェクトです。 161 //! @param[in] renderSortMode 描画ソートモードです。 162 //! 163 template<typename IsVisibleModelFunctor> SubmitView(SkeletonUpdater * skeletonUpdater,BillboardUpdater * billboardUpdater,RenderQueue * renderQueue,SceneContext * sceneContext,const Camera & camera,u8 layerId,u8 particleLayerId,ISceneUpdater::RenderSortMode renderSortMode,ISceneUpdater::DepthSortMode depthSortMode,IsVisibleModelFunctor * isVisibleModel)164 static void SubmitView( 165 SkeletonUpdater* skeletonUpdater, 166 BillboardUpdater* billboardUpdater, 167 RenderQueue* renderQueue, 168 SceneContext* sceneContext, 169 const Camera& camera, 170 u8 layerId, 171 u8 particleLayerId, 172 ISceneUpdater::RenderSortMode renderSortMode, 173 ISceneUpdater::DepthSortMode depthSortMode, 174 IsVisibleModelFunctor* isVisibleModel) 175 { 176 NW_NULL_ASSERT(sceneContext); 177 178 if (depthSortMode == ISceneUpdater::SORT_DEPTH_OF_TRANSLUCENT_MESH) 179 { 180 // 半透明のメッシュのみ深度計算を行います。 181 // 不透明などのメッシュは深度によるソートがされなくなりますが、 182 // 深度計算分のCPUの処理負荷を削減します。 183 184 typedef SubmitViewFunctor< 185 RenderQueue::FastEnqueueModelFunctor, 186 RenderQueue::FastEnqueueSkeletalModelFunctor, 187 IsVisibleModelFunctor> FastMeshBaseSubmitViewFunctor; 188 189 typedef SubmitViewFunctor< 190 RenderQueue::EnqueueModelTranslucentModelBaseFunctor, 191 RenderQueue::EnqueueSkeletalModelTranslucentModelBaseFunctor, 192 IsVisibleModelFunctor> FastTranslucentModelBaseSubmitViewFunctor; 193 194 if (renderSortMode == ISceneUpdater::OPAQUE_MESH_BASE_AND_TRANSLUCENT_MODEL_BASE_SORT) 195 { 196 std::for_each( 197 sceneContext->GetModelsBegin(), 198 sceneContext->GetModelsEnd(), 199 FastTranslucentModelBaseSubmitViewFunctor( 200 skeletonUpdater, billboardUpdater, 201 renderQueue, &camera, layerId, particleLayerId, isVisibleModel)); 202 } 203 else 204 { 205 std::for_each( 206 sceneContext->GetModelsBegin(), 207 sceneContext->GetModelsEnd(), 208 FastMeshBaseSubmitViewFunctor( 209 skeletonUpdater, billboardUpdater, 210 renderQueue, &camera, layerId, particleLayerId, isVisibleModel)); 211 } 212 } 213 else 214 { 215 // すべてのメッシュの深度計算を行います。 216 217 typedef SubmitViewFunctor< 218 RenderQueue::EnqueueModelFunctor, 219 RenderQueue::EnqueueSkeletalModelFunctor, 220 IsVisibleModelFunctor> MeshBaseSubmitViewFunctor; 221 222 typedef SubmitViewFunctor< 223 RenderQueue::EnqueueModelTranslucentModelBaseFunctor, 224 RenderQueue::EnqueueSkeletalModelTranslucentModelBaseFunctor, 225 IsVisibleModelFunctor> TranslucentModelBaseSubmitViewFunctor; 226 227 if (renderSortMode == ISceneUpdater::OPAQUE_MESH_BASE_AND_TRANSLUCENT_MODEL_BASE_SORT) 228 { 229 std::for_each( 230 sceneContext->GetModelsBegin(), 231 sceneContext->GetModelsEnd(), 232 TranslucentModelBaseSubmitViewFunctor( 233 skeletonUpdater, billboardUpdater, 234 renderQueue, &camera, layerId, particleLayerId, isVisibleModel)); 235 } 236 else 237 { 238 std::for_each( 239 sceneContext->GetModelsBegin(), 240 sceneContext->GetModelsEnd(), 241 MeshBaseSubmitViewFunctor( 242 skeletonUpdater, billboardUpdater, 243 renderQueue, &camera, layerId, particleLayerId, isVisibleModel)); 244 } 245 } 246 } 247 248 private: SceneUpdateHelper()249 SceneUpdateHelper() {} ~SceneUpdateHelper()250 ~SceneUpdateHelper() {} 251 }; 252 253 254 } // namespace gfx 255 } // namespace nw 256 257 #endif // NW_GFX_SCENEUPDATEHELPER_H_ 258