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

Revision 13041, 20.1 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 "daeWriter.h"
15
16#include <dom/domCOLLADA.h>
17
18#include <dom/domNode.h>
19#include <dom/domConstants.h>
20#include <dom/domLibrary_cameras.h>
21#include <dom/domLibrary_lights.h>
22#include <dae/domAny.h>
23//#include <dom/domVisual_scene.h>
24//#include <dom/domLibrary_visual_scenes.h>
25
26#include <osgSim/MultiSwitch>
27#include <osg/Sequence>
28#include <osg/Billboard>
29#include <osg/CameraView>
30
31using namespace osgDAE;
32
33// Write non-standard node data as extra of type "Node" with "OpenSceneGraph" technique
34void daeWriter::writeNodeExtra(osg::Node &node)
35{
36    unsigned int numDesc = node.getDescriptions().size();
37    // Only create extra if descriptions are filled in
38    if (_pluginOptions.writeExtras && (numDesc > 0))
39    {
40        // Adds the following to a node
41
42        //<extra type="Node">
43        //    <technique profile="OpenSceneGraph">
44        //        <Descriptions>
45        //            <Description>Some info</Description>
46        //        </Descriptions>
47        //    </technique>
48        //</extra>
49
50        domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
51        extra->setType("Node");
52        domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
53        teq->setProfile( "OpenSceneGraph" );
54        domAny *descriptions = (domAny*)teq->add( "Descriptions" );
55
56        for (unsigned int currDesc = 0; currDesc < numDesc; currDesc++)
57        {
58            std::string value = node.getDescription(currDesc);
59            if (!value.empty())
60            {
61                domAny *description = (domAny*)descriptions->add( "Description" );
62                description->setValue(value.c_str());
63            }
64        }
65    }
66}
67
68void daeWriter::apply( osg::Group &node )
69{
70    debugPrint( node );
71    updateCurrentDaeNode();
72    currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
73
74    // If a multiswitch node, store it's data as extra "MultiSwitch" data in the "OpenSceneGraph" technique
75    osgSim::MultiSwitch* multiswitch = dynamic_cast<osgSim::MultiSwitch*>(&node);
76    if (_pluginOptions.writeExtras && multiswitch)
77    {
78        // Adds the following to a node
79
80        //<extra type="MultiSwitch">
81        //    <technique profile="OpenSceneGraph">
82        //        <ActiveSwitchSet>0</ActiveSwitchSet>
83        //        <ValueLists>
84        //            <ValueList>1 0</ValueList>
85        //            <ValueList>0 1</ValueList>
86        //        </ValueLists>
87        //    </technique>
88        //</extra>
89
90        domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
91        extra->setType("MultiSwitch");
92        domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
93        teq->setProfile( "OpenSceneGraph" );
94
95        domAny *activeSwitchSet = (domAny*)teq->add("ActiveSwitchSet" );
96        activeSwitchSet->setValue(toString<unsigned int>(multiswitch->getActiveSwitchSet()).c_str());
97
98        domAny *valueLists = (domAny*)teq->add( "ValueLists" );
99
100        unsigned int pos = 0;
101        const osgSim::MultiSwitch::SwitchSetList& switchset = multiswitch->getSwitchSetList();
102        for(osgSim::MultiSwitch::SwitchSetList::const_iterator sitr=switchset.begin();
103            sitr!=switchset.end();
104            ++sitr,++pos)
105        {
106            domAny *valueList = (domAny*)valueLists->add( "ValueList" );
107            std::stringstream fw;
108            const osgSim::MultiSwitch::ValueList& values = *sitr;
109            for(osgSim::MultiSwitch::ValueList::const_iterator itr=values.begin();
110                itr!=values.end();
111                ++itr)
112            {
113                if (itr != values.begin())
114                {
115                    fw << " ";
116                }
117                fw << *itr;
118            }
119            valueList->setValue(fw.str().c_str());
120        }
121        currentNode->setId(getNodeName(node,"multiswitch").c_str());
122    }
123    else
124    {
125        writeAnimations(node);
126
127        currentNode->setId(getNodeName(node,"group").c_str());
128    }
129
130    writeNodeExtra(node);
131
132    lastDepth = _nodePath.size();
133
134    traverse( node );
135}
136
137
138void daeWriter::apply( osg::Switch &node )
139{
140    debugPrint( node );
141    updateCurrentDaeNode();
142    currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
143    currentNode->setId(getNodeName(node,"switch").c_str());
144
145    if (_pluginOptions.writeExtras)
146    {
147        // Adds the following to a node
148
149        //<extra type="Switch">
150        //    <technique profile="OpenSceneGraph">
151        //        <ValueList>1 0</ValueList>
152        //    </technique>
153        //</extra>
154
155        domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
156        extra->setType("Switch");
157        domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
158        teq->setProfile( "OpenSceneGraph" );
159
160        domAny *valueList = (domAny*)teq->add( "ValueList" );
161
162        std::stringstream fw;
163        const osg::Switch::ValueList& values = node.getValueList();
164        for(osg::Switch::ValueList::const_iterator itr=values.begin();
165            itr!=values.end();
166            ++itr)
167        {
168            if (itr != values.begin())
169            {
170                fw << " ";
171            }
172            fw << *itr;
173        }
174        valueList->setValue(fw.str().c_str());
175    }
176
177    writeNodeExtra(node);
178
179    lastDepth = _nodePath.size();
180
181    // Process all children
182    traverse( node );
183}
184
185void daeWriter::apply( osg::Sequence &node )
186{
187    debugPrint( node );
188    updateCurrentDaeNode();
189    currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
190    currentNode->setId(getNodeName(node,"sequence").c_str());
191
192    // If a sequence node, store it's data as extra "Sequence" data in the "OpenSceneGraph" technique
193    if (_pluginOptions.writeExtras)
194    {
195        // Adds the following to a node
196
197        //<extra type="Sequence">
198        //    <technique profile="OpenSceneGraph">
199        //        <FrameTime>0 0</FrameTime>
200        //        <LastFrameTime>0</LastFrameTime>
201        //        <LoopMode>0</LoopMode>
202        //        <IntervalBegin>0</IntervalBegin>
203        //        <IntervalEnd>-1</IntervalEnd>
204        //        <DurationSpeed>1</DurationSpeed>
205        //        <DurationNReps>-1</DurationNReps>
206        //        <SequenceMode>0</SequenceMode>
207        //    </technique>
208        //</extra>
209
210        domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
211        extra->setType("Sequence");
212        domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
213        teq->setProfile( "OpenSceneGraph" );
214
215        domAny *frameTime = (domAny*)teq->add("FrameTime");
216        std::stringstream fw;
217        for (unsigned int i = 0; i < node.getNumChildren(); i++)
218        {
219            if (i > 0)
220            {
221                fw << " ";
222            }
223            fw << node.getTime(i);
224        }
225        frameTime->setValue(fw.str().c_str());
226
227        domAny *lastFrameTime = (domAny*)teq->add("LastFrameTime");
228        lastFrameTime->setValue(toString<double>(node.getLastFrameTime()).c_str());
229
230        // loop mode & interval
231        osg::Sequence::LoopMode mode;
232        int begin, end;
233        node.getInterval(mode, begin, end);
234        domAny *loopMode = (domAny*)teq->add("LoopMode");
235        loopMode->setValue(toString<osg::Sequence::LoopMode>(mode).c_str());
236        domAny *intervalBegin = (domAny*)teq->add("IntervalBegin");
237        intervalBegin->setValue(toString<int>(begin).c_str());
238        domAny *intervalEnd = (domAny*)teq->add("IntervalEnd");
239        intervalEnd->setValue(toString<int>(end).c_str());
240
241        // duration
242        float speed;
243        int nreps;
244        node.getDuration(speed, nreps);
245        domAny *durationSpeed = (domAny*)teq->add("DurationSpeed");
246        durationSpeed->setValue(toString<float>(speed).c_str());
247        domAny *durationNReps = (domAny*)teq->add("DurationNReps");
248        durationNReps->setValue(toString<int>(nreps).c_str());
249
250        // sequence mode
251        domAny *sequenceMode = (domAny*)teq->add("SequenceMode");
252        sequenceMode->setValue(toString<osg::Sequence::SequenceMode>(node.getMode()).c_str());
253    }
254
255    writeNodeExtra(node);
256
257    lastDepth = _nodePath.size();
258
259    traverse( node );
260}
261
262void daeWriter::apply( osg::LOD &node )
263{
264    debugPrint( node );
265    updateCurrentDaeNode();
266    lastDepth = _nodePath.size();
267    currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
268    currentNode->setId(getNodeName(node,"LOD").c_str());
269
270    if (_pluginOptions.writeExtras)
271    {
272        // Store LOD data as extra "LOD" data in the "OpenSceneGraph" technique
273        // Adds the following to a node
274
275        //<extra type="LOD">
276        //    <technique profile="OpenSceneGraph">
277        //        <Center>1 2 3</Center> (optional )
278        //        <Radius>-1</Radius> (required if Center is available)
279        //        <RangeMode>0</RangeMode>
280        //        <RangeList>
281        //            <MinMax>0 300</MinMax>
282        //            <MinMax>300 600</MinMax>
283        //        </RangeList>
284        //    </technique>
285        //</extra>
286
287        domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
288        extra->setType("LOD");
289        domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
290        teq->setProfile( "OpenSceneGraph" );
291
292        if ((node.getCenterMode()==osg::LOD::USER_DEFINED_CENTER)||(node.getCenterMode()==osg::LOD::UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED))
293        {
294            domAny *center = (domAny*)teq->add("Center");
295            center->setValue(toString(node.getCenter()).c_str());
296
297            domAny *radius = (domAny*)teq->add("Radius");
298            radius->setValue(toString<osg::LOD::value_type>(node.getRadius()).c_str());
299        }
300
301        domAny *rangeMode = (domAny*)teq->add("RangeMode");
302        rangeMode->setValue(toString<osg::LOD::RangeMode>(node.getRangeMode()).c_str());
303
304        domAny *valueLists = (domAny*)teq->add("RangeList");
305
306        unsigned int pos = 0;
307        const osg::LOD::RangeList& rangelist = node.getRangeList();
308        for(osg::LOD::RangeList::const_iterator sitr=rangelist.begin();
309            sitr!=rangelist.end();
310            ++sitr,++pos)
311        {
312            domAny *valueList = (domAny*)valueLists->add("MinMax");
313            std::stringstream fw;
314            fw << sitr->first << " " << sitr->second;
315            valueList->setValue(fw.str().c_str());
316        }
317    }
318
319    writeNodeExtra(node);
320
321    // Process all children
322    traverse( node );
323}
324
325void daeWriter::apply( osg::ProxyNode &node )
326{
327    OSG_WARN << "ProxyNode. Missing " << node.getNumChildren() << " children" << std::endl;
328}
329
330void daeWriter::apply( osg::LightSource &node )
331{
332    debugPrint( node );
333    updateCurrentDaeNode();
334
335    domInstance_light *il = daeSafeCast< domInstance_light >( currentNode->add( COLLADA_ELEMENT_INSTANCE_LIGHT ) );
336    std::string name = node.getName();
337    if ( name.empty() )
338    {
339        name = uniquify( "light" );
340    }
341    std::string url = "#" + name;
342    il->setUrl( url.c_str() );
343
344    if ( lib_lights == NULL )
345    {
346        lib_lights = daeSafeCast< domLibrary_lights >( dom->add( COLLADA_ELEMENT_LIBRARY_LIGHTS ) );
347    }
348    domLight *light = daeSafeCast< domLight >( lib_lights->add( COLLADA_ELEMENT_LIGHT ) );
349    light->setId( name.c_str() );
350
351    osg::Light* pOsgLight = node.getLight();
352
353    domLight *pDomLight = daeSafeCast< domLight >( lib_lights->add( COLLADA_ELEMENT_LIGHT ) );
354    pDomLight->setId( name.c_str() );
355
356    domLight::domTechnique_common *domTechniqueCommon = daeSafeCast<domLight::domTechnique_common>(pDomLight->add(COLLADA_ELEMENT_TECHNIQUE_COMMON));
357
358    osg::Vec4 position = pOsgLight->getPosition();
359    osg::Vec3 direction = pOsgLight->getDirection();
360    osg::Vec4 ambientColor = pOsgLight->getAmbient();
361    osg::Vec4 diffuseColor = pOsgLight->getDiffuse();
362    //osg::Vec4 specularColor = pOsgLight->getSpecular();
363
364    if (position.w() == 0)
365    {
366        // Directional light
367        domLight::domTechnique_common::domDirectional *domDirectional = daeSafeCast<domLight::domTechnique_common::domDirectional>(domTechniqueCommon->add(COLLADA_ELEMENT_DIRECTIONAL));
368
369        if ((position.x() != 0) || (position.y() != 0) || (position.z() != 0))
370        {
371            osg::Vec3 dir(-position.x(), -position.y(), -position.z());
372            // TODO wrap instance_light in a rotating node to translate default light [0,0,-1] into proper direction
373        }
374
375        domFloat3 color;
376        color.append3(diffuseColor.r(), diffuseColor.g(), diffuseColor.b());
377        domDirectional->add(COLLADA_ELEMENT_COLOR);
378        domDirectional->getColor()->setValue(color);
379    }
380    else if (direction.length() == 0)
381    {
382        // Omni/point light
383        domLight::domTechnique_common::domPoint *domPoint = daeSafeCast<domLight::domTechnique_common::domPoint>(domTechniqueCommon->add(COLLADA_ELEMENT_POINT));
384        domPoint->add(COLLADA_ELEMENT_CONSTANT_ATTENUATION);
385        domPoint->getConstant_attenuation()->setValue(pOsgLight->getConstantAttenuation());
386        domPoint->add(COLLADA_ELEMENT_LINEAR_ATTENUATION);
387        domPoint->getLinear_attenuation()->setValue(pOsgLight->getLinearAttenuation());
388        domPoint->add(COLLADA_ELEMENT_QUADRATIC_ATTENUATION);
389        domPoint->getQuadratic_attenuation()->setValue(pOsgLight->getQuadraticAttenuation());
390
391        if ((position.x() != 0) || (position.y() != 0) || (position.z() != 0))
392        {
393            // TODO wrap instance_light in a transforming node to translate default light [0,0,0] into proper position
394        }
395
396        domFloat3 color;
397        color.append3(diffuseColor.r(), diffuseColor.g(), diffuseColor.b());
398        domPoint->add(COLLADA_ELEMENT_COLOR);
399        domPoint->getColor()->setValue(color);
400    }
401    else
402    {
403        // Spot light
404        domLight::domTechnique_common::domSpot *domSpot = daeSafeCast<domLight::domTechnique_common::domSpot>(domTechniqueCommon->add(COLLADA_ELEMENT_SPOT));
405        domSpot->add(COLLADA_ELEMENT_CONSTANT_ATTENUATION);
406        domSpot->getConstant_attenuation()->setValue(pOsgLight->getConstantAttenuation());
407        domSpot->add(COLLADA_ELEMENT_LINEAR_ATTENUATION);
408        domSpot->getLinear_attenuation()->setValue(pOsgLight->getLinearAttenuation());
409        domSpot->add(COLLADA_ELEMENT_QUADRATIC_ATTENUATION);
410        domSpot->getQuadratic_attenuation()->setValue(pOsgLight->getQuadraticAttenuation());
411
412        if ((position.x() != 0) || (position.y() != 0) || (position.z() != 0))
413        {
414            // TODO wrap instance_light in a transforming node to translate default light [0,0,0] into proper position
415            // and rotate default direction [0,0,-1] into proper dir
416        }
417
418        domFloat3 color;
419        color.append3(diffuseColor.r(), diffuseColor.g(), diffuseColor.b());
420        domSpot->add(COLLADA_ELEMENT_COLOR);
421        domSpot->getColor()->setValue(color);
422
423        domSpot->add(COLLADA_ELEMENT_FALLOFF_ANGLE);
424        domSpot->getFalloff_angle()->setValue(pOsgLight->getSpotCutoff());
425
426        domSpot->add(COLLADA_ELEMENT_FALLOFF_EXPONENT);
427        domSpot->getFalloff_exponent()->setValue(pOsgLight->getSpotExponent());
428    }
429
430    // Write ambient as a separate Collada <ambient> light
431    if ((ambientColor.r() != 0) || (ambientColor.g() != 0) || (ambientColor.b() != 0))
432    {
433        domInstance_light *ambientDomInstanceLight = daeSafeCast< domInstance_light >(currentNode->add( COLLADA_ELEMENT_INSTANCE_LIGHT ));
434        std::string name = node.getName();
435        if (name.empty())
436        {
437            name = uniquify( "light-ambient" );
438        }
439        else
440        {
441            name += "-ambient";
442        }
443        std::string url = "#" + name;
444        ambientDomInstanceLight->setUrl( url.c_str() );
445
446        domLight *ambientDomLight = daeSafeCast< domLight >( lib_lights->add( COLLADA_ELEMENT_LIGHT ) );
447        ambientDomLight->setId(name.c_str());
448
449        domLight::domTechnique_common *ambientDomTechniqueCommon = daeSafeCast<domLight::domTechnique_common>(ambientDomLight->add(COLLADA_ELEMENT_TECHNIQUE_COMMON));
450
451        // Ambient light
452        domLight::domTechnique_common::domAmbient *domAmbient = daeSafeCast<domLight::domTechnique_common::domAmbient>(ambientDomTechniqueCommon->add(COLLADA_ELEMENT_AMBIENT));
453
454        domFloat3 color;
455        color.append3(ambientColor.r(), ambientColor.g(), ambientColor.b());
456        domAmbient->add(COLLADA_ELEMENT_COLOR);
457        domAmbient->getColor()->setValue(color);
458    }
459
460    traverse( node );
461}
462
463void daeWriter::apply( osg::Camera &node )
464{
465    debugPrint( node );
466    updateCurrentDaeNode();
467
468    domInstance_camera *ic = daeSafeCast< domInstance_camera >( currentNode->add( COLLADA_ELEMENT_INSTANCE_CAMERA ) );
469    std::string name = node.getName();
470    if ( name.empty() )
471    {
472        name = uniquify( "camera" );
473    }
474    std::string url = "#" + name;
475    ic->setUrl( url.c_str() );
476
477    if ( lib_cameras == NULL )
478    {
479        lib_cameras = daeSafeCast< domLibrary_cameras >( dom->add( COLLADA_ELEMENT_LIBRARY_CAMERAS ) );
480    }
481    domCamera *cam = daeSafeCast< domCamera >( lib_cameras->add( COLLADA_ELEMENT_CAMERA ) );
482    cam->setId( name.c_str() );
483
484    traverse( node );
485}
486
487void daeWriter::apply( osg::CameraView &node)
488{
489    debugPrint( node );
490    updateCurrentDaeNode();
491
492    domInstance_camera *ic = daeSafeCast< domInstance_camera >( currentNode->add(COLLADA_ELEMENT_INSTANCE_CAMERA));
493    std::string name = node.getName();
494    if ( name.empty() )
495    {
496        name = uniquify( "camera" );
497    }
498    std::string url = "#" + name;
499    ic->setUrl( url.c_str() );
500
501    if ( lib_cameras == NULL )
502    {
503        lib_cameras = daeSafeCast< domLibrary_cameras >( dom->add( COLLADA_ELEMENT_LIBRARY_CAMERAS ) );
504    }
505    domCamera *cam = daeSafeCast< domCamera >( lib_cameras->add( COLLADA_ELEMENT_CAMERA ) );
506    cam->setId( name.c_str() );
507
508    domCamera::domOptics *optics = daeSafeCast< domCamera::domOptics >( cam->add( COLLADA_ELEMENT_OPTICS ) );
509    domCamera::domOptics::domTechnique_common *techniqueCommon = daeSafeCast< domCamera::domOptics::domTechnique_common >( optics->add( COLLADA_ELEMENT_TECHNIQUE_COMMON ) );
510    domCamera::domOptics::domTechnique_common::domPerspective *pDomPerspective = daeSafeCast< domCamera::domOptics::domTechnique_common::domPerspective >( techniqueCommon->add( COLLADA_ELEMENT_PERSPECTIVE ) );
511
512    domTargetableFloat *pXfov = NULL;
513    domTargetableFloat *pYfov = NULL;
514    switch(node.getFieldOfViewMode())
515    {
516        case(osg::CameraView::UNCONSTRAINED):
517            pXfov = daeSafeCast< domTargetableFloat >( pDomPerspective->add( COLLADA_ELEMENT_XFOV ) );
518            pXfov->setValue(node.getFieldOfView());
519            break;
520        case(osg::CameraView::HORIZONTAL):
521            pXfov = daeSafeCast< domTargetableFloat >( pDomPerspective->add( COLLADA_ELEMENT_XFOV ) );
522            pXfov->setValue(node.getFieldOfView());
523            break;
524        case(osg::CameraView::VERTICAL):
525            pYfov = daeSafeCast< domTargetableFloat >( pDomPerspective->add( COLLADA_ELEMENT_YFOV ) );
526            pYfov->setValue(node.getFieldOfView());
527            break;
528    }
529
530    // Using hardcoded values for <aspect_ratio>, <znear> and <zfar>
531    domTargetableFloat *pAspectRatio = daeSafeCast< domTargetableFloat >( pDomPerspective->add( COLLADA_ELEMENT_ASPECT_RATIO ) );
532    pAspectRatio->setValue(1.0);
533
534    domTargetableFloat *pNear = daeSafeCast< domTargetableFloat >( pDomPerspective->add( COLLADA_ELEMENT_ZNEAR ) );
535    pNear->setValue(1);
536
537    domTargetableFloat *pFar = daeSafeCast< domTargetableFloat >( pDomPerspective->add( COLLADA_ELEMENT_ZFAR ) );
538    pFar->setValue(1000);
539}
Note: See TracBrowser for help on using the browser.