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