1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     anim_ResAnimGroup.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:  $
14  *---------------------------------------------------------------------------*/
15 
16 #include "../precompiled.h"
17 
18 #include <nw/anim/res/anim_ResAnimGroup.h>
19 #include <nw/gfx/gfx_SkeletalModel.h>
20 #include <nw/gfx/gfx_Model.h>
21 #include <nw/gfx/res/gfx_ResTexture.h>
22 #include <nw/gfx/gfx_Camera.h>
23 #include <nw/gfx/gfx_Light.h>
24 #include <nw/gfx/gfx_FragmentLight.h>
25 #include <nw/gfx/gfx_AmbientLight.h>
26 #include <nw/gfx/gfx_VertexLight.h>
27 #include <nw/gfx/gfx_HemiSphereLight.h>
28 #include <nw/gfx/gfx_Fog.h>
29 
30 using namespace nw::gfx;
31 
32 namespace nw {
33 namespace anim {
34 namespace res {
35 
36 //----------------------------------------
37 void
SetValueForType(void * object,const void * value) const38 ResAnimGroupMember::SetValueForType(void* object, const void* value) const
39 {
40     NW_NULL_ASSERT(object);
41     NW_NULL_ASSERT(value);
42 
43     // ObjectTypeに対応する派生クラスに処理を委譲
44     switch(GetObjectType())
45     {
46     case OBJECT_TYPE_BONE:
47         ResStaticCast<ResBoneMember>(*this).SetValue(object, value);
48         break;
49 
50     case OBJECT_TYPE_MATERIAL_COLOR:
51         ResStaticCast<ResMaterialColorMember>(*this).SetValue(object, value);
52         break;
53 
54     case OBJECT_TYPE_TEXTURE_SAMPLER:
55         ResStaticCast<ResTextureSamplerMember>(*this).SetValue(object, value);
56         break;
57 
58     case OBJECT_TYPE_TEXTURE_MAPPER:
59         ResStaticCast<ResTextureMapperMember>(*this).SetValue(object, value);
60         break;
61 
62     case OBJECT_TYPE_BLEND_OPERATION:
63         ResStaticCast<ResBlendOperationMember>(*this).SetValue(object, value);
64         break;
65 
66     case OBJECT_TYPE_TEXTURE_COORDINATOR:
67         ResStaticCast<ResTextureCoordinatorMember>(*this).SetValue(object, value);
68         break;
69 
70     case OBJECT_TYPE_MODEL:
71         ResStaticCast<ResModelMember>(*this).SetValue(object, value);
72         break;
73 
74     case OBJECT_TYPE_MESH:
75         ResStaticCast<ResMeshMember>(*this).SetValue(object, value);
76         break;
77 
78     case OBJECT_TYPE_MESH_NODE_VISIBILITY:
79         ResStaticCast<ResMeshNodeVisibilityMember>(*this).SetValue(object, value);
80         break;
81 
82     case OBJECT_TYPE_TRANSFORM:
83         ResStaticCast<ResTransformMember>(*this).SetValue(object, value);
84         break;
85 
86     case OBJECT_TYPE_VIEW_UPDATER:
87         ResStaticCast<ResViewUpdaterMember>(*this).SetValue(object, value);
88         break;
89 
90     case OBJECT_TYPE_PROJECTION_UPDATER:
91         ResStaticCast<ResProjectionUpdaterMember>(*this).SetValue(object, value);
92         break;
93 
94     case OBJECT_TYPE_LIGHT:
95         ResStaticCast<ResLightMember>(*this).SetValue(object, value);
96         break;
97 
98     case OBJECT_TYPE_FRAGMENT_LIGHT:
99         ResStaticCast<ResFragmentLightMember>(*this).SetValue(object, value);
100         break;
101 
102     case OBJECT_TYPE_AMBIENT_LIGHT:
103         ResStaticCast<ResAmbientLightMember>(*this).SetValue(object, value);
104         break;
105 
106     case OBJECT_TYPE_VERTEX_LIGHT:
107         ResStaticCast<ResVertexLightMember>(*this).SetValue(object, value);
108         break;
109 
110     case OBJECT_TYPE_HEMISPHERE_LIGHT:
111         ResStaticCast<ResHemiSphereLightMember>(*this).SetValue(object, value);
112         break;
113 
114     case OBJECT_TYPE_FOG:
115         ResStaticCast<ResFogMember>(*this).SetValue(object, value);
116         break;
117 
118     default:
119         NW_ASSERT(false);
120         break;
121     }
122 }
123 
124 //----------------------------------------
125 void
SetValue(void * object,const void * value) const126 ResBoneMember::SetValue(void* object, const void* value) const
127 {
128     CalculatedTransform* bone =
129         reinterpret_cast<CalculatedTransform*>(object);
130     const math::Transform3* transform =
131         reinterpret_cast<const math::Transform3*>(value);
132 
133     bone->SetTransform(*transform);
134     bone->UpdateScaleFlags();
135     bone->UpdateRotateFlags();
136     bone->UpdateTranslateFlags();
137     bone->UpdateCompositeFlags();
138 }
139 
140 
141 //----------------------------------------
142 void
SetValue(void * object,const void * value) const143 ResMaterialColorMember::SetValue(void* object, const void* value) const
144 {
145     ResMaterialColor materialColor(object);
146     const ut::FloatColor& color = *reinterpret_cast<const ut::FloatColor*>(value);
147 
148     // MemberTypeに対応するsetterを呼び出す
149     switch(GetMemberType())
150     {
151     case MEMBER_TYPE_EMISSION:
152         materialColor.SetEmission(color);
153         break;
154 
155     case MEMBER_TYPE_AMBIENT:
156         materialColor.SetAmbient(color.r, color.g, color.b);
157         break;
158 
159     case MEMBER_TYPE_DIFFUSE:
160         materialColor.SetDiffuse(color);
161         break;
162 
163     case MEMBER_TYPE_SPECULAR0:
164         materialColor.SetSpecular0(color);
165         break;
166 
167     case MEMBER_TYPE_SPECULAR1:
168         materialColor.SetSpecular1(color);
169         break;
170 
171     case MEMBER_TYPE_CONSTANT0:
172         materialColor.SetConstant0(color);
173         break;
174 
175     case MEMBER_TYPE_CONSTANT1:
176         materialColor.SetConstant1(color);
177         break;
178 
179     case MEMBER_TYPE_CONSTANT2:
180         materialColor.SetConstant2(color);
181         break;
182 
183     case MEMBER_TYPE_CONSTANT3:
184         materialColor.SetConstant3(color);
185         break;
186 
187     case MEMBER_TYPE_CONSTANT4:
188         materialColor.SetConstant4(color);
189         break;
190 
191     case MEMBER_TYPE_CONSTANT5:
192         materialColor.SetConstant5(color);
193         break;
194 
195     default:
196         NW_ASSERT(false);
197     }
198 }
199 
200 //----------------------------------------
201 void
SetValue(void * object,const void * value) const202 ResTextureSamplerMember::SetValue(void* object, const void* value) const
203 {
204     ResPixelBasedTextureMapper mapper(object);
205     const ut::FloatColor& color = *reinterpret_cast<const ut::FloatColor*>(value);
206 
207     NW_NULL_ASSERT(ResDynamicCast<ResStandardTextureSampler>(mapper.GetSampler()).ptr());
208 
209     // mapper.GetSampler()はconstなので、内部に直接アクセスする
210     ResStandardTextureSampler sampler(mapper.ref().toSampler.to_ptr());
211 
212     switch(GetMemberType())
213     {
214     case MEMBER_TYPE_BORDER_COLOR:
215         sampler.SetBorderColor(color);
216         break;
217 
218     default:
219         NW_ASSERT(false);
220     }
221 }
222 
223 //----------------------------------------
224 void
SetValue(void * object,const void * value) const225 ResTextureMapperMember::SetValue(void* object, const void* value) const
226 {
227     ResPixelBasedTextureMapper mapper(object);
228     const ut::Offset& offset = *reinterpret_cast<const ut::Offset*>(value);
229 
230     ResReferenceTexture texture(offset.to_ptr());
231 
232     switch(GetMemberType())
233     {
234     case MEMBER_TYPE_TEXTURE:
235         mapper.SetTexture(texture.GetTargetTexture());
236         break;
237 
238     default:
239         NW_ASSERT(false);
240     }
241 }
242 
243 //----------------------------------------
244 void
SetValue(void * object,const void * value) const245 ResBlendOperationMember::SetValue(void* object, const void* value) const
246 {
247     ResBlendOperation operation(object);
248     const ut::FloatColor& color = *reinterpret_cast<const ut::FloatColor*>(value);
249 
250     switch(GetMemberType())
251     {
252     case MEMBER_TYPE_BLEND_COLOR:
253         operation.SetBlendColor(color);
254         break;
255 
256     default:
257         NW_ASSERT(false);
258     }
259 }
260 
261 //----------------------------------------
262 void
SetValue(void * object,const void * value) const263 ResTextureCoordinatorMember::SetValue(void* object, const void* value) const
264 {
265     ResTextureCoordinator coordinator(object);
266 
267     switch(GetMemberType())
268     {
269     case MEMBER_TYPE_SCALE:
270         {
271             const math::VEC2& scale = *reinterpret_cast<const math::VEC2*>(value);
272             coordinator.SetScale(scale);
273         }
274         break;
275 
276     case MEMBER_TYPE_ROTATE:
277         {
278             float rotate = *reinterpret_cast<const float*>(value);
279             coordinator.SetRotate(rotate);
280         }
281         break;
282 
283     case MEMBER_TYPE_TRANSLATE:
284         {
285             const math::VEC2& translate = *reinterpret_cast<const math::VEC2*>(value);
286             coordinator.SetTranslate(translate);
287         }
288         break;
289 
290     default:
291         NW_ASSERT(false);
292     }
293 
294     // Coordinator内で、値が変化した場合のみDirtyフラグを立てるようになっている。
295     // しかし、ここ以前に直接メモリに書き込んでいるので、
296     // 値が変化していないと判定されてしまう。そのため、明示的にフラグを立てる。
297     coordinator.SetDirty(true);
298 }
299 
300 //----------------------------------------
301 void
SetValue(void * object,const void * value) const302 ResModelMember::SetValue(void* object, const void* value) const
303 {
304     Model* model = reinterpret_cast<Model*>(object);
305 
306     switch(GetMemberType())
307     {
308     case MEMBER_TYPE_BRANCH_VISIBLE:
309         {
310             const bool visibility = *static_cast<const bool*>(value);
311             model->SetBranchVisible(visibility);
312         }
313         break;
314     case MEMBER_TYPE_VISIBLE:
315         {
316             const bool visibility = *static_cast<const bool*>(value);
317             model->SetVisible(visibility);
318         }
319         break;
320     default:
321         NW_ASSERT(false);
322     }
323 }
324 
325 //----------------------------------------
326 void
SetValue(void * object,const void * value) const327 ResMeshMember::SetValue(void* object, const void* value) const
328 {
329     ResMesh mesh(object);
330 
331     const bool visibility = *static_cast<const bool*>(value);
332     mesh.SetVisible(visibility);
333 }
334 
335 //----------------------------------------
336 void
SetValue(void * object,const void * value) const337 ResMeshNodeVisibilityMember::SetValue(void* object, const void* value) const
338 {
339     ResMeshNodeVisibility nodeVisibility(object);
340 
341     const bool visibility = *static_cast<const bool*>(value);
342     nodeVisibility.SetVisible(visibility);
343 }
344 
345 //----------------------------------------
346 void
SetValue(void * object,const void * value) const347 ResTransformMember::SetValue(void* object, const void* value) const
348 {
349     TransformNode* transformNode = reinterpret_cast<TransformNode*>(object);
350 
351     switch(GetMemberType())
352     {
353     case MEMBER_TYPE_TRANSFORM:
354         {
355             transformNode->Transform().SetTransform(*reinterpret_cast<const math::Transform3*>(value));
356             transformNode->Transform().EnableFlags(CalculatedTransform::FLAG_IS_DIRTY);
357         }
358         break;
359 
360     default:
361         NW_ASSERT(false);
362     }
363 }
364 
365 //----------------------------------------
366 void
SetValue(void * object,const void * value) const367 ResViewUpdaterMember::SetValue(void* object, const void* value) const
368 {
369     ResCameraViewUpdater viewUpdater(object);
370 
371     switch(viewUpdater.GetTypeInfo())
372     {
373     case ResAimTargetViewUpdater::TYPE_INFO:
374         {
375             ResAimTargetViewUpdater aimUpdater(object);
376 
377             switch(GetMemberType())
378             {
379             case MEMBER_TYPE_TARGET_POSITION:
380                 {
381                     const math::VEC3& position = *reinterpret_cast<const math::VEC3*>(value);
382                     aimUpdater.SetTargetPosition(position);
383                 }
384                 break;
385 
386             case MEMBER_TYPE_TWIST:
387                 {
388                     float twist = *reinterpret_cast<const float*>(value);
389                     aimUpdater.SetTwist(twist);
390                 }
391                 break;
392 
393             default:
394                 NW_ASSERT(false);
395             }
396         }
397         break;
398 
399     case ResLookAtTargetViewUpdater::TYPE_INFO:
400         {
401             ResLookAtTargetViewUpdater lookAtUpdater(object);
402 
403             switch(GetMemberType())
404             {
405             case MEMBER_TYPE_TARGET_POSITION:
406                 {
407                     const math::VEC3& position = *reinterpret_cast<const math::VEC3*>(value);
408                     lookAtUpdater.SetTargetPosition(position);
409                 }
410                 break;
411 
412             case MEMBER_TYPE_UPWARD_VECTOR:
413                 {
414                     const math::VEC3& upVector = *reinterpret_cast<const math::VEC3*>(value);
415                     lookAtUpdater.SetUpwardVector(upVector);
416                 }
417                 break;
418 
419             default:
420                 NW_ASSERT(false);
421             }
422         }
423         break;
424 
425     case ResRotateViewUpdater::TYPE_INFO:
426         {
427             ResRotateViewUpdater rotateUpdater(object);
428 
429             switch(GetMemberType())
430             {
431             case MEMBER_TYPE_VIEW_ROTATE:
432                 {
433                     const math::VEC3& rotate = *reinterpret_cast<const math::VEC3*>(value);
434                     rotateUpdater.SetViewRotate(rotate);
435                 }
436                 break;
437 
438             default:
439                 NW_ASSERT(false);
440             }
441         }
442         break;
443 
444     default:
445         NW_ASSERT(false);
446     }
447 }
448 
449 //----------------------------------------
450 void
SetValue(void * object,const void * value) const451 ResProjectionUpdaterMember::SetValue(void* object, const void* value) const
452 {
453     ResCameraProjectionUpdater projectionUpdater(object);
454 
455     switch(projectionUpdater.GetTypeInfo())
456     {
457     case ResPerspectiveProjectionUpdater::TYPE_INFO:
458         {
459             ResPerspectiveProjectionUpdater perspectiveUpdater(object);
460             float floatValue = *reinterpret_cast<const float*>(value);
461 
462             switch(GetMemberType())
463             {
464             case MEMBER_TYPE_NEAR:
465                 perspectiveUpdater.SetNear(floatValue);
466                 break;
467 
468             case MEMBER_TYPE_FAR:
469                 perspectiveUpdater.SetFar(floatValue);
470                 break;
471 
472             case MEMBER_TYPE_FOVY:
473                 perspectiveUpdater.SetFovy(floatValue);
474                 break;
475 
476             case MEMBER_TYPE_ASPECT_RATIO:
477                 perspectiveUpdater.SetAspectRatio(floatValue);
478                 break;
479 
480             default:
481                 NW_ASSERT(false);
482             }
483         }
484         break;
485 
486     case ResOrthoProjectionUpdater::TYPE_INFO:
487         {
488             ResOrthoProjectionUpdater orthoUpdater(object);
489             float floatValue = *reinterpret_cast<const float*>(value);
490 
491             switch(GetMemberType())
492             {
493             case MEMBER_TYPE_NEAR:
494                 orthoUpdater.SetNear(floatValue);
495                 break;
496 
497             case MEMBER_TYPE_FAR:
498                 orthoUpdater.SetFar(floatValue);
499                 break;
500 
501             case MEMBER_TYPE_ASPECT_RATIO:
502                 {
503                     ResProjectionRect rect = orthoUpdater.GetRect();
504                     rect.Set(floatValue, rect.GetHeight(), rect.GetCenter());
505                     orthoUpdater.SetRect(rect);
506                 }
507                 break;
508 
509             case MEMBER_TYPE_HEIGHT:
510                 {
511                     ResProjectionRect rect = orthoUpdater.GetRect();
512                     rect.Set(rect.GetAspectRatio(), floatValue, rect.GetCenter());
513                     orthoUpdater.SetRect(rect);
514                 }
515                 break;
516 
517             case MEMBER_TYPE_CENTER:
518                 {
519                     const math::VEC2& center = *reinterpret_cast<const math::VEC2*>(value);
520 
521                     ResProjectionRect rect = orthoUpdater.GetRect();
522                     rect.Set(rect.GetAspectRatio(), rect.GetHeight(), center);
523                     orthoUpdater.SetRect(rect);
524                 }
525                 break;
526 
527             default:
528                 NW_ASSERT(false);
529             }
530         }
531         break;
532 
533     // ResFrustumProjectionUpdaterは、アニメーションを設定できない
534 
535     default:
536         NW_ASSERT(false);
537     }
538 }
539 
540 //----------------------------------------
541 void
SetValue(void * object,const void * value) const542 ResLightMember::SetValue(void* object, const void* value) const
543 {
544     ResLight light(object);
545     bool boolValue = *static_cast<const bool*>(value);
546 
547     switch (GetMemberType())
548     {
549     case MEMBER_TYPE_IS_LIGHT_ENABLED:
550         light.SetLightEnabled(boolValue);
551         break;
552 
553     default:
554         NW_ASSERT(false);
555     }
556 }
557 
558 //----------------------------------------
559 void
SetValue(void * object,const void * value) const560 ResFragmentLightMember::SetValue(void* object, const void* value) const
561 {
562     ResFragmentLight light(object);
563     const ut::FloatColor& color = *reinterpret_cast<const ut::FloatColor*>(value);
564 
565     switch (GetMemberType())
566     {
567     case MEMBER_TYPE_AMBIENT:
568         light.SetAmbient(color);
569         break;
570 
571     case MEMBER_TYPE_DIFFUSE:
572         light.SetDiffuse(color);
573         break;
574 
575     case MEMBER_TYPE_SPECULAR0:
576         light.SetSpecular0(color);
577         break;
578 
579     case MEMBER_TYPE_SPECULAR1:
580         light.SetSpecular1(color);
581         break;
582 
583     case MEMBER_TYPE_DIRECTION:
584         {
585             math::VEC3 direction = *reinterpret_cast<const math::VEC3*>(value);
586             direction.Normalize();
587             light.SetDirection(direction);
588         }
589         break;
590 
591     case MEMBER_TYPE_DISTANCE_ATTENUATION_START:
592         {
593             float start = *reinterpret_cast<const float*>(value);
594             light.SetDistanceAttenuationStart(start);
595         }
596         break;
597 
598     case MEMBER_TYPE_DISTANCE_ATTENUATION_END:
599         {
600             float end = *reinterpret_cast<const float*>(value);
601             light.SetDistanceAttenuationEnd(end);
602         }
603         break;
604 
605     default:
606         NW_ASSERT(false);
607     }
608 }
609 
610 //----------------------------------------
611 void
SetValue(void * object,const void * value) const612 ResAmbientLightMember::SetValue(void* object, const void* value) const
613 {
614     ResAmbientLight light(object);
615     const ut::FloatColor& color = *reinterpret_cast<const ut::FloatColor*>(value);
616 
617     switch (GetMemberType())
618     {
619     case MEMBER_TYPE_AMBIENT:
620         light.SetAmbient(color);
621         break;
622 
623     default:
624         NW_ASSERT(false);
625     }
626 }
627 
628 //----------------------------------------
629 void
SetValue(void * object,const void * value) const630 ResVertexLightMember::SetValue(void* object, const void* value) const
631 {
632     ResVertexLight light(object);
633     const ut::FloatColor& color = *reinterpret_cast<const ut::FloatColor*>(value);
634     float floatValue = *static_cast<const float*>(value);
635 
636     switch (GetMemberType())
637     {
638     case MEMBER_TYPE_AMBIENT:
639         light.SetAmbient(color);
640         break;
641 
642     case MEMBER_TYPE_DIFFUSE:
643         light.SetDiffuse(color);
644         break;
645 
646     case MEMBER_TYPE_DIRECTION:
647         {
648             math::VEC3 direction = *reinterpret_cast<const math::VEC3*>(value);
649             direction.Normalize();
650             light.SetDirection(direction);
651         }
652         break;
653 
654     case MEMBER_TYPE_DISTANCE_ATTENUATION_CONSTANT:
655         {
656             math::VEC3 attenuation = light.GetDistanceAttenuation();
657             attenuation.x = floatValue;
658             light.SetDistanceAttenuation(attenuation);
659         }
660         break;
661 
662     case MEMBER_TYPE_DISTANCE_ATTENUATION_LINEAR:
663         {
664             math::VEC3 attenuation = light.GetDistanceAttenuation();
665             attenuation.y = floatValue;
666             light.SetDistanceAttenuation(attenuation);
667         }
668         break;
669 
670     case MEMBER_TYPE_DISTANCE_ATTENUATION_QUADRATIC:
671         {
672             math::VEC3 attenuation = light.GetDistanceAttenuation();
673             attenuation.z = floatValue;
674             light.SetDistanceAttenuation(attenuation);
675         }
676         break;
677 
678     case MEMBER_TYPE_SPOT_EXPONENT:
679         {
680             math::VEC2 spotFactor = light.GetSpotFactor();
681             spotFactor.x = floatValue;
682             light.SetSpotFactor(spotFactor);
683         }
684         break;
685 
686     case MEMBER_TYPE_SPOT_CUTOFF_ANGLE:
687         {
688             math::VEC2 spotFactor = light.GetSpotFactor();
689             spotFactor.y = floatValue;
690             light.SetSpotFactor(spotFactor);
691         }
692         break;
693 
694     default:
695         NW_ASSERT(false);
696     }
697 }
698 
699 //----------------------------------------
700 void
SetValue(void * object,const void * value) const701 ResHemiSphereLightMember::SetValue(void* object, const void* value) const
702 {
703     ResHemiSphereLight light(object);
704     const ut::FloatColor& color = *reinterpret_cast<const ut::FloatColor*>(value);
705 
706     switch (GetMemberType())
707     {
708     case MEMBER_TYPE_GROUND_COLOR:
709         light.SetGroundColor(color);
710         break;
711 
712     case MEMBER_TYPE_SKY_COLOR:
713         light.SetSkyColor(color);
714         break;
715 
716     case MEMBER_TYPE_DIRECTION:
717         {
718             math::VEC3 direction = *reinterpret_cast<const math::VEC3*>(value);
719             direction.Normalize();
720             light.SetDirection(direction);
721         }
722         break;
723 
724     case MEMBER_TYPE_LERP_FACTOR:
725         {
726             float floatValue = *static_cast<const float*>(value);
727             light.SetLerpFactor(floatValue);
728         }
729         break;
730 
731     default:
732         NW_ASSERT(false);
733     }
734 }
735 
736 //----------------------------------------
737 void
SetValue(void * object,const void * value) const738 ResFogMember::SetValue(void* object, const void* value) const
739 {
740     ResFog fog(object);
741 
742     switch (GetMemberType())
743     {
744     case MEMBER_TYPE_COLOR:
745         {
746             const ut::FloatColor& color = *reinterpret_cast<const ut::FloatColor*>(value);
747             fog.SetColor(color);
748         }
749         break;
750 
751     default:
752         NW_ASSERT(false);
753     }
754 }
755 
756 } // namespace res
757 } // namespace anim
758 } // namespace nw
759