1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_HemiSphereLight.cpp
4
5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain proprietary
8 information of Nintendo and/or its licensed developers and are protected by
9 national and international copyright laws. They may not be disclosed to third
10 parties or copied or duplicated in any form, in whole or in part, without the
11 prior written consent of Nintendo.
12
13 The content herein is highly confidential and should be handled accordingly.
14
15 $Revision: 31311 $
16 *---------------------------------------------------------------------------*/
17
18 #include "precompiled.h"
19
20 #include <nw/os/os_Memory.h>
21
22 #include <nw/gfx/gfx_HemiSphereLight.h>
23 #include <nw/gfx/gfx_ISceneVisitor.h>
24
25 #include <cstring>
26
27 namespace nw
28 {
29 namespace gfx
30 {
31
32 NW_UT_RUNTIME_TYPEINFO_DEFINITION(HemiSphereLight, Light);
33
34 //----------------------------------------
35 HemiSphereLight*
Create(os::IAllocator * allocator)36 HemiSphereLight::DynamicBuilder::Create(
37 os::IAllocator* allocator
38 )
39 {
40 NW_NULL_ASSERT(allocator);
41
42 // CreateResHemiSphereLight で名前を指定するようにしたら
43 // GetMemorySize も修正する必要がある。
44
45 ResPtr resource(
46 CreateResHemiSphereLight(allocator),
47 ResHemiSphereLightDataDestroyer(allocator));
48
49 void* memory = allocator->Alloc(sizeof(HemiSphereLight));
50 NW_NULL_ASSERT(memory);
51 HemiSphereLight* light = new(memory) HemiSphereLight(
52 allocator,
53 resource,
54 m_Description);
55
56 Result result = light->Initialize(allocator);
57 NW_ASSERT(result.IsSuccess());
58
59 return light;
60 }
61
62 //----------------------------------------------------------
63 size_t
GetMemorySize(size_t alignment) const64 HemiSphereLight::DynamicBuilder::GetMemorySize( size_t alignment ) const
65 {
66 NW_ASSERT(this->m_Description.isFixedSizeMemory);
67
68 os::MemorySizeCalculator size(alignment);
69
70 // HemiSphereLight::CreateResHemiSphereLight
71 size += sizeof(ResHemiSphereLightData);
72
73 size += sizeof(HemiSphereLight);
74
75 // HemiSphereLight::Initialize
76 TransformNode::GetMemorySizeForInitialize(
77 &size,
78 ResTransformNode(),
79 m_Description);
80
81 // HemiSphereLight::CreateOriginalValue
82 size += sizeof(ResHemiSphereLightData);
83
84 // Light::CreateAnimGroup
85 // DynamicBuilder 使用時には何も行なわれない。
86
87 return size.GetSizeWithPadding(alignment);
88 }
89
90 //----------------------------------------
91 HemiSphereLight*
Create(SceneNode * parent,ResSceneObject resource,const HemiSphereLight::Description & description,os::IAllocator * allocator)92 HemiSphereLight::Create(
93 SceneNode* parent,
94 ResSceneObject resource,
95 const HemiSphereLight::Description& description,
96 os::IAllocator* allocator
97 )
98 {
99 NW_NULL_ASSERT(allocator);
100
101 ResHemiSphereLight resNode = ResDynamicCast<ResHemiSphereLight>(resource);
102 NW_ASSERT(resNode.IsValid());
103 NW_ASSERT( internal::ResCheckRevision( resNode ) );
104
105 void* memory = allocator->Alloc(sizeof(HemiSphereLight));
106 NW_NULL_ASSERT(memory);
107
108 HemiSphereLight* light = new(memory) HemiSphereLight(
109 allocator,
110 resNode,
111 description);
112
113 Result result = light->Initialize(allocator);
114 NW_ASSERT(result.IsSuccess());
115
116 if (parent)
117 {
118 bool isAttached = parent->AttachChild(light);
119 NW_ASSERT(isAttached);
120 }
121
122 return light;
123 }
124
125 //----------------------------------------
126 void
Accept(ISceneVisitor * visitor)127 HemiSphereLight::Accept(
128 ISceneVisitor* visitor
129 )
130 {
131 visitor->VisitHemiSphereLight(this);
132 AcceptChildren(visitor);
133 }
134
135
136 //-----------------------------------------
137 /* static*/ ResHemiSphereLightData*
CreateResHemiSphereLight(os::IAllocator * allocator,const char * name)138 HemiSphereLight::CreateResHemiSphereLight(os::IAllocator* allocator, const char* name /* = NULL */)
139 {
140 // TODO: 細かくアロケートする実装になっているが、まとめて確保できる仕組みも追加予定。
141
142 ResHemiSphereLightData* resHemiSphereLight =
143 AllocateAndFillN<ResHemiSphereLightData>(allocator, sizeof(ResHemiSphereLightData), 0);
144
145 //--------------------------------
146 // ResSceneObjectData のメンバ初期化
147 resHemiSphereLight->typeInfo = ResHemiSphereLight::TYPE_INFO;
148 resHemiSphereLight->m_Header.revision = ResLight::BINARY_REVISION;
149 resHemiSphereLight->m_Header.signature = ResLight::SIGNATURE;
150
151 resHemiSphereLight->m_UserDataDicCount = 0;
152 resHemiSphereLight->toUserDataDic.set_ptr( NULL );
153
154 resHemiSphereLight->toName.set_ptr(AllocateAndCopyString(name, allocator, MAX_NAME_LENGTH));
155
156 //--------------------------------
157 // ResSceneNodeData のメンバ初期化
158 resHemiSphereLight->m_ChildrenTableCount = 0;
159 resHemiSphereLight->toChildrenTable.set_ptr( NULL );
160 resHemiSphereLight->m_AnimGroupsDicCount = 0;
161 resHemiSphereLight->toAnimGroupsDic.set_ptr( NULL );
162
163 //--------------------------------
164 // ResTransformNode のメンバ初期化
165 const math::VEC3 scale(1.0f, 1.0f, 1.0f);
166 const math::VEC3 rotate(0.0f, 0.0f, 0.0f);
167 const math::VEC3 translate(0.0f, 0.0f, 0.0f);
168 resHemiSphereLight->m_Transform = math::Transform3(scale, rotate, translate);
169 resHemiSphereLight->m_WorldMatrix = math::MTX34::Identity();
170 ResTransformNode(resHemiSphereLight).SetBranchVisible(true);
171
172 return resHemiSphereLight;
173 }
174
175
176 //-----------------------------------------
177 /* static */ void
DestroyResHemiSphereLight(os::IAllocator * allocator,ResHemiSphereLightData * resHemiSphereLight)178 HemiSphereLight::DestroyResHemiSphereLight(os::IAllocator* allocator, ResHemiSphereLightData* resHemiSphereLight)
179 {
180 NW_NULL_ASSERT( allocator );
181 NW_NULL_ASSERT( resHemiSphereLight );
182
183 if ( resHemiSphereLight->toName.to_ptr() != NULL )
184 {
185 allocator->Free( const_cast<char*>( resHemiSphereLight->toName.to_ptr() ) );
186 }
187 allocator->Free( resHemiSphereLight );
188 }
189
190
191 //-----------------------------------------
192 Result
CreateOriginalValue(os::IAllocator * allocator)193 HemiSphereLight::CreateOriginalValue(os::IAllocator* allocator)
194 {
195 Result result = INITIALIZE_RESULT_OK;
196
197 void* buffer = allocator->Alloc(sizeof(ResHemiSphereLightData));
198 NW_NULL_ASSERT(buffer);
199
200 // リソースをコピー
201 ResHemiSphereLightData* originalValue = new(buffer) ResHemiSphereLightData(GetResHemiSphereLight().ref());
202 m_OriginalValue = ResHemiSphereLight(originalValue);
203
204 m_OriginalTransform = this->GetResTransformNode().GetTransform();
205
206 return result;
207 }
208
209 //----------------------------------------
210 Result
Initialize(os::IAllocator * allocator)211 HemiSphereLight::Initialize(os::IAllocator* allocator)
212 {
213 Result result = INITIALIZE_RESULT_OK;
214
215 result |= TransformNode::Initialize(allocator);
216 NW_ENSURE_AND_RETURN(result);
217
218 result |= CreateOriginalValue(allocator);
219 NW_ENSURE_AND_RETURN(result);
220
221 result |= CreateAnimGroup(allocator);
222 NW_ENSURE_AND_RETURN(result);
223
224 return result;
225 }
226
227 //----------------------------------------------------------
228 void
GetMemorySizeInternal(os::MemorySizeCalculator * pSize,ResHemiSphereLight resHemiSphereLight,Description description)229 HemiSphereLight::GetMemorySizeInternal(
230 os::MemorySizeCalculator* pSize,
231 ResHemiSphereLight resHemiSphereLight,
232 Description description
233 )
234 {
235 NW_ASSERT(description.isFixedSizeMemory);
236
237 os::MemorySizeCalculator& size = *pSize;
238
239 size += sizeof(HemiSphereLight);
240
241 // HemiSphereLight::Initialize
242 TransformNode::GetMemorySizeForInitialize(
243 &size,
244 resHemiSphereLight,
245 description);
246
247 size += sizeof(ResHemiSphereLightData);
248
249 if (description.isAnimationEnabled &&
250 resHemiSphereLight.GetAnimGroupsCount() > 0)
251 {
252 AnimGroup::Builder()
253 .ResAnimGroup(resHemiSphereLight.GetAnimGroups(0))
254 .UseOriginalValue(true)
255 .GetMemorySizeInternal(&size);
256 }
257 }
258
259 } // namespace gfx
260 } // namespace nw
261