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