root/OpenSceneGraph/trunk/src/osgPlugins/dae/daeRSceneObjects.cpp @ 13041

Revision 13041, 20.6 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * Copyright 2006 Sony Computer Entertainment Inc.
3 *
4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
5 * file except in compliance with the License. You may obtain a copy of the License at:
6 * http://research.scea.com/scea_shared_source_license.html
7 *
8 * Unless required by applicable law or agreed to in writing, software distributed under the License
9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
10 * implied. See the License for the specific language governing permissions and limitations under the
11 * License.
12 */
13
14#include "daeReader.h"
15#include <dae.h>
16#include <dae/domAny.h>
17#include <dom/domCOLLADA.h>
18
19#include <osg/Switch>
20#include <osg/LightSource>
21#include <osg/Geode>
22#include <osg/ShapeDrawable>
23#include <osg/LOD>
24#include <osg/Billboard>
25#include <osgSim/MultiSwitch>
26#include <osg/Sequence>
27#include <osg/CameraView>
28#include <osg/LightModel>
29
30using namespace osgDAE;
31
32osg::Group* daeReader::processOsgMultiSwitch(domTechnique* teq)
33{
34    osgSim::MultiSwitch* msw = new osgSim::MultiSwitch;
35
36    domAny* any = daeSafeCast<domAny>(teq->getChild("ActiveSwitchSet"));
37    if (any)
38    {
39        msw->setActiveSwitchSet(parseString<unsigned int>(any->getValue()));
40    }
41    else
42    {
43        OSG_WARN << "Expected element 'ActiveSwitchSet' not found" << std::endl;
44    }
45
46    any = daeSafeCast<domAny>(teq->getChild("ValueLists"));
47    if (any)
48    {
49        unsigned int numChildren = any->getChildren().getCount();
50        for (unsigned int currChild = 0; currChild < numChildren; currChild++)
51        {
52            domAny* child = daeSafeCast<domAny>(any->getChildren()[currChild]);
53            if (child)
54            {
55                if (strcmp(child->getElementName(), "ValueList" ) == 0 )
56                {
57                    std::list<std::string> stringValues;
58                    osgSim::MultiSwitch::ValueList values;
59
60                    cdom::tokenize(child->getValue(), " ", stringValues);
61                    cdom::tokenIter iter = stringValues.begin();
62
63                    while (iter != stringValues.end())
64                    {
65                        values.push_back(parseString<bool>(*iter));
66                        ++iter;
67                    }
68
69                    msw->setValueList(currChild, values);
70                }
71                else
72                {
73                    OSG_WARN << "Child of element 'ValueLists' is not of type 'ValueList'" << std::endl;
74                }
75            }
76            else
77            {
78                OSG_WARN << "Element 'ValueLists' does not contain expected elements." << std::endl;
79            }
80        }
81    }
82    else
83    {
84        OSG_WARN << "Expected element 'ValueLists' not found" << std::endl;
85    }
86    return msw;
87}
88
89osg::Group* daeReader::processOsgSwitch(domTechnique* teq)
90{
91    osg::Switch* sw = new osg::Switch;
92
93    domAny* any = daeSafeCast< domAny >(teq->getChild("ValueList"));
94    if (any)
95    {
96        std::list<std::string> stringValues;
97
98        cdom::tokenize(any->getValue(), " ", stringValues);
99        cdom::tokenIter iter = stringValues.begin();
100
101        int pos = 0;
102        while (iter != stringValues.end())
103        {
104            sw->setValue(pos++, parseString<bool>(*iter));
105            ++iter;
106        }
107    }
108    else
109    {
110        OSG_WARN << "Expected element 'ValueList' not found" << std::endl;
111    }
112    return sw;
113}
114
115osg::Group* daeReader::processOsgSequence(domTechnique* teq)
116{
117    osg::Sequence* sq = new osg::Sequence;
118
119    domAny* any = daeSafeCast< domAny >(teq->getChild("FrameTime"));
120    if (any)
121    {
122        std::list<std::string> stringValues;
123
124        cdom::tokenize(any->getValue(), " ", stringValues);
125        cdom::tokenIter iter = stringValues.begin();
126
127        int frame = 0;
128        while (iter != stringValues.end())
129        {
130            sq->setTime(frame++, parseString<double>(*iter));
131            ++iter;
132        }
133    }
134    else
135    {
136        OSG_WARN << "Expected element 'FrameTime' not found" << std::endl;
137    }
138
139    any = daeSafeCast< domAny >(teq->getChild("LastFrameTime"));
140    if (any)
141    {
142        sq->setLastFrameTime(parseString<double>(any->getValue()));
143    }
144    else
145    {
146        OSG_WARN << "Expected element 'LastFrameTime' not found" << std::endl;
147    }
148
149    osg::Sequence::LoopMode loopmode = osg::Sequence::LOOP;
150    any = daeSafeCast< domAny >(teq->getChild("LoopMode"));
151    if (any)
152    {
153        loopmode = (osg::Sequence::LoopMode)parseString<int>(any->getValue());
154    }
155    else
156    {
157        OSG_WARN << "Expected element 'LoopMode' not found" << std::endl;
158    }
159
160    int begin=0;
161    any = daeSafeCast< domAny >(teq->getChild("IntervalBegin"));
162    if (any)
163    {
164        begin = parseString<int>(any->getValue());
165    }
166    else
167    {
168        OSG_WARN << "Expected element 'IntervalBegin' not found" << std::endl;
169    }
170
171    int end=-1;
172    any = daeSafeCast< domAny >(teq->getChild("IntervalEnd"));
173    if (any)
174    {
175        end = parseString<int>(any->getValue());
176    }
177    else
178    {
179        OSG_WARN << "Expected element 'IntervalEnd' not found" << std::endl;
180    }
181
182    sq->setInterval(loopmode, begin, end);
183
184    float speed = 0;
185    any = daeSafeCast< domAny >(teq->getChild("DurationSpeed"));
186    if (any)
187    {
188        speed = parseString<float>(any->getValue());
189    }
190    else
191    {
192        OSG_WARN << "Expected element 'DurationSpeed' not found" << std::endl;
193    }
194
195    int nreps = -1;
196    any = daeSafeCast< domAny >(teq->getChild("DurationNReps"));
197    if (any)
198    {
199        nreps = parseString<int>(any->getValue());
200    }
201    else
202    {
203        OSG_WARN << "Expected element 'DurationNReps' not found" << std::endl;
204    }
205
206    sq->setDuration(speed, nreps);
207
208    any = daeSafeCast< domAny >(teq->getChild("SequenceMode"));
209    if (any)
210    {
211        sq->setMode((osg::Sequence::SequenceMode)parseString<int>(any->getValue()));
212    }
213    else
214    {
215        OSG_WARN << "Expected element 'SequenceMode' not found" << std::endl;
216    }
217
218    return sq;
219}
220
221
222osg::Group* daeReader::processOsgLOD(domTechnique* teq)
223{
224    osg::LOD* lod = new osg::LOD;
225
226    domAny* any = daeSafeCast< domAny >(teq->getChild("Center"));
227    if (any)
228    {
229        // If a center is specified
230        lod->setCenterMode(osg::LOD::USER_DEFINED_CENTER);
231        lod->setCenter(parseVec3String(any->getValue()));
232
233        any = daeSafeCast< domAny >(teq->getChild("Radius"));
234        if (any)
235        {
236            lod->setRadius(parseString<osg::LOD::value_type>(any->getValue()));
237        }
238        else
239        {
240            OSG_WARN << "Expected element 'Radius' not found" << std::endl;
241        }
242    }
243
244    any = daeSafeCast< domAny >(teq->getChild("RangeMode"));
245    if (any)
246    {
247        lod->setRangeMode((osg::LOD::RangeMode)parseString<int>(any->getValue()));
248    }
249    else
250    {
251        OSG_WARN << "Expected element 'RangeMode' not found" << std::endl;
252    }
253
254    any = daeSafeCast< domAny >(teq->getChild("RangeList"));
255    if (any)
256    {
257        osg::LOD::RangeList rangelist;
258
259        unsigned int numChildren = any->getChildren().getCount();
260        for (unsigned int currChild = 0; currChild < numChildren; currChild++)
261        {
262            domAny* child = daeSafeCast<domAny>(any->getChildren()[currChild]);
263            if (child)
264            {
265                if (strcmp(child->getElementName(), "MinMax" ) == 0 )
266                {
267                    std::list<std::string> stringValues;
268                    osg::LOD::MinMaxPair minMaxPair;
269
270                    cdom::tokenize(child->getValue(), " ", stringValues);
271                    cdom::tokenIter iter = stringValues.begin();
272
273                    if (iter != stringValues.end())
274                    {
275                        minMaxPair.first = parseString<float>(*iter);
276                        ++iter;
277                    }
278                    else
279                    {
280                        OSG_WARN << "'MinMax' does not contain a valid minimum value" << std::endl;
281                    }
282
283                    if (iter != stringValues.end())
284                    {
285                        minMaxPair.second = parseString<float>(*iter);
286                    }
287                    else
288                    {
289                        OSG_WARN << "'MinMax' does not contain a valid maximum value" << std::endl;
290                    }
291
292                    rangelist.push_back(minMaxPair);
293                }
294                else
295                {
296                    OSG_WARN << "Child of element 'RangeList' is not of type 'MinMax'" << std::endl;
297                }
298            }
299            else
300            {
301                OSG_WARN << "Element 'RangeList' does not contain expected elements." << std::endl;
302            }
303        }
304
305        lod->setRangeList(rangelist);
306    }
307    else
308    {
309        OSG_WARN << "Expected element 'RangeList' not found" << std::endl;
310    }
311
312    return lod;
313}
314
315// <light>
316// attributes:
317// id, name
318// elements:
319// 0..1 <asset>
320// 1    <technique_common>
321//        1    <ambient>, <directional>, <point>, <spot>
322// 0..* <technique>
323// 0..* <extra>
324osg::Node* daeReader::processLight( domLight *dlight )
325{
326    if (_numlights >= 7)
327    {
328        OSG_WARN << "More than 8 lights may not be supported by OpenGL driver." << std::endl;
329    }
330
331    //do light processing here.
332    domLight::domTechnique_common::domAmbient *ambient;
333    domLight::domTechnique_common::domDirectional *directional;
334    domLight::domTechnique_common::domPoint *point;
335    domLight::domTechnique_common::domSpot *spot;
336
337    if ( dlight->getTechnique_common() == NULL ||
338         dlight->getTechnique_common()->getContents().getCount() == 0 )
339    {
340        OSG_WARN << "Invalid content for light" << std::endl;
341        return NULL;
342    }
343
344    osg::Light* light = new osg::Light();
345    light->setPosition(osg::Vec4(0,0,0,1));
346    light->setLightNum(_numlights);
347
348    // Enable OpenGL lighting
349    _rootStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
350    // Enable this OpenGL light
351    _rootStateSet->setMode(GL_LIGHT0 + _numlights++, osg::StateAttribute::ON);
352
353    // Set ambient of lightmodel to zero
354    // Ambient lights are added as separate lights with only an ambient term
355    osg::LightModel* lightmodel = new osg::LightModel;
356    lightmodel->setAmbientIntensity(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
357    _rootStateSet->setAttributeAndModes(lightmodel, osg::StateAttribute::ON);
358
359    osg::LightSource* lightsource = new osg::LightSource();
360    lightsource->setLight(light);
361    std::string name = dlight->getId() ? dlight->getId() : "";
362    if (dlight->getName())
363        name = dlight->getName();
364    lightsource->setName(name);
365
366    daeElement *el = dlight->getTechnique_common()->getContents()[0];
367    ambient = daeSafeCast< domLight::domTechnique_common::domAmbient >( el );
368    directional = daeSafeCast< domLight::domTechnique_common::domDirectional >( el );
369    point = daeSafeCast< domLight::domTechnique_common::domPoint >( el );
370    spot = daeSafeCast< domLight::domTechnique_common::domSpot >( el );
371    if ( ambient != NULL )
372    {
373        if ( ambient->getColor() == NULL )
374        {
375            OSG_WARN << "Invalid content for ambient light" << std::endl;
376            return NULL;
377        }
378
379        light->setAmbient(    osg::Vec4(    ambient->getColor()->getValue()[0],
380                                        ambient->getColor()->getValue()[1],
381                                        ambient->getColor()->getValue()[2], 1.0f ) );
382        light->setDiffuse(    osg::Vec4(    0, 0, 0, 0));
383        light->setSpecular(    osg::Vec4(    0, 0, 0, 0));
384
385        // Tell OpenGL to make it a directional light (w=0)
386        light->setPosition(    osg::Vec4(0,0,0,0));
387    }
388    else if ( directional != NULL )
389    {
390        if ( directional->getColor() == NULL )
391        {
392            OSG_WARN << "Invalid content for directional light" << std::endl;
393            return NULL;
394        }
395        light->setAmbient(    osg::Vec4(    0, 0, 0, 0));
396        light->setDiffuse(    osg::Vec4(    directional->getColor()->getValue()[0],
397                                        directional->getColor()->getValue()[1],
398                                        directional->getColor()->getValue()[2], 1.0f ) );
399        light->setSpecular( osg::Vec4(    directional->getColor()->getValue()[0],
400                                        directional->getColor()->getValue()[1],
401                                        directional->getColor()->getValue()[2], 1.0f ) );
402
403        light->setDirection(osg::Vec3(0,0,-1));
404
405        // Tell OpenGL it is a directional light (w=0)
406        light->setPosition(    osg::Vec4(0,0,1,0));
407    }
408    else if ( point != NULL )
409    {
410        if ( point->getColor() == NULL )
411        {
412            OSG_WARN << "Invalid content for point light" << std::endl;
413            return NULL;
414        }
415        light->setAmbient(    osg::Vec4(    0, 0, 0, 0));
416        light->setDiffuse(    osg::Vec4(    point->getColor()->getValue()[0],
417                                        point->getColor()->getValue()[1],
418                                        point->getColor()->getValue()[2], 1.0f ) );
419        light->setSpecular( osg::Vec4(    point->getColor()->getValue()[0],
420                                        point->getColor()->getValue()[1],
421                                        point->getColor()->getValue()[2], 1.0f ) );
422
423        if ( point->getConstant_attenuation() != NULL )
424        {
425            light->setConstantAttenuation( point->getConstant_attenuation()->getValue() );
426        }
427        else
428        {
429            light->setConstantAttenuation( 1.0 );
430        }
431        if ( point->getLinear_attenuation() != NULL )
432        {
433            light->setLinearAttenuation( point->getLinear_attenuation()->getValue() );
434        }
435        else
436        {
437            light->setLinearAttenuation( 0.0 );
438        }
439        if ( point->getQuadratic_attenuation() != NULL )
440        {
441            light->setQuadraticAttenuation( point->getQuadratic_attenuation()->getValue() );
442        }
443        else
444        {
445            light->setQuadraticAttenuation( 0.0 );
446        }
447
448        // Tell OpenGL this is an omni directional light
449        light->setDirection(osg::Vec3(0, 0, 0));
450    }
451    else if ( spot != NULL )
452    {
453        if ( spot->getColor() == NULL )
454        {
455            OSG_WARN << "Invalid content for spot light" << std::endl;
456            return NULL;
457        }
458        light->setAmbient(    osg::Vec4(    0, 0, 0, 0));
459        light->setDiffuse(    osg::Vec4(    spot->getColor()->getValue()[0],
460                                        spot->getColor()->getValue()[1],
461                                        spot->getColor()->getValue()[2], 1.0f ) );
462        light->setSpecular( osg::Vec4(    spot->getColor()->getValue()[0],
463                                        spot->getColor()->getValue()[1],
464                                        spot->getColor()->getValue()[2], 1.0f ) );
465
466        if ( spot->getConstant_attenuation() != NULL )
467        {
468            light->setConstantAttenuation( spot->getConstant_attenuation()->getValue() );
469        }
470        else
471        {
472            light->setConstantAttenuation( 1.0f );
473        }
474        if ( spot->getLinear_attenuation() != NULL )
475        {
476            light->setLinearAttenuation( spot->getLinear_attenuation()->getValue() );
477        }
478        else
479        {
480            light->setLinearAttenuation( 0.0f );
481        }
482        if ( spot->getQuadratic_attenuation() != NULL )
483        {
484            light->setQuadraticAttenuation( spot->getQuadratic_attenuation()->getValue() );
485        }
486        else
487        {
488            light->setQuadraticAttenuation( 0.0f );
489        }
490        // OpenGL range [0, 90] (degrees) or 180 (omni)
491        if ( spot->getFalloff_angle() != NULL )
492        {
493            float falloffAngle = spot->getFalloff_angle()->getValue();
494            if (falloffAngle != 180)
495            {
496                falloffAngle = osg::clampTo<float>(falloffAngle, 0, 90);
497            }
498            light->setSpotCutoff(falloffAngle);
499        }
500        else
501        {
502            light->setSpotCutoff( 180.0f );
503        }
504        // OpenGL range [0, 128], where 0 means hard edge, and 128 means soft edge
505        if ( spot->getFalloff_exponent() != NULL )
506        {
507            float falloffExponent = spot->getFalloff_exponent()->getValue();
508            falloffExponent = osg::clampTo<float>(falloffExponent, 0, 128);
509            light->setSpotExponent(falloffExponent);
510        }
511        else
512        {
513            light->setSpotExponent( 0.0f );
514        }
515        light->setDirection(osg::Vec3(0, 0, -1));
516    }
517
518    return lightsource;
519}
520
521// <camera>
522// attributes:
523// id, name
524// elements:
525// 0..1 <asset>
526// 1    <optics>
527//        1       <technique_common>
528//                1        <orthographic>, <perspective>
529//        0..*    <technique>
530//        0..*    <extra>
531// 0..* <imager>
532//        1       <technique>
533//        0..*    <extra>
534// 0..* <extra>
535osg::Node* daeReader::processCamera( domCamera * dcamera )
536{
537    osg::CameraView* pOsgCameraView = new osg::CameraView;
538    pOsgCameraView->setName(dcamera->getId());
539
540    domCamera::domOptics::domTechnique_common *pDomTechniqueCommon = dcamera->getOptics()->getTechnique_common();
541    domCamera::domOptics::domTechnique_common::domPerspective *pDomPerspective = pDomTechniqueCommon->getPerspective();
542    domCamera::domOptics::domTechnique_common::domOrthographic *pDomOrthographic = pDomTechniqueCommon->getOrthographic();
543    if (pDomPerspective)
544    {
545        // <perspective>
546        // 1    <xfov>, <yfov>, <xfov> and <yfov>, <xfov> and <aspect_ratio>, <yfov> and <aspect_ratio>
547        // 1    <znear>
548        // 1    <zfar>
549        domTargetableFloat *pXfov = daeSafeCast< domTargetableFloat >(pDomPerspective->getXfov());
550        domTargetableFloat *pYfov = daeSafeCast< domTargetableFloat >(pDomPerspective->getYfov());
551        domTargetableFloat *pAspectRatio = daeSafeCast< domTargetableFloat >(pDomPerspective->getAspect_ratio());
552
553        if (pXfov)
554        {
555            if (pYfov)
556            {
557                // <xfov> and <yfov>
558                pOsgCameraView->setFieldOfView(pXfov->getValue());
559                pOsgCameraView->setFieldOfViewMode(osg::CameraView::HORIZONTAL);
560
561                if (pAspectRatio)
562                {
563                    OSG_WARN << "Unexpected <aspectratio> in <camera> '" << dcamera->getId() << "'" << std::endl;
564                }
565            }
566            else if (pAspectRatio)
567            {
568                // <xfov> and <aspect_ratio>
569                pOsgCameraView->setFieldOfView(pXfov->getValue() * pAspectRatio->getValue());
570                pOsgCameraView->setFieldOfViewMode(osg::CameraView::HORIZONTAL);
571            }
572            else
573            {
574                // <xfov>
575                pOsgCameraView->setFieldOfView(pXfov->getValue());
576                pOsgCameraView->setFieldOfViewMode(osg::CameraView::HORIZONTAL);
577            }
578        }
579        else if (pYfov)
580        {
581            if (pAspectRatio)
582            {
583                // <yfov> and <aspect_ratio>
584                pOsgCameraView->setFieldOfView(pYfov->getValue() / pAspectRatio->getValue());
585                pOsgCameraView->setFieldOfViewMode(osg::CameraView::VERTICAL);
586            }
587            else
588            {
589                // <yfov>
590                pOsgCameraView->setFieldOfView(pYfov->getValue());
591                pOsgCameraView->setFieldOfViewMode(osg::CameraView::VERTICAL);
592            }
593        }
594        else
595        {
596            // xfov or yfov expected
597            OSG_WARN << "Expected <xfov> or <yfov> in <camera> '" << dcamera->getId() << "'" << std::endl;
598        }
599
600        //domTargetableFloat *pZnear = daeSafeCast< domTargetableFloat >(pDomPerspective->getZnear());
601        //domTargetableFloat *pZfar = daeSafeCast< domTargetableFloat >(pDomPerspective->getZfar());
602
603        // TODO The current osg::CameraView does not support storage of near far
604    }
605    else if (pDomOrthographic)
606    {
607        // <orthographic>
608        // 1    <xmag>, <ymag>, <xmag> and <ymag>, <xmag> and <aspect_ratio>, <ymag> and <aspect_ratio>
609        // 1    <znear>
610        // 1    <zfar>
611
612        //domTargetableFloat *pXmag = daeSafeCast< domTargetableFloat >(pDomOrthographic->getXmag());
613        //domTargetableFloat *pYmag = daeSafeCast< domTargetableFloat >(pDomOrthographic->getYmag());
614        //domTargetableFloat *pAspectRatio = daeSafeCast< domTargetableFloat >(pDomOrthographic->getAspect_ratio());
615
616        // TODO The current osg::CameraView does not support an orthographic view
617        OSG_WARN << "Orthographic in <camera> '" << dcamera->getId() << "' not supported" << std::endl;
618
619        //domTargetableFloat *pZnear = daeSafeCast< domTargetableFloat >(pDomOrthographic->getZnear());
620        //domTargetableFloat *pZfar = daeSafeCast< domTargetableFloat >(pDomOrthographic->getZfar());
621
622        // TODO The current osg::CameraView does not support storage of near far
623    }
624
625    return pOsgCameraView;
626}
Note: See TracBrowser for help on using the browser.