1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_SceneTraverser.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: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #include "precompiled.h"
19 
20 #include <nw/gfx/gfx_SceneTraverser.h>
21 #include <nw/gfx/gfx_SceneContext.h>
22 #include <nw/gfx/gfx_SceneNode.h>
23 #include <nw/gfx/gfx_TransformNode.h>
24 #include <nw/gfx/gfx_UserRenderNode.h>
25 #include <nw/gfx/gfx_Model.h>
26 #include <nw/gfx/gfx_SkeletalModel.h>
27 #include <nw/gfx/gfx_Camera.h>
28 #include <nw/gfx/gfx_Fog.h>
29 #include <nw/gfx/gfx_FragmentLight.h>
30 #include <nw/gfx/gfx_VertexLight.h>
31 #include <nw/gfx/gfx_AmbientLight.h>
32 #include <nw/gfx/gfx_HemiSphereLight.h>
33 #include <nw/gfx/gfx_ParticleSet.h>
34 
35 namespace nw
36 {
37 namespace gfx
38 {
39 
40 NW_UT_RUNTIME_TYPEINFO_DEFINITION(SceneTraverser, ISceneVisitor);
41 
42 //----------------------------------------
43 SceneTraverser*
Create(os::IAllocator * allocator)44 SceneTraverser::Builder::Create(
45     os::IAllocator* allocator
46 )
47 {
48     NW_NULL_ASSERT(allocator);
49 
50     void* memory = allocator->Alloc(sizeof(SceneTraverser));
51     NW_NULL_ASSERT(memory);
52 
53     SceneTraverser* traverser = new(memory) SceneTraverser(allocator);
54 
55     return traverser;
56 }
57 
58 //----------------------------------------
Begin(SceneContext * sceneContext)59 void SceneTraverser::Begin(SceneContext* sceneContext)
60 {
61     NW_NULL_ASSERT(sceneContext);
62 
63     this->m_SceneContext = sceneContext;
64 
65     // TODO: 現在はシーンノードの直列化の結果を初期化してますが、
66     //       必要時のみクリアするように検討中です。
67     this->m_SceneContext->Clear();
68 }
69 
70 //----------------------------------------
End()71 void SceneTraverser::End()
72 {
73     NW_NULL_ASSERT(this->m_SceneContext);
74     this->m_SceneContext = NULL;
75 }
76 
77 //----------------------------------------
VisitSceneNode(SceneNode * node)78 void SceneTraverser::VisitSceneNode(SceneNode* node)
79 {
80     NW_NULL_ASSERT(this->m_SceneContext);
81     this->m_SceneContext->PushSceneNode(node);
82 }
83 
84 //----------------------------------------
VisitTransformNode(TransformNode * node)85 void SceneTraverser::VisitTransformNode(TransformNode* node)
86 {
87     NW_NULL_ASSERT(this->m_SceneContext);
88     this->m_SceneContext->PushSceneNode(node);
89 }
90 
91 //----------------------------------------
VisitUserRenderNode(UserRenderNode * node)92 void SceneTraverser::VisitUserRenderNode(UserRenderNode* node)
93 {
94     NW_NULL_ASSERT(this->m_SceneContext);
95     this->m_SceneContext->PushSceneNode(node);
96     this->m_SceneContext->PushUserRenderNode(node);
97 }
98 
99 //----------------------------------------
VisitModel(Model * model)100 void SceneTraverser::VisitModel(Model* model)
101 {
102     NW_NULL_ASSERT(this->m_SceneContext);
103     this->m_SceneContext->PushSceneNode(model);
104     this->m_SceneContext->PushModel(model);
105     this->m_SceneContext->PushAnimatableNode(model);
106 }
107 
108 //----------------------------------------
VisitSkeletalModel(SkeletalModel * model)109 void SceneTraverser::VisitSkeletalModel(SkeletalModel* model)
110 {
111     NW_NULL_ASSERT(this->m_SceneContext);
112     this->m_SceneContext->PushSceneNode(model);
113     this->m_SceneContext->PushModel(model);
114     this->m_SceneContext->PushSkeletalModel(model);
115     this->m_SceneContext->PushAnimatableNode(model);
116 }
117 
118 //----------------------------------------
VisitCamera(Camera * camera)119 void SceneTraverser::VisitCamera(Camera* camera)
120 {
121     NW_NULL_ASSERT(this->m_SceneContext);
122     this->m_SceneContext->PushSceneNode(camera);
123     this->m_SceneContext->PushCamera(camera);
124     this->m_SceneContext->PushAnimatableNode(camera);
125 }
126 
127 //----------------------------------------
VisitFog(Fog * fog)128 void SceneTraverser::VisitFog(Fog* fog)
129 {
130     NW_NULL_ASSERT(this->m_SceneContext);
131     this->m_SceneContext->PushSceneNode(fog);
132     this->m_SceneContext->PushFog(fog);
133     this->m_SceneContext->PushAnimatableNode(fog);
134 }
135 
136 //----------------------------------------
VisitLight(Light * light)137 void SceneTraverser::VisitLight(Light* light)
138 {
139     NW_UNUSED_VARIABLE(light);
140     this->m_SceneContext->PushSceneNode(light);
141     this->m_SceneContext->PushLight(light);
142     this->m_SceneContext->PushAnimatableNode(light);
143 }
144 
145 //----------------------------------------
VisitFragmentLight(FragmentLight * light)146 void SceneTraverser::VisitFragmentLight(FragmentLight* light)
147 {
148     NW_NULL_ASSERT(this->m_SceneContext);
149     this->m_SceneContext->PushSceneNode(light);
150     this->m_SceneContext->PushLight(light);
151     this->m_SceneContext->PushFragmentLight(light);
152     this->m_SceneContext->PushAnimatableNode(light);
153 }
154 
155 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
156 //----------------------------------------
VisitVertexLight(VertexLight * light)157 void SceneTraverser::VisitVertexLight(VertexLight* light)
158 {
159     NW_NULL_ASSERT(this->m_SceneContext);
160     this->m_SceneContext->PushSceneNode(light);
161     this->m_SceneContext->PushLight(light);
162     this->m_SceneContext->PushVertexLight(light);
163     this->m_SceneContext->PushAnimatableNode(light);
164 }
165 #endif
166 
167 //----------------------------------------
VisitAmbientLight(AmbientLight * light)168 void SceneTraverser::VisitAmbientLight(AmbientLight* light)
169 {
170     NW_NULL_ASSERT(this->m_SceneContext);
171     this->m_SceneContext->PushSceneNode(light);
172     this->m_SceneContext->PushLight(light);
173     this->m_SceneContext->PushAmbientLight(light);
174     this->m_SceneContext->PushAnimatableNode(light);
175 }
176 
177 //----------------------------------------
VisitHemiSphereLight(HemiSphereLight * light)178 void SceneTraverser::VisitHemiSphereLight(HemiSphereLight* light)
179 {
180     NW_NULL_ASSERT(this->m_SceneContext);
181     this->m_SceneContext->PushSceneNode(light);
182     this->m_SceneContext->PushLight(light);
183     this->m_SceneContext->PushHemiSphereLight(light);
184     this->m_SceneContext->PushAnimatableNode(light);
185 }
186 
187 //----------------------------------------
VisitParticleSet(ParticleSet * particleSet)188 void SceneTraverser::VisitParticleSet(ParticleSet* particleSet)
189 {
190     particleSet->CopyTraversalResults(particleSet->GetParent());
191 
192     NW_NULL_ASSERT(this->m_SceneContext);
193     this->m_SceneContext->PushSceneNode(particleSet);
194     this->m_SceneContext->PushParticleSet(particleSet);
195 }
196 
197 //----------------------------------------
VisitParticleEmitter(ParticleEmitter * particleEmitter)198 void SceneTraverser::VisitParticleEmitter(ParticleEmitter* particleEmitter)
199 {
200     NW_NULL_ASSERT(this->m_SceneContext);
201     this->m_SceneContext->PushSceneNode(particleEmitter);
202     this->m_SceneContext->PushParticleEmitter(particleEmitter);
203 }
204 
205 //----------------------------------------
VisitParticleModel(ParticleModel * model)206 void SceneTraverser::VisitParticleModel(ParticleModel* model)
207 {
208     NW_NULL_ASSERT(this->m_SceneContext);
209     this->m_SceneContext->PushSceneNode(model);
210     this->m_SceneContext->PushModel(model);
211     this->m_SceneContext->PushParticleModel(model);
212     this->m_SceneContext->PushAnimatableNode(model);
213 }
214 
215 } // namespace gfx
216 } // namespace nw
217