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