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