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