fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / FileIO / Collada / OSGColladaLight.cpp
blob90c015dec7f4fc50bce1e1dc41d08f3cf37acdfc
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2010 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
40 #pragma GCC diagnostic ignored "-Wold-style-cast"
41 #endif
43 #include "OSGColladaLight.h"
45 #ifdef OSG_WITH_COLLADA
47 #include "OSGColladaLog.h"
48 #include "OSGColladaInstanceLight.h"
50 #include "OSGDirectionalLight.h"
51 #include "OSGPointLight.h"
52 #include "OSGSpotLight.h"
53 #include "OSGChunkOverrideGroup.h"
54 #include "OSGNameAttachment.h"
56 OSG_BEGIN_NAMESPACE
58 // ===========================================================================
60 ColladaInstInfoTransitPtr
61 ColladaLight::ColladaLightInstInfo::create(
62 ColladaElement *colInstParent, ColladaInstanceLight *colInst,
63 Node *beaconN )
65 return ColladaInstInfoTransitPtr(
66 new ColladaLightInstInfo(colInstParent, colInst, beaconN));
69 void
70 ColladaLight::ColladaLightInstInfo::process(void)
72 Node *lightInstN = dynamic_cast<Node *>(
73 getColInst()->getTargetElem()->createInstance(this));
75 if(lightInstN == NULL)
76 return;
78 Node *rootN = getColInst()->getGlobal()->getRoot();
80 while(rootN->getNChildren() > 0)
82 lightInstN->addChild(rootN->getChild(0));
85 rootN->addChild(lightInstN);
88 Node *
89 ColladaLight::ColladaLightInstInfo::getBeacon(void) const
91 return _beacon;
94 ColladaLight::ColladaLightInstInfo::ColladaLightInstInfo(
95 ColladaElement *colInstParent, ColladaInstanceLight *colInst,
96 Node *beaconN )
98 : Inherited(colInstParent, colInst)
99 , _beacon (beaconN )
103 ColladaLight::ColladaLightInstInfo::~ColladaLightInstInfo(void)
107 // ===========================================================================
109 // Ambient light sources are a bit tricky to handle. First all ambient sources
110 // in the scene have to be accumulated and then an appropriate LightModelChunk
111 // must be inserted at the top of the scene (using a ChunkOverrideGroup).
112 // The first part is done by ColladaLight::createInstance(), which will also
113 // place an instance of ColladaLightAmbientInstInfo into the instance queue.
114 // That instance will then cause the insertion of the LightModelChunk.
116 ColladaInstInfoTransitPtr
117 ColladaLight::ColladaLightAmbientInstInfo::create(
118 ColladaElement *colInstParent, ColladaInstanceLight *colInst)
120 return ColladaInstInfoTransitPtr(
121 new ColladaLightAmbientInstInfo(colInstParent, colInst));
124 void
125 ColladaLight::ColladaLightAmbientInstInfo::process(void)
127 dynamic_cast<ColladaLight *>(
128 getColInst()->getTargetElem())->createAmbientLight(this);
131 ColladaLight::ColladaLightAmbientInstInfo::ColladaLightAmbientInstInfo(
132 ColladaElement *colInstParent, ColladaInstanceLight *colInst)
134 : Inherited(colInstParent, colInst)
138 ColladaLight::ColladaLightAmbientInstInfo::~ColladaLightAmbientInstInfo(void)
142 // ===========================================================================
144 ColladaLight::LightLoaderStateTransitPtr
145 ColladaLight::LightLoaderState::create(void)
147 return LightLoaderStateTransitPtr(new LightLoaderState());
150 LightModelChunk *
151 ColladaLight::LightLoaderState::getLightModelChunk(void) const
153 return _lightModel;
156 void
157 ColladaLight::LightLoaderState::setLightModelChunk(LightModelChunk *chunk)
159 _lightModel = chunk;
162 ColladaLight::LightLoaderState::LightLoaderState(void)
163 : Inherited ()
164 , _lightModel()
168 ColladaLight::LightLoaderState::~LightLoaderState(void)
172 // ===========================================================================
174 ColladaElementRegistrationHelper ColladaLight::_regHelper(
175 &ColladaLight::create, "light");
176 const std::string ColladaLight::_loaderStateName("ColladaLight");
179 ColladaElementTransitPtr
180 ColladaLight::create(daeElement *elem, ColladaGlobal *global)
182 if(global->getLoaderState(_loaderStateName) == NULL)
184 LightLoaderStateRefPtr state = LightLoaderState::create();
186 global->addLoaderState(_loaderStateName, state);
189 return ColladaElementTransitPtr(new ColladaLight(elem, global));
192 void
193 ColladaLight::read(ColladaElement *colElemParent)
195 domLightRef light = getDOMElementAs<domLight>();
197 OSG_COLLADA_LOG(("ColladaLight::read id [%s]\n", light->getId()));
200 Node *
201 ColladaLight::createInstance(ColladaInstInfo *colInstInfo)
203 domLightRef light = getDOMElementAs<domLight>();
205 OSG_COLLADA_LOG(("ColladaLight::createInstance id [%s]\n",
206 light->getId()));
208 NodeUnrecPtr retVal = NULL;
209 ColladaLightInstInfo *lightInstInfo =
210 dynamic_cast<ColladaLightInstInfo *>(colInstInfo);
211 domLight::domTechnique_commonRef techComm =
212 light->getTechnique_common();
214 const domTechnique_Array &techs = light->getTechnique_array();
216 for(UInt32 i = 0; i < techs.getCount(); ++i)
218 retVal = createInstanceTechnique(lightInstInfo, techs[i]);
220 // stop as soon as something is created
221 if(retVal != NULL)
222 return retVal;
225 // if we get here no technique was choosen so we evaluate
226 // <technique_common>
227 retVal = createInstanceCommon(lightInstInfo, techComm);
229 return retVal;
232 void
233 ColladaLight::createAmbientLight(ColladaLightAmbientInstInfo *colInstInfo)
235 OSG_COLLADA_LOG(("ColladaLight::createAmbientLight\n"));
237 LightLoaderState *state =
238 getGlobal()->getLoaderStateAs<LightLoaderState>(_loaderStateName);
239 OSG_ASSERT(state != NULL);
241 ChunkOverrideGroupUnrecPtr coGroup = ChunkOverrideGroup::create();
242 NodeUnrecPtr coGroupN = makeNodeFor(coGroup);
244 coGroup->addChunk(state->getLightModelChunk());
246 Node *rootN = getGlobal()->getRoot();
248 while(rootN->getNChildren() > 0)
250 coGroupN->addChild(rootN->getChild(0));
253 if(getGlobal()->getOptions()->getCreateNameAttachments() == true)
255 setName(coGroupN, "OpenSG_AmbientLight");
258 rootN->addChild(coGroupN);
261 ColladaLight::ColladaLight(daeElement *elem, ColladaGlobal *global)
262 : Inherited(elem, global)
266 ColladaLight::~ColladaLight(void)
270 Node *
271 ColladaLight::createInstanceTechnique(
272 ColladaLightInstInfo *colInstInfo, domTechnique *tech)
274 domLightRef light = getDOMElementAs<domLight>();
276 OSG_COLLADA_LOG(("ColladaLight::createInstanceTechnique id [%s] "
277 "profile [%s]\n", light->getId(), tech->getProfile()));
279 return NULL;
282 Node *
283 ColladaLight::createInstanceCommon(
284 ColladaLightInstInfo *colInstInfo, domLight::domTechnique_common *tech)
286 domLightRef light = getDOMElementAs<domLight>();
288 OSG_COLLADA_LOG(("ColladaLight::createInstanceCommon id [%s]\n",
289 light->getId()));
291 NodeUnrecPtr lightN = NULL;
293 domLight::domTechnique_common::domAmbientRef ambient =
294 tech->getAmbient();
295 domLight::domTechnique_common::domDirectionalRef directional =
296 tech->getDirectional();
297 domLight::domTechnique_common::domPointRef point =
298 tech->getPoint();
299 domLight::domTechnique_common::domSpotRef spot =
300 tech->getSpot();
302 if(ambient != NULL)
304 Color4f lightColor(ambient->getColor()->getValue()[0],
305 ambient->getColor()->getValue()[1],
306 ambient->getColor()->getValue()[2], 1.f);
308 LightLoaderState *state =
309 getGlobal()->getLoaderStateAs<LightLoaderState>(_loaderStateName);
310 OSG_ASSERT(state != NULL);
312 LightModelChunkUnrecPtr lmChunk = state->getLightModelChunk();
314 if(state->getLightModelChunk() == NULL)
316 lmChunk = LightModelChunk::create();
317 lmChunk->setAmbient(Color4f(0.f, 0.f, 0.f, 1.f));
319 state->setLightModelChunk(lmChunk);
321 // only place one instance into the inst queue, it will
322 // add the LightModelChunk with the accumulated ambient
323 // for the scene
324 ColladaInstInfoRefPtr ambientInstInfo =
325 ColladaLightAmbientInstInfo::create(
326 colInstInfo->getColInstParent(),
327 dynamic_cast<ColladaInstanceLight *>(
328 colInstInfo->getColInst()) );
330 getGlobal()->editInstQueue().push_back(ambientInstInfo);
333 lightColor[0] =
334 osgClamp(0.f, lmChunk->getAmbient()[0] + lightColor[0], 1.f);
335 lightColor[1] =
336 osgClamp(0.f, lmChunk->getAmbient()[1] + lightColor[1], 1.f);
337 lightColor[2] =
338 osgClamp(0.f, lmChunk->getAmbient()[2] + lightColor[0], 1.f);
340 lmChunk->setAmbient(lightColor);
343 if(directional != NULL)
345 Color4f lightColor(directional->getColor()->getValue()[0],
346 directional->getColor()->getValue()[1],
347 directional->getColor()->getValue()[2], 1.f);
349 DirectionalLightUnrecPtr dl = DirectionalLight::create();
350 lightN = makeNodeFor(dl);
352 dl->setBeacon (colInstInfo->getBeacon());
353 dl->setDiffuse (lightColor );
354 dl->setSpecular(lightColor );
357 if(point != NULL)
359 Color4f lightColor(point->getColor()->getValue()[0],
360 point->getColor()->getValue()[1],
361 point->getColor()->getValue()[2], 1.f);
363 PointLightUnrecPtr pl = PointLight::create();
364 lightN = makeNodeFor(pl);
366 Real32 constAtt = 1.f;
367 Real32 linAtt = 0.f;
368 Real32 quadAtt = 0.f;
370 if(point->getConstant_attenuation() != NULL)
371 constAtt = point->getConstant_attenuation()->getValue();
373 if(point->getLinear_attenuation() != NULL)
374 linAtt = point->getLinear_attenuation()->getValue();
376 if(point->getQuadratic_attenuation() != NULL)
377 quadAtt = point->getQuadratic_attenuation()->getValue();
379 pl->setBeacon (colInstInfo->getBeacon());
380 pl->setDiffuse (lightColor );
381 pl->setSpecular (lightColor );
382 pl->setConstantAttenuation (constAtt );
383 pl->setLinearAttenuation (linAtt );
384 pl->setQuadraticAttenuation(quadAtt );
387 if(spot != NULL)
389 Color4f lightColor(spot->getColor()->getValue()[0],
390 spot->getColor()->getValue()[1],
391 spot->getColor()->getValue()[2], 1.f);
393 SpotLightUnrecPtr sl = SpotLight::create();
394 lightN = makeNodeFor(sl);
396 Real32 constAtt = 1.f;
397 Real32 linAtt = 0.f;
398 Real32 quadAtt = 0.f;
399 Real32 cutOff = 180.f;
400 Real32 exponent = 0.f;
402 if(spot->getConstant_attenuation() != NULL)
403 constAtt = spot->getConstant_attenuation()->getValue();
405 if(spot->getLinear_attenuation() != NULL)
406 linAtt = spot->getLinear_attenuation()->getValue();
408 if(spot->getQuadratic_attenuation() != NULL)
409 quadAtt = spot->getQuadratic_attenuation()->getValue();
411 if(spot->getFalloff_angle() != NULL)
412 cutOff = spot->getFalloff_angle()->getValue();
414 if(spot->getFalloff_exponent() != NULL)
415 exponent = spot->getFalloff_exponent()->getValue();
417 sl->setBeacon (colInstInfo->getBeacon());
418 sl->setDiffuse (lightColor );
419 sl->setSpecular (lightColor );
420 sl->setConstantAttenuation (constAtt );
421 sl->setLinearAttenuation (linAtt );
422 sl->setQuadraticAttenuation(quadAtt );
423 sl->setSpotCutOff (osgDegree2Rad(cutOff) );
424 sl->setSpotExponent (exponent );
427 if(lightN != NULL)
429 editInstStore().push_back(lightN);
431 if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
432 light->getName() != NULL )
434 setName(lightN, light->getName());
437 getGlobal()->getStatCollector()->getElem(
438 ColladaGlobal::statNLightCreated)->inc();
441 return lightN;
444 OSG_END_NAMESPACE
446 #endif // OSG_WITH_COLLADA