1 /*---------------------------------------------------------------------------*
2   Project: NintendoWare
3   File   : gfx_SceneEnvironmentSetting.h
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: 27868 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 
18 #include <nw/os/os_Memory.h>
19 
20 #include <nw/gfx/gfx_SceneEnvironmentSetting.h>
21 #include <nw/gfx/gfx_ISceneVisitor.h>
22 
23 namespace nw
24 {
25 namespace gfx
26 {
27 
28 NW_UT_RUNTIME_TYPEINFO_DEFINITION(SceneEnvironmentSetting, SceneObject);
29 
30 //----------------------------------------
31 SceneEnvironmentSetting*
Create(ResSceneObject resource,const SceneEnvironmentSetting::Description & description,os::IAllocator * allocator)32 SceneEnvironmentSetting::Create(
33     ResSceneObject resource,
34     const SceneEnvironmentSetting::Description& description,
35     os::IAllocator* allocator
36 )
37 {
38     NW_NULL_ASSERT(allocator);
39 
40     ResSceneEnvironmentSetting resSetting = ResDynamicCast<ResSceneEnvironmentSetting>(resource);
41     NW_ASSERT(resSetting.IsValid());
42     NW_ASSERT( internal::ResCheckRevision( resSetting ) );
43 
44     void* memory = allocator->Alloc(sizeof(SceneEnvironmentSetting));
45     NW_NULL_ASSERT(memory);
46 
47     SceneEnvironmentSetting* setting = new(memory) SceneEnvironmentSetting(
48         allocator,
49         resSetting,
50         description);
51 
52     setting->CreateEnvironmentArray(allocator, resSetting);
53 
54     return setting;
55 }
56 
57 //-----------------------------------------
58 void
CreateEnvironmentArray(os::IAllocator * allocator,ResSceneEnvironmentSetting resSetting)59 SceneEnvironmentSetting::CreateEnvironmentArray(os::IAllocator* allocator, ResSceneEnvironmentSetting resSetting)
60 {
61     if (resSetting.GetLightSetsCount() != 0)
62     {
63         void* lightSetsMemory = allocator->Alloc(sizeof(LightSetBinder) * resSetting.GetLightSetsCount());
64         m_LightSets = ut::MoveArray<LightSetBinder>(lightSetsMemory, resSetting.GetLightSetsCount(), allocator);
65         m_LightSets.resize(resSetting.GetLightSetsCount());
66 
67         ResLightSetArray::iterator lightSetEnd = resSetting.GetLightSets().end();
68 
69         int lightSetIndex = 0;
70         for (ResLightSetArray::iterator iter = resSetting.GetLightSets().begin();
71             iter != lightSetEnd;
72             ++iter)
73         {
74             m_LightSets[lightSetIndex].lightSet = GfxPtr<LightSet>(LightSet::Create((*iter), allocator));
75             m_LightSets[lightSetIndex].index = -1;
76             ++lightSetIndex;
77         }
78     }
79 
80     if (resSetting.GetCamerasCount() != 0)
81     {
82         void* camerasMemory = allocator->Alloc(sizeof(CameraBinder) * resSetting.GetCamerasCount());
83         NW_NULL_ASSERT(camerasMemory);
84         m_Cameras = ut::MoveArray<CameraBinder>(camerasMemory, resSetting.GetCamerasCount(), allocator);
85     }
86 
87     if (resSetting.GetFogsCount() != 0)
88     {
89         void* fogsMemory = allocator->Alloc(sizeof(FogBinder) * resSetting.GetFogsCount());
90         NW_NULL_ASSERT(fogsMemory);
91         m_Fogs = ut::MoveArray<FogBinder>(fogsMemory, resSetting.GetFogsCount(), allocator);
92     }
93 }
94 
95 //-----------------------------------------
96 void
ResolveReference(const SceneContext & sceneContext)97 SceneEnvironmentSetting::ResolveReference(const SceneContext& sceneContext)
98 {
99     ResSceneEnvironmentSetting resSetting = ResStaticCast<ResSceneEnvironmentSetting>(this->GetResSceneObject());
100     NW_ASSERT(resSetting.IsValid());
101 
102     ResReferenceSceneObjectArray::iterator cameraEnd = resSetting.GetCameras().end();
103     for (ResReferenceSceneObjectArray::iterator iter = resSetting.GetCameras().begin();
104         iter != cameraEnd;
105         ++iter)
106     {
107         // TODO: ResSceneObjectがNULLの場合の処理を追加する
108         if ((*iter).IsValid())
109         {
110             CameraArray::const_iterator found =
111                 std::find_if(sceneContext.GetCameraBegin(), sceneContext.GetCameraEnd(), SceneObjectCompare<const Camera>((*iter)));
112 
113             if (found != sceneContext.GetCameraEnd())
114             {
115                 CameraBinder cameraBinder;
116                 cameraBinder.index = (*iter).GetIndex();
117                 cameraBinder.camera = (*found);
118                 bool isSuccess = this->m_Cameras.push_back(cameraBinder);
119                 NW_ASSERT(isSuccess);
120             }
121         }
122     }
123 
124     ResReferenceSceneObjectArray::iterator fogEnd = resSetting.GetFogs().end();
125     for (ResReferenceSceneObjectArray::iterator iter = resSetting.GetFogs().begin();
126         iter != fogEnd;
127         ++iter)
128     {
129         // TODO: ResSceneObjectがNULLの場合の処理を追加する
130         if ((*iter).IsValid())
131         {
132             FogArray::const_iterator found =
133                 std::find_if(sceneContext.GetFogBegin(), sceneContext.GetFogEnd(), SceneObjectCompare<const Fog>((*iter)));
134 
135             if (found != sceneContext.GetFogEnd())
136             {
137                 FogBinder fogBinder;
138                 fogBinder.index = (*iter).GetIndex();
139                 fogBinder.fog = (*found);
140                 bool isSuccess = this->m_Fogs.push_back(fogBinder);
141                 NW_ASSERT(isSuccess);
142             }
143         }
144     }
145 
146     int lightSetIndex = 0;
147     ResLightSetArray::iterator lightSetEnd = resSetting.GetLightSets().end();
148     for (ResLightSetArray::iterator iter = resSetting.GetLightSets().begin();
149         iter != lightSetEnd;
150         ++iter)
151     {
152         NW_ASSERT(lightSetIndex < this->m_LightSets.size());
153         LightSet* lightSet = this->m_LightSets[lightSetIndex].lightSet.Get();
154         NW_ASSERT(lightSet != NULL);
155         lightSet->ClearAll();
156 
157         ResReferenceSceneObjectArray::iterator lightEnd = (*iter).GetLights().end();
158         for (ResReferenceSceneObjectArray::iterator lightIter = (*iter).GetLights().begin();
159             lightIter != lightEnd;
160             ++lightIter)
161         {
162             // TODO: ResSceneObjectがNULLの場合の処理を追加する
163             if ((*lightIter).IsValid())
164             {
165                 AmbientLightArray::const_iterator foundAmbient =
166                     std::find_if(sceneContext.GetAmbientLightsBegin(), sceneContext.GetAmbientLightsEnd(), SceneObjectCompare<const AmbientLight>((*lightIter)));
167 
168                 if (foundAmbient != sceneContext.GetAmbientLightsEnd())
169                 {
170                     lightSet->SetAmbientLight(*foundAmbient);
171                 }
172 
173                 HemiSphereLightArray::const_iterator foundHemiSphere =
174                     std::find_if(sceneContext.GetHemiSphereLightsBegin(), sceneContext.GetHemiSphereLightsEnd(), SceneObjectCompare<const HemiSphereLight>((*lightIter)));
175 
176                 if (foundHemiSphere != sceneContext.GetHemiSphereLightsEnd())
177                 {
178                     lightSet->SetHemiSphereLight(*foundHemiSphere);
179                 }
180 
181 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
182                 VertexLightArray::const_iterator foundVertex =
183                     std::find_if(sceneContext.GetVertexLightsBegin(), sceneContext.GetVertexLightsEnd(), SceneObjectCompare<const VertexLight>((*lightIter)));
184 
185                 if (foundVertex != sceneContext.GetVertexLightsEnd())
186                 {
187                     lightSet->SetVertexLight(*foundVertex);
188                 }
189 #endif
190 
191                 FragmentLightArray::const_iterator foundFragment =
192                     std::find_if(sceneContext.GetFragmentLightsBegin(), sceneContext.GetFragmentLightsEnd(), SceneObjectCompare<const FragmentLight>((*lightIter)));
193 
194                 if (foundFragment != sceneContext.GetFragmentLightsEnd())
195                 {
196                     lightSet->SetFragmentLight(*foundFragment);
197                 }
198             }
199         }
200 
201         this->m_LightSets[lightSetIndex].index = (*iter).GetIndex();
202         ++lightSetIndex;
203     }
204 }
205 
206 //-----------------------------------------
207 void
Clear()208 SceneEnvironmentSetting::Clear()
209 {
210     this->m_Cameras.Clear();
211 
212     this->m_Fogs.Clear();
213 
214     LightSetBinderArray::iterator lightSetBinderEnd = this->m_LightSets.end();
215     for (LightSetBinderArray::iterator iter = this->m_LightSets.begin();
216         iter != lightSetBinderEnd;
217         ++iter)
218     {
219         LightSet* lightSet = iter->lightSet.Get();
220         NW_ASSERT(lightSet != NULL);
221         lightSet->ClearAll();
222         iter->index = -1;
223     }
224 }
225 
226 //----------------------------------------------------------
227 void
GetMemorySizeInternal(os::MemorySizeCalculator * pSize,ResSceneEnvironmentSetting resource,Description description)228 SceneEnvironmentSetting::GetMemorySizeInternal(
229     os::MemorySizeCalculator* pSize,
230     ResSceneEnvironmentSetting resource,
231     Description description
232 )
233 {
234     //NW_ASSERT(description.isFixedSizeMemory);
235     NW_UNUSED_VARIABLE(description);
236 
237     os::MemorySizeCalculator& size = *pSize;
238 
239     // SceneEnvironmentSetting::Create
240     size += sizeof(SceneEnvironmentSetting);
241 
242     // CreateEnvironmentArray
243     size += sizeof(LightSetBinder) * resource.GetLightSetsCount();
244 
245     ResLightSetArray::iterator lightSetEnd = resource.GetLightSets().end();
246 
247     for (ResLightSetArray::iterator iter = resource.GetLightSets().begin();
248         iter != lightSetEnd;
249         ++iter)
250     {
251         LightSet::GetMemorySizeInternal(&size, (*iter));
252     }
253 
254     size += sizeof(CameraBinder) * resource.GetCamerasCount();
255     size += sizeof(FogBinder) * resource.GetFogsCount();
256 }
257 
258 } // namespace gfx
259 } // namespace nw
260