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

Revision 13531, 59.2 kB (checked in by robert, 37 hours ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

  • 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 BIND_PER_PRIMITIVE remain
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.