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