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