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