1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_FragmentLight.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: 29649 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/os/os_Memory.h>
19
20 #include <nw/gfx/gfx_FragmentLight.h>
21 #include <nw/gfx/gfx_ISceneVisitor.h>
22
23 #include <cstring>
24
25 namespace nw
26 {
27 namespace gfx
28 {
29
30 NW_UT_RUNTIME_TYPEINFO_DEFINITION(FragmentLight, Light);
31
32 //----------------------------------------
33 FragmentLight*
Create(os::IAllocator * allocator)34 FragmentLight::DynamicBuilder::Create(
35 os::IAllocator* allocator
36 )
37 {
38 NW_NULL_ASSERT(allocator);
39
40 // CreateResFragmentLight で名前を指定するようにしたら
41 // GetMemorySize も修正する必要がある。
42
43 ResPtr resource(
44 CreateResFragmentLight(allocator),
45 ResFragmentLightDataDestroyer(allocator));
46
47 void* memory = allocator->Alloc(sizeof(FragmentLight));
48 NW_NULL_ASSERT(memory);
49 FragmentLight* light = new(memory) FragmentLight(
50 allocator,
51 resource,
52 m_Description);
53
54 Result result = light->Initialize(allocator);
55 NW_ASSERT(result.IsSuccess());
56
57 return light;
58 }
59
60 //----------------------------------------------------------
61 size_t
GetMemorySize(size_t alignment) const62 FragmentLight::DynamicBuilder::GetMemorySize( size_t alignment ) const
63 {
64 NW_ASSERT(this->m_Description.isFixedSizeMemory);
65
66 os::MemorySizeCalculator size(alignment);
67
68 // FragmentLight::CreateResFragmentLight
69 size += sizeof(ResFragmentLightData);
70 size += sizeof(ResReferenceLookupTable);
71 size += sizeof(ResLightingLookupTable);
72 size += sizeof(ResReferenceLookupTable);
73
74 size += sizeof(FragmentLight);
75
76 // FragmentLight::Initialize
77 TransformNode::GetMemorySizeForInitialize(
78 &size,
79 ResTransformNode(),
80 m_Description);
81
82 // FragmentLight::CreateOriginalValue
83 size += sizeof(ResFragmentLightData);
84
85 // Light::CreateAnimGroup
86 // DynamicBuilder 使用時には何も行なわれない。
87
88 return size.GetSizeWithPadding(alignment);
89 }
90
91 //----------------------------------------
92 FragmentLight*
Create(SceneNode * parent,ResSceneObject resource,const FragmentLight::Description & description,os::IAllocator * allocator)93 FragmentLight::Create(
94 SceneNode* parent,
95 ResSceneObject resource,
96 const FragmentLight::Description& description,
97 os::IAllocator* allocator
98 )
99 {
100 NW_NULL_ASSERT(allocator);
101
102 ResFragmentLight resNode = ResDynamicCast<ResFragmentLight>(resource);
103 NW_ASSERT(resNode.IsValid());
104 NW_ASSERT( internal::ResCheckRevision( resNode ) );
105
106 void* memory = allocator->Alloc(sizeof(FragmentLight));
107 NW_NULL_ASSERT(memory);
108
109 FragmentLight* light = new(memory) FragmentLight(
110 allocator,
111 resNode,
112 description);
113
114 Result result = light->Initialize(allocator);
115 NW_ASSERT(result.IsSuccess());
116
117 if (parent)
118 {
119 bool isAttached = parent->AttachChild(light);
120 NW_ASSERT(isAttached);
121 }
122
123 return light;
124 }
125
126 //----------------------------------------
127 void
UpdateDirection()128 FragmentLight::UpdateDirection()
129 {
130 ResFragmentLight resLight = this->GetResFragmentLight();
131
132 if (ut::CheckFlag(resLight.GetFlags(), ResFragmentLightData::FLAG_IS_INHERITING_DIRECTION_ROTATE))
133 {
134 this->CalcInheritingDiretion(this->Direction(), resLight.GetDirection());
135 }
136 else
137 {
138 this->Direction() = resLight.GetDirection();
139 }
140 }
141
142
143 //----------------------------------------
144 void
Accept(ISceneVisitor * visitor)145 FragmentLight::Accept(
146 ISceneVisitor* visitor
147 )
148 {
149 visitor->VisitFragmentLight(this);
150 AcceptChildren(visitor);
151 }
152
153
154 //-----------------------------------------
155 /* static*/ ResFragmentLightData*
CreateResFragmentLight(os::IAllocator * allocator,const char * name)156 FragmentLight::CreateResFragmentLight(os::IAllocator* allocator, const char* name /* = NULL */)
157 {
158 // TODO: 細かくアロケートする実装になっているが、まとめて確保できる仕組みも追加予定。
159
160 ResFragmentLightData* resFragmentLight =
161 AllocateAndFillN<ResFragmentLightData>(allocator, sizeof(ResFragmentLightData), 0);
162
163 //--------------------------------
164 // ResSceneObjectData のメンバ初期化
165 resFragmentLight->typeInfo = ResFragmentLight::TYPE_INFO;
166 resFragmentLight->m_Header.revision = ResLight::BINARY_REVISION;
167 resFragmentLight->m_Header.signature = ResLight::SIGNATURE;
168
169 resFragmentLight->m_UserDataDicCount = 0;
170 resFragmentLight->toUserDataDic.set_ptr( NULL );
171
172 resFragmentLight->toName.set_ptr(AllocateAndCopyString(name, allocator, MAX_NAME_LENGTH));
173
174 //--------------------------------
175 // ResSceneNodeData のメンバ初期化
176 resFragmentLight->m_ChildrenTableCount = 0;
177 resFragmentLight->toChildrenTable.set_ptr( NULL );
178 resFragmentLight->m_AnimGroupsDicCount = 0;
179 resFragmentLight->toAnimGroupsDic.set_ptr( NULL );
180
181 //--------------------------------
182 // ResTransformNode のメンバ初期化
183 const math::VEC3 scale(1.0f, 1.0f, 1.0f);
184 const math::VEC3 rotate(0.0f, 0.0f, 0.0f);
185 const math::VEC3 translate(0.0f, 0.0f, 0.0f);
186 resFragmentLight->m_Transform = math::Transform3(scale, rotate, translate);
187 resFragmentLight->m_WorldMatrix = math::MTX34::Identity();
188 ResTransformNode(resFragmentLight).SetBranchVisible(true);
189
190 //--------------------------------
191 // ResFragmentLightData のメンバ初期化
192 ResReferenceLookupTableData* distanceSampler =
193 AllocateAndFill<ResReferenceLookupTableData>(allocator, 0);
194
195 distanceSampler->typeInfo = ResReferenceLookupTable_TYPE_INFO;
196 distanceSampler->toTargetLut.set_ptr(NULL);
197 distanceSampler->toPath.set_ptr(NULL);
198
199 ResLightingLookupTableData* angleSampler =
200 AllocateAndFill<ResLightingLookupTableData>(allocator, 0);
201
202 ResReferenceLookupTableData* referenceAngleSampler =
203 AllocateAndFill<ResReferenceLookupTableData>(allocator, 0);
204
205 referenceAngleSampler->typeInfo = ResReferenceLookupTable_TYPE_INFO;
206 referenceAngleSampler->toPath.set_ptr(NULL);
207 referenceAngleSampler->toTargetLut.set_ptr(NULL);
208
209 angleSampler->toSampler.set_ptr(referenceAngleSampler);
210 angleSampler->m_Input = ResLightingLookupTable::INPUT_NH;
211 angleSampler->m_Scale = ResLightingLookupTable::SCALE_1;
212
213 resFragmentLight->toDistanceSampler.set_ptr( distanceSampler );
214 resFragmentLight->toAngleSampler.set_ptr( angleSampler );
215
216 return resFragmentLight;
217 }
218
219
220 //-----------------------------------------
221 /* static */ void
DestroyResFragmentLight(os::IAllocator * allocator,ResFragmentLightData * resFragmentLight)222 FragmentLight::DestroyResFragmentLight(os::IAllocator* allocator, ResFragmentLightData* resFragmentLight)
223 {
224 NW_NULL_ASSERT( allocator );
225 NW_NULL_ASSERT( resFragmentLight );
226
227 allocator->Free( resFragmentLight->toDistanceSampler.to_ptr() );
228
229 ResLightingLookupTableData* angleSampler =
230 reinterpret_cast<ResLightingLookupTableData*>(resFragmentLight->toAngleSampler.to_ptr());
231 allocator->Free( angleSampler->toSampler.to_ptr() );
232 allocator->Free( resFragmentLight->toAngleSampler.to_ptr() );
233 if ( resFragmentLight->toName.to_ptr() != NULL )
234 {
235 allocator->Free( const_cast<char*>( resFragmentLight->toName.to_ptr() ) );
236 }
237 allocator->Free( resFragmentLight );
238 }
239
240
241 //-----------------------------------------
242 Result
CreateOriginalValue(os::IAllocator * allocator)243 FragmentLight::CreateOriginalValue(os::IAllocator* allocator)
244 {
245 Result result = INITIALIZE_RESULT_OK;
246
247 void* buffer = allocator->Alloc(sizeof(ResFragmentLightData));
248 NW_NULL_ASSERT(buffer);
249
250 // リソースをコピー
251 ResFragmentLightData* originalValue = new(buffer) ResFragmentLightData(GetResFragmentLight().ref());
252 m_OriginalValue = ResFragmentLight(originalValue);
253
254 m_OriginalTransform = this->GetResTransformNode().GetTransform();
255
256 return result;
257 }
258
259 //----------------------------------------
260 Result
Initialize(os::IAllocator * allocator)261 FragmentLight::Initialize(os::IAllocator* allocator)
262 {
263 Result result = INITIALIZE_RESULT_OK;
264
265 result |= TransformNode::Initialize(allocator);
266 NW_ENSURE_AND_RETURN(result);
267
268 result |= CreateOriginalValue(allocator);
269 NW_ENSURE_AND_RETURN(result);
270
271 result |= CreateAnimGroup(allocator);
272 NW_ENSURE_AND_RETURN(result);
273
274 return result;
275 }
276
277 //----------------------------------------------------------
278 void
GetMemorySizeInternal(os::MemorySizeCalculator * pSize,ResFragmentLight resFragmentLight,Description description)279 FragmentLight::GetMemorySizeInternal(
280 os::MemorySizeCalculator* pSize,
281 ResFragmentLight resFragmentLight,
282 Description description
283 )
284 {
285 NW_ASSERT(description.isFixedSizeMemory);
286
287 os::MemorySizeCalculator& size = *pSize;
288
289 size += sizeof(FragmentLight);
290
291 // FragmentLight::Initialize
292 TransformNode::GetMemorySizeForInitialize(
293 &size,
294 resFragmentLight,
295 description);
296
297 size += sizeof(ResFragmentLightData);
298
299 if (description.isAnimationEnabled &&
300 resFragmentLight.GetAnimGroupsCount() > 0)
301 {
302 AnimGroup::Builder()
303 .ResAnimGroup(resFragmentLight.GetAnimGroups(0))
304 .UseOriginalValue(true)
305 .GetMemorySizeInternal(&size);
306 }
307 }
308
309 } // namespace gfx
310 } // namespace nw
311