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