1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_HemiSphereLight.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_HemiSphereLight.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(HemiSphereLight, Light);
31
32 //----------------------------------------
33 HemiSphereLight*
Create(os::IAllocator * allocator)34 HemiSphereLight::DynamicBuilder::Create(
35 os::IAllocator* allocator
36 )
37 {
38 NW_NULL_ASSERT(allocator);
39
40 // CreateResHemiSphereLight で名前を指定するようにしたら
41 // GetMemorySize も修正する必要がある。
42
43 ResPtr resource(
44 CreateResHemiSphereLight(allocator),
45 ResHemiSphereLightDataDestroyer(allocator));
46
47 void* memory = allocator->Alloc(sizeof(HemiSphereLight));
48 NW_NULL_ASSERT(memory);
49 HemiSphereLight* light = new(memory) HemiSphereLight(
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 HemiSphereLight::DynamicBuilder::GetMemorySize( size_t alignment ) const
63 {
64 NW_ASSERT(this->m_Description.isFixedSizeMemory);
65
66 os::MemorySizeCalculator size(alignment);
67
68 // HemiSphereLight::CreateResHemiSphereLight
69 size += sizeof(ResHemiSphereLightData);
70
71 size += sizeof(HemiSphereLight);
72
73 // HemiSphereLight::Initialize
74 TransformNode::GetMemorySizeForInitialize(
75 &size,
76 ResTransformNode(),
77 m_Description);
78
79 // HemiSphereLight::CreateOriginalValue
80 size += sizeof(ResHemiSphereLightData);
81
82 // Light::CreateAnimGroup
83 // DynamicBuilder 使用時には何も行なわれない。
84
85 return size.GetSizeWithPadding(alignment);
86 }
87
88 //----------------------------------------
89 HemiSphereLight*
Create(SceneNode * parent,ResSceneObject resource,const HemiSphereLight::Description & description,os::IAllocator * allocator)90 HemiSphereLight::Create(
91 SceneNode* parent,
92 ResSceneObject resource,
93 const HemiSphereLight::Description& description,
94 os::IAllocator* allocator
95 )
96 {
97 NW_NULL_ASSERT(allocator);
98
99 ResHemiSphereLight resNode = ResDynamicCast<ResHemiSphereLight>(resource);
100 NW_ASSERT(resNode.IsValid());
101 NW_ASSERT( internal::ResCheckRevision( resNode ) );
102
103 void* memory = allocator->Alloc(sizeof(HemiSphereLight));
104 NW_NULL_ASSERT(memory);
105
106 HemiSphereLight* light = new(memory) HemiSphereLight(
107 allocator,
108 resNode,
109 description);
110
111 Result result = light->Initialize(allocator);
112 NW_ASSERT(result.IsSuccess());
113
114 if (parent)
115 {
116 bool isAttached = parent->AttachChild(light);
117 NW_ASSERT(isAttached);
118 }
119
120 return light;
121 }
122
123 //----------------------------------------
124 void
Accept(ISceneVisitor * visitor)125 HemiSphereLight::Accept(
126 ISceneVisitor* visitor
127 )
128 {
129 visitor->VisitHemiSphereLight(this);
130 AcceptChildren(visitor);
131 }
132
133
134 //-----------------------------------------
135 /* static*/ ResHemiSphereLightData*
CreateResHemiSphereLight(os::IAllocator * allocator,const char * name)136 HemiSphereLight::CreateResHemiSphereLight(os::IAllocator* allocator, const char* name /* = NULL */)
137 {
138 // TODO: 細かくアロケートする実装になっているが、まとめて確保できる仕組みも追加予定。
139
140 ResHemiSphereLightData* resHemiSphereLight =
141 AllocateAndFillN<ResHemiSphereLightData>(allocator, sizeof(ResHemiSphereLightData), 0);
142
143 //--------------------------------
144 // ResSceneObjectData のメンバ初期化
145 resHemiSphereLight->typeInfo = ResHemiSphereLight::TYPE_INFO;
146 resHemiSphereLight->m_Header.revision = ResLight::BINARY_REVISION;
147 resHemiSphereLight->m_Header.signature = ResLight::SIGNATURE;
148
149 resHemiSphereLight->m_UserDataDicCount = 0;
150 resHemiSphereLight->toUserDataDic.set_ptr( NULL );
151
152 resHemiSphereLight->toName.set_ptr(AllocateAndCopyString(name, allocator, MAX_NAME_LENGTH));
153
154 //--------------------------------
155 // ResSceneNodeData のメンバ初期化
156 resHemiSphereLight->m_ChildrenTableCount = 0;
157 resHemiSphereLight->toChildrenTable.set_ptr( NULL );
158 resHemiSphereLight->m_AnimGroupsDicCount = 0;
159 resHemiSphereLight->toAnimGroupsDic.set_ptr( NULL );
160
161 //--------------------------------
162 // ResTransformNode のメンバ初期化
163 const math::VEC3 scale(1.0f, 1.0f, 1.0f);
164 const math::VEC3 rotate(0.0f, 0.0f, 0.0f);
165 const math::VEC3 translate(0.0f, 0.0f, 0.0f);
166 resHemiSphereLight->m_Transform = math::Transform3(scale, rotate, translate);
167 resHemiSphereLight->m_WorldMatrix = math::MTX34::Identity();
168 ResTransformNode(resHemiSphereLight).SetBranchVisible(true);
169
170 return resHemiSphereLight;
171 }
172
173
174 //-----------------------------------------
175 /* static */ void
DestroyResHemiSphereLight(os::IAllocator * allocator,ResHemiSphereLightData * resHemiSphereLight)176 HemiSphereLight::DestroyResHemiSphereLight(os::IAllocator* allocator, ResHemiSphereLightData* resHemiSphereLight)
177 {
178 NW_NULL_ASSERT( allocator );
179 NW_NULL_ASSERT( resHemiSphereLight );
180
181 if ( resHemiSphereLight->toName.to_ptr() != NULL )
182 {
183 allocator->Free( const_cast<char*>( resHemiSphereLight->toName.to_ptr() ) );
184 }
185 allocator->Free( resHemiSphereLight );
186 }
187
188
189 //-----------------------------------------
190 Result
CreateOriginalValue(os::IAllocator * allocator)191 HemiSphereLight::CreateOriginalValue(os::IAllocator* allocator)
192 {
193 Result result = INITIALIZE_RESULT_OK;
194
195 void* buffer = allocator->Alloc(sizeof(ResHemiSphereLightData));
196 NW_NULL_ASSERT(buffer);
197
198 // リソースをコピー
199 ResHemiSphereLightData* originalValue = new(buffer) ResHemiSphereLightData(GetResHemiSphereLight().ref());
200 m_OriginalValue = ResHemiSphereLight(originalValue);
201
202 m_OriginalTransform = this->GetResTransformNode().GetTransform();
203
204 return result;
205 }
206
207 //----------------------------------------
208 Result
Initialize(os::IAllocator * allocator)209 HemiSphereLight::Initialize(os::IAllocator* allocator)
210 {
211 Result result = INITIALIZE_RESULT_OK;
212
213 result |= TransformNode::Initialize(allocator);
214 NW_ENSURE_AND_RETURN(result);
215
216 result |= CreateOriginalValue(allocator);
217 NW_ENSURE_AND_RETURN(result);
218
219 result |= CreateAnimGroup(allocator);
220 NW_ENSURE_AND_RETURN(result);
221
222 return result;
223 }
224
225 //----------------------------------------------------------
226 void
GetMemorySizeInternal(os::MemorySizeCalculator * pSize,ResHemiSphereLight resHemiSphereLight,Description description)227 HemiSphereLight::GetMemorySizeInternal(
228 os::MemorySizeCalculator* pSize,
229 ResHemiSphereLight resHemiSphereLight,
230 Description description
231 )
232 {
233 NW_ASSERT(description.isFixedSizeMemory);
234
235 os::MemorySizeCalculator& size = *pSize;
236
237 size += sizeof(HemiSphereLight);
238
239 // HemiSphereLight::Initialize
240 TransformNode::GetMemorySizeForInitialize(
241 &size,
242 resHemiSphereLight,
243 description);
244
245 size += sizeof(ResHemiSphereLightData);
246
247 if (description.isAnimationEnabled &&
248 resHemiSphereLight.GetAnimGroupsCount() > 0)
249 {
250 AnimGroup::Builder()
251 .ResAnimGroup(resHemiSphereLight.GetAnimGroups(0))
252 .UseOriginalValue(true)
253 .GetMemorySizeInternal(&size);
254 }
255 }
256
257 } // namespace gfx
258 } // namespace nw
259