root/OpenSceneGraph/trunk/src/osgPlugins/dae/daeWGeometry.cpp @ 13557

Revision 13557, 59.2 kB (checked in by robert, 14 hours ago)

Changed the osgUI behaviour so that events are set to be handled by Widgets that have focus even if they don't directly use them.

  • 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#include <osgAnimation/RigGeometry>
16
17#include <dom/domCOLLADA.h>
18#include <dom/domNode.h>
19#include <dom/domLibrary_geometries.h>
20#include <dom/domSource.h>
21#include <dom/domGeometry.h>
22#include <dom/domConstants.h>
23//#include <dom/domSkin.h>
24
25#include <sstream>
26
27using namespace osgDAE;
28
29
30unsigned int daeWriter::ArrayNIndices::getDAESize()
31{
32    switch( mode )
33    {
34    case VEC2F:
35    case VEC2D:
36        return 2;
37    case VEC3F:
38    case VEC3D:
39        return 3;
40    case VEC4F:
41    case VEC4D:
42    case VEC4_UB:
43        return 4;
44    case NONE:
45        return 0;
46    }
47    return 0;
48}
49
50/// Appends an OSG vector (Vec2, Vec3...) to a domListOfFloats.
51template<class VecType>
52inline void append(domListOfFloats & list, const VecType & vec)
53{
54    for(unsigned int i=0; i<VecType::num_components; ++i) list.append( vec[i] );
55}
56
57/// Appends an OSG vector array (Vec2Array, Vec3Array...) to a domListOfFloats.
58bool daeWriter::ArrayNIndices::append(domListOfFloats & list)
59{
60    switch(getMode())
61    {
62    case VEC2F:
63        for (osg::Vec2Array::const_iterator it=vec2->begin(), itEnd=vec2->end(); it!=itEnd; ++it) ::append<osg::Vec2>(list, *it);
64        break;
65    case VEC2D:
66        for (osg::Vec2dArray::const_iterator it=vec2d->begin(), itEnd=vec2d->end(); it!=itEnd; ++it) ::append<osg::Vec2d>(list, *it);
67        break;
68    case VEC3F:
69        for (osg::Vec3Array::const_iterator it=vec3->begin(), itEnd=vec3->end(); it!=itEnd; ++it) ::append<osg::Vec3>(list, *it);
70        break;
71    case VEC3D:
72        for (osg::Vec3dArray::const_iterator it=vec3d->begin(), itEnd=vec3d->end(); it!=itEnd; ++it) ::append<osg::Vec3d>(list, *it);
73        break;
74    case VEC4F:
75        for (osg::Vec4Array::const_iterator it=vec4->begin(), itEnd=vec4->end(); it!=itEnd; ++it) ::append<osg::Vec4>(list, *it);
76        break;
77    case VEC4D:
78        for (osg::Vec4dArray::const_iterator it=vec4d->begin(), itEnd=vec4d->end(); it!=itEnd; ++it) ::append<osg::Vec4d>(list, *it);
79        break;
80    case VEC4_UB:
81        for (osg::Vec4ubArray::const_iterator it=vec4ub->begin(), itEnd=vec4ub->end(); it!=itEnd; ++it) ::append<osg::Vec4ub>(list, *it);
82        break;
83    default:
84        return false;
85    }
86    return true;
87}
88
89
90
91
92
93domGeometry* daeWriter::getOrCreateDomGeometry(osg::Geometry* pOsgGeometry)
94{
95    // See if geometry exists in cache
96    OsgGeometryDomGeometryMap::iterator iter = geometryMap.find( pOsgGeometry );
97    if ( iter != geometryMap.end() )
98    {
99        return iter->second;
100    }
101    else
102    {
103        if (!lib_geoms)
104        {
105            lib_geoms = daeSafeCast< domLibrary_geometries >( dom->add( COLLADA_ELEMENT_LIBRARY_GEOMETRIES ) );
106        }
107        domGeometry* pDomGeometry = daeSafeCast< domGeometry >( lib_geoms->add( COLLADA_ELEMENT_GEOMETRY ) );
108
109        std::string name( pOsgGeometry->getName() );
110        if (name.empty())
111            name = uniquify("geometry");
112        else
113            name = uniquify(name);
114        pDomGeometry->setId( name.c_str() );
115    #ifndef EARTH_GEO
116        geometryMap.insert( std::make_pair( pOsgGeometry, pDomGeometry ) );
117    #endif
118
119        if ( !processGeometry( pOsgGeometry, pDomGeometry, name ) )
120        {
121            daeElement::removeFromParent( pDomGeometry );
122            return NULL;
123        }
124        return pDomGeometry;
125    }
126}
127
128void daeWriter::writeRigGeometry(osgAnimation::RigGeometry *pOsgRigGeometry)
129{
130    // See if controller exists in cache
131    OsgRigGeometryDomControllerMap::iterator iter = _osgRigGeometryDomControllerMap.find(pOsgRigGeometry);
132    domController* pDomController = NULL;
133    if ( iter != _osgRigGeometryDomControllerMap.end() )
134    {
135        pDomController = iter->second;
136    }
137    else
138    {
139        domGeometry* pDomGeometry = getOrCreateDomGeometry(pOsgRigGeometry);
140        if (pDomGeometry)
141        {
142            if (!lib_controllers)
143            {
144                lib_controllers = daeSafeCast< domLibrary_controllers >( dom->add( COLLADA_ELEMENT_LIBRARY_CONTROLLERS ) );
145            }
146
147            // <controller>
148            // 1 <skin>
149            //   source
150            //   0..1    <bind_shape_matrix>
151            //   3..*    <source>
152            //   1        <joints>
153            //   1      <vertex_weights>
154            //   0..1    <extra>
155            pDomController = daeSafeCast< domController >( lib_controllers->add( COLLADA_ELEMENT_CONTROLLER) );
156            std::string name( pOsgRigGeometry->getName() );
157            if (name.empty())
158                name = uniquify("skincontroller");
159            else
160                name = uniquify(name);
161            pDomController->setId( name.c_str() );
162            _osgRigGeometryDomControllerMap.insert( std::make_pair( pOsgRigGeometry, pDomController ) );
163
164            // Link <skin> to cache hit or created <geometry>
165            domSkin* pDomSkin = daeSafeCast< domSkin >(pDomController->add( COLLADA_ELEMENT_SKIN ));
166            std::string url = "#" + std::string(pDomGeometry->getId());
167            pDomSkin->setSource(url.c_str());
168
169
170            domSource* pDomJointsSource = daeSafeCast< domSource >(pDomSkin->add( COLLADA_ELEMENT_SOURCE ));
171            std::string skinJointsName = name + "_skin_joints";
172            pDomJointsSource->setId(skinJointsName.c_str());
173
174            domListOfNames jointNames; // TODO fill with joint ids
175            int size = 0; // TODO number of animated joints
176
177            osgAnimation::VertexInfluenceMap* vim = pOsgRigGeometry->getInfluenceMap();
178            osgAnimation::VertexInfluenceMap::iterator iter =    vim->begin();
179            while (iter != vim->end())
180            {
181                jointNames.append(iter->first.c_str());
182                //iter->second.getn
183                ++iter;
184            }
185
186            domName_array* pDomJointsNameArray = daeSafeCast< domName_array >(pDomJointsSource->add(COLLADA_ELEMENT_NAME_ARRAY));
187            std::string jointsNameArrayName = name + "_joints_array";
188            pDomJointsNameArray->setId(jointsNameArrayName.c_str());
189            pDomJointsNameArray->setCount(size);
190            pDomJointsNameArray->setValue(jointNames);
191            {
192                domSource::domTechnique_common* pDomSourceTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomJointsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON));
193
194                domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomSourceTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR));
195                std::string url = "#" + jointsNameArrayName;
196                pDomAccessor->setSource(url.c_str());
197                pDomAccessor->setCount(size);
198
199                domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM));
200                pDomParam->setType(COLLADA_TYPE_NAME);
201            }
202
203            domSource* pDomSkinBindPoseSource = daeSafeCast< domSource >(pDomSkin->add( COLLADA_ELEMENT_SOURCE ));
204            std::string skinBindPoseName = name + "_skin_bind_pose";
205            pDomSkinBindPoseSource->setId(skinBindPoseName.c_str());
206
207            domListOfFloats matrices; // TODO fill with bind matrices
208            int numMatrices = 0; // TODO number of bind matrices
209            domFloat_array* pDomMatricesArray = daeSafeCast< domFloat_array >(pDomSkinBindPoseSource->add(COLLADA_ELEMENT_FLOAT_ARRAY));
210            std::string matricesArrayName = name + "_matrices_array";
211            pDomMatricesArray->setId(matricesArrayName.c_str());
212            pDomMatricesArray->setCount(numMatrices);
213            pDomMatricesArray->setValue(matrices);
214            {
215                domSource::domTechnique_common* pDomSourceTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomSkinBindPoseSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON));
216
217                domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomSourceTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR));
218                std::string url = "#" + matricesArrayName;
219                pDomAccessor->setSource(url.c_str());
220                pDomAccessor->setCount(size);
221                pDomAccessor->setStride(16);
222
223                domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM));
224                pDomParam->setType(COLLADA_TYPE_FLOAT4X4);
225            }
226
227            domSource* pDomSkinWeightsSource = daeSafeCast< domSource >(pDomSkin->add( COLLADA_ELEMENT_SOURCE ));
228            std::string skinWeightsName = name + "_skin_weights";
229            pDomSkinWeightsSource->setId(skinWeightsName.c_str());
230
231            domListOfFloats weights; // TODO fill with vertex weights
232            int numWeights = 0; // TODO number of vertices vertex weights
233            domFloat_array* pDomWeightsArray = daeSafeCast< domFloat_array >(pDomSkinWeightsSource->add(COLLADA_ELEMENT_FLOAT_ARRAY));
234            std::string weightsArrayName = name + "_weights_array";
235            pDomWeightsArray->setId(weightsArrayName.c_str());
236            pDomWeightsArray->setCount(numWeights);
237            pDomWeightsArray->setValue(weights);
238            {
239                domSource::domTechnique_common* pDomSourceTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomSkinWeightsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON));
240
241                domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomSourceTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR));
242                std::string url = "#" + weightsArrayName;
243                pDomAccessor->setSource(url.c_str());
244                pDomAccessor->setCount(size);
245
246                domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM));
247                pDomParam->setType(COLLADA_TYPE_FLOAT);
248            }
249
250            domSkin::domJoints* pDomJoints = daeSafeCast< domSkin::domJoints >(pDomSkin->add( COLLADA_ELEMENT_JOINTS ));
251
252            domInputLocal* pDomInput = daeSafeCast< domInputLocal >(pDomJoints->add(COLLADA_ELEMENT_INPUT));
253            pDomInput->setSemantic(COMMON_PROFILE_INPUT_JOINT);
254            url = "#" + skinJointsName;
255            pDomInput->setSource(url.c_str());
256
257            pDomInput = daeSafeCast< domInputLocal >(pDomJoints->add(COLLADA_ELEMENT_INPUT));
258            pDomInput->setSemantic(COMMON_PROFILE_INPUT_INV_BIND_MATRIX);
259            url = "#" + skinBindPoseName;
260            pDomInput->setSource(url.c_str());
261
262            domSkin::domVertex_weights* pDomVertexWeights = daeSafeCast< domSkin::domVertex_weights >(pDomSkin->add( COLLADA_ELEMENT_VERTEX_WEIGHTS ));
263            pDomVertexWeights->setCount(0);// TODO set number of vertex weights
264
265            domInputLocalOffset* pDomInputLocalOffset = daeSafeCast< domInputLocalOffset >(pDomVertexWeights->add(COLLADA_ELEMENT_INPUT));
266            pDomInputLocalOffset->setSemantic(COMMON_PROFILE_INPUT_JOINT);
267            url = "#" + skinJointsName;
268            pDomInputLocalOffset->setSource(url.c_str());
269            pDomInputLocalOffset->setOffset(0);
270
271            pDomInputLocalOffset = daeSafeCast< domInputLocalOffset >(pDomVertexWeights->add(COLLADA_ELEMENT_INPUT));
272            pDomInputLocalOffset->setSemantic(COMMON_PROFILE_INPUT_WEIGHT);
273            url = "#" + weightsArrayName;
274            pDomInputLocalOffset->setSource(url.c_str());
275            pDomInputLocalOffset->setOffset(1);
276
277            domSkin::domVertex_weights::domVcount* pDomVcount = daeSafeCast< domSkin::domVertex_weights::domVcount >(pDomVertexWeights->add(COLLADA_ELEMENT_VCOUNT));
278            domListOfUInts valueCounts;
279            // TODO
280            pDomVcount->setValue(valueCounts);
281            domSkin::domVertex_weights::domV* pDomV = daeSafeCast< domSkin::domVertex_weights::domV >(pDomVertexWeights->add(COLLADA_ELEMENT_V));
282            domListOfInts values;
283            //TODO
284            pDomV->setValue(values);
285        }
286    }
287
288    if (pDomController)
289    {
290        // Link <instance_controller> to cache hit or created <controller>
291        domInstance_controller* pDomInstanceController = daeSafeCast< domInstance_controller >( currentNode->add( COLLADA_ELEMENT_INSTANCE_CONTROLLER ) );
292        std::string url = "#" + std::string(pDomController->getId());
293        pDomInstanceController->setUrl( url.c_str() );
294    }
295}
296
297void daeWriter::writeMorphGeometry(osgAnimation::MorphGeometry *pOsgMorphGeometry)
298{
299    // See if controller exists in cache
300    OsgMorphGeometryDomControllerMap::iterator iter = _osgMorphGeometryDomControllerMap.find(pOsgMorphGeometry);
301    domController* pDomController = NULL;
302    if ( iter != _osgMorphGeometryDomControllerMap.end() )
303    {
304        pDomController = iter->second;
305    }
306    else
307    {
308        domGeometry* pDomGeometry = getOrCreateDomGeometry(pOsgMorphGeometry);
309        if (pDomGeometry)
310        {
311            if (!lib_controllers)
312            {
313                lib_controllers = daeSafeCast< domLibrary_controllers >( dom->add( COLLADA_ELEMENT_LIBRARY_CONTROLLERS ) );
314            }
315
316            // <controller>
317            // 1 <morph source (method)>
318            //     2..*    <source>
319            //   1        <targets>
320            //        2..*    <input semantic source>
321            //        0..*    <extra>
322            //   0..* <extra>
323            pDomController = daeSafeCast< domController >( lib_controllers->add( COLLADA_ELEMENT_CONTROLLER) );
324            std::string name( pOsgMorphGeometry->getName() );
325            if (name.empty())
326                name = uniquify("morphcontroller");
327            else
328                name = uniquify(name);
329            pDomController->setId( name.c_str() );
330            _osgMorphGeometryDomControllerMap.insert( std::make_pair( pOsgMorphGeometry, pDomController ) );
331
332            // Link <morph> to cache hit or created <geometry>
333            domMorph* pDomMorph = daeSafeCast< domMorph >(pDomController->add( COLLADA_ELEMENT_MORPH ));
334            std::string url = "#" + std::string(pDomGeometry->getId());
335            pDomMorph->setSource(url.c_str());
336            pDomMorph->setMethod(MORPHMETHODTYPE_NORMALIZED);
337            //pDomMorph->setMethod(MORPHMETHODTYPE_RELATIVE);
338
339            domSource* pDomTargetsSource = daeSafeCast< domSource >(pDomMorph->add( COLLADA_ELEMENT_SOURCE ));
340            std::string targetsName = name + "_morph_targets";
341            pDomTargetsSource->setId(targetsName.c_str());
342
343            domIDREF_array* pDomIDREFArray = daeSafeCast< domIDREF_array >(pDomTargetsSource->add(COLLADA_ELEMENT_IDREF_ARRAY));
344            xsIDREFS idrefs;
345            osgAnimation::MorphGeometry::MorphTargetList morphTargetList = pOsgMorphGeometry->getMorphTargetList();
346            for (unsigned int i=0; i < morphTargetList.size(); i++)
347            {
348                domGeometry* pDomGeometry = getOrCreateDomGeometry(morphTargetList[i].getGeometry());
349                idrefs.append(pDomGeometry->getId());
350            }
351            pDomIDREFArray->setValue(idrefs);
352            std::string targetsArrayName = targetsName + "_array";
353            pDomIDREFArray->setId(targetsArrayName.c_str());
354            pDomIDREFArray->setCount(morphTargetList.size());
355
356            domSource::domTechnique_common* pDomTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomTargetsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON));
357            domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR));
358            pDomAccessor->setCount(morphTargetList.size());
359            url = "#" + targetsArrayName;
360            pDomAccessor->setSource(url.c_str());
361
362            domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM));
363            pDomParam->setName(COMMON_PROFILE_INPUT_MORPH_TARGET);
364            pDomParam->setType("IDREF"); // COLLADA_TYPE_IDREF does not exist
365
366            domSource* pDomWeightsSource = daeSafeCast< domSource >(pDomMorph->add( COLLADA_ELEMENT_SOURCE ));
367            std::string weightsName = name + "_morph_weights";
368            pDomWeightsSource->setId(weightsName.c_str());
369
370            domFloat_array* pDomFloatArray = daeSafeCast< domFloat_array >(pDomWeightsSource->add(COLLADA_ELEMENT_FLOAT_ARRAY));
371            domListOfFloats weights;
372            for (unsigned int i=0; i < morphTargetList.size(); i++)
373            {
374                weights.append(morphTargetList[i].getWeight());
375            }
376            pDomFloatArray->setValue(weights);
377            std::string weigthsArrayName = weightsName + "_array";
378            pDomFloatArray->setId(weigthsArrayName.c_str());
379            pDomFloatArray->setCount(morphTargetList.size());
380
381            pDomTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomWeightsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON));
382            pDomAccessor = daeSafeCast< domAccessor >(pDomTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR));
383            pDomAccessor->setCount(morphTargetList.size());
384            url = "#" + weightsName;
385            pDomAccessor->setSource(url.c_str());
386
387            pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM));
388            pDomParam->setName(COMMON_PROFILE_INPUT_MORPH_WEIGHT);
389            pDomParam->setType(COLLADA_TYPE_FLOAT);
390
391            domMorph::domTargets* pDomTargets = daeSafeCast< domMorph::domTargets >(pDomMorph->add( COLLADA_ELEMENT_TARGETS ));
392
393            domInputLocal* pDomTargetsInput = daeSafeCast< domInputLocal >(pDomTargets->add( COLLADA_ELEMENT_INPUT ));
394            pDomTargetsInput->setSemantic(COMMON_PROFILE_INPUT_MORPH_TARGET);
395            url = "#" + targetsName;
396            pDomTargetsInput->setSource(url.c_str());
397
398            domInputLocal* pDomWeightsInput = daeSafeCast< domInputLocal >(pDomTargets->add( COLLADA_ELEMENT_INPUT ));
399            pDomWeightsInput->setSemantic(COMMON_PROFILE_INPUT_MORPH_WEIGHT);
400            url = "#" + weightsName;
401            pDomWeightsInput->setSource(url.c_str());
402        }
403    }
404
405    if (pDomController)
406    {
407        // Transparency at drawable level
408        if (pOsgMorphGeometry->getStateSet())
409            m_CurrentRenderingHint = pOsgMorphGeometry->getStateSet()->getRenderingHint();
410
411        pushStateSet(pOsgMorphGeometry->getStateSet());
412
413        // Link <instance_controller> to cache hit or created <controller>
414        domInstance_controller* pDomInstanceController = daeSafeCast< domInstance_controller >( currentNode->add( COLLADA_ELEMENT_INSTANCE_CONTROLLER ) );
415        std::string url = "#" + std::string(pDomController->getId());
416        pDomInstanceController->setUrl( url.c_str() );
417
418        if (!stateSetStack.empty())
419        {
420            domBind_material *pDomBindMaterial = daeSafeCast< domBind_material >( pDomInstanceController->add( COLLADA_ELEMENT_BIND_MATERIAL ) );
421            processMaterial( currentStateSet.get(), pDomBindMaterial, pOsgMorphGeometry->getName() );
422        }
423
424        popStateSet(pOsgMorphGeometry->getStateSet());
425    }
426}
427
428void daeWriter::apply( osg::Geode &node )
429{
430    debugPrint( node );
431    updateCurrentDaeNode();
432
433    pushStateSet(node.getStateSet());
434    if (NULL != node.getStateSet())
435        m_CurrentRenderingHint = node.getStateSet()->getRenderingHint();
436
437    // TODO
438    // Write a Geode as a single instance_geometry if all drawables use the same vertex streams
439    // Reuse an existing Geode if only statesets differ
440    unsigned int count = node.getNumDrawables();
441    for ( unsigned int i = 0; i < count; i++ )
442    {
443        osg::Geometry *g = node.getDrawable( i )->asGeometry();
444
445        if ( g != NULL )
446        {
447            osgAnimation::RigGeometry *pOsgRigGeometry = dynamic_cast<osgAnimation::RigGeometry*>(g);
448            if (pOsgRigGeometry)
449            {
450                writeRigGeometry(pOsgRigGeometry);
451            }
452            else
453            {
454                osgAnimation::MorphGeometry *pOsgMorphGeometry = dynamic_cast<osgAnimation::MorphGeometry*>(g);
455                if (pOsgMorphGeometry)
456                {
457                    writeMorphGeometry(pOsgMorphGeometry);
458                }
459                else
460                {
461                    // Write a default osg::Geometry
462
463                    // Transparency at drawable level
464                    if (NULL != g->getStateSet())
465                        m_CurrentRenderingHint = g->getStateSet()->getRenderingHint();
466
467                    pushStateSet(g->getStateSet());
468
469                    domGeometry* pDomGeometry = getOrCreateDomGeometry(g);
470                    if (pDomGeometry)
471                    {
472                        // Link <instance_geometry> to cache hit or created <geometry>
473                        domInstance_geometry *pDomInstanceGeometry = daeSafeCast< domInstance_geometry >( currentNode->add( COLLADA_ELEMENT_INSTANCE_GEOMETRY ) );
474                        std::string url = "#" + std::string(pDomGeometry->getId());
475                        pDomInstanceGeometry->setUrl( url.c_str() );
476
477                        if (!stateSetStack.empty())
478                        {
479                            domBind_material *pDomBindMaterial = daeSafeCast< domBind_material >( pDomInstanceGeometry->add( COLLADA_ELEMENT_BIND_MATERIAL ) );
480                            processMaterial( currentStateSet.get(), pDomBindMaterial, pDomGeometry->getId() );
481                        }
482                    }
483
484                    popStateSet(g->getStateSet());
485                }
486            }
487        }
488        else
489        {
490            OSG_WARN << "Non-geometry drawables are not supported" << std::endl;
491        }
492    }
493
494    popStateSet(node.getStateSet());
495}
496
497/** append elements (verts, normals, colors and texcoord) for file write */
498void daeWriter::appendGeometryIndices(osg::Geometry *geom,
499                    domP * p,
500                    unsigned int vindex,
501                    domSource * norm,
502                    domSource * color,
503                    const ArrayNIndices & verts,
504                    const ArrayNIndices & normals,
505                    const ArrayNIndices & colors,
506                    const std::vector<ArrayNIndices> & texcoords,
507                    unsigned int  ncount,
508                    unsigned int  ccount)
509{
510  p->getValue().append( verts.inds!=NULL?verts.inds->index( vindex ):vindex );
511
512  if ( norm != NULL )
513  {
514    if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX )
515      p->getValue().append( normals.inds!=NULL?normals.inds->index( vindex ):vindex );
516    else
517      p->getValue().append( normals.inds!=NULL?normals.inds->index( ncount ):ncount );
518  }
519
520  if ( color != NULL )
521  {
522    if ( geom->getColorBinding() == osg::Geometry::BIND_PER_VERTEX )
523      p->getValue().append( colors.inds!=NULL?colors.inds->index( vindex ):vindex );
524    else
525      p->getValue().append( colors.inds!=NULL?colors.inds->index( ccount ):ccount );
526  }
527
528  for ( unsigned int ti = 0; ti < texcoords.size(); ti++ )
529  {
530    //ArrayNIndices &tc = texcoords[ti];
531    p->getValue().append( texcoords[ti].inds!=NULL?texcoords[ti].inds->index(vindex):vindex );
532  }
533
534}
535
536
537bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const std::string &name )
538{
539    domMesh *mesh = daeSafeCast< domMesh >( geo->add( COLLADA_ELEMENT_MESH ) );
540    domSource *pos = NULL;
541    domSource *norm = NULL;
542    domSource *color = NULL;
543    std::vector< domSource * >texcoord;
544    std::vector< domSource * > vertexAttribute;
545    domLines *lines = NULL;
546    domLinestrips *linestrips = NULL;
547    domTriangles *tris = NULL;
548    domTristrips *tristrips = NULL;
549    domTrifans *trifans = NULL;
550    domPolygons *polys = NULL;
551    domPolylist *polylist = NULL;
552
553    // make sure no deprecated indices or binding exist
554    if (geom->containsDeprecatedData()) geom->fixDeprecatedData();
555
556    ArrayNIndices verts( geom->getVertexArray(), 0 );
557    ArrayNIndices normals( geom->getNormalArray(), 0 );
558    ArrayNIndices colors( geom->getColorArray(), 0 );
559
560    // RS BUG
561    // getNumTexCoordArrays may return larger number
562    // where getTexCoordArray(0) may have a BIND_OFF and an empty array
563    std::vector<ArrayNIndices> texcoords;
564    for ( unsigned int i = 0; i < geom->getNumTexCoordArrays(); i++ )
565    {
566        if (geom->getTexCoordArray(i))
567        {
568            texcoords.push_back( ArrayNIndices( geom->getTexCoordArray( i ), 0 ) );
569        }
570    }
571    std::vector<ArrayNIndices> vertexAttributes;
572    for ( unsigned int i = 0; i < geom->getNumVertexAttribArrays(); i++ )
573    {
574        if (geom->getVertexAttribArray(i))
575        {
576            vertexAttributes.push_back(ArrayNIndices( geom->getVertexAttribArray( i ), 0));
577        }
578    }
579
580    // process POSITION
581    std::string sName;
582    {
583        sName = name + "-positions";
584        unsigned int elementSize = verts.getDAESize();
585        unsigned int numElements = verts.valArray->getNumElements();
586        pos = createSource( mesh, sName, elementSize );
587        pos->getFloat_array()->setCount( numElements * elementSize );
588        pos->getTechnique_common()->getAccessor()->setCount( numElements );
589        if (!verts.append(pos->getFloat_array()->getValue()))
590        {
591            OSG_WARN << "Invalid array type for vertices" << std::endl;
592        }
593
594        //create a vertices element
595        domVertices *vertices = daeSafeCast< domVertices >( mesh->add( COLLADA_ELEMENT_VERTICES ) );
596        std::string vName = name + "-vertices";
597        vertices->setId( vName.c_str() );
598
599        //make a POSITION input in it
600        domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) );
601        il->setSemantic( COMMON_PROFILE_INPUT_POSITION );
602        std::string url("#" + std::string(pos->getId()) );
603        il->setSource( url.c_str() );
604    }
605
606    //process NORMAL
607    if ( normals.getMode() != ArrayNIndices::NONE )
608    {
609        sName = name + "-normals";
610        unsigned int elementSize = normals.getDAESize();
611        unsigned int numElements = normals.valArray->getNumElements();
612        norm = createSource( mesh, sName, elementSize );
613        norm->getFloat_array()->setCount( numElements * elementSize );
614        norm->getTechnique_common()->getAccessor()->setCount( numElements );
615        if (!normals.append(norm->getFloat_array()->getValue()))
616        {
617            OSG_WARN << "Invalid array type for normals" << std::endl;
618        }
619
620        //if NORMAL shares same indices as POSITION put it in the vertices
621        /*if ( normalInds == vertInds && vertInds != NULL ) {
622            il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) );
623            il->setSemantic( COMMON_PROFILE_INPUT_NORMAL );
624            url = "#" + std::string(md->norm->getId());
625            il->setSource( url.c_str() );
626        }*/
627    }
628
629    //process COLOR
630    if ( colors.getMode() != ArrayNIndices::NONE )
631    {
632        sName = name + "-colors";
633        unsigned int elementSize = colors.getDAESize();
634        unsigned int numElements = colors.valArray->getNumElements();
635        color = createSource( mesh, sName, elementSize, true );
636        color->getFloat_array()->setCount( numElements * elementSize );
637        color->getTechnique_common()->getAccessor()->setCount( numElements );
638        if (!colors.append(color->getFloat_array()->getValue()))
639        {
640            OSG_WARN << "Invalid array type for colors" << std::endl;
641        }
642
643        //if COLOR shares same indices as POSITION put it in the vertices
644        /*if ( colorInds == vertInds && vertInds != NULL ) {
645            il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) );
646            il->setSemantic( COMMON_PROFILE_INPUT_COLOR );
647            url = "#" + std::string(md->color->getId());
648            il->setSource( url.c_str() );
649        }*/
650    }
651
652    //process TEXCOORD
653    //TODO: Do the same as normal and colors for texcoods. But in a loop since you can have many
654    for ( unsigned int ti = 0; ti < texcoords.size(); ti++ )
655    {
656        if (texcoords[ti].getMode() == ArrayNIndices::NONE) continue;
657
658        std::ostringstream intstr;
659        intstr << std::dec << ti;
660        sName = name + "-texcoord_" + intstr.str();
661
662        unsigned int elementSize = texcoords[ti].getDAESize();
663        unsigned int numElements = texcoords[ti].valArray->getNumElements();
664        domSource *t = createSource( mesh, sName, elementSize, false, true );
665        t->getFloat_array()->setCount( numElements * elementSize );
666        t->getTechnique_common()->getAccessor()->setCount( numElements );
667        if (!texcoords[ti].append(t->getFloat_array()->getValue()))
668        {
669            OSG_WARN << "Invalid array type for texcoord" << std::endl;
670        }
671
672        texcoord.push_back( t );
673    }
674
675    //RS
676    //process VERTEX ATTRIBUTES
677    //TODO: Do the same as normal and colors for texcoods. But in a loop since you can have many
678    for ( unsigned int ti = 0; ti < vertexAttributes.size(); ti++ )
679    {
680        if (vertexAttributes[ti].getMode() == ArrayNIndices::NONE) continue;
681
682        std::ostringstream intstr;
683        intstr << std::dec << ti;
684        sName = name + "-vertexAttribute_" + intstr.str();
685
686        unsigned int elementSize = vertexAttributes[ti].getDAESize();
687        unsigned int numElements = vertexAttributes[ti].valArray->getNumElements();
688        domSource *t = createSource( mesh, sName, elementSize, false, true );        // Sukender: should we *REALLY* call createSource(... false, true)? (I mean with such flags)
689        t->getFloat_array()->setCount( numElements * elementSize );
690        t->getTechnique_common()->getAccessor()->setCount( numElements );
691        if (!vertexAttributes[ti].append(t->getFloat_array()->getValue()))
692        {
693            OSG_WARN << "Invalid array type for vertex attribute" << ti << std::endl;
694        }
695
696        vertexAttribute.push_back( t );
697    }
698
699    //process each primitive group
700    unsigned int ncount = 0; //Normal index counter
701    unsigned int ccount = 0; //Color index counter
702    if ( geom->getNumPrimitiveSets() == 0 )
703    {
704        OSG_WARN << "NO PRIMITIVE SET!!" << std::endl;
705        return false;
706    }
707    bool valid = false;
708    //for each primitive group
709    for ( unsigned int i = 0; i < geom->getNumPrimitiveSets(); i++ )
710    {
711        osg::PrimitiveSet *ps = geom->getPrimitiveSet( i );
712        GLenum mode = ps->getMode();
713        unsigned int primLength;
714        //unsigned int offset = 0;
715        //domInputLocalOffset *ilo = NULL;
716
717        //process primitive group
718        switch( mode )
719        {
720            case GL_POINTS:
721            {
722                OSG_WARN << "Geometry contains points rendering. COLLADA does not" << std::endl;
723                continue;
724            }
725            case GL_LINES:
726            {
727                if ( lines == NULL )
728                {
729                    lines = createPrimGroup<domLines>( COLLADA_ELEMENT_LINES, mesh, norm, color, texcoord );
730                    lines->add( COLLADA_ELEMENT_P );
731                    std::string mat = name + "_material";
732                    lines->setMaterial( mat.c_str() );
733                }
734                primLength = 2;
735                valid = true;
736                break;
737            }
738            case GL_TRIANGLES:
739            {
740                if ( tris == NULL )
741                {
742                    tris = createPrimGroup<domTriangles>( COLLADA_ELEMENT_TRIANGLES, mesh, norm, color, texcoord );
743                    tris->add( COLLADA_ELEMENT_P );
744                    std::string mat = name + "_material";
745                    tris->setMaterial( mat.c_str() );
746                }
747                primLength = 3;
748                valid = true;
749                break;
750            }
751            case GL_QUADS:
752            {
753                if ( polys == NULL )
754                {
755                    if (_pluginOptions.usePolygons)
756                    {
757                          polys = createPrimGroup<domPolygons>( COLLADA_ELEMENT_POLYGONS, mesh, norm, color, texcoord );
758                          polys->add( COLLADA_ELEMENT_P );
759                          std::string mat = name + "_material";
760                          polys->setMaterial( mat.c_str() );
761                    }
762                    else
763                    {
764                          polylist = createPrimGroup<domPolylist>( COLLADA_ELEMENT_POLYLIST, mesh, norm, color, texcoord );
765
766                          polylist->add( COLLADA_ELEMENT_VCOUNT );
767                          polylist->add( COLLADA_ELEMENT_P );
768                          std::string mat = name + "_material";
769                          polylist->setMaterial( mat.c_str() );
770                    }
771                }
772                primLength = 4;
773                valid = true;
774                break;
775            }
776            case GL_LINE_STRIP:
777            {
778                if ( linestrips == NULL )
779                {
780                    linestrips = createPrimGroup<domLinestrips>( COLLADA_ELEMENT_LINESTRIPS, mesh, norm, color, texcoord );
781                    std::string mat = name + "_material";
782                    linestrips->setMaterial( mat.c_str() );
783                }
784                primLength = 0;
785                valid = true;
786                break;
787            }
788            case GL_TRIANGLE_STRIP:
789            {
790                if ( tristrips == NULL )
791                {
792                    tristrips = createPrimGroup<domTristrips>( COLLADA_ELEMENT_TRISTRIPS, mesh, norm, color, texcoord );
793                    std::string mat = name + "_material";
794                    tristrips->setMaterial( mat.c_str() );
795                }
796                primLength = 0;
797                valid = true;
798                break;
799            }
800            case GL_TRIANGLE_FAN:
801            {
802                if ( trifans == NULL )
803                {
804                    trifans = createPrimGroup<domTrifans>( COLLADA_ELEMENT_TRIFANS, mesh, norm, color, texcoord );
805                    std::string mat = name + "_material";
806                    trifans->setMaterial( mat.c_str() );
807                }
808                primLength = 0;
809                valid = true;
810                break;
811            }
812            default:
813            {
814                if ( polys == NULL )
815                {
816                    if (_pluginOptions.usePolygons)
817                    {
818                        polys = createPrimGroup<domPolygons>( COLLADA_ELEMENT_POLYGONS, mesh, norm, color, texcoord );
819                        polys->add( COLLADA_ELEMENT_P );
820                        std::string mat = name + "_material";
821                        polys->setMaterial( mat.c_str() );
822                    }
823                    else
824                    {
825                        polylist = createPrimGroup<domPolylist>( COLLADA_ELEMENT_POLYLIST, mesh, norm, color, texcoord );
826
827                        polylist->add( COLLADA_ELEMENT_VCOUNT );
828                        polylist->add( COLLADA_ELEMENT_P );
829                        std::string mat = name + "_material";
830                        polylist->setMaterial( mat.c_str() );
831                    }
832                }
833                primLength = 0;
834                valid = true;
835                break; // compute later when =0.
836            }
837        }
838
839                //process upon primitive set type
840                // 1- set data source,accumulate count of primitives and write it to file
841                // 2- read data source for primitive set and write it to file
842        switch( ps->getType() )
843        {
844                //draw arrays (array of contiguous vertices)
845
846                       //(primitive type+begin+end),(primitive type+begin+end)...
847            case osg::PrimitiveSet::DrawArraysPrimitiveType:
848            {
849                //OSG_WARN << "DrawArrays" << std::endl;
850
851                if ( primLength == 0 )
852                {
853                    primLength = ps->getNumIndices();
854                }
855                osg::DrawArrays* drawArray = static_cast< osg::DrawArrays* >( ps );
856                unsigned int vcount = 0;
857                unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
858
859                std::vector<domP *> p;
860                switch ( mode )
861                {
862                    case GL_LINES:
863                    {
864                                                p.push_back(lines->getP());
865                        lines->setCount( lines->getCount() + drawArray->getCount()/primLength );
866                        break;
867                    }
868                    case GL_TRIANGLES:
869                    {
870                                                p.push_back(tris->getP());
871                        tris->setCount( tris->getCount() + drawArray->getCount()/primLength );
872                        break;
873                    }
874                    case GL_LINE_STRIP:
875                    {
876                                                p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
877                        linestrips->setCount( linestrips->getCount() + 1 );
878                        break;
879                    }
880                    case GL_TRIANGLE_STRIP:
881                    {
882                                                p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
883                        tristrips->setCount( tristrips->getCount() + 1 );
884                        break;
885                    }
886                    case GL_TRIANGLE_FAN:
887                    {
888                                                p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
889                        trifans->setCount( trifans->getCount() + 1 );
890                        break;
891                    }
892                    default:
893                    {
894                        //TODO : test this case
895                        unsigned int nbPolygons=drawArray->getCount()/primLength;
896                        if (_pluginOptions.usePolygons)
897                        {
898                            //for( unsigned int idx = 0; idx < nbPolygons; ++idx )
899                            p.push_back(polys->getP_array()[0]);
900                            polys->setCount( polys->getCount() + nbPolygons );
901                        }
902                        else
903                        {
904                            for( unsigned int idx = 0; idx < nbPolygons; ++idx )
905                                    polylist->getVcount()->getValue().append( primLength );
906                            p.push_back(polylist->getP());
907                            polylist->setCount( polylist->getCount() + nbPolygons);
908                        }
909                        break;
910                    }
911                }
912
913                unsigned int indexBegin = drawArray->getFirst();
914                unsigned int nbVerticesPerPoly=(indexEnd-indexBegin)/p.size();
915                unsigned int indexPolyEnd = indexBegin+nbVerticesPerPoly;
916                for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly )
917                {
918                    for (unsigned int vindex=indexBegin; vindex< indexPolyEnd;vindex++)
919                    {
920
921                       appendGeometryIndices(geom,p[iPoly],vindex,
922                                     norm,color,
923                                     verts,normals,colors,texcoords,
924                                     ncount,ccount);
925
926                       vcount++;
927                    }
928                    indexBegin+=nbVerticesPerPoly;
929                    indexPolyEnd+=nbVerticesPerPoly;
930                }
931                break;
932            }
933            //(primitive type) + (end1),(end2),(end3)...
934            case osg::PrimitiveSet::DrawArrayLengthsPrimitiveType:
935            {
936                //OSG_WARN << "DrawArrayLengths" << std::endl;
937
938                osg::DrawArrayLengths* drawArrayLengths = static_cast<osg::DrawArrayLengths*>( ps );
939
940                unsigned int vindex = drawArrayLengths->getFirst();
941                for( osg::DrawArrayLengths::iterator primItr = drawArrayLengths->begin();
942                    primItr != drawArrayLengths->end();
943                    ++primItr )
944                {
945                    unsigned int localPrimLength;
946                    if ( primLength == 0 ) localPrimLength = *primItr;
947                    else localPrimLength = primLength;
948
949                    std::vector<domP *> p;
950                    switch ( mode )
951                    {
952                        case GL_LINES:
953                        {
954                            p.push_back(lines->getP());
955                            lines->setCount( lines->getCount() + (*primItr)/localPrimLength );
956                            break;
957                        }
958                        case GL_TRIANGLES:
959                        {
960                            p.push_back(tris->getP());
961                            tris->setCount( tris->getCount() + (*primItr)/localPrimLength );
962                            break;
963                        }
964                        case GL_LINE_STRIP:
965                        {
966                            p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
967                            linestrips->setCount( linestrips->getCount() + 1 );
968                            break;
969                        }
970                        case GL_TRIANGLE_STRIP:
971                        {
972                            p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
973                            tristrips->setCount( tristrips->getCount() + 1 );
974                            break;
975                        }
976                        case GL_TRIANGLE_FAN:
977                        {
978                            p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
979                            trifans->setCount( trifans->getCount() + 1 );
980                            break;
981                        }
982                        default:
983                        {
984
985                            if (_pluginOptions.usePolygons)
986                            {
987                                //for( unsigned int idx = 0; idx < nbPolygons; ++idx )
988                                p.push_back(polys->getP_array()[0]);
989                                polys->setCount( polys->getCount() + 1 );
990                            }
991                            else
992                            {
993                                polylist->getVcount()->getValue().append( localPrimLength );
994                                p.push_back(polylist->getP());
995                                polylist->setCount( polylist->getCount() + 1);
996                            }
997                            break;
998                        }
999                    }
1000
1001                    unsigned int indexBegin = 0;
1002                    unsigned int nbVerticesPerPoly=*primItr/p.size();
1003                    unsigned int indexEnd=indexBegin+nbVerticesPerPoly;
1004                    for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly )
1005                    {
1006                        // printf("indexBegin %d,indexPolyEnd %d \n",indexBegin,indexEnd);
1007                        for( unsigned int primCount = indexBegin; primCount < indexEnd; ++primCount )
1008                        {
1009                            appendGeometryIndices(geom,p[iPoly],vindex,
1010                                                  norm,color,
1011                                                  verts,normals,colors,texcoords,
1012                                                  ncount,ccount);
1013
1014                            vindex++;
1015                        }
1016                        indexBegin+=nbVerticesPerPoly;
1017                        indexEnd+=nbVerticesPerPoly;
1018                     }
1019                }
1020                break;
1021            }
1022
1023            //draw elements (array of shared vertices + array of indices)
1024           case osg::PrimitiveSet::DrawElementsUBytePrimitiveType:
1025                     {
1026                //OSG_WARN << "DrawElementsUByte" << std::endl;
1027
1028                if ( primLength == 0 ) primLength = ps->getNumIndices();
1029
1030                osg::DrawElementsUByte* drawElements = static_cast<osg::DrawElementsUByte*>( ps );
1031
1032                std::vector<domP *> p;
1033                switch ( mode )
1034                {
1035                    case GL_LINES:
1036                    {
1037                        p.push_back(lines->getP());
1038                        lines->setCount( lines->getCount() + drawElements->size()/primLength );
1039                        break;
1040                    }
1041                    case GL_TRIANGLES:
1042                    {
1043                        p.push_back(tris->getP());
1044                        tris->setCount( tris->getCount() + drawElements->size()/primLength );
1045                        break;
1046                    }
1047                    case GL_LINE_STRIP:
1048                    {
1049                        p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
1050                        linestrips->setCount( linestrips->getCount() + 1 );
1051                        break;
1052                    }
1053                    case GL_TRIANGLE_STRIP:
1054                    {
1055                        p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
1056                        tristrips->setCount( tristrips->getCount() + 1 );
1057                        break;
1058                    }
1059                    case GL_TRIANGLE_FAN:
1060                    {
1061                        p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
1062                        trifans->setCount( trifans->getCount() + 1 );
1063                        break;
1064                    }
1065                    default:
1066                    {
1067                        unsigned int nbPolygons=drawElements->size()/primLength;
1068                        if (_pluginOptions.usePolygons)
1069                        {
1070                            //for( unsigned int idx = 0; idx < nbPolygons; ++idx ) /*idx*/
1071                            //huh ? why only one ?
1072                            p.push_back(polys->getP_array()[0]);
1073                            polys->setCount( polys->getCount() + nbPolygons );
1074                        }
1075                        else
1076                        {
1077                            polylist->getVcount()->getValue().append( primLength );
1078                            p.push_back(polylist->getP());
1079                            polylist->setCount( polylist->getCount() + nbPolygons );
1080                        }
1081                        break;
1082                    }
1083                }
1084
1085
1086                unsigned int primCount = 0;
1087                osg::DrawElementsUByte::iterator primItrBegin = drawElements->begin();
1088                unsigned int nbVerticesPerPoly= drawElements->size()/p.size();
1089                osg::DrawElementsUByte::iterator primItrEnd=primItrBegin+nbVerticesPerPoly;
1090                for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly )
1091                {
1092                    for( osg::DrawElementsUByte::iterator primItr = primItrBegin;primItr != primItrEnd;
1093                    ++primCount, ++primItr )
1094                    {
1095
1096                        unsigned int vindex = *primItr;
1097
1098                        appendGeometryIndices(geom,p[iPoly],vindex,
1099                                              norm,color,
1100                                              verts,normals,colors,texcoords,
1101                                              ncount,ccount);
1102
1103                    }
1104
1105                    primItrBegin+=nbVerticesPerPoly;
1106#if ( _SECURE_SCL == 1 )
1107                    if (primItrBegin != drawElements->end())
1108#endif
1109                    primItrEnd+=nbVerticesPerPoly;
1110                }
1111                break;
1112            }
1113            case osg::PrimitiveSet::DrawElementsUShortPrimitiveType:
1114            {
1115                //OSG_WARN << "DrawElementsUShort" << std::endl;
1116                if ( primLength == 0 ) primLength = ps->getNumIndices();
1117
1118                osg::DrawElementsUShort* drawElements = static_cast<osg::DrawElementsUShort*>( ps );
1119
1120                                std::vector<domP *> p;
1121                switch ( mode )
1122                {
1123                    case GL_LINES:
1124                    {
1125                        p.push_back(lines->getP());
1126                        lines->setCount( lines->getCount() + drawElements->size()/primLength );
1127                        break;
1128                    }
1129                    case GL_TRIANGLES:
1130                    {
1131                        p.push_back(tris->getP());
1132                        tris->setCount( tris->getCount() + drawElements->size()/primLength );
1133                        break;
1134                    }
1135                    case GL_LINE_STRIP:
1136                    {
1137                        p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
1138                        linestrips->setCount( linestrips->getCount() + 1 );
1139                        break;
1140                    }
1141                    case GL_TRIANGLE_STRIP:
1142                    {
1143                        p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
1144                        tristrips->setCount( tristrips->getCount() + 1 );
1145                        break;
1146                    }
1147                    case GL_TRIANGLE_FAN:
1148                    {
1149                        p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
1150                        trifans->setCount( trifans->getCount() + 1 );
1151                        break;
1152                    }
1153                    default:
1154                    {
1155                        unsigned int nbPolygons=drawElements->size()/primLength;
1156                        if (_pluginOptions.usePolygons)
1157                        {
1158                            //for( unsigned int idx = 0; idx < nbPolygons; ++idx ) /*idx*/
1159                            //huh ? why only one ?
1160                            p.push_back(polys->getP_array()[0]);
1161                            polys->setCount( polys->getCount() + nbPolygons );
1162                        }
1163                        else
1164                        {
1165                            polylist->getVcount()->getValue().append( primLength );
1166                            p.push_back(polylist->getP());
1167                            polylist->setCount( polylist->getCount() + nbPolygons );
1168                        }
1169                        break;
1170                    }
1171                }
1172
1173                unsigned int primCount = 0;
1174                osg::DrawElementsUShort::iterator primItrBegin = drawElements->begin();
1175                unsigned int nbVerticesPerPoly= drawElements->size()/p.size();
1176                osg::DrawElementsUShort::iterator primItrEnd=primItrBegin+nbVerticesPerPoly;
1177
1178                for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly )
1179                {
1180                  for( osg::DrawElementsUShort::iterator primItr = primItrBegin;primItr != primItrEnd;
1181                       ++primCount, ++primItr )
1182                  {
1183
1184                    unsigned int vindex = *primItr;
1185
1186                    appendGeometryIndices(geom,p[iPoly],vindex,
1187                                       norm,color,
1188                                       verts,normals,colors,texcoords,
1189                                       ncount,ccount);
1190
1191                  }
1192                  primItrBegin+=nbVerticesPerPoly;
1193#if ( _SECURE_SCL == 1 )
1194                  if (primItrBegin != drawElements->end())
1195#endif
1196                  primItrEnd+=nbVerticesPerPoly;
1197                }
1198
1199                break;
1200            }
1201            case osg::PrimitiveSet::DrawElementsUIntPrimitiveType:
1202            {
1203                //OSG_WARN << "DrawElementsUInt" << std::endl;
1204
1205                if ( primLength == 0 ) primLength = ps->getNumIndices();
1206
1207                osg::DrawElementsUInt* drawElements = static_cast<osg::DrawElementsUInt*>( ps );
1208
1209                std::vector<domP *> p;
1210                switch ( mode )
1211                {
1212                    case GL_LINES:
1213                    {
1214                        p.push_back(lines->getP());
1215                        lines->setCount( lines->getCount() + drawElements->size()/primLength );
1216                        break;
1217                    }
1218                    case GL_TRIANGLES:
1219                    {
1220                        p.push_back(tris->getP());
1221                        tris->setCount( tris->getCount() + drawElements->size()/primLength );
1222                        break;
1223                    }
1224                    case GL_LINE_STRIP:
1225                    {
1226                        p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
1227                        linestrips->setCount( linestrips->getCount() + 1 );
1228                        break;
1229                    }
1230                    case GL_TRIANGLE_STRIP:
1231                    {
1232                        p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
1233                        tristrips->setCount( tristrips->getCount() + 1 );
1234                        break;
1235                    }
1236                    case GL_TRIANGLE_FAN:
1237                    {
1238                        p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
1239                        trifans->setCount( trifans->getCount() + 1 );
1240                        break;
1241                    }
1242                    default:
1243                    {
1244                        unsigned int nbPolygons=drawElements->size()/primLength;
1245                        if (_pluginOptions.usePolygons)
1246                        {
1247                            //for( unsigned int idx = 0; idx < nbPolygons; ++idx ) /*idx*/
1248                            //huh ? why only one ?
1249                            p.push_back(polys->getP_array()[0]);
1250                            polys->setCount( polys->getCount() + nbPolygons );
1251                        }
1252                        else
1253                        {
1254                            polylist->getVcount()->getValue().append( primLength );
1255                            p.push_back(polylist->getP());
1256                            polylist->setCount( polylist->getCount() + nbPolygons );
1257                        }
1258                        break;
1259                    }
1260                }
1261
1262                unsigned int primCount = 0;
1263                osg::DrawElementsUInt::iterator primItrBegin = drawElements->begin();
1264                unsigned int nbVerticesPerPoly= drawElements->size()/p.size();
1265                osg::DrawElementsUInt::iterator primItrEnd=primItrBegin+nbVerticesPerPoly;
1266
1267                for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly )
1268                {
1269
1270                  for( osg::DrawElementsUInt::iterator primItr = primItrBegin;primItr != primItrEnd;
1271                       ++primCount, ++primItr )
1272                  {
1273
1274                    unsigned int vindex = *primItr;
1275
1276                    appendGeometryIndices(geom,p[iPoly],vindex,
1277                                       norm,color,
1278                                       verts,normals,colors,texcoords,
1279                                       ncount,ccount);
1280
1281                  }
1282                  primItrBegin+=nbVerticesPerPoly;
1283#if ( _SECURE_SCL == 1 )
1284                  if (primItrBegin != drawElements->end())
1285#endif
1286                  primItrEnd+=nbVerticesPerPoly;
1287                }
1288                break;
1289            }
1290            default:
1291                OSG_WARN << "Unsupported primitiveSet" << std::endl;
1292                break;
1293        }
1294
1295        if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE_SET )
1296        {
1297            ncount++;
1298        }
1299        if ( geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE_SET )
1300        {
1301            ccount++;
1302        }
1303    }
1304    return valid;
1305}
1306
1307domSource *daeWriter::createSource( daeElement *parent, const std::string &baseName, int size, bool color, bool uv )
1308{
1309    domSource *src = daeSafeCast< domSource >( parent->add( COLLADA_ELEMENT_SOURCE ) );
1310    if ( src == NULL )
1311    {
1312        return NULL;
1313    }
1314    src->setId( baseName.c_str() );
1315
1316    domFloat_array *fa = daeSafeCast< domFloat_array >( src->add( COLLADA_ELEMENT_FLOAT_ARRAY ) );
1317    std::string fName = baseName + "-array";
1318    fa->setId( fName.c_str() );
1319
1320    domSource::domTechnique_common *teq = daeSafeCast< domSource::domTechnique_common >( src->add( COLLADA_ELEMENT_TECHNIQUE_COMMON ) );
1321    domAccessor *acc = daeSafeCast< domAccessor >( teq->add( COLLADA_ELEMENT_ACCESSOR ) );
1322    std::string url = "#" + fName;
1323    acc->setSource( url.c_str() );
1324    domParam *param;
1325    if ( color )
1326    {
1327        acc->setStride( size );
1328        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1329        param->setName( "R" );
1330        param->setType( "float" );
1331
1332        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1333        param->setName( "G" );
1334        param->setType( "float" );
1335
1336        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1337        param->setName( "B" );
1338        param->setType( "float" );
1339
1340        if ( size == 4 )
1341        {
1342            param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1343            param->setName( "A" );
1344            param->setType( "float" );
1345        }
1346
1347    }
1348    else if ( uv )
1349    {
1350        const char * const type = "float";
1351
1352        acc->setStride( size );
1353        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1354        param->setName( "S" );
1355        param->setType( type );
1356
1357        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1358        param->setName( "T" );
1359        param->setType( type );
1360
1361        if ( size >=3 )
1362        {
1363            param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1364            param->setName( "P" );
1365            param->setType( type );
1366        }
1367    }
1368    else
1369    {
1370        const char * const type = "float";
1371        acc->setStride( size );
1372        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1373        param->setName( "X" );
1374        param->setType( type );
1375
1376        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1377        param->setName( "Y" );
1378        param->setType( type );
1379
1380        if ( size >=3 )
1381        {
1382            param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1383            param->setName( "Z" );
1384            param->setType( type );
1385
1386            if ( size == 4 )
1387            {
1388                param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1389                param->setName( "W" );
1390                param->setType( type );
1391            }
1392        }
1393    }
1394
1395    return src;
1396}
1397
1398template < typename Ty >
1399Ty *daeWriter::createPrimGroup( daeString type, domMesh *mesh, domSource *norm, domSource *color, const std::vector< domSource* > &texcoord )
1400{
1401    unsigned int offset = 0;
1402    Ty *retVal = daeSafeCast< Ty >( mesh->add( type ) );
1403    domInputLocalOffset *ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) );
1404    ilo->setOffset( offset++ );
1405    ilo->setSemantic( COMMON_PROFILE_INPUT_VERTEX );
1406    std::string url = "#" + std::string(mesh->getVertices()->getId());
1407    ilo->setSource( url.c_str() );
1408    if ( norm != NULL )
1409    {
1410        ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) );
1411        ilo->setOffset( offset++ );
1412        ilo->setSemantic( COMMON_PROFILE_INPUT_NORMAL );
1413        url = "#" + std::string( norm->getId() );
1414        ilo->setSource( url.c_str() );
1415    }
1416    if ( color != NULL )
1417    {
1418        ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) );
1419        ilo->setOffset( offset++ );
1420        ilo->setSemantic( COMMON_PROFILE_INPUT_COLOR );
1421        url = "#" + std::string( color->getId() );
1422        ilo->setSource( url.c_str() );
1423    }
1424    for ( unsigned int i = 0; i < texcoord.size(); i++ )
1425    {
1426        ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) );
1427        ilo->setOffset( offset++ );
1428        ilo->setSemantic( COMMON_PROFILE_INPUT_TEXCOORD );
1429        ilo->setSet( i );
1430        url = "#" + std::string( texcoord[i]->getId() );
1431        ilo->setSource( url.c_str() );
1432    }
1433
1434    return retVal;
1435}
Note: See TracBrowser for help on using the browser.