1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_Light.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: 23073 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 
18 #include <nw/gfx/gfx_Light.h>
19 #include <nw/gfx/gfx_ISceneVisitor.h>
20 
21 namespace nw
22 {
23 namespace gfx
24 {
25 
26 NW_UT_RUNTIME_TYPEINFO_DEFINITION(Light, TransformNode);
27 
28 //----------------------------------------
29 void
Accept(ISceneVisitor * visitor)30 Light::Accept(
31     ISceneVisitor* visitor
32 )
33 {
34     visitor->VisitLight(this);
35     AcceptChildren(visitor);
36 }
37 
38 //----------------------------------------
39 Result
CreateAnimGroup(os::IAllocator * allocator)40 Light::CreateAnimGroup(os::IAllocator* allocator)
41 {
42     Result result = INITIALIZE_RESULT_OK;
43 
44     NW_ASSERT(m_OriginalValue.IsValid());
45 
46     if (!m_AnimBinding)
47     {
48         // DynamicBuilderを使用した場合は生成されない
49         return result;
50     }
51 
52     ResSceneNode resSceneNode = GetResSceneNode();
53     NW_ASSERT(resSceneNode.IsValid());
54 
55     NW_ASSERT(resSceneNode.GetAnimGroupsCount() == 1);
56     anim::ResAnimGroup resAnimGroup = resSceneNode.GetAnimGroups(0);
57 
58     NW_ASSERT(resAnimGroup.GetTargetType() == anim::ResGraphicsAnimGroup::TARGET_TYPE_LIGHT);
59 
60     AnimGroup* animGroup = AnimGroup::Builder()
61         .ResAnimGroup(resAnimGroup)
62         .SetSceneNode(this)
63         .UseOriginalValue(true) // TODO: 選択できる必要はある?
64         .Create(allocator);
65 
66     if (animGroup == NULL)
67     {
68         result |= Result::MASK_FAIL_BIT;
69     }
70 
71     NW_ENSURE_AND_RETURN(result);
72 
73     m_AnimGroup = animGroup;
74 
75     // 各メンバの参照解決
76     const int animMemberCount = m_AnimGroup->GetMemberCount();
77     for (int memberIdx = 0; memberIdx < animMemberCount; ++memberIdx)
78     {
79         anim::ResAnimGroupMember member = m_AnimGroup->GetResAnimGroupMember(memberIdx);
80 
81         void* object = GetAnimTargetObject(member);
82         m_AnimGroup->SetTargetObject(memberIdx, object);
83 
84         // TODO: アドレス算出もSetterに似た実装で行う?
85         if (member.GetObjectType() == anim::ResAnimGroupMember::OBJECT_TYPE_TRANSFORM &&
86             member.GetMemberType() == anim::ResTransformMember::MEMBER_TYPE_TRANSFORM)
87         {
88             m_AnimGroup->SetTargetPtr(memberIdx, &this->Transform());
89         }
90         else
91         {
92             u8* target = static_cast<u8*>(object);
93             target += member.GetMemberOffset();
94             m_AnimGroup->SetTargetPtr(memberIdx, target);
95         }
96 
97         m_AnimGroup->SetTargetObjectIndex(memberIdx, 0); // TODO: 要検討
98 
99         if (member.GetObjectType() == nw::anim::ResAnimGroupMember::OBJECT_TYPE_TRANSFORM)
100         {
101             m_AnimGroup->SetOriginalValue(memberIdx, &m_OriginalTransform);
102         }
103         else
104         {
105             u8* originalValue = reinterpret_cast<u8*>(m_OriginalValue.ptr());
106             originalValue += member.GetMemberOffset();
107             m_AnimGroup->SetOriginalValue(memberIdx, originalValue);
108         }
109     }
110 
111     m_AnimBinding->SetAnimGroup(0, m_AnimGroup);
112 
113     return result;
114 }
115 
116 //----------------------------------------
117 void
DestroyOriginalValue()118 Light::DestroyOriginalValue()
119 {
120     NW_ASSERT(m_OriginalValue.IsValid());
121 
122     GetAllocator().Free(m_OriginalValue.ptr());
123     m_OriginalValue = ResLight(NULL);
124 }
125 
126 //----------------------------------------
127 void*
GetAnimTargetObject(const anim::ResAnimGroupMember & anim)128 Light::GetAnimTargetObject(const anim::ResAnimGroupMember& anim)
129 {
130     switch (anim.GetObjectType())
131     {
132     case anim::ResAnimGroupMember::OBJECT_TYPE_TRANSFORM:
133         {
134             return static_cast<gfx::TransformNode*>(this);
135         }
136 
137     case anim::ResAnimGroupMember::OBJECT_TYPE_LIGHT:
138         {
139             ResLight resLight = ResDynamicCast<ResLight>(this->GetResSceneObject());
140             NW_ASSERT(resLight.IsValid());
141 
142             ResLightData* ptr = resLight.ptr();
143             return ptr;
144         }
145 
146     case anim::ResAnimGroupMember::OBJECT_TYPE_FRAGMENT_LIGHT:
147         {
148             NW_ASSERT(ut::IsTypeOf<gfx::FragmentLight>(this));
149             ResFragmentLightData* ptr = static_cast<gfx::FragmentLight&>(*this).GetResFragmentLight().ptr();
150             return ptr;
151         }
152 
153     case anim::ResAnimGroupMember::OBJECT_TYPE_AMBIENT_LIGHT:
154         {
155             NW_ASSERT(ut::IsTypeOf<gfx::AmbientLight>(this));
156             ResAmbientLightData* ptr = static_cast<gfx::AmbientLight&>(*this).GetResAmbientLight().ptr();
157             return ptr;
158         }
159 
160 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
161     case anim::ResAnimGroupMember::OBJECT_TYPE_VERTEX_LIGHT:
162         {
163             NW_ASSERT(ut::IsTypeOf<gfx::VertexLight>(this));
164             ResVertexLightData* ptr = static_cast<gfx::VertexLight&>(*this).GetResVertexLight().ptr();
165             return ptr;
166         }
167 #endif
168     case anim::ResAnimGroupMember::OBJECT_TYPE_HEMISPHERE_LIGHT:
169         {
170             NW_ASSERT(ut::IsTypeOf<gfx::HemiSphereLight>(this));
171             ResHemiSphereLightData* ptr = static_cast<gfx::HemiSphereLight&>(*this).GetResHemiSphereLight().ptr();
172             return ptr;
173         }
174 
175     default:
176         NW_ASSERT(false);
177         return NULL;
178     }
179 }
180 
181 } // namespace gfx
182 } // namespace nw
183