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: 27306 $
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     this->m_SceneContext->PushAnimatableNode(fog);
123 }
124 
125 //----------------------------------------
VisitLight(Light * light)126 void SceneTraverser::VisitLight(Light* light)
127 {
128     NW_UNUSED_VARIABLE(light);
129     this->m_SceneContext->PushSceneNode(light);
130     this->m_SceneContext->PushLight(light);
131     this->m_SceneContext->PushAnimatableNode(light);
132 }
133 
134 //----------------------------------------
VisitFragmentLight(FragmentLight * light)135 void SceneTraverser::VisitFragmentLight(FragmentLight* light)
136 {
137     NW_NULL_ASSERT(this->m_SceneContext);
138     this->m_SceneContext->PushSceneNode(light);
139     this->m_SceneContext->PushLight(light);
140     this->m_SceneContext->PushFragmentLight(light);
141     this->m_SceneContext->PushAnimatableNode(light);
142 }
143 
144 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
145 //----------------------------------------
VisitVertexLight(VertexLight * light)146 void SceneTraverser::VisitVertexLight(VertexLight* 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->PushVertexLight(light);
152     this->m_SceneContext->PushAnimatableNode(light);
153 }
154 #endif
155 
156 //----------------------------------------
VisitAmbientLight(AmbientLight * light)157 void SceneTraverser::VisitAmbientLight(AmbientLight* 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->PushAmbientLight(light);
163     this->m_SceneContext->PushAnimatableNode(light);
164 }
165 
166 //----------------------------------------
VisitHemiSphereLight(HemiSphereLight * light)167 void SceneTraverser::VisitHemiSphereLight(HemiSphereLight* light)
168 {
169     NW_NULL_ASSERT(this->m_SceneContext);
170     this->m_SceneContext->PushSceneNode(light);
171     this->m_SceneContext->PushLight(light);
172     this->m_SceneContext->PushHemiSphereLight(light);
173     this->m_SceneContext->PushAnimatableNode(light);
174 }
175 
176 //----------------------------------------
VisitParticleSet(ParticleSet * particleSet)177 void SceneTraverser::VisitParticleSet(ParticleSet* particleSet)
178 {
179     particleSet->CopyTraversalResults(particleSet->GetParent());
180 
181     NW_NULL_ASSERT(this->m_SceneContext);
182     this->m_SceneContext->PushSceneNode(particleSet);
183     this->m_SceneContext->PushParticleSet(particleSet);
184 }
185 
186 //----------------------------------------
VisitParticleEmitter(ParticleEmitter * particleEmitter)187 void SceneTraverser::VisitParticleEmitter(ParticleEmitter* particleEmitter)
188 {
189     NW_NULL_ASSERT(this->m_SceneContext);
190     this->m_SceneContext->PushSceneNode(particleEmitter);
191     this->m_SceneContext->PushParticleEmitter(particleEmitter);
192 }
193 
194 //----------------------------------------
VisitParticleModel(ParticleModel * model)195 void SceneTraverser::VisitParticleModel(ParticleModel* model)
196 {
197     NW_NULL_ASSERT(this->m_SceneContext);
198     this->m_SceneContext->PushSceneNode(model);
199     this->m_SceneContext->PushModel(model);
200     this->m_SceneContext->PushParticleModel(model);
201 }
202 
203 } // namespace gfx
204 } // namespace nw
205