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

Revision 13041, 61.7 kB (checked in by robert, 2 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#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    ArrayNIndices verts( geom->getVertexArray(), geom->getVertexIndices() );
554    ArrayNIndices normals( geom->getNormalArray(), geom->getNormalIndices() );
555    ArrayNIndices colors( geom->getColorArray(), geom->getColorIndices() );
556
557    // RS BUG
558    // getNumTexCoordArrays may return larger number
559    // where getTexCoordArray(0) may have a BIND_OFF and an empty array
560    std::vector<ArrayNIndices> texcoords;
561    for ( unsigned int i = 0; i < geom->getNumTexCoordArrays(); i++ )
562    {
563        if (geom->getTexCoordArray(i))
564        {
565            texcoords.push_back( ArrayNIndices( geom->getTexCoordArray( i ), geom->getTexCoordIndices( i ) ) );
566        }
567    }
568    std::vector<ArrayNIndices> vertexAttributes;
569    for ( unsigned int i = 0; i < geom->getNumVertexAttribArrays(); i++ )
570    {
571        if (geom->getVertexAttribArray(i))
572        {
573            vertexAttributes.push_back(ArrayNIndices( geom->getVertexAttribArray( i ), geom->getVertexAttribIndices(i)));
574        }
575    }
576
577    // process POSITION
578    std::string sName;
579    {
580        sName = name + "-positions";
581        unsigned int elementSize = verts.getDAESize();
582        unsigned int numElements = verts.valArray->getNumElements();
583        pos = createSource( mesh, sName, elementSize );
584        pos->getFloat_array()->setCount( numElements * elementSize );
585        pos->getTechnique_common()->getAccessor()->setCount( numElements );
586        if (!verts.append(pos->getFloat_array()->getValue()))
587        {
588            OSG_WARN << "Invalid array type for vertices" << std::endl;
589        }
590
591        //create a vertices element
592        domVertices *vertices = daeSafeCast< domVertices >( mesh->add( COLLADA_ELEMENT_VERTICES ) );
593        std::string vName = name + "-vertices";
594        vertices->setId( vName.c_str() );
595
596        //make a POSITION input in it
597        domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) );
598        il->setSemantic( COMMON_PROFILE_INPUT_POSITION );
599        std::string url("#" + std::string(pos->getId()) );
600        il->setSource( url.c_str() );
601    }
602
603    //process NORMAL
604    if ( normals.getMode() != ArrayNIndices::NONE )
605    {
606        sName = name + "-normals";
607        unsigned int elementSize = normals.getDAESize();
608        unsigned int numElements = normals.valArray->getNumElements();
609        norm = createSource( mesh, sName, elementSize );
610        norm->getFloat_array()->setCount( numElements * elementSize );
611        norm->getTechnique_common()->getAccessor()->setCount( numElements );
612        if (!normals.append(norm->getFloat_array()->getValue()))
613        {
614            OSG_WARN << "Invalid array type for normals" << std::endl;
615        }
616
617        //if NORMAL shares same indices as POSITION put it in the vertices
618        /*if ( normalInds == vertInds && vertInds != NULL ) {
619            il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) );
620            il->setSemantic( COMMON_PROFILE_INPUT_NORMAL );
621            url = "#" + std::string(md->norm->getId());
622            il->setSource( url.c_str() );
623        }*/
624    }
625
626    //process COLOR
627    if ( colors.getMode() != ArrayNIndices::NONE )
628    {
629        sName = name + "-colors";
630        unsigned int elementSize = colors.getDAESize();
631        unsigned int numElements = colors.valArray->getNumElements();
632        color = createSource( mesh, sName, elementSize, true );
633        color->getFloat_array()->setCount( numElements * elementSize );
634        color->getTechnique_common()->getAccessor()->setCount( numElements );
635        if (!colors.append(color->getFloat_array()->getValue()))
636        {
637            OSG_WARN << "Invalid array type for colors" << std::endl;
638        }
639
640        //if COLOR shares same indices as POSITION put it in the vertices
641        /*if ( colorInds == vertInds && vertInds != NULL ) {
642            il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) );
643            il->setSemantic( COMMON_PROFILE_INPUT_COLOR );
644            url = "#" + std::string(md->color->getId());
645            il->setSource( url.c_str() );
646        }*/
647    }
648
649    //process TEXCOORD
650    //TODO: Do the same as normal and colors for texcoods. But in a loop since you can have many
651    for ( unsigned int ti = 0; ti < texcoords.size(); ti++ )
652    {
653        if (texcoords[ti].getMode() == ArrayNIndices::NONE) continue;
654
655        std::ostringstream intstr;
656        intstr << std::dec << ti;
657        sName = name + "-texcoord_" + intstr.str();
658
659        unsigned int elementSize = texcoords[ti].getDAESize();
660        unsigned int numElements = texcoords[ti].valArray->getNumElements();
661        domSource *t = createSource( mesh, sName, elementSize, false, true );
662        t->getFloat_array()->setCount( numElements * elementSize );
663        t->getTechnique_common()->getAccessor()->setCount( numElements );
664        if (!texcoords[ti].append(t->getFloat_array()->getValue()))
665        {
666            OSG_WARN << "Invalid array type for texcoord" << std::endl;
667        }
668
669        texcoord.push_back( t );
670    }
671
672    //RS
673    //process VERTEX ATTRIBUTES
674    //TODO: Do the same as normal and colors for texcoods. But in a loop since you can have many
675    for ( unsigned int ti = 0; ti < vertexAttributes.size(); ti++ )
676    {
677        if (vertexAttributes[ti].getMode() == ArrayNIndices::NONE) continue;
678
679        std::ostringstream intstr;
680        intstr << std::dec << ti;
681        sName = name + "-vertexAttribute_" + intstr.str();
682
683        unsigned int elementSize = vertexAttributes[ti].getDAESize();
684        unsigned int numElements = vertexAttributes[ti].valArray->getNumElements();
685        domSource *t = createSource( mesh, sName, elementSize, false, true );        // Sukender: should we *REALLY* call createSource(... false, true)? (I mean with such flags)
686        t->getFloat_array()->setCount( numElements * elementSize );
687        t->getTechnique_common()->getAccessor()->setCount( numElements );
688        if (!vertexAttributes[ti].append(t->getFloat_array()->getValue()))
689        {
690            OSG_WARN << "Invalid array type for vertex attribute" << ti << std::endl;
691        }
692
693        vertexAttribute.push_back( t );
694    }
695
696    //process each primitive group
697    unsigned int ncount = 0; //Normal index counter
698    unsigned int ccount = 0; //Color index counter
699    if ( geom->getNumPrimitiveSets() == 0 )
700    {
701        OSG_WARN << "NO PRIMITIVE SET!!" << std::endl;
702        return false;
703    }
704    bool valid = false;
705    //for each primitive group
706    for ( unsigned int i = 0; i < geom->getNumPrimitiveSets(); i++ )
707    {
708        osg::PrimitiveSet *ps = geom->getPrimitiveSet( i );
709        GLenum mode = ps->getMode();
710        unsigned int primLength;
711        //unsigned int offset = 0;
712        //domInputLocalOffset *ilo = NULL;
713
714        //process primitive group
715        switch( mode )
716        {
717            case GL_POINTS:
718            {
719                OSG_WARN << "Geometry contains points rendering. COLLADA does not" << std::endl;
720                continue;
721            }
722            case GL_LINES:
723            {
724                if ( lines == NULL )
725                {
726                    lines = createPrimGroup<domLines>( COLLADA_ELEMENT_LINES, mesh, norm, color, texcoord );
727                    lines->add( COLLADA_ELEMENT_P );
728                    std::string mat = name + "_material";
729                    lines->setMaterial( mat.c_str() );
730                }
731                primLength = 2;
732                valid = true;
733                break;
734            }
735            case GL_TRIANGLES:
736            {
737                if ( tris == NULL )
738                {
739                    tris = createPrimGroup<domTriangles>( COLLADA_ELEMENT_TRIANGLES, mesh, norm, color, texcoord );
740                    tris->add( COLLADA_ELEMENT_P );
741                    std::string mat = name + "_material";
742                    tris->setMaterial( mat.c_str() );
743                }
744                primLength = 3;
745                valid = true;
746                break;
747            }
748            case GL_QUADS:
749            {
750                if ( polys == NULL )
751                {
752                    if (_pluginOptions.usePolygons)
753                    {
754                          polys = createPrimGroup<domPolygons>( COLLADA_ELEMENT_POLYGONS, mesh, norm, color, texcoord );
755                          polys->add( COLLADA_ELEMENT_P );
756                          std::string mat = name + "_material";
757                          polys->setMaterial( mat.c_str() );
758                    }
759                    else
760                    {
761                          polylist = createPrimGroup<domPolylist>( COLLADA_ELEMENT_POLYLIST, mesh, norm, color, texcoord );
762
763                          polylist->add( COLLADA_ELEMENT_VCOUNT );
764                          polylist->add( COLLADA_ELEMENT_P );
765                          std::string mat = name + "_material";
766                          polylist->setMaterial( mat.c_str() );
767                    }
768                }
769                primLength = 4;
770                valid = true;
771                break;
772            }
773            case GL_LINE_STRIP:
774            {
775                if ( linestrips == NULL )
776                {
777                    linestrips = createPrimGroup<domLinestrips>( COLLADA_ELEMENT_LINESTRIPS, mesh, norm, color, texcoord );
778                    std::string mat = name + "_material";
779                    linestrips->setMaterial( mat.c_str() );
780                }
781                primLength = 0;
782                valid = true;
783                break;
784            }
785            case GL_TRIANGLE_STRIP:
786            {
787                if ( tristrips == NULL )
788                {
789                    tristrips = createPrimGroup<domTristrips>( COLLADA_ELEMENT_TRISTRIPS, mesh, norm, color, texcoord );
790                    std::string mat = name + "_material";
791                    tristrips->setMaterial( mat.c_str() );
792                }
793                primLength = 0;
794                valid = true;
795                break;
796            }
797            case GL_TRIANGLE_FAN:
798            {
799                if ( trifans == NULL )
800                {
801                    trifans = createPrimGroup<domTrifans>( COLLADA_ELEMENT_TRIFANS, mesh, norm, color, texcoord );
802                    std::string mat = name + "_material";
803                    trifans->setMaterial( mat.c_str() );
804                }
805                primLength = 0;
806                valid = true;
807                break;
808            }
809            default:
810            {
811                if ( polys == NULL )
812                {
813                    if (_pluginOptions.usePolygons)
814                    {
815                        polys = createPrimGroup<domPolygons>( COLLADA_ELEMENT_POLYGONS, mesh, norm, color, texcoord );
816                        polys->add( COLLADA_ELEMENT_P );
817                        std::string mat = name + "_material";
818                        polys->setMaterial( mat.c_str() );
819                    }
820                    else
821                    {
822                        polylist = createPrimGroup<domPolylist>( COLLADA_ELEMENT_POLYLIST, mesh, norm, color, texcoord );
823
824                        polylist->add( COLLADA_ELEMENT_VCOUNT );
825                        polylist->add( COLLADA_ELEMENT_P );
826                        std::string mat = name + "_material";
827                        polylist->setMaterial( mat.c_str() );
828                    }
829                }
830                primLength = 0;
831                valid = true;
832                break; // compute later when =0.
833            }
834        }
835
836                //process upon primitive set type
837                // 1- set data source,accumulate count of primitives and write it to file
838                // 2- read data source for primitive set and write it to file
839        switch( ps->getType() )
840        {
841                //draw arrays (array of contiguous vertices)
842
843                       //(primitive type+begin+end),(primitive type+begin+end)...
844            case osg::PrimitiveSet::DrawArraysPrimitiveType:
845            {
846                //OSG_WARN << "DrawArrays" << std::endl;
847
848                if ( primLength == 0 )
849                {
850                    primLength = ps->getNumIndices();
851                }
852                osg::DrawArrays* drawArray = static_cast< osg::DrawArrays* >( ps );
853                unsigned int vcount = 0;
854                unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
855
856                std::vector<domP *> p;
857                switch ( mode )
858                {
859                    case GL_LINES:
860                    {
861                                                p.push_back(lines->getP());
862                        lines->setCount( lines->getCount() + drawArray->getCount()/primLength );
863                        break;
864                    }
865                    case GL_TRIANGLES:
866                    {
867                                                p.push_back(tris->getP());
868                        tris->setCount( tris->getCount() + drawArray->getCount()/primLength );
869                        break;
870                    }
871                    case GL_LINE_STRIP:
872                    {
873                                                p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
874                        linestrips->setCount( linestrips->getCount() + 1 );
875                        break;
876                    }
877                    case GL_TRIANGLE_STRIP:
878                    {
879                                                p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
880                        tristrips->setCount( tristrips->getCount() + 1 );
881                        break;
882                    }
883                    case GL_TRIANGLE_FAN:
884                    {
885                                                p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
886                        trifans->setCount( trifans->getCount() + 1 );
887                        break;
888                    }
889                    default:
890                    {
891                        //TODO : test this case
892                        unsigned int nbPolygons=drawArray->getCount()/primLength;
893                        if (_pluginOptions.usePolygons)
894                        {
895                            //for( unsigned int idx = 0; idx < nbPolygons; ++idx )
896                            p.push_back(polys->getP_array()[0]);
897                            polys->setCount( polys->getCount() + nbPolygons );
898                        }
899                        else
900                        {
901                            for( unsigned int idx = 0; idx < nbPolygons; ++idx )
902                                    polylist->getVcount()->getValue().append( primLength );
903                            p.push_back(polylist->getP());
904                            polylist->setCount( polylist->getCount() + nbPolygons);
905                        }
906                        break;
907                    }
908                }
909
910                unsigned int indexBegin = drawArray->getFirst();
911                unsigned int nbVerticesPerPoly=(indexEnd-indexBegin)/p.size();
912                unsigned int indexPolyEnd = indexBegin+nbVerticesPerPoly;
913                for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly )
914                {
915                    for (unsigned int vindex=indexBegin; vindex< indexPolyEnd;vindex++)
916                    {
917
918                       appendGeometryIndices(geom,p[iPoly],vindex,
919                                     norm,color,
920                                     verts,normals,colors,texcoords,
921                                     ncount,ccount);
922
923                       if ( vcount>0 && ((vcount % primLength) == 0) )
924                       {
925                         if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE )
926                         {
927                           ncount++;
928                         }
929                         if ( geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE )
930                         {
931                           ccount++;
932                         }
933                       }
934                       vcount++;
935                    }
936                    indexBegin+=nbVerticesPerPoly;
937                    indexPolyEnd+=nbVerticesPerPoly;
938                }
939                break;
940            }
941            //(primitive type) + (end1),(end2),(end3)...
942            case osg::PrimitiveSet::DrawArrayLengthsPrimitiveType:
943            {
944                //OSG_WARN << "DrawArrayLengths" << std::endl;
945
946                osg::DrawArrayLengths* drawArrayLengths = static_cast<osg::DrawArrayLengths*>( ps );
947
948                unsigned int vindex = drawArrayLengths->getFirst();
949                for( osg::DrawArrayLengths::iterator primItr = drawArrayLengths->begin();
950                    primItr != drawArrayLengths->end();
951                    ++primItr )
952                {
953                    unsigned int localPrimLength;
954                    if ( primLength == 0 ) localPrimLength = *primItr;
955                    else localPrimLength = primLength;
956
957                    std::vector<domP *> p;
958                    switch ( mode )
959                    {
960                        case GL_LINES:
961                        {
962                            p.push_back(lines->getP());
963                            lines->setCount( lines->getCount() + (*primItr)/localPrimLength );
964                            break;
965                        }
966                        case GL_TRIANGLES:
967                        {
968                            p.push_back(tris->getP());
969                            tris->setCount( tris->getCount() + (*primItr)/localPrimLength );
970                            break;
971                        }
972                        case GL_LINE_STRIP:
973                        {
974                            p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
975                            linestrips->setCount( linestrips->getCount() + 1 );
976                            break;
977                        }
978                        case GL_TRIANGLE_STRIP:
979                        {
980                            p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
981                            tristrips->setCount( tristrips->getCount() + 1 );
982                            break;
983                        }
984                        case GL_TRIANGLE_FAN:
985                        {
986                            p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
987                            trifans->setCount( trifans->getCount() + 1 );
988                            break;
989                        }
990                        default:
991                        {
992
993                            if (_pluginOptions.usePolygons)
994                            {
995                                //for( unsigned int idx = 0; idx < nbPolygons; ++idx )
996                                p.push_back(polys->getP_array()[0]);
997                                polys->setCount( polys->getCount() + 1 );
998                            }
999                            else
1000                            {
1001                                polylist->getVcount()->getValue().append( localPrimLength );
1002                                p.push_back(polylist->getP());
1003                                polylist->setCount( polylist->getCount() + 1);
1004                            }
1005                            break;
1006                        }
1007                    }
1008
1009                    unsigned int indexBegin = 0;
1010                    unsigned int nbVerticesPerPoly=*primItr/p.size();
1011                    unsigned int indexEnd=indexBegin+nbVerticesPerPoly;
1012                    for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly )
1013                    {
1014                        // printf("indexBegin %d,indexPolyEnd %d \n",indexBegin,indexEnd);
1015                        for( unsigned int primCount = indexBegin; primCount < indexEnd; ++primCount )
1016                        {
1017                            appendGeometryIndices(geom,p[iPoly],vindex,
1018                                                  norm,color,
1019                                                  verts,normals,colors,texcoords,
1020                                                  ncount,ccount);
1021
1022                            if ( primCount>0 && ((primCount % localPrimLength) == 0) )
1023                            {
1024                                if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE )
1025                                {
1026                                    ncount++;
1027                                }
1028                                if ( geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE )
1029                                {
1030                                    ccount++;
1031                                }
1032                            }
1033                            vindex++;
1034                        }
1035                        indexBegin+=nbVerticesPerPoly;
1036                        indexEnd+=nbVerticesPerPoly;
1037                     }
1038                }
1039                break;
1040            }
1041
1042            //draw elements (array of shared vertices + array of indices)
1043           case osg::PrimitiveSet::DrawElementsUBytePrimitiveType:
1044                     {
1045                //OSG_WARN << "DrawElementsUByte" << std::endl;
1046
1047                if ( primLength == 0 ) primLength = ps->getNumIndices();
1048
1049                osg::DrawElementsUByte* drawElements = static_cast<osg::DrawElementsUByte*>( ps );
1050
1051                std::vector<domP *> p;
1052                switch ( mode )
1053                {
1054                    case GL_LINES:
1055                    {
1056                        p.push_back(lines->getP());
1057                        lines->setCount( lines->getCount() + drawElements->size()/primLength );
1058                        break;
1059                    }
1060                    case GL_TRIANGLES:
1061                    {
1062                        p.push_back(tris->getP());
1063                        tris->setCount( tris->getCount() + drawElements->size()/primLength );
1064                        break;
1065                    }
1066                    case GL_LINE_STRIP:
1067                    {
1068                        p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
1069                        linestrips->setCount( linestrips->getCount() + 1 );
1070                        break;
1071                    }
1072                    case GL_TRIANGLE_STRIP:
1073                    {
1074                        p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
1075                        tristrips->setCount( tristrips->getCount() + 1 );
1076                        break;
1077                    }
1078                    case GL_TRIANGLE_FAN:
1079                    {
1080                        p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
1081                        trifans->setCount( trifans->getCount() + 1 );
1082                        break;
1083                    }
1084                    default:
1085                    {
1086                        unsigned int nbPolygons=drawElements->size()/primLength;
1087                        if (_pluginOptions.usePolygons)
1088                        {
1089                            //for( unsigned int idx = 0; idx < nbPolygons; ++idx ) /*idx*/
1090                            //huh ? why only one ?
1091                            p.push_back(polys->getP_array()[0]);
1092                            polys->setCount( polys->getCount() + nbPolygons );
1093                        }
1094                        else
1095                        {
1096                            polylist->getVcount()->getValue().append( primLength );
1097                            p.push_back(polylist->getP());
1098                            polylist->setCount( polylist->getCount() + nbPolygons );
1099                        }
1100                        break;
1101                    }
1102                }
1103
1104
1105                unsigned int primCount = 0;
1106                osg::DrawElementsUByte::iterator primItrBegin = drawElements->begin();
1107                unsigned int nbVerticesPerPoly= drawElements->size()/p.size();
1108                osg::DrawElementsUByte::iterator primItrEnd=primItrBegin+nbVerticesPerPoly;
1109                for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly )
1110                {
1111                    for( osg::DrawElementsUByte::iterator primItr = primItrBegin;primItr != primItrEnd;
1112                    ++primCount, ++primItr )
1113                    {
1114
1115                        unsigned int vindex = *primItr;
1116
1117                        appendGeometryIndices(geom,p[iPoly],vindex,
1118                                              norm,color,
1119                                              verts,normals,colors,texcoords,
1120                                              ncount,ccount);
1121
1122                        if ( primCount>0 && ((primCount % primLength) == 0) )
1123                        {
1124                            if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE )
1125                            {
1126                              ncount++;
1127                            }
1128                            if ( geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE )
1129                            {
1130                              ccount++;
1131                            }
1132                        }
1133                    }
1134
1135                    primItrBegin+=nbVerticesPerPoly;
1136#if ( _SECURE_SCL == 1 )
1137                    if (primItrBegin != drawElements->end())
1138#endif
1139                    primItrEnd+=nbVerticesPerPoly;
1140                }
1141                break;
1142            }
1143            case osg::PrimitiveSet::DrawElementsUShortPrimitiveType:
1144            {
1145                //OSG_WARN << "DrawElementsUShort" << std::endl;
1146                if ( primLength == 0 ) primLength = ps->getNumIndices();
1147
1148                osg::DrawElementsUShort* drawElements = static_cast<osg::DrawElementsUShort*>( ps );
1149
1150                                std::vector<domP *> p;
1151                switch ( mode )
1152                {
1153                    case GL_LINES:
1154                    {
1155                        p.push_back(lines->getP());
1156                        lines->setCount( lines->getCount() + drawElements->size()/primLength );
1157                        break;
1158                    }
1159                    case GL_TRIANGLES:
1160                    {
1161                        p.push_back(tris->getP());
1162                        tris->setCount( tris->getCount() + drawElements->size()/primLength );
1163                        break;
1164                    }
1165                    case GL_LINE_STRIP:
1166                    {
1167                        p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
1168                        linestrips->setCount( linestrips->getCount() + 1 );
1169                        break;
1170                    }
1171                    case GL_TRIANGLE_STRIP:
1172                    {
1173                        p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
1174                        tristrips->setCount( tristrips->getCount() + 1 );
1175                        break;
1176                    }
1177                    case GL_TRIANGLE_FAN:
1178                    {
1179                        p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
1180                        trifans->setCount( trifans->getCount() + 1 );
1181                        break;
1182                    }
1183                    default:
1184                    {
1185                        unsigned int nbPolygons=drawElements->size()/primLength;
1186                        if (_pluginOptions.usePolygons)
1187                        {
1188                            //for( unsigned int idx = 0; idx < nbPolygons; ++idx ) /*idx*/
1189                            //huh ? why only one ?
1190                            p.push_back(polys->getP_array()[0]);
1191                            polys->setCount( polys->getCount() + nbPolygons );
1192                        }
1193                        else
1194                        {
1195                            polylist->getVcount()->getValue().append( primLength );
1196                            p.push_back(polylist->getP());
1197                            polylist->setCount( polylist->getCount() + nbPolygons );
1198                        }
1199                        break;
1200                    }
1201                }
1202
1203                unsigned int primCount = 0;
1204                osg::DrawElementsUShort::iterator primItrBegin = drawElements->begin();
1205                unsigned int nbVerticesPerPoly= drawElements->size()/p.size();
1206                osg::DrawElementsUShort::iterator primItrEnd=primItrBegin+nbVerticesPerPoly;
1207
1208                for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly )
1209                {
1210                  for( osg::DrawElementsUShort::iterator primItr = primItrBegin;primItr != primItrEnd;
1211                       ++primCount, ++primItr )
1212                  {
1213
1214                    unsigned int vindex = *primItr;
1215
1216                    appendGeometryIndices(geom,p[iPoly],vindex,
1217                                       norm,color,
1218                                       verts,normals,colors,texcoords,
1219                                       ncount,ccount);
1220
1221                    if ( primCount>0 && ((primCount % primLength) == 0) )
1222                    {
1223                      if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE )
1224                      {
1225                        ncount++;
1226                      }
1227                      if ( geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE )
1228                      {
1229                        ccount++;
1230                      }
1231                    }
1232
1233                  }
1234                  primItrBegin+=nbVerticesPerPoly;
1235#if ( _SECURE_SCL == 1 )
1236                  if (primItrBegin != drawElements->end())
1237#endif
1238                  primItrEnd+=nbVerticesPerPoly;
1239                }
1240
1241                break;
1242            }
1243            case osg::PrimitiveSet::DrawElementsUIntPrimitiveType:
1244            {
1245                //OSG_WARN << "DrawElementsUInt" << std::endl;
1246
1247                if ( primLength == 0 ) primLength = ps->getNumIndices();
1248
1249                osg::DrawElementsUInt* drawElements = static_cast<osg::DrawElementsUInt*>( ps );
1250
1251                std::vector<domP *> p;
1252                switch ( mode )
1253                {
1254                    case GL_LINES:
1255                    {
1256                        p.push_back(lines->getP());
1257                        lines->setCount( lines->getCount() + drawElements->size()/primLength );
1258                        break;
1259                    }
1260                    case GL_TRIANGLES:
1261                    {
1262                        p.push_back(tris->getP());
1263                        tris->setCount( tris->getCount() + drawElements->size()/primLength );
1264                        break;
1265                    }
1266                    case GL_LINE_STRIP:
1267                    {
1268                        p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
1269                        linestrips->setCount( linestrips->getCount() + 1 );
1270                        break;
1271                    }
1272                    case GL_TRIANGLE_STRIP:
1273                    {
1274                        p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
1275                        tristrips->setCount( tristrips->getCount() + 1 );
1276                        break;
1277                    }
1278                    case GL_TRIANGLE_FAN:
1279                    {
1280                        p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
1281                        trifans->setCount( trifans->getCount() + 1 );
1282                        break;
1283                    }
1284                    default:
1285                    {
1286                        unsigned int nbPolygons=drawElements->size()/primLength;
1287                        if (_pluginOptions.usePolygons)
1288                        {
1289                            //for( unsigned int idx = 0; idx < nbPolygons; ++idx ) /*idx*/
1290                            //huh ? why only one ?
1291                            p.push_back(polys->getP_array()[0]);
1292                            polys->setCount( polys->getCount() + nbPolygons );
1293                        }
1294                        else
1295                        {
1296                            polylist->getVcount()->getValue().append( primLength );
1297                            p.push_back(polylist->getP());
1298                            polylist->setCount( polylist->getCount() + nbPolygons );
1299                        }
1300                        break;
1301                    }
1302                }
1303
1304                unsigned int primCount = 0;
1305                osg::DrawElementsUInt::iterator primItrBegin = drawElements->begin();
1306                unsigned int nbVerticesPerPoly= drawElements->size()/p.size();
1307                osg::DrawElementsUInt::iterator primItrEnd=primItrBegin+nbVerticesPerPoly;
1308
1309                for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly )
1310                {
1311
1312                  for( osg::DrawElementsUInt::iterator primItr = primItrBegin;primItr != primItrEnd;
1313                       ++primCount, ++primItr )
1314                  {
1315
1316                    unsigned int vindex = *primItr;
1317
1318                    appendGeometryIndices(geom,p[iPoly],vindex,
1319                                       norm,color,
1320                                       verts,normals,colors,texcoords,
1321                                       ncount,ccount);
1322
1323                    if ( primCount>0 && ((primCount % primLength) == 0) )
1324                    {
1325                      if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE )
1326                      {
1327                        ncount++;
1328                      }
1329                      if ( geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE )
1330                      {
1331                        ccount++;
1332                      }
1333                    }
1334                  }
1335                  primItrBegin+=nbVerticesPerPoly;
1336#if ( _SECURE_SCL == 1 )
1337                  if (primItrBegin != drawElements->end())
1338#endif
1339                  primItrEnd+=nbVerticesPerPoly;
1340                }
1341                break;
1342            }
1343            default:
1344                OSG_WARN << "Unsupported primitiveSet" << std::endl;
1345                break;
1346        }
1347
1348        if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE_SET )
1349        {
1350            ncount++;
1351        }
1352        if ( geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE_SET )
1353        {
1354            ccount++;
1355        }
1356    }
1357    return valid;
1358}
1359
1360domSource *daeWriter::createSource( daeElement *parent, const std::string &baseName, int size, bool color, bool uv )
1361{
1362    domSource *src = daeSafeCast< domSource >( parent->add( COLLADA_ELEMENT_SOURCE ) );
1363    if ( src == NULL )
1364    {
1365        return NULL;
1366    }
1367    src->setId( baseName.c_str() );
1368
1369    domFloat_array *fa = daeSafeCast< domFloat_array >( src->add( COLLADA_ELEMENT_FLOAT_ARRAY ) );
1370    std::string fName = baseName + "-array";
1371    fa->setId( fName.c_str() );
1372
1373    domSource::domTechnique_common *teq = daeSafeCast< domSource::domTechnique_common >( src->add( COLLADA_ELEMENT_TECHNIQUE_COMMON ) );
1374    domAccessor *acc = daeSafeCast< domAccessor >( teq->add( COLLADA_ELEMENT_ACCESSOR ) );
1375    std::string url = "#" + fName;
1376    acc->setSource( url.c_str() );
1377    domParam *param;
1378    if ( color )
1379    {
1380        acc->setStride( size );
1381        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1382        param->setName( "R" );
1383        param->setType( "float" );
1384
1385        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1386        param->setName( "G" );
1387        param->setType( "float" );
1388
1389        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1390        param->setName( "B" );
1391        param->setType( "float" );
1392
1393        if ( size == 4 )
1394        {
1395            param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1396            param->setName( "A" );
1397            param->setType( "float" );
1398        }
1399
1400    }
1401    else if ( uv )
1402    {
1403        const char * const type = "float";
1404
1405        acc->setStride( size );
1406        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1407        param->setName( "S" );
1408        param->setType( type );
1409
1410        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1411        param->setName( "T" );
1412        param->setType( type );
1413
1414        if ( size >=3 )
1415        {
1416            param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1417            param->setName( "P" );
1418            param->setType( type );
1419        }
1420    }
1421    else
1422    {
1423        const char * const type = "float";
1424        acc->setStride( size );
1425        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1426        param->setName( "X" );
1427        param->setType( type );
1428
1429        param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1430        param->setName( "Y" );
1431        param->setType( type );
1432
1433        if ( size >=3 )
1434        {
1435            param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1436            param->setName( "Z" );
1437            param->setType( type );
1438
1439            if ( size == 4 )
1440            {
1441                param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
1442                param->setName( "W" );
1443                param->setType( type );
1444            }
1445        }
1446    }
1447
1448    return src;
1449}
1450
1451template < typename Ty >
1452Ty *daeWriter::createPrimGroup( daeString type, domMesh *mesh, domSource *norm, domSource *color, const std::vector< domSource* > &texcoord )
1453{
1454    unsigned int offset = 0;
1455    Ty *retVal = daeSafeCast< Ty >( mesh->add( type ) );
1456    domInputLocalOffset *ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) );
1457    ilo->setOffset( offset++ );
1458    ilo->setSemantic( COMMON_PROFILE_INPUT_VERTEX );
1459    std::string url = "#" + std::string(mesh->getVertices()->getId());
1460    ilo->setSource( url.c_str() );
1461    if ( norm != NULL )
1462    {
1463        ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) );
1464        ilo->setOffset( offset++ );
1465        ilo->setSemantic( COMMON_PROFILE_INPUT_NORMAL );
1466        url = "#" + std::string( norm->getId() );
1467        ilo->setSource( url.c_str() );
1468    }
1469    if ( color != NULL )
1470    {
1471        ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) );
1472        ilo->setOffset( offset++ );
1473        ilo->setSemantic( COMMON_PROFILE_INPUT_COLOR );
1474        url = "#" + std::string( color->getId() );
1475        ilo->setSource( url.c_str() );
1476    }
1477    for ( unsigned int i = 0; i < texcoord.size(); i++ )
1478    {
1479        ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) );
1480        ilo->setOffset( offset++ );
1481        ilo->setSemantic( COMMON_PROFILE_INPUT_TEXCOORD );
1482        ilo->setSet( i );
1483        url = "#" + std::string( texcoord[i]->getId() );
1484        ilo->setSource( url.c_str() );
1485    }
1486
1487    return retVal;
1488}
Note: See TracBrowser for help on using the browser.