1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_FragmentLight.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: 29199 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/os/os_Memory.h>
19
20 #include <nw/gfx/gfx_FragmentLight.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(FragmentLight, Light);
31
32 //----------------------------------------
33 FragmentLight*
Create(os::IAllocator * allocator)34 FragmentLight::DynamicBuilder::Create(
35 os::IAllocator* allocator
36 )
37 {
38 NW_NULL_ASSERT(allocator);
39
40 ResPtr resource(
41 CreateResFragmentLight(allocator),
42 ResFragmentLightDataDestroyer(allocator));
43
44 void* memory = allocator->Alloc(sizeof(FragmentLight));
45 NW_NULL_ASSERT(memory);
46 FragmentLight* light = new(memory) FragmentLight(
47 allocator,
48 resource,
49 m_Description);
50
51 Result result = light->Initialize(allocator);
52 NW_ASSERT(result.IsSuccess());
53
54 return light;
55 }
56
57 //----------------------------------------
58 FragmentLight*
Create(SceneNode * parent,ResSceneObject resource,const FragmentLight::Description & description,os::IAllocator * allocator)59 FragmentLight::Create(
60 SceneNode* parent,
61 ResSceneObject resource,
62 const FragmentLight::Description& description,
63 os::IAllocator* allocator
64 )
65 {
66 NW_NULL_ASSERT(allocator);
67
68 ResFragmentLight resNode = ResDynamicCast<ResFragmentLight>(resource);
69 NW_ASSERT(resNode.IsValid());
70 NW_ASSERT( internal::ResCheckRevision( resNode ) );
71
72 void* memory = allocator->Alloc(sizeof(FragmentLight));
73 NW_NULL_ASSERT(memory);
74
75 FragmentLight* light = new(memory) FragmentLight(
76 allocator,
77 resNode,
78 description);
79
80 Result result = light->Initialize(allocator);
81 NW_ASSERT(result.IsSuccess());
82
83 if (parent)
84 {
85 bool isAttached = parent->AttachChild(light);
86 NW_ASSERT(isAttached);
87 }
88
89 return light;
90 }
91
92 //----------------------------------------
93 void
UpdateDirection()94 FragmentLight::UpdateDirection()
95 {
96 ResFragmentLight resLight = this->GetResFragmentLight();
97
98 if (ut::CheckFlag(resLight.GetFlags(), ResFragmentLightData::FLAG_IS_INHERITING_DIRECTION_ROTATE))
99 {
100 this->CalcInheritingDiretion(this->Direction(), resLight.GetDirection());
101 }
102 else
103 {
104 this->Direction() = resLight.GetDirection();
105 }
106 }
107
108
109 //----------------------------------------
110 void
Accept(ISceneVisitor * visitor)111 FragmentLight::Accept(
112 ISceneVisitor* visitor
113 )
114 {
115 visitor->VisitFragmentLight(this);
116 AcceptChildren(visitor);
117 }
118
119
120 //-----------------------------------------
121 /* static*/ ResFragmentLightData*
CreateResFragmentLight(os::IAllocator * allocator,const char * name)122 FragmentLight::CreateResFragmentLight(os::IAllocator* allocator, const char* name /* = NULL */)
123 {
124 // TODO: 細かくアロケートする実装になっているが、まとめて確保できる仕組みも追加予定。
125
126 ResFragmentLightData* resFragmentLight =
127 AllocateAndFillN<ResFragmentLightData>(allocator, sizeof(ResFragmentLightData), 0);
128
129 //--------------------------------
130 // ResSceneObjectData のメンバ初期化
131 resFragmentLight->typeInfo = ResFragmentLight::TYPE_INFO;
132 resFragmentLight->m_Header.revision = ResLight::BINARY_REVISION;
133 resFragmentLight->m_Header.signature = ResLight::SIGNATURE;
134
135 resFragmentLight->m_UserDataDicCount = 0;
136 resFragmentLight->toUserDataDic.set_ptr( NULL );
137
138 resFragmentLight->toName.set_ptr(AllocateAndCopyString(name, allocator, MAX_NAME_LENGTH));
139
140 //--------------------------------
141 // ResSceneNodeData のメンバ初期化
142 resFragmentLight->m_ChildrenTableCount = 0;
143 resFragmentLight->toChildrenTable.set_ptr( NULL );
144 resFragmentLight->m_AnimGroupsDicCount = 0;
145 resFragmentLight->toAnimGroupsDic.set_ptr( NULL );
146
147 //--------------------------------
148 // ResTransformNode のメンバ初期化
149 const math::VEC3 scale(1.0f, 1.0f, 1.0f);
150 const math::VEC3 rotate(0.0f, 0.0f, 0.0f);
151 const math::VEC3 translate(0.0f, 0.0, 0.0f);
152 resFragmentLight->m_Transform = math::Transform3(scale, rotate, translate);
153 resFragmentLight->m_WorldMatrix = math::MTX34::Identity();
154
155 //--------------------------------
156 // ResFragmentLightData のメンバ初期化
157 ResReferenceLookupTableData* distanceSampler =
158 AllocateAndFill<ResReferenceLookupTableData>(allocator, 0);
159
160 distanceSampler->typeInfo = ResReferenceLookupTable_TYPE_INFO;
161 distanceSampler->toTargetLut.set_ptr(NULL);
162 distanceSampler->toPath.set_ptr(NULL);
163
164 ResLightingLookupTableData* angleSampler =
165 AllocateAndFill<ResLightingLookupTableData>(allocator, 0);
166
167 ResReferenceLookupTableData* referenceAngleSampler =
168 AllocateAndFill<ResReferenceLookupTableData>(allocator, 0);
169
170 referenceAngleSampler->typeInfo = ResReferenceLookupTable_TYPE_INFO;
171 referenceAngleSampler->toPath.set_ptr(NULL);
172 referenceAngleSampler->toTargetLut.set_ptr(NULL);
173
174 angleSampler->toSampler.set_ptr(referenceAngleSampler);
175 angleSampler->m_Input = ResLightingLookupTable::INPUT_NH;
176 angleSampler->m_Scale = ResLightingLookupTable::SCALE_1;
177
178 resFragmentLight->toDistanceSampler.set_ptr( distanceSampler );
179 resFragmentLight->toAngleSampler.set_ptr( angleSampler );
180
181 return resFragmentLight;
182 }
183
184
185 //-----------------------------------------
186 /* static */ void
DestroyResFragmentLight(os::IAllocator * allocator,ResFragmentLightData * resFragmentLight)187 FragmentLight::DestroyResFragmentLight(os::IAllocator* allocator, ResFragmentLightData* resFragmentLight)
188 {
189 NW_NULL_ASSERT( allocator );
190 NW_NULL_ASSERT( resFragmentLight );
191
192 allocator->Free( resFragmentLight->toDistanceSampler.to_ptr() );
193
194 ResLightingLookupTableData* angleSampler =
195 reinterpret_cast<ResLightingLookupTableData*>(resFragmentLight->toAngleSampler.to_ptr());
196 allocator->Free( angleSampler->toSampler.to_ptr() );
197 allocator->Free( resFragmentLight->toAngleSampler.to_ptr() );
198 if ( resFragmentLight->toName.to_ptr() != NULL )
199 {
200 allocator->Free( const_cast<char*>( resFragmentLight->toName.to_ptr() ) );
201 }
202 allocator->Free( resFragmentLight );
203 }
204
205
206 //-----------------------------------------
207 Result
CreateOriginalValue(os::IAllocator * allocator)208 FragmentLight::CreateOriginalValue(os::IAllocator* allocator)
209 {
210 Result result = INITIALIZE_RESULT_OK;
211
212 void* buffer = allocator->Alloc(sizeof(ResFragmentLightData));
213 NW_NULL_ASSERT(buffer);
214
215 // リソースをコピー
216 ResFragmentLightData* originalValue = new(buffer) ResFragmentLightData(GetResFragmentLight().ref());
217 m_OriginalValue = ResFragmentLight(originalValue);
218
219 m_OriginalTransform = this->GetResTransformNode().GetTransform();
220
221 return result;
222 }
223
224 //----------------------------------------
225 Result
Initialize(os::IAllocator * allocator)226 FragmentLight::Initialize(os::IAllocator* allocator)
227 {
228 Result result = INITIALIZE_RESULT_OK;
229
230 result |= TransformNode::Initialize(allocator);
231 NW_ENSURE_AND_RETURN(result);
232
233 result |= CreateOriginalValue(allocator);
234 NW_ENSURE_AND_RETURN(result);
235
236 result |= CreateAnimGroup(allocator);
237 NW_ENSURE_AND_RETURN(result);
238
239 return result;
240 }
241
242 } // namespace gfx
243 } // namespace nw
244