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: 27617 $
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 // フルベイクアニメを使用する場合は処理をスキップする。
184 if ((*model)->GetFullBakedAnimEnabled()) { continue; }
185
186 Skeleton* skeleton = (*model)->GetSkeleton();
187
188 // スケルトンが既に更新済みの場合は処理をスキップする。
189 if (skeleton->IsUpdated()) { continue; }
190
191 this->m_SkeletonUpdater->UpdateWorld(
192 skeleton,
193 *(this->m_WorldMatrixUpdater.Get()));
194
195 skeleton->SetUpdated(true);
196 }
197 }
198
199 //----------------------------------------
200 void
UpdateAnim(SceneContext * sceneContext) const201 SceneUpdater::UpdateAnim(SceneContext* sceneContext) const
202 {
203 NW_NULL_ASSERT(sceneContext);
204
205 std::for_each(
206 sceneContext->GetAnimatableNodesBegin(),
207 sceneContext->GetAnimatableNodesEnd(),
208 std::mem_fun(&SceneNode::UpdateFrame));
209 }
210
211 //----------------------------------------
212 void
EvaluateAnim(SceneContext * sceneContext,anim::ResGraphicsAnimGroup::EvaluationTiming timing) const213 SceneUpdater::EvaluateAnim(SceneContext* sceneContext, anim::ResGraphicsAnimGroup::EvaluationTiming timing) const
214 {
215 NW_NULL_ASSERT(sceneContext);
216
217 AnimatableNodeArray::iterator animatableNodesEnd = sceneContext->GetAnimatableNodesEnd();
218 for (AnimatableNodeArray::iterator animNode = sceneContext->GetAnimatableNodesBegin();
219 animNode != animatableNodesEnd; ++animNode)
220 {
221 // SceneContext::AnimNodesに格納されたノードは、AnimBindingを持っている
222 (*animNode)->GetAnimBinding()->Evaluate(timing);
223 }
224 }
225
226
227
228 } // namespace gfx
229 } // namespace nw
230