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