1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_SceneUpdater.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_SceneUpdater.h>
19
20 #include <nw/gfx/gfx_SceneUpdateHelper.h>
21 #include <nw/gfx/gfx_SceneContext.h>
22 #include <nw/gfx/gfx_SkeletalModel.h>
23 #include <nw/gfx/gfx_ParticleModel.h>
24 #include <nw/gfx/gfx_ParticleSet.h>
25 #include <nw/gfx/res/gfx_ResShape.h>
26
27 #include <nw/dev.h>
28
29 namespace nw
30 {
31 namespace gfx
32 {
33
34 NW_UT_RUNTIME_TYPEINFO_DEFINITION(SceneUpdater, ISceneUpdater);
35
36 //----------------------------------------
37 SceneUpdater*
Create(os::IAllocator * allocator)38 SceneUpdater::Builder::Create(os::IAllocator* allocator)
39 {
40 NW_NULL_ASSERT(allocator);
41
42 if (!this->m_SkeletonUpdater)
43 {
44 this->m_SkeletonUpdater.Reset(SkeletonUpdater::Builder()
45 .Create(allocator));
46 }
47
48 if (!this->m_WorldMatrixUpdater)
49 {
50 this->m_WorldMatrixUpdater.Reset(WorldMatrixUpdater::Builder()
51 .Create(allocator));
52 }
53
54 if (!this->m_BillboardUpdater)
55 {
56 this->m_BillboardUpdater.Reset(BillboardUpdater::Create(allocator));
57 }
58
59 void* memory = allocator->Alloc(sizeof(SceneUpdater));
60 NW_NULL_ASSERT(memory);
61
62 return new(memory) SceneUpdater(
63 allocator,
64 this->m_SkeletonUpdater,
65 this->m_WorldMatrixUpdater,
66 this->m_BillboardUpdater);
67 }
68
69 //----------------------------------------
70 void
UpdateAll(SceneContext * sceneContext)71 SceneUpdater::UpdateAll(SceneContext* sceneContext)
72 {
73 NW_NULL_ASSERT(sceneContext);
74
75 this->EvaluateAnim(sceneContext, anim::ResGraphicsAnimGroup::EVALUATION_BEFORE_WORLD_UPDATE);
76 this->UpdateTransformNode(sceneContext);
77 // TODO: 将来、描画カリングを行う場合はここで処理する
78 this->EvaluateAnim(sceneContext, anim::ResGraphicsAnimGroup::EVALUATION_AFTER_SCENE_CULLING);
79 this->UpdateSkeletalModel(sceneContext);
80 this->UpdateAnim(sceneContext);
81 }
82
83 //----------------------------------------
84 void
SubmitView(RenderQueue * renderQueue,SceneContext * sceneContext,const Camera & camera,u8 layerId,RenderSortMode renderSortMode)85 SceneUpdater::SubmitView(
86 RenderQueue* renderQueue,
87 SceneContext* sceneContext,
88 const Camera& camera,
89 u8 layerId,
90 RenderSortMode renderSortMode)
91 {
92 Model::IsVisibleModelDefaultFunctor isVisibleModel;
93
94 SceneUpdateHelper::SubmitView(
95 this->m_SkeletonUpdater.Get(),
96 this->m_BillboardUpdater.Get(),
97 renderQueue,
98 sceneContext,
99 camera,
100 layerId,
101 layerId,
102 renderSortMode,
103 this->m_DepthSortMode,
104 &isVisibleModel);
105 }
106
107 //----------------------------------------
108 void
SubmitView(RenderQueue * renderQueue,SceneContext * sceneContext,const Camera & camera,u8 layerId,u8 particleLayerId,RenderSortMode renderSortMode)109 SceneUpdater::SubmitView(
110 RenderQueue* renderQueue,
111 SceneContext* sceneContext,
112 const Camera& camera,
113 u8 layerId,
114 u8 particleLayerId,
115 RenderSortMode renderSortMode)
116 {
117 Model::IsVisibleModelDefaultFunctor isVisibleModel;
118
119 SceneUpdateHelper::SubmitView(
120 this->m_SkeletonUpdater.Get(),
121 this->m_BillboardUpdater.Get(),
122 renderQueue,
123 sceneContext,
124 camera,
125 layerId,
126 particleLayerId,
127 renderSortMode,
128 this->m_DepthSortMode,
129 &isVisibleModel);
130 }
131
132 //----------------------------------------
133 void
SubmitView(RenderQueue * renderQueue,SceneContext * sceneContext,const Camera & camera,u8 layerId,u8 particleLayerId,SceneUpdater::IsVisibleModelFunctor * isVisibleModel,RenderSortMode renderSortMode)134 SceneUpdater::SubmitView(
135 RenderQueue* renderQueue,
136 SceneContext* sceneContext,
137 const Camera& camera,
138 u8 layerId,
139 u8 particleLayerId,
140 SceneUpdater::IsVisibleModelFunctor* isVisibleModel,
141 RenderSortMode renderSortMode)
142 {
143 SceneUpdateHelper::SubmitView(
144 this->m_SkeletonUpdater.Get(),
145 this->m_BillboardUpdater.Get(),
146 renderQueue,
147 sceneContext,
148 camera,
149 layerId,
150 particleLayerId,
151 renderSortMode,
152 this->m_DepthSortMode,
153 isVisibleModel);
154 }
155
156 //----------------------------------------
157 void
UpdateTransformNode(SceneContext * sceneContext) const158 SceneUpdater::UpdateTransformNode(SceneContext* sceneContext) const
159 {
160 NW_NULL_ASSERT(sceneContext);
161
162 SceneNodeArray::iterator end = sceneContext->GetSceneNodesEnd();
163 for (SceneNodeArray::iterator node = sceneContext->GetSceneNodesBegin(); node != end; ++node)
164 {
165 (*node)->PreUpdateSignal()(*node, sceneContext);
166
167 // 親ノードからフラグを継承します。
168 (*node)->InheritTraversalResults();
169
170 (*node)->UpdateTransform(this->m_WorldMatrixUpdater.Get(), sceneContext);
171 }
172 }
173
174 //----------------------------------------
175 void
UpdateSkeletalModel(SceneContext * sceneContext) const176 SceneUpdater::UpdateSkeletalModel(SceneContext* sceneContext) const
177 {
178 NW_NULL_ASSERT(sceneContext);
179
180 SkeletalModelArray::iterator end = sceneContext->GetSkeletalModelsEnd();
181 for (SkeletalModelArray::iterator model = sceneContext->GetSkeletalModelsBegin(); model != end; ++model)
182 {
183 Skeleton* skeleton = (*model)->GetSkeleton();
184
185 // スケルトンが既に更新済みの場合は処理をスキップする。
186 if (skeleton->IsUpdated()) { continue; }
187
188 this->m_SkeletonUpdater->UpdateWorld(
189 skeleton,
190 *(this->m_WorldMatrixUpdater.Get()));
191
192 skeleton->SetUpdated(true);
193 }
194 }
195
196 //----------------------------------------
197 void
UpdateAnim(SceneContext * sceneContext) const198 SceneUpdater::UpdateAnim(SceneContext* sceneContext) const
199 {
200 NW_NULL_ASSERT(sceneContext);
201
202 std::for_each(
203 sceneContext->GetAnimatableNodesBegin(),
204 sceneContext->GetAnimatableNodesEnd(),
205 std::mem_fun(&SceneNode::UpdateFrame));
206 }
207
208 //----------------------------------------
209 void
EvaluateAnim(SceneContext * sceneContext,anim::ResGraphicsAnimGroup::EvaluationTiming timing) const210 SceneUpdater::EvaluateAnim(SceneContext* sceneContext, anim::ResGraphicsAnimGroup::EvaluationTiming timing) const
211 {
212 NW_NULL_ASSERT(sceneContext);
213
214 AnimatableNodeArray::iterator animatableNodesEnd = sceneContext->GetAnimatableNodesEnd();
215 for (AnimatableNodeArray::iterator animNode = sceneContext->GetAnimatableNodesBegin();
216 animNode != animatableNodesEnd; ++animNode)
217 {
218 // SceneContext::AnimNodesに格納されたノードは、AnimBindingを持っている
219 (*animNode)->GetAnimBinding()->Evaluate(timing);
220 }
221 }
222
223
224
225 } // namespace gfx
226 } // namespace nw
227