1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: SmModel.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: 1 $
14 *---------------------------------------------------------------------------*/
15
16 #include "../include/SmModel.h"
17
18 namespace
19 {
20
21 //----------------------------------------
22 // コンストラクタ
SmModel()23 SmModel::SmModel()
24 : m_pParentNode( NULL ),
25 m_pSceneNode( NULL ),
26 m_Model( NULL ),
27 m_SkeletalModel( NULL ),
28 m_AnimationFrame( 0.f ),
29 m_CurrentAnimEvNo( -1 ),
30 m_CostrainId( -1 ),
31 m_Duplicated( false )
32 {
33 m_AnimEvaluatorArray.clear();
34 }
35
36
37 //----------------------------------------
38 //
~SmModel()39 SmModel::~SmModel()
40 {
41
42 }
43
44
45 //----------------------------------------
46 // ノードをセットする
47 void
SetSceneNode(nw::gfx::SceneNode * pParentNode,nw::gfx::SceneNode * pSceneNode)48 SmModel::SetSceneNode( nw::gfx::SceneNode* pParentNode, nw::gfx::SceneNode* pSceneNode )
49 {
50 NW_NULL_ASSERT(pParentNode);
51
52 m_pParentNode = pParentNode;
53 if ( pSceneNode )
54 {
55 m_pSceneNode = pSceneNode;
56 }
57 }
58
59
60 //----------------------------------------
61 // モデルをセットする
62 void
SetModel(nw::gfx::Model * pModel,nw::gfx::SkeletalModel * pSkelModel)63 SmModel::SetModel( nw::gfx::Model* pModel, nw::gfx::SkeletalModel* pSkelModel )
64 {
65 m_Model = pModel;
66 m_SkeletalModel = pSkelModel;
67 }
68
69
70 //----------------------------------------
71 // アップデート、コンストレイン等の解決を行う
72 void
Update()73 SmModel::Update()
74 {
75 // 親子関係の解決
76 updateConstrain();
77 }
78
79
80
81 //----------------------------------------
82 // 位置
83 void
SetPosition(f32 x,f32 y,f32 z)84 SmModel::SetPosition( f32 x, f32 y, f32 z )
85 {
86 nw::gfx::TransformNode* transformNode =
87 nw::ut::DynamicCast<nw::gfx::TransformNode*>(m_pSceneNode);
88 NW_NULL_ASSERT(transformNode);
89
90 transformNode->Transform().SetTranslate( x, y, z );
91 }
92
93
94 //----------------------------------------
95 // 拡縮
96 void
SetScale(f32 x,f32 y,f32 z)97 SmModel::SetScale( f32 x, f32 y, f32 z )
98 {
99 nw::gfx::TransformNode* transformNode =
100 nw::ut::DynamicCast<nw::gfx::TransformNode*>(m_pSceneNode);
101 NW_NULL_ASSERT(transformNode);
102
103 transformNode->Transform().SetScale( x, y, z );
104 }
105
106
107 //----------------------------------------
108 // 回転 Degree
109 void
SetRotate(f32 x,f32 y,f32 z)110 SmModel::SetRotate( f32 x, f32 y, f32 z )
111 {
112 nw::gfx::TransformNode* transformNode =
113 nw::ut::DynamicCast<nw::gfx::TransformNode*>(m_pSceneNode);
114 NW_NULL_ASSERT(transformNode);
115
116 transformNode->Transform().SetRotateXYZ( NW_MATH_DEG_TO_RAD(x),
117 NW_MATH_DEG_TO_RAD(y),
118 NW_MATH_DEG_TO_RAD(z) );
119 }
120
121
122 //----------------------------------------
123 // マトリクス
124 void
SetMatrix(const nw::math::MTX34 * matrix)125 SmModel::SetMatrix( const nw::math::MTX34* matrix )
126 {
127 NW_NULL_ASSERT( matrix );
128
129 nw::gfx::TransformNode* transformNode =
130 nw::ut::DynamicCast<nw::gfx::TransformNode*>(m_pSceneNode);
131 NW_NULL_ASSERT(transformNode);
132
133 transformNode->Transform().SetTransformMatrix( *matrix );
134 }
135
136
SetWorldMatrix(const nw::math::MTX34 * matrix)137 void SmModel::SetWorldMatrix( const nw::math::MTX34* matrix )
138 {
139 NW_NULL_ASSERT( matrix );
140
141 nw::gfx::TransformNode* transformNode =
142 nw::ut::DynamicCast<nw::gfx::TransformNode*>(m_pSceneNode);
143 NW_NULL_ASSERT(transformNode);
144
145 transformNode->WorldMatrix() = *matrix;
146 }
147
148
149
150
151 //----------------------------------------
152 // 表示/非表示
153 void
SetVisible(bool visible)154 SmModel::SetVisible( bool visible )
155 {
156 if ( !m_SkeletalModel ) return;
157 m_SkeletalModel->SetVisible( visible );
158
159 // 親が居る居ないでシーンツーリーに登録されているか判断する。
160 if ( !visible )
161 {
162 if ( m_pSceneNode->GetParent() )
163 {
164 m_pParentNode->DetachChild( m_pSceneNode );
165 }
166 }
167 else
168 {
169 if ( !m_pSceneNode->GetParent() )
170 {
171 m_pParentNode->AttachChild( m_pSceneNode );
172 }
173 }
174 }
175
176 void
SwapVisible()177 SmModel::SwapVisible()
178 {
179 if ( !m_SkeletalModel ) return;
180
181 // 親が居る居ないでシーンツーリーに登録されているか判断する。
182 if ( m_SkeletalModel->IsVisible() )
183 {
184 m_SkeletalModel->SetVisible( false );
185
186 if ( m_pSceneNode->GetParent() )
187 {
188 m_pParentNode->DetachChild( m_pSceneNode );
189 }
190 }
191 else
192 {
193 m_SkeletalModel->SetVisible( true );
194
195 if ( !m_pSceneNode->GetParent() )
196 {
197 m_pParentNode->AttachChild( m_pSceneNode );
198 }
199 }
200 }
201
202 bool
IsVisible()203 SmModel::IsVisible()
204 {
205 if ( !m_SkeletalModel ) return false;
206 return m_SkeletalModel->IsVisible();
207 }
208
209
210 //----------------------------------------
211 // 複製する
Duplicate()212 SmModel* SmModel::Duplicate()
213 {
214 SmModel* model = new SmModel();
215
216 #if 1
217 // スケルトン共有ナシ
218 nw::gfx::SkeletalModel* skeletalModel = nw::gfx::SkeletalModel::Builder()
219 .Create( NULL, nw::gfx::ResSceneObject( m_SkeletalModel->GetResModel() ), m_Allocator );
220 #else
221 // スケルトン共有アリ
222 nw::gfx::SkeletalModel* skeletalModel = nw::gfx::SkeletalModel::Builder()
223 .SharedSkeleton( m_SkeletalModel->GetSkeleton() )
224 .Create(NULL, nw::gfx::ResSceneObject(m_SkeletalModel->GetResModel()), m_Allocator);
225 #endif
226
227 NW_NULL_ASSERT(skeletalModel);
228
229 // コピー元モデルから値のコピー
230 model->m_SkeletalModel = skeletalModel;
231 model->m_Duplicated = true;
232 model->m_pSceneNode = static_cast<nw::gfx::SceneNode*>(model->m_SkeletalModel);
233
234 model->SetLayerId( this->GetLayerId() );
235
236 // todo:パラでアニメーションさせるには、
237 // アニメーションをコピーする必要がアリ。
238 model->m_AnimEvaluatorArray.CopyFrom( m_AnimEvaluatorArray );
239
240 return model;
241 }
242
243
244 //----------------------------------------
245 // アニメーションを追加する
246 void
AddAnimEvaluator(nw::gfx::TransformAnimEvaluator * animEvaluator)247 SmModel::AddAnimEvaluator( nw::gfx::TransformAnimEvaluator* animEvaluator )
248 {
249 m_AnimEvaluatorArray.push_back( animEvaluator );
250 }
251
252
253 //----------------------------------------
254 // アニメーション数を取得する
255 uint
GetAnimEvaluatorNum() const256 SmModel::GetAnimEvaluatorNum() const
257 {
258 return m_AnimEvaluatorArray.size();
259 }
260
261
262 //----------------------------------------
263 // アニメーションを設定する
264 bool
SetAnimEvaluatorNo(uint animEvaluatorNo)265 SmModel::SetAnimEvaluatorNo( uint animEvaluatorNo )
266 {
267 if ( animEvaluatorNo >= GetAnimEvaluatorNum() ) return false;
268 if ( !m_SkeletalModel ) return false;
269
270 nw::gfx::AnimGroup* animGroup = m_SkeletalModel->GetSkeletalAnimGroup();
271 if (animGroup == NULL){ NW_FATAL_ERROR("Dont have AnimGroup");; }
272
273 // アニメーションをバインドします。
274 m_AnimEvaluatorArray[animEvaluatorNo]->Release();
275 bool bindResult = m_AnimEvaluatorArray[animEvaluatorNo]->Bind(animGroup);
276
277 // アニメーションをモデルに登録します。
278 m_SkeletalModel->SetSkeletalAnimObject(m_AnimEvaluatorArray[animEvaluatorNo]);
279
280 // 番号を保持
281 m_CurrentAnimEvNo = animEvaluatorNo;
282
283 return true;
284 }
285
286
287 //----------------------------------------
288 // アニメーションフレームを設定する
289 void
SetAnimationFrame(f32 setFrame)290 SmModel::SetAnimationFrame( f32 setFrame )
291 {
292 m_AnimationFrame = setFrame;
293 if ( m_CurrentAnimEvNo == -1 ) return;
294
295 // 非表示であればアニメーションは更新しません
296 if ( !this->IsVisible() ) return;
297
298 // フレーム数をセット
299 m_AnimEvaluatorArray[m_CurrentAnimEvNo]->SetFrame(m_AnimationFrame);
300 }
301
302
303 //----------------------------------------
304 // アニメーションフレームを進める
305 // 最終フレームに到達した場合は、trueを返す
306 bool
AddAnimationFrame(f32 addFrame,bool loop)307 SmModel::AddAnimationFrame( f32 addFrame, bool loop )
308 {
309 bool ret = false;
310
311 m_AnimationFrame += addFrame;
312 if ( m_CurrentAnimEvNo == -1 ) return ret;
313
314 // 最終フレームで固定
315 f32 endFrame = m_AnimEvaluatorArray[m_CurrentAnimEvNo]->AnimFrameController().GetEndFrame();
316 if ( m_AnimationFrame > endFrame )
317 {
318 if ( loop )
319 {
320 m_AnimationFrame = 0.f;
321 }
322 else
323 {
324 m_AnimationFrame = endFrame;
325 }
326
327 ret = true;
328 }
329
330 // 非表示であればアニメーションは更新しません
331 if ( !this->IsVisible() ) return ret;
332
333 // フレーム数をセットします
334 m_AnimEvaluatorArray[m_CurrentAnimEvNo]->SetFrame(m_AnimationFrame);
335
336 return ret;
337 }
338
339
340 //----------------------------------------
341 // アニメーションフレームを取得する
342 f32
GetAnimationFrame() const343 SmModel::GetAnimationFrame() const
344 {
345 return m_AnimationFrame;
346 }
347
348
349 //----------------------------------------
350 // 設定されているアニメーションの最大フレームを取得する
351 f32
GetAnimationMaxFrame() const352 SmModel::GetAnimationMaxFrame() const
353 {
354 if ( m_CurrentAnimEvNo == -1 ) return 0.f;
355
356 return m_AnimEvaluatorArray[m_CurrentAnimEvNo]->AnimFrameController().GetEndFrame();
357 }
358
359
360 //----------------------------------------
361 // マテリアルアニメーションを設定する
362 bool
SetMaterialAnim(nw::gfx::AnimEvaluator * animEvaluator)363 SmModel::SetMaterialAnim( nw::gfx::AnimEvaluator* animEvaluator )
364 {
365 nw::gfx::AnimGroup* animGroup = m_Model->GetMaterialAnimGroup();
366 if ( !animGroup ) return false;
367
368 bool bindResult = animEvaluator->Bind( animGroup );
369 if ( !bindResult ) return false;
370
371 // アニメーションをモデルに登録します。
372 m_Model->SetMaterialAnimObject( animEvaluator );
373
374 return true;
375 }
376
377
378
379 //----------------------------------------
380 // 親のノードIDを指定する
381 void
SetConstrainId(s32 boneId)382 SmModel::SetConstrainId( s32 boneId )
383 {
384 m_CostrainId = boneId;
385
386 nw::gfx::TransformNode* transformNode =
387 nw::ut::DynamicCast<nw::gfx::TransformNode*>(m_pSceneNode);
388 NW_NULL_ASSERT(transformNode);
389
390 // -1 でキャンセル
391 if ( m_CostrainId == -1 )
392 {
393 // FLAG_IS_WORLDMATRIX_CALCULATION_ENABLED フラグを立てる
394 transformNode->Transform().EnableFlags(nw::gfx::CalculatedTransform::FLAG_IS_WORLDMATRIX_CALCULATION_ENABLED);
395
396 transformNode->Transform().DisableFlags(nw::gfx::CalculatedTransform::FLAG_IS_WORLDMATRIX_CALCULATION_ENABLED);
397
398 }
399 else
400 {
401 // FLAG_IS_WORLDMATRIX_CALCULATION_ENABLED フラグを下げる
402 transformNode->Transform().DisableFlags(nw::gfx::CalculatedTransform::FLAG_IS_WORLDMATRIX_CALCULATION_ENABLED);
403
404 transformNode->Transform().EnableFlags(nw::gfx::CalculatedTransform::FLAG_IS_WORLDMATRIX_CALCULATION_ENABLED);
405 }
406 }
407
408
409 //----------------------------------------
410 // 親子継承を解決
411 void
updateConstrain()412 SmModel::updateConstrain()
413 {
414 if ( m_CostrainId == -1 ) return;
415
416 // 親が骨構造を持つか?
417 nw::gfx::SkeletalModel* pParentSkeletalModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(m_pParentNode);
418
419 if ( pParentSkeletalModel )
420 {
421 // Skeleton を取得
422 nw::gfx::Skeleton* pSkeleton = pParentSkeletalModel->GetSkeleton();
423 NW_NULL_ASSERT(pSkeleton);
424
425 nw::gfx::Skeleton::TransformPose& transformPose = pSkeleton->WorldTransformPose();
426 // nw::gfx::Skeleton::TransformPose& transformPose = pSkeleton->LocalTransformPose();
427 if ( transformPose.GetBonesCount() < m_CostrainId ) return;
428
429 // 指定ノードのマトリクスを取得して、自分にワールドマトリクスへセットする
430 nw::gfx::Skeleton::TransformPose::Transform* transForm = transformPose.GetTransform( m_CostrainId );
431 // this->SetWorldMatrix( &transForm->TransformMatrix() );
432 this->SetMatrix( &transForm->TransformMatrix() );
433 }
434 else
435 {
436 // 骨なしの場合は何もしない
437 }
438 }
439
440
441 //----------------------------------------
442 // テスト機能
443 // モデル内メッシュを0~1で表示/非表示する
444 void
SetVisibleZone(f32 term)445 SmModel::SetVisibleZone( f32 term )
446 {
447 if ( !m_SkeletalModel ) return;
448
449 nw::gfx::ResMeshArray meshArray = m_SkeletalModel->GetResMeshes();
450
451 s32 visibleNum = meshArray.size() * term;
452
453 for ( int i = 0; i < meshArray.size(); i++ )
454 {
455 if ( i < visibleNum )
456 {
457 meshArray[i].SetVisible( true );
458 }
459 else
460 {
461 meshArray[i].SetVisible( false );
462 }
463 }
464 }
465
466
467
468 } // namespace
469
470
471