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