1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: anim_ResAnim.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: 19698 $
14 *---------------------------------------------------------------------------*/
15
16 #include "../precompiled.h"
17
18 #include <nw/anim/res/anim_ResAnim.h>
19 #include <nw/ut/ut_Color.h>
20 #include <nw/gfx/res/gfx_ResUtil.h>
21 #include <nw/gfx/res/gfx_ResGraphicsFile.h>
22 #include <nw/gfx/gfx_CalculatedTransform.h>
23 #include <nw/ut/ut_ResDictionary.h>
24
25 namespace nw {
26 namespace anim {
27 namespace res {
28
29 //----------------------------------------------------------
GetPrimitiveSize() const30 int ResMemberAnim::GetPrimitiveSize() const
31 {
32 // ここを変更した場合、
33 // AnimResult::m_ValueBuf のサイズを同時に修正すること
34
35 switch (GetPrimitiveType())
36 {
37 case ResMemberAnim::PRIMITIVETYPE_FLOAT:
38 return sizeof(float);
39 case ResMemberAnim::PRIMITIVETYPE_INT:
40 return sizeof(int);
41 case ResMemberAnim::PRIMITIVETYPE_BOOL:
42 return sizeof(bool);
43 case ResMemberAnim::PRIMITIVETYPE_VECTOR2:
44 return sizeof(math::VEC2);
45 case ResMemberAnim::PRIMITIVETYPE_VECTOR3:
46 return sizeof(math::VEC3);
47 case ResMemberAnim::PRIMITIVETYPE_TRANSFORM:
48 return sizeof(gfx::CalculatedTransform);
49 case ResMemberAnim::PRIMITIVETYPE_RGBA_COLOR:
50 return sizeof(ut::ResFloatColor);
51 case ResMemberAnim::PRIMITIVETYPE_TEXTURE:
52 return sizeof(ut::Offset);
53 default:
54 NW_ASSERT(false);
55 }
56 return 0;
57 }
58
59 //----------------------------------------------------------
60 bit32
EvaluateResult(void * dstBuf,bit32 dstFlags,float frame) const61 ResVec2Anim::EvaluateResult(
62 void* dstBuf,
63 bit32 dstFlags,
64 float frame)
65 const
66 {
67 math::VEC2* dst = reinterpret_cast<math::VEC2*>(dstBuf);
68 const bit32 animFlags = GetFlags();
69 if (!(animFlags & ResVec2AnimData::FLAG_X_NOT_EXIST))
70 {
71 dst->x = EvaluateCurveX(frame);
72 dstFlags |= AnimResult::FLAG_VALID_COMPONENT0;
73 }
74 if (!(animFlags & ResVec2AnimData::FLAG_Y_NOT_EXIST))
75 {
76 dst->y = EvaluateCurveY(frame);
77 dstFlags |= AnimResult::FLAG_VALID_COMPONENT1;
78 }
79 return dstFlags;
80 }
81
82 //----------------------------------------------------------
83 void
ApplyCache(void * target,const void * cacheBuf) const84 ResVec2Anim::ApplyCache(
85 void* target,
86 const void* cacheBuf
87 ) const
88 {
89 math::VEC2* dst = reinterpret_cast<math::VEC2*>(target);
90 const math::VEC2* src = reinterpret_cast<const math::VEC2*>(cacheBuf);
91 const bit32 animFlags = GetFlags();
92 if (!(animFlags & ResVec2AnimData::FLAG_X_NOT_EXIST))
93 {
94 dst->x = src->x;
95 }
96 if (!(animFlags & ResVec2AnimData::FLAG_Y_NOT_EXIST))
97 {
98 dst->y = src->y;
99 }
100 }
101
102 //----------------------------------------------------------
103 bit32
EvaluateResult(void * dstBuf,bit32 dstFlags,float frame) const104 ResVec3Anim::EvaluateResult(
105 void* dstBuf,
106 bit32 dstFlags,
107 float frame
108 ) const
109 {
110 math::VEC3* dst = reinterpret_cast<math::VEC3*>(dstBuf);
111 const bit32 animFlags = GetFlags();
112 if (!(animFlags & ResVec3AnimData::FLAG_X_NOT_EXIST))
113 {
114 dst->x = EvaluateCurveX(frame);
115 dstFlags |= AnimResult::FLAG_VALID_COMPONENT0;
116 }
117 if (!(animFlags & ResVec3AnimData::FLAG_Y_NOT_EXIST))
118 {
119 dst->y = EvaluateCurveY(frame);
120 dstFlags |= AnimResult::FLAG_VALID_COMPONENT1;
121 }
122 if (!(animFlags & ResVec3AnimData::FLAG_Z_NOT_EXIST))
123 {
124 dst->z = EvaluateCurveZ(frame);
125 dstFlags |= AnimResult::FLAG_VALID_COMPONENT2;
126 }
127 return dstFlags;
128 }
129
130 //----------------------------------------------------------
131 void
ApplyCache(void * target,const void * cacheBuf) const132 ResVec3Anim::ApplyCache(
133 void* target,
134 const void* cacheBuf
135 ) const
136 {
137 math::VEC3* dst = reinterpret_cast<math::VEC3*>(target);
138 const math::VEC3* src = reinterpret_cast<const math::VEC3*>(cacheBuf);
139 const bit32 animFlags = GetFlags();
140 if (!(animFlags & ResVec3AnimData::FLAG_X_NOT_EXIST))
141 {
142 dst->x = src->x;
143 }
144 if (!(animFlags & ResVec3AnimData::FLAG_Y_NOT_EXIST))
145 {
146 dst->y = src->y;
147 }
148 if (!(animFlags & ResVec3AnimData::FLAG_Z_NOT_EXIST))
149 {
150 dst->z = src->z;
151 }
152 }
153
154 //----------------------------------------------------------
155 bit32
EvaluateResult(void * dstBuf,bit32 dstFlags,float frame) const156 ResRgbaColorAnim::EvaluateResult(
157 void* dstBuf,
158 bit32 dstFlags,
159 float frame
160 ) const
161 {
162 ut::ResFloatColor* dst = reinterpret_cast<ut::ResFloatColor*>(dstBuf);
163 const bit32 animFlags = GetFlags();
164 if (!(animFlags & ResRgbaColorAnimData::FLAG_R_NOT_EXIST))
165 {
166 dst->r = EvaluateCurveR(frame);
167 dstFlags |= AnimResult::FLAG_VALID_COMPONENT0;
168 }
169 if (!(animFlags & ResRgbaColorAnimData::FLAG_G_NOT_EXIST))
170 {
171 dst->g = EvaluateCurveG(frame);
172 dstFlags |= AnimResult::FLAG_VALID_COMPONENT1;
173 }
174 if (!(animFlags & ResRgbaColorAnimData::FLAG_B_NOT_EXIST))
175 {
176 dst->b = EvaluateCurveB(frame);
177 dstFlags |= AnimResult::FLAG_VALID_COMPONENT2;
178 }
179 if (!(animFlags & ResRgbaColorAnimData::FLAG_A_NOT_EXIST))
180 {
181 dst->a = EvaluateCurveA(frame);
182 dstFlags |= AnimResult::FLAG_VALID_COMPONENT3;
183 }
184 return dstFlags;
185 }
186
187 //----------------------------------------------------------
188 void
ApplyCache(void * target,const void * cacheBuf) const189 ResRgbaColorAnim::ApplyCache(
190 void* target,
191 const void* cacheBuf
192 ) const
193 {
194 ut::ResFloatColor* dst = reinterpret_cast<ut::ResFloatColor*>(target);
195 const ut::ResFloatColor* src = reinterpret_cast<const ut::ResFloatColor*>(cacheBuf);
196 const bit32 animFlags = GetFlags();
197 if (!(animFlags & ResRgbaColorAnimData::FLAG_R_NOT_EXIST))
198 {
199 dst->r = src->r;
200 }
201 if (!(animFlags & ResRgbaColorAnimData::FLAG_G_NOT_EXIST))
202 {
203 dst->g = src->g;
204 }
205 if (!(animFlags & ResRgbaColorAnimData::FLAG_B_NOT_EXIST))
206 {
207 dst->b = src->b;
208 }
209 if (!(animFlags & ResRgbaColorAnimData::FLAG_A_NOT_EXIST))
210 {
211 dst->a = src->a;
212 }
213 }
214
215 //----------------------------------------------------------
216 gfx::Result
Setup(os::IAllocator * allocator,gfx::ResGraphicsFile graphicsFile)217 ResTextureAnim::Setup(os::IAllocator* allocator, gfx::ResGraphicsFile graphicsFile)
218 {
219 NW_UNUSED_VARIABLE(allocator);
220
221 gfx::Result result = gfx::RESOURCE_RESULT_OK;
222
223 for (int i = 0; i < GetTexturesCount(); ++i)
224 {
225 if (!GetTextures(i).GetTargetTexture().IsValid())
226 {
227 ::std::pair<gfx::ResTexture, bool> target = gfx::GetReferenceTextureTarget(GetTextures(i), graphicsFile);
228
229 if (!target.second)
230 {
231 result |= gfx::Result::MASK_FAIL_BIT;
232 result |= gfx::RESOURCE_RESULT_NOT_FOUND_TEXTURE;
233 }
234 }
235 }
236
237 return result;
238 }
239
240 //----------------------------------------------------------
241 void
Cleanup()242 ResTextureAnim::Cleanup()
243 {
244 }
245
246 //----------------------------------------------------------
247 bit32
EvaluateResult(void * dstBuf,bit32 dstFlags,float frame) const248 ResTextureAnim::EvaluateResult(
249 void* dstBuf,
250 bit32 dstFlags,
251 float frame
252 ) const
253 {
254 ut::Offset* dst = reinterpret_cast<ut::Offset*>(dstBuf);
255 s32 textureIndex = (s32)EvaluateCurve(frame);
256
257 if (0 <= textureIndex && textureIndex < GetTexturesCount())
258 {
259 dst->set_ptr(GetTextures(textureIndex).ptr());
260 dstFlags |= AnimResult::FLAG_VALID_COMPONENT0;
261 }
262
263 return dstFlags;
264 }
265
266 //----------------------------------------------------------
267 void
ApplyCache(void * target,const void * cacheBuf) const268 ResTextureAnim::ApplyCache(
269 void* target,
270 const void* cacheBuf
271 ) const
272 {
273 ut::Offset* dst = reinterpret_cast<ut::Offset*>(target);
274 const ut::Offset* src = reinterpret_cast<const ut::Offset*>(cacheBuf);
275
276 dst->set_ptr(src->to_ptr());
277 }
278
279 //----------------------------------------------------------
EvaluateResult(void * dstBuf,bit32 dstFlags,float frame,const void * originalValue) const280 bit32 ResTransformAnim::EvaluateResult(
281 void* dstBuf,
282 bit32 dstFlags,
283 float frame,
284 const void* originalValue
285 ) const
286 {
287 const math::Transform3& originalTransform =
288 *static_cast<const math::Transform3*>(originalValue);
289
290 const u32 flags = GetFlags();
291 math::Transform3 transform;
292
293 // TODO: Rotateアニメがない場合は回転行列計算を省略できるかも
294 // 初期化時にOriginalValueで回転行列が生成されているか確認が必要
295 transform.scale.x = (flags & ResTransformAnimData::FLAG_SCALE_X_NOT_EXIST) ?
296 originalTransform.scale.x : EvaluateScaleX(frame);
297 transform.scale.y = (flags & ResTransformAnimData::FLAG_SCALE_Y_NOT_EXIST) ?
298 originalTransform.scale.y : EvaluateScaleY(frame);
299 transform.scale.z = (flags & ResTransformAnimData::FLAG_SCALE_Z_NOT_EXIST) ?
300 originalTransform.scale.z : EvaluateScaleZ(frame);
301
302 transform.rotate.x = (flags & ResTransformAnimData::FLAG_ROTATE_X_NOT_EXIST) ?
303 originalTransform.rotate.x : EvaluateRotateX(frame);
304 transform.rotate.y = (flags & ResTransformAnimData::FLAG_ROTATE_Y_NOT_EXIST) ?
305 originalTransform.rotate.y : EvaluateRotateY(frame);
306 transform.rotate.z = (flags & ResTransformAnimData::FLAG_ROTATE_Z_NOT_EXIST) ?
307 originalTransform.rotate.z : EvaluateRotateZ(frame);
308
309 transform.translate.x = (flags & ResTransformAnimData::FLAG_TRANSLATE_X_NOT_EXIST) ?
310 originalTransform.translate.x : EvaluateTranslateX(frame);
311 transform.translate.y = (flags & ResTransformAnimData::FLAG_TRANSLATE_Y_NOT_EXIST) ?
312 originalTransform.translate.y : EvaluateTranslateY(frame);
313 transform.translate.z = (flags & ResTransformAnimData::FLAG_TRANSLATE_Z_NOT_EXIST) ?
314 originalTransform.translate.z : EvaluateTranslateZ(frame);
315
316 gfx::CalculatedTransform* dst = new (dstBuf) gfx::CalculatedTransform();
317 dst->SetTransform(transform);
318 dst->UpdateScaleFlags();
319 dst->UpdateRotateFlags();
320 dst->UpdateTranslateFlags();
321 dst->UpdateCompositeFlags();
322
323 // TransformAnimでは、FLAG_VALID_COMPONENT*は使用しない
324 return dstFlags;
325 }
326
327 //----------------------------------------------------------
ApplyCache(void * target,const void * cacheBuf) const328 void ResTransformAnim::ApplyCache(
329 void* target,
330 const void* cacheBuf
331 ) const
332 {
333 gfx::CalculatedTransform* dst = reinterpret_cast<gfx::CalculatedTransform*>(target);
334 const gfx::CalculatedTransform* src = reinterpret_cast<const gfx::CalculatedTransform*>(cacheBuf);
335
336 *dst = *src;
337 }
338
339 //----------------------------------------------------------
340 void
ApplyBakedFlags(gfx::CalculatedTransform * transform,const bit32 flags)341 ResBakedTransformAnim::ApplyBakedFlags(gfx::CalculatedTransform* transform, const bit32 flags)
342 {
343 static const bit32 CLEAR_FLAGS = (0 |
344 gfx::CalculatedTransform::FLAG_IS_IDENTITY |
345 gfx::CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO |
346 gfx::CalculatedTransform::FLAG_IS_ROTATE_ZERO |
347 gfx::CalculatedTransform::FLAG_IS_TRANSLATE_ZERO |
348 gfx::CalculatedTransform::FLAG_IS_SCALE_ONE |
349 gfx::CalculatedTransform::FLAG_IS_UNIFORM_SCALE
350 );
351
352 static const bit32 CLEAR_COMPOSITE_FLAGS = (0 |
353 gfx::CalculatedTransform::FLAG_IS_IDENTITY |
354 gfx::CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO
355 );
356
357 bit32 originalFlags = transform->GetFlags() & ~CLEAR_FLAGS;
358
359 bit32 f = flags & ~CLEAR_COMPOSITE_FLAGS;
360
361 if (ut::CheckFlag(flags,
362 gfx::CalculatedTransform::FLAG_IS_ROTATE_ZERO | gfx::CalculatedTransform::FLAG_IS_TRANSLATE_ZERO))
363 {
364 f |= gfx::CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO;
365 }
366
367 if (ut::CheckFlag(flags,
368 gfx::CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO | gfx::CalculatedTransform::FLAG_IS_SCALE_ONE))
369 {
370 f |= gfx::CalculatedTransform::FLAG_IS_IDENTITY;
371 }
372
373 transform->SetFlags(originalFlags | f);
374 }
375
376 //----------------------------------------------------------
377 gfx::Result
Setup(os::IAllocator * allocator,gfx::ResGraphicsFile graphicsFile)378 ResMemberAnim::Setup(os::IAllocator* allocator, gfx::ResGraphicsFile graphicsFile)
379 {
380 switch ( GetPrimitiveType() )
381 {
382 case ResMemberAnim::PRIMITIVETYPE_TEXTURE:
383 return static_cast<ResTextureAnim&>(*this).Setup(allocator, graphicsFile);
384 }
385
386 return gfx::RESOURCE_RESULT_OK;
387 }
388
389 //----------------------------------------------------------
390 void
Cleanup()391 ResMemberAnim::Cleanup()
392 {
393 switch ( GetPrimitiveType() )
394 {
395 case ResMemberAnim::PRIMITIVETYPE_TEXTURE:
396 static_cast<ResTextureAnim&>(*this).Cleanup();
397 break;
398 }
399 }
400
401 //----------------------------------------------------------
402 bit32
EvaluateResultForType(void * dstBuf,bit32 dstFlags,float frame,const void * originalValue) const403 ResMemberAnim::EvaluateResultForType(
404 void* dstBuf,
405 bit32 dstFlags,
406 float frame,
407 const void* originalValue
408 ) const
409 {
410 const int primType = GetPrimitiveType();
411 switch (primType)
412 {
413 case ResMemberAnim::PRIMITIVETYPE_FLOAT:
414 dstFlags = static_cast<const ResFloatAnim&>(*this)
415 .EvaluateResult(dstBuf, dstFlags, frame);
416 break;
417 case ResMemberAnim::PRIMITIVETYPE_INT:
418 dstFlags = static_cast<const ResIntAnim&>(*this)
419 .EvaluateResult(dstBuf, dstFlags, frame);
420 break;
421 case ResMemberAnim::PRIMITIVETYPE_BOOL:
422 dstFlags = static_cast<const ResBoolAnim&>(*this)
423 .EvaluateResult(dstBuf, dstFlags, frame);
424 break;
425 case ResMemberAnim::PRIMITIVETYPE_VECTOR2:
426 dstFlags = static_cast<const ResVec2Anim&>(*this)
427 .EvaluateResult(dstBuf, dstFlags, frame);
428 break;
429 case ResMemberAnim::PRIMITIVETYPE_VECTOR3:
430 dstFlags = static_cast<const ResVec3Anim&>(*this)
431 .EvaluateResult(dstBuf, dstFlags, frame);
432 break;
433 case ResMemberAnim::PRIMITIVETYPE_TRANSFORM:
434 // この型のみOriginalValueが必要
435 dstFlags = static_cast<const ResTransformAnim&>(*this)
436 .EvaluateResult(dstBuf, dstFlags, frame, originalValue);
437 break;
438 case ResMemberAnim::PRIMITIVETYPE_RGBA_COLOR:
439 dstFlags = static_cast<const ResRgbaColorAnim&>(*this)
440 .EvaluateResult(dstBuf, dstFlags, frame);
441 break;
442 case ResMemberAnim::PRIMITIVETYPE_TEXTURE:
443 dstFlags = static_cast<const ResTextureAnim&>(*this)
444 .EvaluateResult(dstBuf, dstFlags, frame);
445 break;
446 default:
447 NW_ASSERT(false);
448 break;
449 }
450 return dstFlags;
451 }
452
453 //----------------------------------------------------------
454 void
ApplyCacheForType(void * target,const void * cacheBuf) const455 ResMemberAnim::ApplyCacheForType(
456 void* target,
457 const void* cacheBuf
458 ) const
459 {
460 const int primType = GetPrimitiveType();
461 switch (primType)
462 {
463 case ResMemberAnim::PRIMITIVETYPE_FLOAT:
464 static_cast<const ResFloatAnim&>(*this).ApplyCache(target, cacheBuf);
465 break;
466 case ResMemberAnim::PRIMITIVETYPE_INT:
467 static_cast<const ResIntAnim&>(*this).ApplyCache(target, cacheBuf);
468 break;
469 case ResMemberAnim::PRIMITIVETYPE_BOOL:
470 static_cast<const ResBoolAnim&>(*this).ApplyCache(target, cacheBuf);
471 break;
472 case ResMemberAnim::PRIMITIVETYPE_VECTOR2:
473 static_cast<const ResVec2Anim&>(*this).ApplyCache(target, cacheBuf);
474 break;
475 case ResMemberAnim::PRIMITIVETYPE_VECTOR3:
476 static_cast<const ResVec3Anim&>(*this).ApplyCache(target, cacheBuf);
477 break;
478 case ResMemberAnim::PRIMITIVETYPE_TRANSFORM:
479 static_cast<const ResTransformAnim&>(*this).ApplyCache(target, cacheBuf);
480 break;
481 case ResMemberAnim::PRIMITIVETYPE_RGBA_COLOR:
482 static_cast<const ResRgbaColorAnim&>(*this).ApplyCache(target, cacheBuf);
483 break;
484 case ResMemberAnim::PRIMITIVETYPE_TEXTURE:
485 static_cast<const ResTextureAnim&>(*this).ApplyCache(target, cacheBuf);
486 break;
487 default:
488 NW_ASSERT(false);
489 break;
490 }
491 }
492
493 //----------------------------------------------------------
494 gfx::Result
Setup(os::IAllocator * allocator,gfx::ResGraphicsFile graphicsFile)495 ResAnim::Setup(os::IAllocator* allocator, gfx::ResGraphicsFile graphicsFile)
496 {
497 gfx::Result result = gfx::RESOURCE_RESULT_OK;
498
499 for(int i=0; i<GetMemberAnimSetCount(); i++)
500 {
501 ResMemberAnim member = GetMemberAnimSet(i);
502 result |= member.Setup(allocator, graphicsFile);
503 }
504
505 return result;
506 }
507
508 //----------------------------------------------------------
509 void
Cleanup()510 ResAnim::Cleanup()
511 {
512 for(int i=0; i<GetMemberAnimSetCount(); i++)
513 {
514 ResMemberAnim member = GetMemberAnimSet(i);
515 member.Cleanup();
516 }
517 }
518
519 //----------------------------------------------------------
520 ResAnim
CreateEmptyResAnim(nw::os::IAllocator * allocator,const char * targetAnimGroupName)521 ResAnim::CreateEmptyResAnim(
522 nw::os::IAllocator* allocator,
523 const char* targetAnimGroupName
524 )
525 {
526 size_t size = sizeof(ResAnimData);
527 size += sizeof(ut::ResDicPatriciaData);
528
529 u8* memory = reinterpret_cast<u8*>( allocator->Alloc(size) );
530
531 ResAnimData* data = reinterpret_cast<ResAnimData*>(memory);
532 memory += sizeof(ResAnimData);
533 ut::ResDicPatriciaData* dicData = reinterpret_cast<ut::ResDicPatriciaData*>(memory);
534
535 data->m_Header.revision = ResAnim::BINARY_REVISION;
536 data->m_Header.signature = ResAnim::SIGNATURE;
537 data->toName.set_ptr("");
538 data->toTargetAnimGroupName.set_ptr(targetAnimGroupName);
539 data->m_LoopMode = ResAnimData::LOOP_MODE_ONETIME;
540 data->m_FrameSize = 1;
541 data->m_MemberAnimSetDicCount = 0;
542 data->toMemberAnimSetDic.set_ptr(dicData);
543 data->m_UserDataDicCount = 0;
544 data->toUserDataDic.set_ptr(dicData);
545
546 ut::internal::InitializeResDicPatricia(dicData);
547
548 return ResAnim(data);
549 }
550
551 //----------------------------------------------------------
552 bool
IsFullBakedAnim() const553 ResAnim::IsFullBakedAnim() const
554 {
555 if (GetMemberAnimSetCount() == 0)
556 {
557 return false;
558 }
559
560 // PrimitiveTypeが混在することはないので、1つ目だけ判定すればよい
561 return GetMemberAnimSet(0).GetPrimitiveType() == ResMemberAnim::PRIMITIVETYPE_FULL_BAKED;
562 }
563
564 } // namespace res
565 } // namespace anim
566 } // namespace nw
567