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