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