1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     SmSceneCtrl.cpp
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 #include "../include/SmSceneCtrl.h"
19 
20 
21 //----------------------------------------
22 //
23 struct RenderSceneInternalFunctor
24     : public std::unary_function<nw::gfx::RenderElement&, void>
25 {
26     nw::gfx::RenderContext* m_RenderContext;
27     nw::gfx::MeshRenderer* m_MeshRenderer;
28 
RenderSceneInternalFunctorRenderSceneInternalFunctor29     RenderSceneInternalFunctor(nw::gfx::RenderContext* renderContext, nw::gfx::MeshRenderer* meshRenderer)
30     : m_RenderContext(renderContext), m_MeshRenderer(meshRenderer)
31     {
32         NW_NULL_ASSERT(renderContext);
33         NW_NULL_ASSERT(meshRenderer);
34     }
35 
operator ()RenderSceneInternalFunctor36     void operator()(nw::gfx::RenderElement& element)
37     {
38         if (element.IsCommand())
39         {
40             nw::gfx::RenderCommand* command = element.GetCommand();
41             NW_NULL_ASSERT(command);
42             command->Invoke(m_RenderContext);
43         }
44         else
45         {
46             nw::gfx::ResMesh mesh = element.GetMesh();
47             nw::gfx::Model* model = element.GetModel();
48             model->PreRenderSignal()(model, mesh, m_RenderContext);
49             m_MeshRenderer->RenderMesh(mesh, model);
50             model->PostRenderSignal()(model, mesh, m_RenderContext);
51         }
52         NW_GL_ASSERT();
53     }
54 };
55 
56 
57 //----------------------------------------
58 // コンストラクタ
SmSceneCtrl(nw::gfx::RenderContext * renderContext)59 SmSceneCtrl::SmSceneCtrl( nw::gfx::RenderContext* renderContext )
60 : m_SceneContext( NULL ),
61   m_SceneTraverser( NULL ),
62   m_SceneUpdater( NULL ),
63   m_SceneInitializer( NULL ),
64   m_RenderContext( renderContext ),
65   m_PriorMaterialRenderKeyFactory( NULL ),
66   m_PriorDepthRenderKeyFactory( NULL ),
67   m_RenderQueue( NULL ),
68   m_MeshRenderer( NULL )
69 {
70     m_SceneContext = nw::gfx::SceneContext::Builder()
71         .MaxSceneNodes( 128 ).MaxModels(128).Create( m_Allocator );
72 
73     m_SceneTraverser = nw::gfx::SceneTraverser::Builder()
74         .Create( m_Allocator );
75 
76     nw::gfx::WorldMatrixUpdater* worldMatrixUpdater = nw::gfx::WorldMatrixUpdater::Builder()
77         .Create( m_Allocator );
78 
79     nw::gfx::SkeletonUpdater* skeletonUpdater = nw::gfx::SkeletonUpdater::Builder()
80         .Create( m_Allocator );
81 
82     m_SceneUpdater = nw::gfx::SceneUpdater::Builder()
83         .WorldMatrixUpdaterPtr(worldMatrixUpdater)
84         .SkeletonUpdaterPtr(skeletonUpdater)
85         .Create( m_Allocator );
86 
87     nw::gfx::IMaterialIdGenerator* materialIdGenerator =
88         nw::gfx::SortingMaterialIdGenerator::Builder()
89         .IsFixedSizeMemory(true)
90         .MaxMaterials(128)
91         .Create(m_Allocator);
92 
93     m_SceneInitializer = nw::gfx::SceneInitializer::Builder()
94         .MaterialIdGenerator(materialIdGenerator)
95         .Create( m_Allocator );
96 
97     m_PriorMaterialRenderKeyFactory =
98         nw::gfx::CreatePriorMaterialRenderKeyFactory( m_Allocator );
99 
100     m_PriorDepthRenderKeyFactory =
101         nw::gfx::CreatePriorDepthReverseDepthRenderKeyFactory( m_Allocator );
102 
103     m_RenderQueue = nw::gfx::RenderQueue::Builder()
104         .MaxRenderElements(512)
105         .Create( m_Allocator );
106 
107     m_RenderQueue->Reset(
108         m_PriorMaterialRenderKeyFactory,
109         m_PriorDepthRenderKeyFactory,
110         m_PriorMaterialRenderKeyFactory,
111         m_PriorMaterialRenderKeyFactory);
112 
113     m_MeshRenderer = nw::gfx::MeshRenderer::Create( m_Allocator );
114     m_MeshRenderer->SetRenderContext( m_RenderContext );
115 }
116 
117 
118 //----------------------------------------
119 // デストラクタ
~SmSceneCtrl()120 SmSceneCtrl::~SmSceneCtrl()
121 {
122     nw::gfx::SafeDestroy(m_SceneInitializer);
123     nw::gfx::SafeDestroy(m_SceneTraverser);
124     nw::gfx::SafeDestroy(m_SceneUpdater);
125     nw::gfx::SafeDestroy(m_SceneContext);
126 
127 
128     nw::gfx::SafeDestroy(m_MeshRenderer);
129     nw::gfx::SafeDestroy(m_RenderQueue);
130     nw::gfx::SafeDestroy(m_PriorMaterialRenderKeyFactory);
131     nw::gfx::SafeDestroy(m_PriorDepthRenderKeyFactory);
132 }
133 
134 
135 //----------------------------------------
136 // シーンを更新する
137 void
UpdateScene()138 SmSceneCtrl::UpdateScene()
139 {
140     m_SceneUpdater->UpdateAll(m_SceneContext);
141 }
142 
143 
144 //----------------------------------------
145 // シーンを初期化する
146 void
InitializeScene(nw::gfx::SceneNode * sceneRoot)147 SmSceneCtrl::InitializeScene(nw::gfx::SceneNode* sceneRoot)
148 {
149     m_SceneTraverser->Begin(m_SceneContext);
150     sceneRoot->Accept(m_SceneInitializer);
151     m_SceneTraverser->End();
152 
153     TraverseScene(sceneRoot);
154 }
155 
156 
157 //----------------------------------------
158 void
TraverseScene(nw::gfx::SceneNode * sceneRoot)159 SmSceneCtrl::TraverseScene(nw::gfx::SceneNode* sceneRoot)
160 {
161     this->m_SceneTraverser->Begin(this->m_SceneContext);
162     sceneRoot->Accept(this->m_SceneTraverser);
163     this->m_SceneTraverser->End();
164 
165     // パーティクルセットの依存順でソートする
166     std::sort(
167         this->m_SceneContext->GetParticleSetBegin(),
168         this->m_SceneContext->GetParticleSetEnd(),
169         nw::gfx::ParticleSetCompare());
170 }
171 
172 //----------------------------------------
173 void
SetSceneEnvironmentSetting(nw::gfx::SceneEnvironmentSetting * sceneEnvironmentSetting)174 SmSceneCtrl::SetSceneEnvironmentSetting( nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting )
175 {
176     nw::gfx::SceneEnvironment& sceneEnvironment = m_RenderContext->GetSceneEnvironment();
177     sceneEnvironmentSetting->ResolveReference(*m_SceneContext);
178     sceneEnvironment.ApplyFrom(*sceneEnvironmentSetting);
179 }
180 
181 
182 
183 //----------------------------------------
184 // カメラの視界に基づいてシーンを更新し、描画キューを構築します。
185 void
SubmitView(nw::gfx::Camera * currentCamera)186 SmSceneCtrl::SubmitView( nw::gfx::Camera* currentCamera )
187 {
188     nw::gfx::SceneEnvironment& sceneEnvironment = m_RenderContext->GetSceneEnvironment();
189 //    nw::gfx::Camera* camera = sceneEnvironment.GetActiveCamera();
190 
191     // Fog を更新します。
192     nw::gfx::FogArray::iterator fogEnd = m_SceneContext->GetFogEnd();
193     for (nw::gfx::FogArray::iterator fog = m_SceneContext->GetFogBegin();
194         fog != fogEnd;
195         ++fog)
196     {
197         if (*fog != NULL)
198         {
199             (*fog)->Update( currentCamera );
200         }
201     }
202 
203     m_RenderQueue->Reset();
204     m_SceneUpdater->SubmitView( m_RenderQueue, m_SceneContext, *currentCamera, 0 );
205 
206     // ソートする
207     std::sort( m_RenderQueue->Begin(), m_RenderQueue->End(), nw::gfx::RenderElementCompare());
208 }
209 
210 //----------------------------------------
211 // 描画を行います。
212 void
Render()213 SmSceneCtrl::Render()
214 {
215 //    m_RenderContext->SetCameraMatrix(camera);
216 
217     std::for_each(
218         m_RenderQueue->Begin(),
219         m_RenderQueue->End(),
220         RenderSceneInternalFunctor(m_RenderContext, m_MeshRenderer));
221 }
222 
223 
224 //----------------------------------------
225 // ログを出力します。
226 void
OutputLog()227 SmSceneCtrl::OutputLog()
228 {
229     // m_SceneContextが保持するノードの状況を出力します。
230     {
231         u32 cnt = 0;
232         {
233             nw::gfx::SceneContext::SceneNodeArray::iterator end = m_SceneContext->GetSceneNodesEnd();
234             for (nw::gfx::SceneContext::SceneNodeArray::iterator i = m_SceneContext->GetSceneNodesBegin(); i != end;)
235             {
236                 i++;
237                 cnt++;
238             }
239             NW_DEV_LOG( "SceneContex:SceneNode Num %d\n", cnt );
240             cnt = 0;
241         }
242 
243         {
244             nw::gfx::SceneContext::ModelArray::iterator end = m_SceneContext->GetModelsEnd();
245             for (nw::gfx::SceneContext::ModelArray::iterator i = m_SceneContext->GetModelsBegin(); i != end;)
246             {
247                 i++;
248                 cnt++;
249             }
250             NW_DEV_LOG( "SceneContex:ModelArray Num %d\n", cnt );
251             cnt = 0;
252         }
253 
254         {
255             nw::gfx::SceneContext::ParticleModelArray::iterator end = m_SceneContext->GetParticleModelEnd();
256             for (nw::gfx::SceneContext::ParticleModelArray::iterator i = m_SceneContext->GetParticleModelBegin(); i != end;)
257             {
258                 i++;
259                 cnt++;
260             }
261             NW_DEV_LOG( "SceneContex:Particle Model Array Num %d\n", cnt );
262             cnt = 0;
263         }
264 
265         {
266             nw::gfx::SceneContext::ParticleSetArray::iterator end = m_SceneContext->GetParticleSetEnd();
267             for (nw::gfx::SceneContext::ParticleSetArray::iterator i = m_SceneContext->GetParticleSetBegin(); i != end;)
268             {
269                 i++;
270                 cnt++;
271             }
272             NW_DEV_LOG( "SceneContex:Particle Set Array Num %d\n", cnt );
273             cnt = 0;
274         }
275     }
276 
277 }
278 
279 
280 #if 0
281 //----------------------------------------
282 // 描画環境をセットする
283 void
284 SmSceneCtrl::SetEnvironment( s32 cameraIndex )
285 {
286     NW_UNUSED_VARIABLE(cameraIndex);
287 
288     nw::gfx::SceneEnvironment& sceneEnvironment = m_RenderContext->GetSceneEnvironment();
289 
290 //    sceneEnvironment.SetActiveCamera(cameraIndex);
291     m_RenderContext->SetActiveCamera(cameraIndex);
292 
293     if (m_SceneContext->GetAmbientLightsBegin() != m_SceneContext->GetAmbientLightsEnd())
294     {
295         sceneEnvironment.SetAmbientLight(*m_SceneContext->GetAmbientLightsBegin());
296     }
297 
298     if (m_SceneContext->GetHemiSphereLightsBegin() != m_SceneContext->GetHemiSphereLightsEnd())
299     {
300         sceneEnvironment.SetHemiSphereLight(*m_SceneContext->GetHemiSphereLightsBegin());
301     }
302 
303     std::for_each(
304         m_SceneContext->GetFragmentLightsBegin(),
305         m_SceneContext->GetFragmentLightsEnd(),
306         std::bind1st(std::mem_fun(&nw::gfx::SceneEnvironment::SetFragmentLight), &sceneEnvironment));
307 
308     std::for_each(
309         m_SceneContext->GetVertexLightsBegin(),
310         m_SceneContext->GetVertexLightsEnd(),
311         std::bind1st(std::mem_fun(&nw::gfx::SceneEnvironment::SetVertexLight), &sceneEnvironment));
312 
313     if (m_SceneContext->GetFogBegin() != m_SceneContext->GetFogEnd())
314     {
315         sceneEnvironment.SetFog(0, *m_SceneContext->GetFogBegin());
316     }
317 }
318 #endif
319