1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_VertexLight.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_VertexLight.h>
23 #include <nw/gfx/gfx_ISceneVisitor.h>
24
25 #include <cstring>
26
27 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
28 namespace nw
29 {
30 namespace gfx
31 {
32
33 NW_UT_RUNTIME_TYPEINFO_DEFINITION(VertexLight, Light);
34
35 //----------------------------------------
36 VertexLight*
Create(os::IAllocator * allocator)37 VertexLight::DynamicBuilder::Create(
38 os::IAllocator* allocator
39 )
40 {
41 NW_NULL_ASSERT(allocator);
42
43 // CreateResVertexLight で名前を指定するようにしたら
44 // GetMemorySize も修正する必要がある。
45
46 ResPtr resource(
47 CreateResVertexLight(allocator),
48 ResVertexLightDataDestroyer(allocator));
49
50 void* memory = allocator->Alloc(sizeof(VertexLight));
51 NW_NULL_ASSERT(memory);
52 VertexLight* light = new(memory) VertexLight(
53 allocator,
54 resource,
55 m_Description);
56
57 Result result = light->Initialize(allocator);
58 NW_ASSERT(result.IsSuccess());
59
60 return light;
61 }
62
63 //----------------------------------------------------------
64 size_t
GetMemorySize(size_t alignment) const65 VertexLight::DynamicBuilder::GetMemorySize( size_t alignment ) const
66 {
67 NW_ASSERT(this->m_Description.isFixedSizeMemory);
68
69 os::MemorySizeCalculator size(alignment);
70
71 // VertexLight::CreateResAmbientLight
72 size += sizeof(ResVertexLightData);
73
74 size += sizeof(VertexLight);
75
76 // VertexLight::Initialize
77 TransformNode::GetMemorySizeForInitialize(
78 &size,
79 ResTransformNode(),
80 m_Description);
81
82 // AmbientLight::CreateOriginalValue
83 size += sizeof(ResVertexLightData);
84
85 // Light::CreateAnimGroup
86 // DynamicBuilder 使用時には何も行なわれない。
87
88 return size.GetSizeWithPadding(alignment);
89 }
90
91 //----------------------------------------
92 VertexLight*
Create(SceneNode * parent,ResSceneObject resource,const VertexLight::Description & description,os::IAllocator * allocator)93 VertexLight::Create(
94 SceneNode* parent,
95 ResSceneObject resource,
96 const VertexLight::Description& description,
97 os::IAllocator* allocator
98 )
99 {
100 NW_NULL_ASSERT(allocator);
101
102 ResVertexLight resNode = ResDynamicCast<ResVertexLight>(resource);
103 NW_ASSERT(resNode.IsValid());
104 NW_ASSERT( internal::ResCheckRevision( resNode ) );
105
106 void* memory = allocator->Alloc(sizeof(VertexLight));
107 NW_NULL_ASSERT(memory);
108
109 VertexLight* light = new(memory) VertexLight(
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 VertexLight::UpdateDirection()
129 {
130 ResVertexLight resLight = this->GetResVertexLight();
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 void
Accept(ISceneVisitor * visitor)144 VertexLight::Accept(
145 ISceneVisitor* visitor
146 )
147 {
148 visitor->VisitVertexLight(this);
149 AcceptChildren(visitor);
150 }
151
152
153 //-----------------------------------------
154 /* static*/ ResVertexLightData*
CreateResVertexLight(os::IAllocator * allocator,const char * name)155 VertexLight::CreateResVertexLight(os::IAllocator* allocator, const char* name /* = NULL */)
156 {
157 const int MAX_NAME_LENGTH = 256;
158
159 // TODO: 細かくアロケートする実装になっているが、まとめて確保できる仕組みも追加予定。
160 ResVertexLightData* resVertexLight =
161 AllocateAndFillN<ResVertexLightData>(allocator, sizeof(ResVertexLightData), 0);
162
163 //--------------------------------
164 // ResSceneObjectData のメンバ初期化
165 resVertexLight->typeInfo = ResVertexLight::TYPE_INFO;
166 resVertexLight->m_Header.revision = ResLight::BINARY_REVISION;
167 resVertexLight->m_Header.signature = ResLight::SIGNATURE;
168
169 resVertexLight->m_UserDataDicCount = 0;
170 resVertexLight->toUserDataDic.set_ptr( NULL );
171
172 resVertexLight->toName.set_ptr(AllocateAndCopyString(name, allocator, MAX_NAME_LENGTH));
173
174 //--------------------------------
175 // ResSceneNodeData のメンバ初期化
176 resVertexLight->m_ChildrenTableCount = 0;
177 resVertexLight->toChildrenTable.set_ptr( NULL );
178 resVertexLight->m_AnimGroupsDicCount = 0;
179 resVertexLight->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 resVertexLight->m_Transform = math::Transform3(scale, rotate, translate);
187 resVertexLight->m_WorldMatrix = math::MTX34::Identity();
188 ResTransformNode(resVertexLight).SetBranchVisible(true);
189
190 return resVertexLight;
191 }
192
193
194 //-----------------------------------------
195 /* static */ void
DestroyResVertexLight(os::IAllocator * allocator,ResVertexLightData * resVertexLight)196 VertexLight::DestroyResVertexLight(os::IAllocator* allocator, ResVertexLightData* resVertexLight)
197 {
198 NW_NULL_ASSERT( allocator );
199 NW_NULL_ASSERT( resVertexLight );
200
201 if ( resVertexLight->toName.to_ptr() != NULL )
202 {
203 allocator->Free( const_cast<char*>( resVertexLight->toName.to_ptr() ) );
204 }
205 allocator->Free( resVertexLight );
206 }
207
208
209 //-----------------------------------------
210 Result
CreateOriginalValue(os::IAllocator * allocator)211 VertexLight::CreateOriginalValue(os::IAllocator* allocator)
212 {
213 Result result = INITIALIZE_RESULT_OK;
214
215 void* buffer = allocator->Alloc(sizeof(ResVertexLightData));
216 NW_NULL_ASSERT(buffer);
217
218 // リソースをコピー
219 ResVertexLightData* originalValue = new(buffer) ResVertexLightData(GetResVertexLight().ref());
220 m_OriginalValue = ResVertexLight(originalValue);
221
222 m_OriginalTransform = this->GetResTransformNode().GetTransform();
223
224 return result;
225 }
226
227 //----------------------------------------
228 Result
Initialize(os::IAllocator * allocator)229 VertexLight::Initialize(os::IAllocator* allocator)
230 {
231 Result result = INITIALIZE_RESULT_OK;
232
233 result |= TransformNode::Initialize(allocator);
234 NW_ENSURE_AND_RETURN(result);
235
236 result |= CreateOriginalValue(allocator);
237 NW_ENSURE_AND_RETURN(result);
238
239 result |= CreateAnimGroup(allocator);
240 NW_ENSURE_AND_RETURN(result);
241
242 return result;
243 }
244
245 //----------------------------------------------------------
246 void
247 VertexLight::
GetMemorySizeInternal(os::MemorySizeCalculator * pSize,ResVertexLight resVertexLight,Description description)248 GetMemorySizeInternal(
249 os::MemorySizeCalculator* pSize,
250 ResVertexLight resVertexLight,
251 Description description
252 )
253 {
254 NW_ASSERT(description.isFixedSizeMemory);
255
256 os::MemorySizeCalculator& size = *pSize;
257
258 size += sizeof(VertexLight);
259
260 // VertexLight::Initialize
261 TransformNode::GetMemorySizeForInitialize(
262 &size,
263 resVertexLight,
264 description);
265
266 size += sizeof(ResVertexLightData);
267
268 if (description.isAnimationEnabled &&
269 resVertexLight.GetAnimGroupsCount() > 0)
270 {
271 AnimGroup::Builder()
272 .ResAnimGroup(resVertexLight.GetAnimGroups(0))
273 .UseOriginalValue(true)
274 .GetMemorySizeInternal(&size);
275 }
276 }
277
278 } // namespace gfx
279 } // namespace nw
280 #endif
281