changed: gcc8 base update
[opensg.git] / Source / System / FileIO / Collada / OSGColladaGeometry.cpp
blob334ea1e2860164c534bb46f32a1c037a89f5f5d3
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2009 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
40 #pragma GCC diagnostic ignored "-Wold-style-cast"
41 #endif
43 #include "OSGColladaGeometry.h"
45 #if defined(OSG_WITH_COLLADA) || defined(OSG_DO_DOC)
47 #include "OSGColladaLog.h"
48 #include "OSGColladaGlobal.h"
49 #include "OSGColladaInstanceGeometry.h"
50 #include "OSGColladaInstanceEffect.h"
51 #include "OSGColladaNode.h"
52 #include "OSGColladaSource.h"
53 #include "OSGColladaExtraHandler.h"
54 #include "OSGColladaHandlerFactory.h"
56 #include "OSGGroup.h"
57 #include "OSGTypedGeoVectorProperty.h"
58 #include "OSGTypedGeoIntegralProperty.h"
59 #include "OSGNameAttachment.h"
60 #include "OSGPrimeMaterial.h"
62 #include <dom/domGeometry.h>
63 #include <dom/domMesh.h>
64 #include <dom/domSource.h>
65 #include <dom/domLines.h>
66 #include <dom/domLinestrips.h>
67 #include <dom/domPolygons.h>
68 #include <dom/domPolylist.h>
69 #include <dom/domTriangles.h>
70 #include <dom/domTrifans.h>
71 #include <dom/domTristrips.h>
73 OSG_BEGIN_NAMESPACE
75 ColladaInstInfoTransitPtr
76 ColladaGeometry::ColladaGeometryInstInfo::create(
77 ColladaNode *colInstParent, ColladaInstanceGeometry *colInst,
78 Node *parentN )
80 OSG_ASSERT(colInstParent != NULL);
81 OSG_ASSERT(colInst != NULL);
83 return ColladaInstInfoTransitPtr(
84 new ColladaGeometryInstInfo(colInstParent, colInst, parentN));
87 void
88 ColladaGeometry::ColladaGeometryInstInfo::process(void)
90 Node *geoInstN = dynamic_cast<Node *>(
91 getColInst()->getTargetElem()->createInstance(this));
93 getParentNode()->addChild(geoInstN);
96 ColladaGeometry::ColladaGeometryInstInfo::ColladaGeometryInstInfo(
97 ColladaNode *colInstParent, ColladaInstanceGeometry *colInst,
98 Node *parentN )
100 : Inherited(colInstParent, colInst)
101 , _parentN (parentN )
105 ColladaGeometry::ColladaGeometryInstInfo::~ColladaGeometryInstInfo(void)
109 /*---------------------------------------------------------------------------*/
111 ColladaGeometry::PropInfo::PropInfo(void)
112 : _semantic()
113 , _set ()
114 , _prop (NULL)
118 ColladaGeometry::PropInfo::PropInfo(const PropInfo &source)
119 : _semantic(source._semantic)
120 , _set (source._set)
121 , _prop (source._prop)
125 /*---------------------------------------------------------------------------*/
127 ColladaElementRegistrationHelper ColladaGeometry::_regHelper(
128 &ColladaGeometry::create, "geometry");
130 ColladaElementTransitPtr
131 ColladaGeometry::create(daeElement *elem, ColladaGlobal *global)
133 return ColladaElementTransitPtr(new ColladaGeometry(elem, global));
136 void
137 ColladaGeometry::setDoubleSided(bool value)
139 _doubleSided = value;
142 void
143 ColladaGeometry::read(ColladaElement *colElemParent)
145 domGeometryRef geometry = getDOMElementAs<domGeometry>();
146 domMeshRef mesh = geometry->getMesh();
148 OSG_COLLADA_LOG(("ColladaGeometry::read id [%s]\n",
149 geometry->getId()));
151 if(mesh == NULL)
153 SWARNING << "ColladaGeometry::read: No <mesh>" << std::endl;
154 return;
157 readMesh(mesh);
159 const domExtra_Array &extras = geometry->getExtra_array();
161 if(extras.getCount() != 0 && _extraHandlers.size() != 0)
163 for(UInt32 i = 0; i < extras.getCount(); ++i)
165 ExtraHandlerStoreIt ehIt = _extraHandlers.begin();
166 ExtraHandlerStoreConstIt ehEnd = _extraHandlers.end ();
168 for(; ehIt != ehEnd; ++ehIt)
170 (*ehIt)->readGeometryExtraElements(this, extras[i]);
177 Node *
178 ColladaGeometry::createInstance(ColladaInstInfo *colInstInfo)
180 typedef ColladaInstanceGeometry::MaterialMap ColMaterialMap;
181 typedef ColladaInstanceGeometry::MaterialMapConstIt ColMaterialMapConstIt;
183 domGeometryRef geometry = getDOMElementAs<domGeometry>();
184 NodeUnrecPtr groupN = makeCoredNode<Group>();
186 OSG_COLLADA_LOG(("ColladaGeometry::createInstance id [%s]\n",
187 geometry->getId()));
189 if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
190 geometry->getName() != NULL )
192 setName(groupN, geometry->getName());
195 ColladaInstanceGeometryRefPtr colInstGeo =
196 dynamic_cast<ColladaInstanceGeometry *>(colInstInfo->getColInst());
197 const ColMaterialMap &matMap =
198 colInstGeo->getMaterialMap();
200 // iterate over all parts of geometry
201 GeoStoreIt gsIt = _geoStore.begin();
202 GeoStoreIt gsEnd = _geoStore.end ();
204 for(; gsIt != gsEnd; ++gsIt)
206 OSG_ASSERT(gsIt->_propStore.size() == gsIt->_indexStore.size());
208 // find the material associated with the geometry's material symbol
209 ColMaterialMapConstIt mmIt = matMap.find(gsIt->_matSymbol);
210 std::string matTarget;
212 if(mmIt != matMap.end())
214 matTarget = mmIt->second->getTarget();
217 // check if the geometry was already used with that material
219 GeometryUnrecPtr geo = NULL;
220 InstanceMapConstIt instIt = gsIt->_instMap.find(matTarget);
222 if(instIt != gsIt->_instMap.end())
224 // reuse geometry
226 geo = dynamic_pointer_cast<Geometry>(
227 getInstStore()[instIt->second]);
229 getGlobal()->getStatCollector()->getElem(
230 ColladaGlobal::statNGeometryUsed)->inc();
232 else
234 // create new geometry
236 geo = Geometry::create();
238 getGlobal()->getStatCollector()->getElem(
239 ColladaGlobal::statNGeometryCreated)->inc();
241 geo->setLengths(gsIt->_lengths);
242 geo->setTypes (gsIt->_types );
244 handleBindMaterial(*gsIt, geo, colInstGeo);
246 // record the instantiation of the geometry with the
247 // material for reuse
248 gsIt->_instMap.insert(
249 InstanceMap::value_type(matTarget, UInt32(getInstStore().size())));
251 editInstStore().push_back(geo);
254 NodeUnrecPtr geoN = makeNodeFor(geo);
256 groupN->addChild(geoN);
259 // if there is only one child remove the group
260 if(groupN->getNChildren() == 1)
262 Node *geoN = groupN->getChild(0);
264 groupN->setCore(geoN->getCore());
265 geoN ->setCore(NULL );
267 groupN->clearChildren();
270 // store the generated group node
271 editInstStore().push_back(groupN);
273 return groupN;
276 ColladaGeometry::ColladaGeometry(daeElement *elem, ColladaGlobal *global)
277 : Inherited (elem, global)
278 , _sourceMap()
279 , _geoStore ()
280 , _doubleSided (false)
281 , _extraHandlers()
283 ColladaHandlerFactory::the()->createExtraHandlers(_extraHandlers);
286 ColladaGeometry::~ColladaGeometry(void)
288 _extraHandlers.clear();
291 void
292 ColladaGeometry::readMesh(domMesh *mesh)
294 readSources(mesh->getSource_array());
296 const domLines_Array &linesArray = mesh->getLines_array();
298 for(UInt32 i = 0; i < linesArray.getCount(); ++i)
300 readLines(mesh, linesArray[i]);
303 const domLinestrips_Array &lineStripsArray = mesh->getLinestrips_array();
305 for(UInt32 i = 0; i < lineStripsArray.getCount(); ++i)
307 readLineStrips(mesh, lineStripsArray[i]);
310 const domPolygons_Array &polygonsArray = mesh->getPolygons_array();
312 for(UInt32 i = 0; i < polygonsArray.getCount(); ++i)
314 readPolygons(mesh, polygonsArray[i]);
316 const domPolylist_Array &polyListArray = mesh->getPolylist_array();
318 for(UInt32 i = 0; i < polyListArray.getCount(); ++i)
320 readPolyList(mesh, polyListArray[i]);
323 const domTriangles_Array &triArray = mesh->getTriangles_array();
325 for(UInt32 i = 0; i < triArray.getCount(); ++i)
327 readTriangles(mesh, triArray[i]);
330 const domTrifans_Array &triFansArray = mesh->getTrifans_array();
332 for(UInt32 i = 0; i < triFansArray.getCount(); ++i)
334 readTriFans(mesh, triFansArray[i]);
337 const domTristrips_Array &triStripsArray = mesh->getTristrips_array();
339 for(UInt32 i = 0; i < triStripsArray.getCount(); ++i)
341 readTriStrips(mesh, triStripsArray[i]);
345 void
346 ColladaGeometry::readSources(const domSource_Array &sources)
348 for(UInt32 i = 0; i < sources.getCount(); ++i)
350 ColladaSourceRefPtr colSource =
351 getUserDataAs<ColladaSource>(sources[i]);
353 if(colSource == NULL)
355 colSource = dynamic_pointer_cast<ColladaSource>(
356 ColladaElementFactory::the()->create(sources[i], getGlobal()));
358 colSource->read(this);
361 _sourceMap.insert(
362 SourceMap::value_type(sources[i]->getId(), colSource));
366 void
367 ColladaGeometry::readLines(domMesh *mesh, domLines *lines)
369 OSG_COLLADA_LOG(("ColladaGeometry::readLines\n"));
371 const domInputLocal_Array &vertInputs =
372 mesh->getVertices()->getInput_array();
373 const domInputLocalOffset_Array &inputs =
374 lines ->getInput_array();
376 IndexStore idxStore;
377 UInt32 geoIdx = setupGeometry(vertInputs, inputs,
378 lines->getMaterial(), idxStore);
380 const domListOfUInts &pList = lines->getP()->getValue();
381 UInt32 currIdx = 0;
382 UInt32 length = 0;
384 for(UInt32 i = 0; i < pList.getCount(); ++i)
386 idxStore[currIdx]->push_back(pList[i]);
388 ++currIdx;
390 if(currIdx == idxStore.size())
392 currIdx = 0;
393 ++length;
397 OSG_COLLADA_LOG(("ColladaGeometry::readLines: material symbol [%s] "
398 "vertices [%d]\n",
399 (lines->getMaterial() != NULL ? lines->getMaterial() : ""),
400 length));
402 _geoStore[geoIdx]._types ->push_back(GL_LINES);
403 _geoStore[geoIdx]._lengths->push_back(length );
405 // remove empty geometry
406 if(length == 0)
408 SWARNING << "ColladaGeometry::readLines: Empty <lines> with material ["
409 << (lines->getMaterial() != NULL ? lines->getMaterial() : "")
410 << "]." << std::endl;
412 _geoStore.erase(_geoStore.begin() + geoIdx);
416 void
417 ColladaGeometry::readLineStrips(domMesh *mesh, domLinestrips *lineStrips)
419 OSG_COLLADA_LOG(("ColladaGeometry::readLineStrips\n"));
421 const domInputLocal_Array &vertInputs =
422 mesh->getVertices()->getInput_array();
423 const domInputLocalOffset_Array &inputs =
424 lineStrips ->getInput_array();
426 IndexStore idxStore;
427 UInt32 geoIdx = setupGeometry(vertInputs, inputs,
428 lineStrips->getMaterial(), idxStore);
430 const domP_Array &pArray = lineStrips->getP_array();
431 UInt32 currIdx = 0;
432 UInt32 length = 0;
433 UInt32 verts = 0;
435 for(UInt32 i = 0; i < pArray.getCount(); ++i)
437 const domListOfUInts &pList = pArray[i]->getValue();
439 for(UInt32 j = 0; j < pList.getCount(); ++j)
441 idxStore[currIdx]->push_back(pList[j]);
443 ++currIdx;
445 if(currIdx == idxStore.size())
447 currIdx = 0;
448 ++length;
452 // only add non-empty line strip
453 if(length > 0)
455 _geoStore[geoIdx]._types ->push_back(GL_LINE_STRIP);
456 _geoStore[geoIdx]._lengths->push_back(length );
459 verts += length;
460 length = 0;
463 OSG_COLLADA_LOG(("ColladaGeometry::readLineStrips: material symbol [%s] "
464 "vertices [%d] strips [%" PRIUSize "]\n",
465 (lineStrips->getMaterial() != NULL ?
466 lineStrips->getMaterial() : ""),
467 verts,
468 _geoStore[geoIdx]._lengths->size()));
470 // remove empty geometry
471 if(verts == 0)
473 SWARNING << "ColladaGeometry::readLineStrips: Empty <linestrips> "
474 << "with material ["
475 << (lineStrips->getMaterial() != NULL ?
476 lineStrips->getMaterial() : "")
477 << "]." << std::endl;
479 _geoStore.erase(_geoStore.begin() + geoIdx);
483 void
484 ColladaGeometry::readPolygons(domMesh *mesh, domPolygons *polygons)
486 OSG_COLLADA_LOG(("ColladaGeometry::readPolygons\n"));
488 const domInputLocal_Array &vertInputs =
489 mesh->getVertices()->getInput_array();
490 const domInputLocalOffset_Array &inputs =
491 polygons ->getInput_array();
493 IndexStore idxStore;
494 UInt32 geoIdx = setupGeometry(vertInputs, inputs,
495 polygons->getMaterial(), idxStore);
497 const domP_Array &pArray = polygons->getP_array();
498 UInt32 currIdx = 0;
499 UInt32 length = 0;
500 UInt32 verts = 0;
502 for(UInt32 i = 0; i < pArray.getCount(); ++i)
504 const domListOfUInts &pList = pArray[i]->getValue();
506 for(UInt32 j = 0; j < pList.getCount(); ++j)
508 idxStore[currIdx]->push_back(pList[j]);
510 ++currIdx;
512 if(currIdx == idxStore.size())
514 currIdx = 0;
515 ++length;
519 // only add non-empty polygon
520 if(length > 0)
522 _geoStore[geoIdx]._types ->push_back(GL_POLYGON);
523 _geoStore[geoIdx]._lengths->push_back(length );
526 verts += length;
527 length = 0;
530 const domPolygons::domPh_Array &phArray = polygons->getPh_array();
531 currIdx = 0;
532 length = 0;
534 for(UInt32 i = 0; i < phArray.getCount(); ++i)
536 // we only get the <p> elements (polygons) and skip the <h> elements
537 // (holes)
539 const domListOfUInts &pList = phArray[i]->getP()->getValue();
541 for(UInt32 j = 0; j < pList.getCount(); ++j)
543 idxStore[currIdx]->push_back(pList[j]);
545 ++currIdx;
547 if(currIdx == idxStore.size())
549 currIdx = 0;
550 ++length;
554 // only add non-empty polygon
555 if(length > 0)
557 _geoStore[geoIdx]._types ->push_back(GL_POLYGON);
558 _geoStore[geoIdx]._lengths->push_back(length );
561 verts += length;
562 length = 0;
564 if(phArray[i]->getH_array().getCount() > 0)
566 SWARNING << "ColladaGeometry::readPolygon: Ignoring ["
567 << phArray[i]->getH_array().getCount()
568 << "] holes in polygon." << std::endl;
572 OSG_COLLADA_LOG(("ColladaGeometry::readPolygons: material symbol [%s] "
573 "vertices [%d] polygons [%" PRIUSize "]\n",
574 (polygons->getMaterial() != NULL ?
575 polygons->getMaterial() : ""), verts,
576 _geoStore[geoIdx]._lengths->size()));
578 // remove empty geometry
579 if(verts == 0)
581 SWARNING << "ColladaGeometry::readPolygons: Empty <polygons> "
582 << "with material ["
583 << (polygons->getMaterial() != NULL ?
584 polygons->getMaterial() : "")
585 << "]." << std::endl;
587 _geoStore.erase(_geoStore.begin() + geoIdx);
591 void
592 ColladaGeometry::readPolyList(domMesh *mesh, domPolylist *polyList)
594 OSG_COLLADA_LOG(("ColladaGeometry::readPolyList\n"));
596 const domInputLocal_Array &vertInputs =
597 mesh->getVertices()->getInput_array();
598 const domInputLocalOffset_Array &inputs =
599 polyList ->getInput_array();
601 if(polyList->getVcount() == NULL)
603 SWARNING << "ColladaGeometry::readPolyList: Empty <vcount> "
604 << std::endl;
606 return;
609 IndexStore idxStore;
610 UInt32 geoIdx = setupGeometry(vertInputs, inputs,
611 polyList->getMaterial(), idxStore);
613 const domListOfUInts &pList = polyList->getP ()->getValue();
614 const domListOfUInts &vList = polyList->getVcount()->getValue();
615 UInt32 currIdx = 0;
616 UInt32 verts = 0;
617 UInt32 prims = 0;
618 bool useQuads = true;
620 std::vector<bool> vIdxValid;
622 vIdxValid.resize(idxStore.size(), true);
624 // check if all polys are quads
625 for(UInt32 i = 0; i < vList.getCount(); ++i)
627 if(vList[i] != 4)
629 useQuads = false;
630 break;
634 OSG_COLLADA_LOG(("ColladaGeometry::readPolyList: useQuads [%d]\n",
635 useQuads));
637 if(useQuads == true)
639 for(UInt32 i = 0; i < 4 * vList.getCount(); ++i)
641 for(UInt32 k = 0; k < idxStore.size(); ++k)
643 idxStore[k]->push_back(pList[currIdx]);
645 if(pList[currIdx] == domUint(-1))
647 vIdxValid[k] = false;
650 ++currIdx;
654 // only add non-empty quads
655 if(vList.getCount() > 0)
657 _geoStore[geoIdx]._types ->push_back(GL_QUADS );
658 _geoStore[geoIdx]._lengths->push_back(4 * vList.getCount());
661 verts += 4 * UInt32(vList.getCount());
662 prims += UInt32(vList.getCount());
664 else
666 for(UInt32 i = 0; i < vList.getCount(); ++i)
668 for(UInt32 j = 0; j < vList[i]; ++j)
670 for(UInt32 k = 0; k < idxStore.size(); ++k)
672 idxStore[k]->push_back(pList[currIdx]);
674 if(pList[currIdx] == domUint(-1))
676 vIdxValid[k] = false;
679 ++currIdx;
683 // only add non-empty polygons
684 if(vList[i] > 0)
686 _geoStore[geoIdx]._types ->push_back(GL_POLYGON);
687 _geoStore[geoIdx]._lengths->push_back(vList[i] );
690 verts += vList[i];
691 prims += 1;
695 this->validateIndices(geoIdx, vIdxValid, idxStore);
697 OSG_COLLADA_LOG(("ColladaGeometry::readPolyList: material symbol [%s] "
698 "vertices [%d] %s [%d]\n",
699 (polyList->getMaterial() != NULL ?
700 polyList->getMaterial() : ""),
701 verts,
702 (useQuads == true ? "quads" : "polygons"), prims));
704 // remove empty geometry
705 if(verts == 0)
707 SWARNING << "ColladaGeometry::readPolyList: Empty <polylist> "
708 << "with material ["
709 << (polyList->getMaterial() != NULL ?
710 polyList->getMaterial() : "")
711 << "]." << std::endl;
713 _geoStore.erase(_geoStore.begin() + geoIdx);
717 void ColladaGeometry::validateIndices( UInt32 geoIdx,
718 const std::vector<bool> &vIdxValid,
719 const IndexStore idxStore)
721 if(getGlobal()->getOptions()->getTryMergeInvalidIndices() == false)
723 for(SizeT i = 0; i < vIdxValid.size(); ++i)
725 if(vIdxValid[i] == false)
726 idxStore[i]->clear();
729 return;
733 typedef std::pair<GeoIntegralProperty *,
734 GeoIntegralPropertyUnrecPtr *> IndexPair;
736 std::vector<IndexPair> vIdxPairs;
738 bool hasInvalidIndices = false;
739 bool bMergable = true;
741 for(SizeT i = 0; i < vIdxValid.size(); ++i)
743 if(vIdxValid[i] == false)
745 vIdxPairs.push_back(
746 std::make_pair(
747 idxStore[i],
748 static_cast<GeoIntegralPropertyUnrecPtr *>(NULL)));
750 if(vIdxPairs[0].first->size() != idxStore[i]->size())
752 bMergable = false;
755 hasInvalidIndices = true;
759 if(hasInvalidIndices == false)
760 return;
762 if(bMergable == false)
764 for(SizeT i = 0; i < vIdxValid.size(); ++i)
766 if(vIdxValid[i] == false)
767 idxStore[i]->clear();
770 return;
774 for(SizeT i = 0; i < vIdxPairs.size(); ++i)
776 for(SizeT j = 0; j < _geoStore[geoIdx]._indexStore.size(); ++j)
778 if(vIdxPairs[i].first == _geoStore[geoIdx]._indexStore[j])
780 vIdxPairs[i].second = &_geoStore[geoIdx]._indexStore[j];
781 break;
786 GeoUInt32PropertyUnrecPtr pMergedIdx = GeoUInt32Property::create();
788 pMergedIdx->resize(vIdxPairs[0].first->size());
790 bool bMergeSucceeded = true;
792 for(SizeT i = 0; i < pMergedIdx->size(); ++i)
794 UInt32 iVal = UInt32(domUint(-1));
796 for(SizeT j = 0; j < vIdxPairs.size(); ++j)
798 if(vIdxPairs[j].first->getValue(i) != UInt32(-1))
800 if(iVal == UInt32(-1))
802 iVal = vIdxPairs[j].first->getValue(i);
804 else
806 if(iVal != vIdxPairs[j].first->getValue(i))
808 bMergeSucceeded = false;
814 if(iVal == UInt32(-1))
816 bMergeSucceeded = false;
818 else
820 pMergedIdx->setValue(iVal, i);
823 if(bMergeSucceeded == false)
824 break;
827 if(bMergeSucceeded == true)
829 for(SizeT i = 0; i < vIdxPairs.size(); ++i)
831 (*(vIdxPairs[i].second)) = pMergedIdx;
834 return;
837 for(SizeT i = 0; i < vIdxValid.size(); ++i)
839 if(vIdxValid[i] == false)
840 idxStore[i]->clear();
844 void
845 ColladaGeometry::readTriangles(domMesh *mesh, domTriangles *triangles)
847 OSG_COLLADA_LOG(("ColladaGeometry::readTriangles\n"));
849 const domInputLocal_Array &vertInputs =
850 mesh->getVertices()->getInput_array();
851 const domInputLocalOffset_Array &inputs =
852 triangles ->getInput_array();
854 IndexStore idxStore;
855 UInt32 geoIdx = setupGeometry(vertInputs, inputs,
856 triangles->getMaterial(), idxStore);
858 const domListOfUInts &pList = triangles->getP()->getValue();
859 UInt32 currIdx = 0;
860 UInt32 length = 0;
862 std::vector<bool> vIdxValid;
864 vIdxValid.resize(idxStore.size(), true);
866 for(UInt32 i = 0; i < pList.getCount(); ++i)
868 domUint uiIdx = pList[i];
870 if(uiIdx == domUint(-1))
872 vIdxValid[currIdx] = false;
875 idxStore[currIdx]->push_back(uiIdx);
877 ++currIdx;
879 if(currIdx == idxStore.size())
881 currIdx = 0;
882 ++length;
886 this->validateIndices(geoIdx, vIdxValid, idxStore);
888 _geoStore[geoIdx]._types ->push_back(GL_TRIANGLES);
889 _geoStore[geoIdx]._lengths->push_back(length );
891 OSG_COLLADA_LOG(("ColladaGeometry::readTriangles: material symbol [%s] "
892 "vertices [%d] triangles [%d]\n",
893 (triangles->getMaterial() != NULL ?
894 triangles->getMaterial() : ""),
895 length, length/3));
897 if(length == 0)
899 SWARNING << "ColladaGeometry::readTriangles: Empty <triangles> "
900 << "with material ["
901 << (triangles->getMaterial() != NULL ?
902 triangles->getMaterial() : "")
903 << "]." << std::endl;
905 _geoStore.erase(_geoStore.begin() + geoIdx);
909 void
910 ColladaGeometry::readTriFans(domMesh *mesh, domTrifans *triFans)
912 OSG_COLLADA_LOG(("ColladaGeometry::readTriFans\n"));
914 const domInputLocal_Array &vertInputs =
915 mesh->getVertices()->getInput_array();
916 const domInputLocalOffset_Array &inputs =
917 triFans ->getInput_array();
919 IndexStore idxStore;
920 UInt32 geoIdx = setupGeometry(vertInputs, inputs,
921 triFans->getMaterial(), idxStore);
923 const domP_Array &pArray = triFans->getP_array();
924 UInt32 currIdx = 0;
925 UInt32 length = 0;
926 UInt32 verts = 0;
928 for(UInt32 i = 0; i < pArray.getCount(); ++i)
930 const domListOfUInts &pList = pArray[i]->getValue();
932 for(UInt32 j = 0; j < pList.getCount(); ++j)
934 idxStore[currIdx]->push_back(pList[j]);
936 ++currIdx;
938 if(currIdx == idxStore.size())
940 currIdx = 0;
941 ++length;
945 // only add non-empty tri fans
946 if(length > 0)
948 _geoStore[geoIdx]._types ->push_back(GL_TRIANGLE_FAN);
949 _geoStore[geoIdx]._lengths->push_back(length );
952 verts += length;
953 length = 0;
956 OSG_COLLADA_LOG(("ColladaGeometry::readTriFans: material symbol [%s] "
957 "vertices [%d] fans [%" PRIUSize "]\n",
958 (triFans->getMaterial() != NULL ?
959 triFans->getMaterial() : ""),
960 verts,
961 _geoStore[geoIdx]._lengths->size()));
963 // remove empty geometry
964 if(verts == 0)
966 SWARNING << "ColladaGeometry::readTriFans: Empty <trifans> "
967 << "with material ["
968 << (triFans->getMaterial() != NULL ?
969 triFans->getMaterial() : "")
970 << "]." << std::endl;
972 _geoStore.erase(_geoStore.begin() + geoIdx);
976 void
977 ColladaGeometry::readTriStrips(domMesh *mesh, domTristrips *triStrips)
979 OSG_COLLADA_LOG(("ColladaGeometry::readTriStrips\n"));
981 const domInputLocal_Array &vertInputs =
982 mesh->getVertices()->getInput_array();
983 const domInputLocalOffset_Array &inputs =
984 triStrips ->getInput_array();
986 IndexStore idxStore;
987 UInt32 geoIdx = setupGeometry(vertInputs, inputs,
988 triStrips->getMaterial(), idxStore);
990 const domP_Array &pArray = triStrips->getP_array();
991 UInt32 currIdx = 0;
992 UInt32 length = 0;
993 UInt32 verts = 0;
995 for(UInt32 i = 0; i < pArray.getCount(); ++i)
997 const domListOfUInts &pList = pArray[i]->getValue();
999 for(UInt32 j = 0; j < pList.getCount(); ++j)
1001 idxStore[currIdx]->push_back(pList[j]);
1003 ++currIdx;
1005 if(currIdx == idxStore.size())
1007 currIdx = 0;
1008 ++length;
1012 // only add non-empty tri strip
1013 if(length > 0)
1015 _geoStore[geoIdx]._types ->push_back(GL_TRIANGLE_STRIP);
1016 _geoStore[geoIdx]._lengths->push_back(length );
1019 verts += length;
1020 length = 0;
1023 OSG_COLLADA_LOG(("ColladaGeometry::readTriStrips: material symbol [%s] "
1024 "vertices [%d] strips [%" PRIUSize "]\n",
1025 (triStrips->getMaterial() != NULL ?
1026 triStrips->getMaterial() : ""),
1027 verts,
1028 _geoStore[geoIdx]._lengths->size()));
1030 // remove empty geometry
1031 if(verts == 0)
1033 SWARNING << "ColladaGeometry::readTriStrips: Empty <tristrips> "
1034 << "with material ["
1035 << (triStrips->getMaterial() != NULL ?
1036 triStrips->getMaterial() : "")
1037 << "]." << std::endl;
1039 _geoStore.erase(_geoStore.begin() + geoIdx);
1043 UInt32
1044 ColladaGeometry::mapSemantic(
1045 const std::string &semantic, UInt32 set, UInt32 geoIdx)
1047 UInt32 propIdx = Geometry::MaxAttribs;
1049 if(semantic == "POSITION")
1051 propIdx = Geometry::PositionsIndex;
1053 else if(semantic == "NORMAL")
1055 propIdx = Geometry::NormalsIndex;
1057 else if(semantic == "TEXCOORD")
1059 if(set <= Geometry::TexCoords7Index)
1061 propIdx = Geometry::TexCoordsIndex + set;
1063 else
1065 SWARNING << "ColladaGeometry::mapSemantic: TEXCOORD semantic has "
1066 << "out of range set [" << set << "]"
1067 << std::endl;
1070 else if(semantic == "TANGENT")
1072 propIdx = Geometry::TexCoords6Index;
1074 else if(semantic == "BINORMAL")
1076 propIdx = Geometry::TexCoords7Index;
1078 else
1080 OSG_COLLADA_LOG(("ColladaGeometry::mapSemantic: Unknown semantic [%s] "
1081 "set [%d]\n", semantic.c_str(), set));
1084 OSG_COLLADA_LOG(("ColladaGeometry::mapSemantic: semantic [%s] "
1085 "set [%d] -> propIdx [%d]\n",
1086 semantic.c_str(), set, propIdx));
1088 return propIdx;
1091 void
1092 ColladaGeometry::setupProperty(
1093 UInt32 geoIdx, UInt32 propIdx, const std::string &semantic, UInt32 set,
1094 const std::string &sourceId, GeoIntegralProperty *idxProp )
1096 // resize
1097 _geoStore[geoIdx]._propStore .resize(
1098 osgMax<UInt32>(UInt32(_geoStore[geoIdx]._propStore .size()),
1099 propIdx + 1),
1100 PropInfo() );
1101 _geoStore[geoIdx]._indexStore.resize(
1102 osgMax<UInt32>(UInt32(_geoStore[geoIdx]._indexStore.size()),
1103 propIdx + 1),
1104 NULL );
1106 // set index for the property
1107 _geoStore[geoIdx]._indexStore[propIdx] = idxProp;
1109 // get property from source
1110 SourceMapConstIt smIt = _sourceMap.find(sourceId);
1111 GeoVectorProperty *prop = NULL;
1113 if(smIt != _sourceMap.end())
1115 prop = smIt->second->getProperty(semantic);
1117 else
1119 SFATAL << "ColladaGeometry::setupProperty: "
1120 << "No <source> with id [" << sourceId << "] found."
1121 << std::endl;
1124 // set property
1125 _geoStore[geoIdx]._propStore[propIdx]._semantic = semantic;
1126 _geoStore[geoIdx]._propStore[propIdx]._set = set;
1127 _geoStore[geoIdx]._propStore[propIdx]._prop = prop;
1130 UInt32
1131 ColladaGeometry::setupGeometry(const domInputLocal_Array &vertInputs,
1132 const domInputLocalOffset_Array &inputs,
1133 xsNCName matSymbol,
1134 IndexStore &idxStore )
1136 OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry\n"));
1138 typedef std::vector<UInt32> UnhandledStore;
1139 typedef UnhandledStore::const_iterator UnhandledStoreConstIt;
1141 Int32 vertInputIndex = -1; // <input> with sem "VERTEX"
1142 UnhandledStore unhandledVertInputs;
1143 UnhandledStore unhandledInputs;
1145 UInt32 geoIdx = UInt32(_geoStore.size());
1146 _geoStore.push_back(GeoInfo());
1148 if(matSymbol != NULL)
1150 _geoStore[geoIdx]._matSymbol = matSymbol;
1152 else
1154 SWARNING << "ColladaGeometry::setupGeometry: "
1155 << "Found empty material symbol." << std::endl;
1158 for(UInt32 i = 0; i < inputs.getCount(); ++i)
1160 std::string semantic = inputs[i]->getSemantic();
1161 UInt32 set = inputs[i]->getSet ();
1162 UInt32 offset = inputs[i]->getOffset ();
1163 std::string sourceId = inputs[i]->getSource ().id();
1165 OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: input [%d] "
1166 "semantic [%s] set [%d] offset [%d] - source [%s]\n",
1167 i, semantic.c_str(), set, offset, sourceId.c_str()));
1169 if(semantic == "VERTEX")
1171 // handle <input> tag with semantic "VERTEX"
1172 // by processing vertInputs, i.e. the <vertices> tag
1174 vertInputIndex = i;
1176 // all vertInputs use the same index - with the offset from the
1177 // <input> with semantic == VERTEX
1178 if(offset >= idxStore.size() || idxStore[offset] == NULL)
1180 OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: "
1181 "new index property for offset [%d]\n",
1182 offset));
1184 // new index
1185 idxStore.resize(
1186 osgMax<UInt32>(offset + 1, UInt32(idxStore.size())), NULL);
1187 idxStore[offset] = GeoUInt32Property::create();
1190 for(UInt32 j = 0; j < vertInputs.getCount(); ++j)
1192 semantic = vertInputs[j]->getSemantic();
1193 sourceId = vertInputs[j]->getSource ().id();
1195 OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: vertices [%d] "
1196 "semantic [%s] - source [%s]\n",
1197 j, semantic.c_str(), sourceId.c_str()));
1199 UInt32 propIdx = mapSemantic(semantic, 0, geoIdx);
1201 if(propIdx == Geometry::MaxAttribs)
1203 unhandledVertInputs.push_back(j);
1205 else
1207 setupProperty(geoIdx, propIdx, semantic, set, sourceId,
1208 idxStore[offset] );
1212 else
1214 // handle regular <input> tags
1216 if(offset >= idxStore.size() || idxStore[offset] == NULL)
1218 OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: "
1219 "new index property for offset [%d]\n",
1220 offset));
1222 // new index
1223 idxStore.resize(osgMax<UInt32>(offset + 1,
1224 UInt32(idxStore.size())), NULL);
1226 idxStore[offset] = GeoUInt32Property::create();
1229 UInt32 propIdx = mapSemantic(semantic, set, geoIdx);
1231 if(propIdx == Geometry::MaxAttribs)
1233 unhandledInputs.push_back(i);
1235 else
1237 setupProperty(geoIdx, propIdx, semantic, set, sourceId,
1238 idxStore[offset] );
1243 // some <inputs> could not be handled above because their
1244 // semantic was not recognized.
1245 // after everything else is set put them into free attribute
1246 // slots, starting at Geometry::TexCoordsIndex
1248 UnhandledStoreConstIt uhIt = unhandledVertInputs.begin();
1249 UnhandledStoreConstIt uhEnd = unhandledVertInputs.end ();
1251 for(; uhIt != uhEnd; ++uhIt)
1253 std::string semantic = vertInputs[*uhIt ]->getSemantic();
1254 UInt32 set = inputs [vertInputIndex]->getSet ();
1255 UInt32 offset = inputs [vertInputIndex]->getOffset ();
1256 std::string sourceId = vertInputs[*uhIt ]->getSource ().id();
1258 UInt32 propIdx = findFreePropertyIndex(geoIdx);
1260 OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: unhandled vertex "
1261 " <input> [%d] semantic [%s] set [%d] offset [%d] - "
1262 "source [%s] mapped to propIdx [%d]\n",
1263 *uhIt, semantic.c_str(), set, offset, sourceId.c_str(),
1264 propIdx));
1266 setupProperty(geoIdx, propIdx, semantic, set, sourceId,
1267 idxStore[offset] );
1270 uhIt = unhandledInputs.begin();
1271 uhEnd = unhandledInputs.end ();
1273 for(; uhIt != uhEnd; ++uhIt)
1275 std::string semantic = inputs[*uhIt]->getSemantic();
1276 UInt32 set = inputs[*uhIt]->getSet ();
1277 UInt32 offset = inputs[*uhIt]->getOffset ();
1278 std::string sourceId = inputs[*uhIt]->getSource ().id();
1280 UInt32 propIdx = findFreePropertyIndex(geoIdx);
1282 OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: unhandled <input> "
1283 "[%d] semantic [%s] set [%d] offset [%d] - "
1284 "source [%s] mapped to propIdx [%d]\n",
1285 *uhIt, semantic.c_str(), set, offset, sourceId.c_str(),
1286 propIdx));
1288 setupProperty(geoIdx, propIdx, semantic, set, sourceId,
1289 idxStore[offset] );
1292 #ifdef OSG_DEBUG
1293 // check for holes in idxStore - which is not supported
1294 IndexStoreConstIt idxIt = idxStore.begin();
1295 IndexStoreConstIt idxEnd = idxStore.end ();
1297 for(UInt32 i = 0; idxIt != idxEnd; ++idxIt, ++i)
1299 if(*idxIt == NULL)
1301 SWARNING << "ColladaGeometry::setupGeometry: idxStore contains "
1302 << "hole at [" << i << "]" << std::endl;
1305 #endif
1307 _geoStore[geoIdx]._lengths = GeoUInt32Property::create();
1308 _geoStore[geoIdx]._types = GeoUInt8Property ::create();
1310 return geoIdx;
1313 void
1314 ColladaGeometry::handleBindMaterial(
1315 const GeoInfo &geoInfo, Geometry *geo, ColladaInstanceGeometry *colInstGeo)
1317 typedef ColladaInstanceGeometry::MaterialMap ColMaterialMap;
1318 typedef ColladaInstanceGeometry::MaterialMapConstIt ColMaterialMapConstIt;
1320 const ColMaterialMap &matMap = colInstGeo->getMaterialMap();
1321 ColMaterialMapConstIt mmIt = matMap.find(geoInfo._matSymbol);
1322 Material *material = NULL;
1323 ColladaInstanceMaterial *colInstMat = NULL;
1324 ColladaInstanceEffect *colInstEffect = NULL;
1326 if(mmIt != matMap.end())
1328 colInstMat = mmIt->second;
1330 OSG_ASSERT(colInstMat != NULL);
1331 OSG_ASSERT(colInstMat->getTargetElem() != NULL);
1333 ColladaInstInfoRefPtr colInstInfo =
1334 ColladaMaterial::ColladaMaterialInstInfo::create(this, colInstMat);
1336 material =
1337 colInstMat->getTargetElem()->createInstance(colInstInfo);
1338 colInstEffect = colInstMat->getInstanceEffect();
1340 else
1342 SWARNING << "ColladaGeometry::handleBindMaterial: No material found "
1343 << "for symbol [" << geoInfo._matSymbol << "]."
1344 << std::endl;
1346 geo->setMaterial(getDefaultMaterial());
1347 return;
1350 const BindStore &bindStore = colInstMat->getBindStore ();
1351 const BindVertexStore &bindVertexStore = colInstMat->getBindVertexStore();
1353 PropStoreConstIt psIt = geoInfo._propStore .begin();
1354 PropStoreConstIt psEnd = geoInfo._propStore .end ();
1355 IndexStoreConstIt isIt = geoInfo._indexStore.begin();
1356 IndexStoreConstIt isEnd = geoInfo._indexStore.end ();
1358 // for every property in geoInfo we need to check if it gets remapped by a
1359 // <bind> or <bind_vertex_input>
1361 for(UInt32 i = 0; psIt != psEnd && isIt != isEnd; ++psIt, ++isIt, ++i)
1363 if(psIt->_prop == NULL || *isIt == NULL || (*isIt)->size() == 0)
1364 continue;
1366 bool handledProperty = false;
1367 UInt32 bindOffset = 0;
1368 UInt32 bindVertexOffset = 0;
1370 const BindInfo *bi = findBind (bindStore,
1371 psIt->_semantic,
1372 bindOffset );
1373 const BindVertexInfo *bvi = findBindVertex(bindVertexStore,
1374 psIt->_semantic,
1375 psIt->_set,
1376 bindVertexOffset);
1378 // there may be multiple consumers for a property, keep looping
1379 // until no more consumers are found
1380 while(bi != NULL || bvi != NULL)
1382 UInt32 mappedProp = i;
1384 if(bi != NULL && bvi != NULL)
1386 // is it a problem if there is a <bind> AND a
1387 // <bind_vertex_input> for the same property ??
1389 SWARNING << "ColladaGeometry::handleBindMaterial: "
1390 << "Found <bind> AND <bind_vertex_input> for "
1391 << "semantic [" << bi->semantic
1392 << "] target/inSemantic [" << bi->target << "/"
1393 << bvi->inSemantic << "] inSet [" << bvi->inSet
1394 << "]" << std::endl;
1397 if(bi != NULL)
1399 if(colInstEffect->findTC(bi->target, mappedProp) == true)
1401 OSG_COLLADA_LOG(("ColladaGeometry::handleBindMaterial: "
1402 "Resolved <bind> semantic [%s] "
1403 "target [%s] to property [%d]\n",
1404 bi->semantic.c_str(), bi->target.c_str(),
1405 mappedProp));
1407 geo->setProperty( psIt->_prop, mappedProp);
1408 geo->setIndex (*isIt, mappedProp);
1410 handledProperty = true;
1412 else
1414 SWARNING << "ColladaGeometry::handleBindMaterial: "
1415 << "Failed to resolve <bind> semantic ["
1416 << bi->semantic << "] target [" << bi->target
1417 << "]." << std::endl;
1420 else if(bvi != NULL)
1422 if(colInstEffect->findTC(bvi->semantic, mappedProp) == true)
1424 OSG_COLLADA_LOG(("ColladaGeometry::handleBindMaterial: "
1425 "Resolved <bind_vertex_input> "
1426 "inSemantic [%s] inSet [%d] semantic [%s] "
1427 "to property [%d]\n",
1428 bvi->inSemantic.c_str(), bvi->inSet,
1429 bvi->semantic.c_str(), mappedProp));
1431 geo->setProperty( psIt->_prop, mappedProp);
1432 geo->setIndex (*isIt, mappedProp);
1433 handledProperty = true;
1435 else
1437 SWARNING << "ColladaGeometry::handleBindMaterial: "
1438 << "Failed to resolve <bind_vertex_input> "
1439 << "inSemantic ["
1440 << bvi->inSemantic << "] inSet [" << bvi->inSet
1441 << "] semantic [" << bvi->semantic
1442 << "]." << std::endl;
1446 // find next consumers if any
1447 ++bindOffset;
1448 ++bindVertexOffset;
1450 bi = findBind (bindStore, psIt->_semantic,
1451 bindOffset );
1452 bvi = findBindVertex(bindVertexStore, psIt->_semantic,
1453 psIt->_set, bindVertexOffset);
1456 // Check for autodesk implicit channel mappings
1457 if(handledProperty == false)
1459 std::string szChannel;
1461 switch(i)
1463 case Geometry::TexCoordsIndex:
1464 szChannel = "CHANNEL0";
1465 break;
1466 case Geometry::TexCoords1Index:
1467 szChannel = "CHANNEL1";
1468 break;
1469 case Geometry::TexCoords2Index:
1470 szChannel = "CHANNEL2";
1471 break;
1472 case Geometry::TexCoords3Index:
1473 szChannel = "CHANNEL3";
1474 break;
1475 case Geometry::TexCoords4Index:
1476 szChannel = "CHANNEL4";
1477 break;
1478 case Geometry::TexCoords5Index:
1479 szChannel = "CHANNEL5";
1480 break;
1481 case Geometry::TexCoords6Index:
1482 szChannel = "CHANNEL6";
1483 break;
1484 case Geometry::TexCoords7Index:
1485 szChannel = "CHANNEL7";
1486 break;
1488 default:
1489 break;
1492 if(szChannel.empty() == false)
1494 UInt32 mappedProp = i;
1496 if(colInstEffect->findTC(szChannel, mappedProp) == true)
1498 OSG_COLLADA_LOG(("ColladaGeometry::handleBindMaterial: "
1499 "Resolved autodesk implicit semantic [%s] "
1500 "to property [%d]\n",
1501 szChannel.c_str(),
1502 mappedProp));
1504 geo->setProperty( psIt->_prop, mappedProp);
1505 geo->setIndex (*isIt, mappedProp);
1507 handledProperty = true;
1512 // if the property is not remapped by <bind> or <bind_vertex_input>
1513 // we just put it at the location it received at read time
1514 // this is for properties that are not of interest to the material
1515 // directly (e.g. positions, normals)
1516 if(handledProperty == false)
1518 OSG_COLLADA_LOG(("ColladaGeometry::handleBindMaterial: "
1519 "Setting property [%d] (semantic [%s] set [%d]) "
1520 "without <bind>/<bind_vertex_input> mapping.\n",
1521 i, psIt->_semantic.c_str(), psIt->_set));
1523 geo->setProperty( psIt->_prop, i);
1524 geo->setIndex (*isIt, i);
1528 // Clean up the texcood property indices by ensuring that if we have at
1529 // least one texture coordinate property, that it is assigned to the first
1530 // texture coordinate slot. This should be a safe assumption since we are
1531 // in the common profile.
1533 GeoVectorProperty *tex_coord0 = geo->getProperty(Geometry::TexCoordsIndex);
1535 if(NULL == tex_coord0)
1538 for(UInt16 idx = Geometry::TexCoords1Index;
1539 idx <= Geometry::TexCoords7Index;
1540 ++idx)
1542 GeoVectorProperty *tex_coord = geo->getProperty(idx);
1544 if (NULL != tex_coord)
1546 OSG_COLLADA_LOG(
1547 ("ColladaGeometry::handleBindMaterial: "
1548 "Manual switch texture coords from [%d] to [%d].\n",
1549 idx,
1550 Geometry::TexCoordsIndex));
1552 geo->setProperty(tex_coord, Geometry::TexCoordsIndex);
1553 geo->setProperty(NULL, idx);
1555 GeoIntegralProperty *index = geo->getIndex(idx);
1557 geo->setIndex(index, Geometry::TexCoordsIndex);
1558 geo->setIndex(NULL, idx);
1560 break;
1565 if(material != NULL)
1567 geo->setMaterial(material);
1569 else
1571 SWARNING << "ColladaGeometry::handleBindMaterial: No material created "
1572 << "for symbol [" << geoInfo._matSymbol << "]."
1573 << std::endl;
1575 geo->setMaterial(getDefaultMaterial());
1579 /*! Returns a &lt;bind&gt; (actually a BindInfo built from a &lt;bind&gt;)
1580 that has the given \a semantic. The search starts at the given \a offset to
1581 allow multiple &lt;bind&gt; with the same semantic to be found.
1583 const ColladaGeometry::BindInfo *
1584 ColladaGeometry::findBind(
1585 const BindStore &store, const std::string &semantic, UInt32 &offset)
1587 const BindInfo *retVal = NULL;
1589 for(UInt32 i = offset; i < store.size(); ++i)
1591 if(store[i].semantic == semantic)
1593 retVal = &store[i];
1594 offset = i;
1595 break;
1599 return retVal;
1602 /*! Returns a &lt;bind_vertex_input&gt; (actually a BindVertexInfo built from
1603 a &lt;bind_vertex_input&gt;) that has the given \a inSemantic and \a inSet.
1604 The search starts at the given \a offset to allow
1605 multiple &lt;bind_vertex_input&gt; with the same inSemantic/inSet to be
1606 found.
1608 const ColladaGeometry::BindVertexInfo *
1609 ColladaGeometry::findBindVertex(
1610 const BindVertexStore &store, const std::string &inSemantic,
1611 UInt32 inSet, UInt32 &offset )
1613 const BindVertexInfo *retVal = NULL;
1615 for(UInt32 i = offset; i < store.size(); ++i)
1617 if(store[i].inSemantic == inSemantic &&
1618 store[i].inSet == inSet )
1620 retVal = &store[i];
1621 offset = i;
1622 break;
1626 return retVal;
1628 UInt16
1629 ColladaGeometry::findFreePropertyIndex(UInt32 geoIdx)
1631 // find an unused property
1632 UInt16 retVal = osgMax<UInt16>(UInt16(_geoStore[geoIdx]._propStore.size()),
1633 Geometry::TexCoordsIndex );
1635 for(UInt16 i = Geometry::TexCoordsIndex;
1636 i < _geoStore[geoIdx]._propStore.size(); ++i)
1638 if(_geoStore[geoIdx]._propStore[i]._prop == NULL)
1640 retVal = i;
1641 break;
1645 return retVal;
1648 OSG_END_NAMESPACE
1650 #endif // OSG_WITH_COLLADA