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