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