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->UpdateFlags();
319 
320     // TransformAnimでは、FLAG_VALID_COMPONENT*は使用しない
321     return dstFlags;
322 }
323 
324 //----------------------------------------------------------
ApplyCache(void * target,const void * cacheBuf) const325 void ResTransformAnim::ApplyCache(
326     void* target,
327     const void* cacheBuf
328 ) const
329 {
330     gfx::CalculatedTransform* dst = reinterpret_cast<gfx::CalculatedTransform*>(target);
331     const gfx::CalculatedTransform* src = reinterpret_cast<const gfx::CalculatedTransform*>(cacheBuf);
332 
333     *dst = *src;
334 }
335 
336 //----------------------------------------------------------
337 void
ApplyBakedFlags(gfx::CalculatedTransform * transform,const bit32 flags)338 ResBakedTransformAnim::ApplyBakedFlags(gfx::CalculatedTransform* transform, const bit32 flags)
339 {
340     static const bit32 CLEAR_FLAGS = (0 |
341         gfx::CalculatedTransform::FLAG_IS_IDENTITY |
342         gfx::CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO |
343         gfx::CalculatedTransform::FLAG_IS_ROTATE_ZERO |
344         gfx::CalculatedTransform::FLAG_IS_TRANSLATE_ZERO |
345         gfx::CalculatedTransform::FLAG_IS_SCALE_ONE |
346         gfx::CalculatedTransform::FLAG_IS_UNIFORM_SCALE
347     );
348 
349     static const bit32 CLEAR_COMPOSITE_FLAGS = (0 |
350         gfx::CalculatedTransform::FLAG_IS_IDENTITY |
351         gfx::CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO
352         );
353 
354     bit32 originalFlags = transform->GetFlags() & ~CLEAR_FLAGS;
355 
356     bit32 f = flags & ~CLEAR_COMPOSITE_FLAGS;
357 
358     if (ut::CheckFlag(flags,
359             gfx::CalculatedTransform::FLAG_IS_ROTATE_ZERO | gfx::CalculatedTransform::FLAG_IS_TRANSLATE_ZERO))
360     {
361         f |= gfx::CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO;
362     }
363 
364     if (ut::CheckFlag(flags,
365             gfx::CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO | gfx::CalculatedTransform::FLAG_IS_SCALE_ONE))
366     {
367         f |= gfx::CalculatedTransform::FLAG_IS_IDENTITY;
368     }
369 
370     transform->SetFlags(originalFlags | f);
371 }
372 
373 //----------------------------------------------------------
374 gfx::Result
Setup(os::IAllocator * allocator,gfx::ResGraphicsFile graphicsFile)375 ResMemberAnim::Setup(os::IAllocator* allocator, gfx::ResGraphicsFile graphicsFile)
376 {
377     switch ( GetPrimitiveType() )
378     {
379     case ResMemberAnim::PRIMITIVETYPE_TEXTURE:
380         return static_cast<ResTextureAnim&>(*this).Setup(allocator, graphicsFile);
381     }
382 
383     return gfx::RESOURCE_RESULT_OK;
384 }
385 
386 //----------------------------------------------------------
387 void
Cleanup()388 ResMemberAnim::Cleanup()
389 {
390     switch ( GetPrimitiveType() )
391     {
392     case ResMemberAnim::PRIMITIVETYPE_TEXTURE:
393         static_cast<ResTextureAnim&>(*this).Cleanup();
394         break;
395     }
396 }
397 
398 //----------------------------------------------------------
399 bit32
EvaluateResultForType(void * dstBuf,bit32 dstFlags,float frame,const void * originalValue) const400 ResMemberAnim::EvaluateResultForType(
401     void* dstBuf,
402     bit32 dstFlags,
403     float frame,
404     const void* originalValue
405 ) const
406 {
407     const int primType = GetPrimitiveType();
408     switch (primType)
409     {
410     case ResMemberAnim::PRIMITIVETYPE_FLOAT:
411         dstFlags = static_cast<const ResFloatAnim&>(*this)
412             .EvaluateResult(dstBuf, dstFlags, frame);
413         break;
414     case ResMemberAnim::PRIMITIVETYPE_INT:
415         dstFlags = static_cast<const ResIntAnim&>(*this)
416             .EvaluateResult(dstBuf, dstFlags, frame);
417         break;
418     case ResMemberAnim::PRIMITIVETYPE_BOOL:
419         dstFlags = static_cast<const ResBoolAnim&>(*this)
420             .EvaluateResult(dstBuf, dstFlags, frame);
421         break;
422     case ResMemberAnim::PRIMITIVETYPE_VECTOR2:
423         dstFlags = static_cast<const ResVec2Anim&>(*this)
424             .EvaluateResult(dstBuf, dstFlags, frame);
425         break;
426     case ResMemberAnim::PRIMITIVETYPE_VECTOR3:
427         dstFlags = static_cast<const ResVec3Anim&>(*this)
428             .EvaluateResult(dstBuf, dstFlags, frame);
429         break;
430     case ResMemberAnim::PRIMITIVETYPE_TRANSFORM:
431         // この型のみOriginalValueが必要
432         dstFlags = static_cast<const ResTransformAnim&>(*this)
433             .EvaluateResult(dstBuf, dstFlags, frame, originalValue);
434         break;
435     case ResMemberAnim::PRIMITIVETYPE_RGBA_COLOR:
436         dstFlags = static_cast<const ResRgbaColorAnim&>(*this)
437             .EvaluateResult(dstBuf, dstFlags, frame);
438         break;
439     case ResMemberAnim::PRIMITIVETYPE_TEXTURE:
440         dstFlags = static_cast<const ResTextureAnim&>(*this)
441             .EvaluateResult(dstBuf, dstFlags, frame);
442         break;
443     default:
444         NW_ASSERT(false);
445         break;
446     }
447     return dstFlags;
448 }
449 
450 //----------------------------------------------------------
451 void
ApplyCacheForType(void * target,const void * cacheBuf) const452 ResMemberAnim::ApplyCacheForType(
453     void* target,
454     const void* cacheBuf
455 ) const
456 {
457     const int primType = GetPrimitiveType();
458     switch (primType)
459     {
460     case ResMemberAnim::PRIMITIVETYPE_FLOAT:
461         static_cast<const ResFloatAnim&>(*this).ApplyCache(target, cacheBuf);
462         break;
463     case ResMemberAnim::PRIMITIVETYPE_INT:
464         static_cast<const ResIntAnim&>(*this).ApplyCache(target, cacheBuf);
465         break;
466     case ResMemberAnim::PRIMITIVETYPE_BOOL:
467         static_cast<const ResBoolAnim&>(*this).ApplyCache(target, cacheBuf);
468         break;
469     case ResMemberAnim::PRIMITIVETYPE_VECTOR2:
470         static_cast<const ResVec2Anim&>(*this).ApplyCache(target, cacheBuf);
471         break;
472     case ResMemberAnim::PRIMITIVETYPE_VECTOR3:
473         static_cast<const ResVec3Anim&>(*this).ApplyCache(target, cacheBuf);
474         break;
475     case ResMemberAnim::PRIMITIVETYPE_TRANSFORM:
476         static_cast<const ResTransformAnim&>(*this).ApplyCache(target, cacheBuf);
477         break;
478     case ResMemberAnim::PRIMITIVETYPE_RGBA_COLOR:
479         static_cast<const ResRgbaColorAnim&>(*this).ApplyCache(target, cacheBuf);
480         break;
481     case ResMemberAnim::PRIMITIVETYPE_TEXTURE:
482         static_cast<const ResTextureAnim&>(*this).ApplyCache(target, cacheBuf);
483         break;
484     default:
485         NW_ASSERT(false);
486         break;
487     }
488 }
489 
490 //----------------------------------------------------------
491 gfx::Result
Setup(os::IAllocator * allocator,gfx::ResGraphicsFile graphicsFile)492 ResAnim::Setup(os::IAllocator* allocator, gfx::ResGraphicsFile graphicsFile)
493 {
494     gfx::Result result = gfx::RESOURCE_RESULT_OK;
495 
496     for(int i=0; i<GetMemberAnimSetCount(); i++)
497     {
498         ResMemberAnim member = GetMemberAnimSet(i);
499         result |= member.Setup(allocator, graphicsFile);
500     }
501 
502     return result;
503 }
504 
505 //----------------------------------------------------------
506 void
Cleanup()507 ResAnim::Cleanup()
508 {
509     for(int i=0; i<GetMemberAnimSetCount(); i++)
510     {
511         ResMemberAnim member = GetMemberAnimSet(i);
512         member.Cleanup();
513     }
514 }
515 
516 //----------------------------------------------------------
517 ResAnim
CreateEmptyResAnim(nw::os::IAllocator * allocator,const char * targetAnimGroupName)518 ResAnim::CreateEmptyResAnim(
519     nw::os::IAllocator* allocator,
520     const char* targetAnimGroupName
521 )
522 {
523     size_t size = sizeof(ResAnimData);
524     size += sizeof(ut::ResDicPatriciaData);
525 
526     u8* memory = reinterpret_cast<u8*>( allocator->Alloc(size) );
527 
528     ResAnimData* data = reinterpret_cast<ResAnimData*>(memory);
529     memory += sizeof(ResAnimData);
530     ut::ResDicPatriciaData* dicData = reinterpret_cast<ut::ResDicPatriciaData*>(memory);
531 
532     data->m_Header.revision = ResAnim::BINARY_REVISION;
533     data->m_Header.signature = ResAnim::SIGNATURE;
534     data->toName.set_ptr("");
535     data->toTargetAnimGroupName.set_ptr(targetAnimGroupName);
536     data->m_LoopMode = ResAnimData::LOOP_MODE_ONETIME;
537     data->m_FrameSize = 1;
538     data->m_MemberAnimSetDicCount = 0;
539     data->toMemberAnimSetDic.set_ptr(dicData);
540     data->m_UserDataDicCount = 0;
541     data->toUserDataDic.set_ptr(dicData);
542 
543     ut::internal::InitializeResDicPatricia(dicData);
544 
545     return ResAnim(data);
546 }
547 
548 } // namespace res
549 } // namespace anim
550 } // namespace nw
551