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