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: 24950 $
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     return setting;
53 }
54 
55 //-----------------------------------------
56 void
CreateEnvironmentArray(os::IAllocator * allocator,ResSceneEnvironmentSetting resSetting)57 SceneEnvironmentSetting::CreateEnvironmentArray(os::IAllocator* allocator, ResSceneEnvironmentSetting resSetting)
58 {
59     if (resSetting.GetLightSetsCount() != 0)
60     {
61         void* lightSetsMemory = allocator->Alloc(sizeof(LightSetBinder) * resSetting.GetLightSetsCount());
62         m_LightSets = ut::MoveArray<LightSetBinder>(lightSetsMemory, resSetting.GetLightSetsCount(), allocator);
63         m_LightSets.resize(resSetting.GetLightSetsCount());
64 
65         ResLightSetArray::iterator lightSetEnd = resSetting.GetLightSets().end();
66 
67         int lightSetIndex = 0;
68         for (ResLightSetArray::iterator iter = resSetting.GetLightSets().begin();
69             iter != lightSetEnd;
70             ++iter)
71         {
72             m_LightSets[lightSetIndex].lightSet = GfxPtr<LightSet>(LightSet::Create((*iter), allocator));
73             ++lightSetIndex;
74         }
75     }
76 
77     if (resSetting.GetCamerasCount() != 0)
78     {
79         void* camerasMemory = allocator->Alloc(sizeof(CameraBinder) * resSetting.GetCamerasCount());
80         NW_NULL_ASSERT(camerasMemory);
81         m_Cameras = ut::MoveArray<CameraBinder>(camerasMemory, resSetting.GetCamerasCount(), allocator);
82     }
83 
84     if (resSetting.GetFogsCount() != 0)
85     {
86         void* fogsMemory = allocator->Alloc(sizeof(FogBinder) * resSetting.GetFogsCount());
87         NW_NULL_ASSERT(fogsMemory);
88         m_Fogs = ut::MoveArray<FogBinder>(fogsMemory, resSetting.GetFogsCount(), allocator);
89     }
90 }
91 
92 //-----------------------------------------
93 void
ResolveReference(const SceneContext & sceneContext)94 SceneEnvironmentSetting::ResolveReference(const SceneContext& sceneContext)
95 {
96     ResSceneEnvironmentSetting resSetting = ResStaticCast<ResSceneEnvironmentSetting>(this->GetResSceneObject());
97     NW_ASSERT(resSetting.IsValid());
98 
99     ResReferenceSceneObjectArray::iterator cameraEnd = resSetting.GetCameras().end();
100     for (ResReferenceSceneObjectArray::iterator iter = resSetting.GetCameras().begin();
101         iter != cameraEnd;
102         ++iter)
103     {
104         // TODO: ResSceneObjectがNULLの場合の処理を追加する
105         if ((*iter).IsValid())
106         {
107             CameraArray::const_iterator found =
108                 std::find_if(sceneContext.GetCameraBegin(), sceneContext.GetCameraEnd(), SceneObjectCompare<const Camera>((*iter)));
109 
110             if (found != sceneContext.GetCameraEnd())
111             {
112                 CameraBinder cameraBinder;
113                 cameraBinder.index = (*iter).GetIndex();
114                 cameraBinder.camera = (*found);
115                 bool isSuccess = this->m_Cameras.push_back(cameraBinder);
116                 NW_ASSERT(isSuccess);
117             }
118         }
119     }
120 
121     ResReferenceSceneObjectArray::iterator fogEnd = resSetting.GetFogs().end();
122     for (ResReferenceSceneObjectArray::iterator iter = resSetting.GetFogs().begin();
123         iter != fogEnd;
124         ++iter)
125     {
126         // TODO: ResSceneObjectがNULLの場合の処理を追加する
127         if ((*iter).IsValid())
128         {
129             FogArray::const_iterator found =
130                 std::find_if(sceneContext.GetFogBegin(), sceneContext.GetFogEnd(), SceneObjectCompare<const Fog>((*iter)));
131 
132             if (found != sceneContext.GetFogEnd())
133             {
134                 FogBinder fogBinder;
135                 fogBinder.index = (*iter).GetIndex();
136                 fogBinder.fog = (*found);
137                 bool isSuccess = this->m_Fogs.push_back(fogBinder);
138                 NW_ASSERT(isSuccess);
139             }
140         }
141     }
142 
143     int lightSetIndex = 0;
144     ResLightSetArray::iterator lightSetEnd = resSetting.GetLightSets().end();
145     for (ResLightSetArray::iterator iter = resSetting.GetLightSets().begin();
146         iter != lightSetEnd;
147         ++iter)
148     {
149         NW_ASSERT(lightSetIndex < this->m_LightSets.size());
150         LightSet* lightSet = this->m_LightSets[lightSetIndex].lightSet.Get();
151         NW_ASSERT(lightSet != NULL);
152         lightSet->ClearAll();
153 
154         ResReferenceSceneObjectArray::iterator lightEnd = (*iter).GetLights().end();
155         for (ResReferenceSceneObjectArray::iterator lightIter = (*iter).GetLights().begin();
156             lightIter != lightEnd;
157             ++lightIter)
158         {
159             // TODO: ResSceneObjectがNULLの場合の処理を追加する
160             if ((*lightIter).IsValid())
161             {
162                 AmbientLightArray::const_iterator foundAmbient =
163                     std::find_if(sceneContext.GetAmbientLightsBegin(), sceneContext.GetAmbientLightsEnd(), SceneObjectCompare<const AmbientLight>((*lightIter)));
164 
165                 if (foundAmbient != sceneContext.GetAmbientLightsEnd())
166                 {
167                     lightSet->SetAmbientLight(*foundAmbient);
168                 }
169 
170                 HemiSphereLightArray::const_iterator foundHemiSphere =
171                     std::find_if(sceneContext.GetHemiSphereLightsBegin(), sceneContext.GetHemiSphereLightsEnd(), SceneObjectCompare<const HemiSphereLight>((*lightIter)));
172 
173                 if (foundHemiSphere != sceneContext.GetHemiSphereLightsEnd())
174                 {
175                     lightSet->SetHemiSphereLight(*foundHemiSphere);
176                 }
177 
178 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
179                 VertexLightArray::const_iterator foundVertex =
180                     std::find_if(sceneContext.GetVertexLightsBegin(), sceneContext.GetVertexLightsEnd(), SceneObjectCompare<const VertexLight>((*lightIter)));
181 
182                 if (foundVertex != sceneContext.GetVertexLightsEnd())
183                 {
184                     lightSet->SetVertexLight(*foundVertex);
185                 }
186 #endif
187 
188                 FragmentLightArray::const_iterator foundFragment =
189                     std::find_if(sceneContext.GetFragmentLightsBegin(), sceneContext.GetFragmentLightsEnd(), SceneObjectCompare<const FragmentLight>((*lightIter)));
190 
191                 if (foundFragment != sceneContext.GetFragmentLightsEnd())
192                 {
193                     lightSet->SetFragmentLight(*foundFragment);
194                 }
195             }
196         }
197 
198         this->m_LightSets[lightSetIndex].index = (*iter).GetIndex();
199         ++lightSetIndex;
200     }
201 }
202 
203 } // namespace gfx
204 } // namespace nw
205