changed: gcc8 base update
[opensg.git] / Source / System / FileIO / Collada / OSGColladaSource.cpp
blob456d9495fb8a99bb48cf319681edcb7387265f44
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 "OSGColladaSource.h"
45 #if defined(OSG_WITH_COLLADA) || defined(OSG_DO_DOC)
47 #include "OSGColladaLog.h"
48 #include "OSGTypedGeoVectorProperty.h"
49 #include "OSGAnimMatrixDataSource.h"
50 #include "OSGAnimQuaternionDataSource.h"
51 #include "OSGAnimVec3fDataSource.h"
53 #include <dom/domSource.h>
54 #include <dom/domAccessor.h>
55 #include <dom/domParam.h>
56 #include <dom/domIDREF_array.h>
58 OSG_BEGIN_NAMESPACE
60 ColladaElementRegistrationHelper ColladaSource::_regHelper(
61 &ColladaSource::create, "source");
64 ColladaElementTransitPtr
65 ColladaSource::create(daeElement *elem, ColladaGlobal *global)
67 return ColladaElementTransitPtr(new ColladaSource(elem, global));
70 void
71 ColladaSource::read(ColladaElement *colElemParent)
73 OSG_COLLADA_LOG(("ColladaSource::read\n"));
75 domSourceRef source = getDOMElementAs<domSource>();
77 OSG_COLLADA_LOG(("ColladaSource::read: id [%s]\n",
78 source->getID()));
80 domSource::domTechnique_commonRef techCom = source ->getTechnique_common();
81 domAccessorRef acc = techCom->getAccessor ();
83 _offset = acc->getOffset();
84 _count = acc->getCount ();
85 _stride = acc->getStride();
86 _elemSize = 0;
88 _strideMap.resize(_stride, -1);
90 const domParam_Array &params = acc->getParam_array();
92 UInt32 idx = 0;
94 for(UInt32 i = 0; i < params.getCount(); ++i)
96 if(params[i]->getName() == NULL)
98 _strideMap[idx] = -1;
99 ++idx;
101 else
103 std::string paramType = params[i]->getType();
105 if(paramType == "float")
107 _strideMap[idx] = _elemSize;
108 ++idx;
109 ++_elemSize;
111 else if(paramType == "float4x4")
113 for(UInt32 j = 0; j < 16; ++j)
115 _strideMap[idx] = _elemSize;
116 ++idx;
117 ++_elemSize;
120 else if(paramType == "Name")
122 _strideMap[idx] = _elemSize;
123 ++idx;
124 ++_elemSize;
126 else
128 SWARNING << "ColladaSource::read: Unknown <param> type ["
129 << paramType << "], defaulting to elemSize 1"
130 << std::endl;
132 _strideMap[idx] = _elemSize;
133 ++idx;
134 ++_elemSize;
139 OSG_COLLADA_LOG(("ColladaSource::read: offset [%d] count [%d] "
140 "stride [%d] elemSize [%d]\n",
141 _offset, _count, _stride, _elemSize));
144 GeoVectorProperty *
145 ColladaSource::getProperty(const std::string &semantic)
147 GeoVectorProperty *retVal = NULL;
148 domSourceRef source = getDOMElementAs<domSource>();
149 PropertyMapIt pmIt = _propMap.find(semantic);
151 if(pmIt != _propMap.end())
153 retVal = pmIt->second;
155 else
157 retVal = fillProperty(semantic);
160 if(retVal == NULL)
162 SFATAL << "ColladaSource::getProperty: Could not read data for "
163 << "semantic [" << semantic << "] from source ["
164 << source->getId() << "]."
165 << std::endl;
168 return retVal;
171 AnimKeyFrameDataSource *
172 ColladaSource::getDataSource(const std::string &semantic)
174 AnimKeyFrameDataSource *retVal = NULL;
175 domSourceRef source = getDOMElementAs<domSource>();
176 DataSourceMapIt dmIt = _dataMap.find(semantic);
178 if(dmIt != _dataMap.end())
180 retVal = dmIt->second;
182 else
184 retVal = fillDataSource(semantic);
187 if(retVal == NULL)
189 SFATAL << "ColladaSource::getDataSource: Could not read data for "
190 << "semantic [" << semantic << "] from source ["
191 << source->getId() << "]." << std::endl;
194 return retVal;
197 const ColladaSource::NameStore &
198 ColladaSource::getNameStore(void)
200 if(_nameStore.empty() == true && _count > 0)
202 fillNameStore();
205 return _nameStore;
208 const ColladaSource::MatrixStore &
209 ColladaSource::getMatrixStore(void)
211 if(_matrixStore.empty() == true && _count > 0)
213 fillMatrixStore();
216 return _matrixStore;
219 const ColladaSource::FloatStore &
220 ColladaSource::getFloatStore(void)
222 if(_floatStore.empty() == true && _count > 0)
224 fillFloatStore();
227 return _floatStore;
230 std::string
231 ColladaSource::getNameValue(UInt32 idx)
233 std::string retVal;
234 getNameValue(idx, retVal);
236 return retVal;
239 bool
240 ColladaSource::getNameValue(UInt32 idx, std::string &nameVal)
242 bool retVal = false;
243 domSourceRef source = getDOMElementAs<domSource> ();
244 domSource::domTechnique_commonRef techCom = source ->getTechnique_common();
245 domAccessorRef acc = techCom->getAccessor ();
247 daeURI dataURI = acc->getSource();
248 domName_arrayRef dataArray =
249 daeSafeCast<domName_array>(dataURI.getElement());
251 if(dataArray == NULL)
253 SWARNING << "ColladaSource::getNameValue: Could not find <name_array> "
254 << "for [" << dataURI.str() << "]." << std::endl;
255 return retVal;
258 if(_elemSize != 1)
260 SWARNING << "ColladaSource::getNameValue: Unexpected elemSize ["
261 << _elemSize << "] != 1." << std::endl;
264 nameVal = dataArray->getValue()[_offset + idx * _stride];
265 retVal = true;
267 return retVal;
270 Real32
271 ColladaSource::getFloatValue(UInt32 idx)
273 Real32 retVal;
274 getFloatValue(idx, retVal);
276 return retVal;
279 bool
280 ColladaSource::getFloatValue(UInt32 idx, Real32 &floatVal)
282 bool retVal = false;
283 domSourceRef source = getDOMElementAs<domSource> ();
284 domSource::domTechnique_commonRef techCom = source->getTechnique_common();
285 domAccessorRef acc = techCom->getAccessor ();
287 daeURI dataURI = acc->getSource();
288 domFloat_arrayRef dataArray =
289 daeSafeCast<domFloat_array>(dataURI.getElement());
291 if(dataArray == NULL)
293 SWARNING << "ColladaSource::getFloatValue: Could not find "
294 << "<float_array> for [" << dataURI.str() << "]."
295 << std::endl;
296 return retVal;
299 if(_elemSize != 1)
301 SWARNING << "ColladaSource::getFloatValue: Unexpected elemSize ["
302 << _elemSize << "] != 1." << std::endl;
305 floatVal = dataArray->getValue()[_offset + idx * _stride];
306 retVal = true;
308 return retVal;
311 Matrix
312 ColladaSource::getMatrixValue(UInt32 idx)
314 Matrix retVal;
315 getMatrixValue(idx, retVal);
317 return retVal;
320 bool
321 ColladaSource::getMatrixValue(UInt32 idx, Matrix &matVal)
323 bool retVal = false;
324 domSourceRef source = getDOMElementAs<domSource> ();
325 domSource::domTechnique_commonRef techCom = source->getTechnique_common();
326 domAccessorRef acc = techCom->getAccessor ();
328 daeURI dataURI = acc->getSource();
329 domFloat_arrayRef dataArray =
330 daeSafeCast<domFloat_array>(dataURI.getElement());
332 if(dataArray == NULL)
334 SWARNING << "ColladaSource::getMatrixValue: Could not find "
335 << "<float_array> for [" << dataURI.str() << "]."
336 << std::endl;
337 return retVal;
340 if(_elemSize != 16)
342 SWARNING << "ColladaSource::getMatrixValue: Not a matrix <source>, "
343 << "elemSize [" << _elemSize << "] != 16" << std::endl;
346 UInt32 currIdx = 0;
347 UInt32 currRow = 0;
348 UInt32 currCol = 0;
349 const domListOfFloats &data = dataArray->getValue();
351 for(UInt32 i = _offset + (idx * _stride);
352 i < _offset + (idx + 1) * _stride; ++i)
354 if(_strideMap[currIdx] != -1)
356 matVal[currCol][currRow] = data[i];
359 ++currIdx;
360 ++currRow;
362 if(currRow >= 4)
364 currRow = 0;
365 ++currCol;
369 return true;
373 ColladaSource::ColladaSource(daeElement *elem, ColladaGlobal *global)
374 : Inherited (elem, global)
375 , _offset (0)
376 , _count (0)
377 , _stride (1)
378 , _elemSize (0)
379 , _strideMap ()
380 , _propMap ()
381 , _dataMap ()
382 , _nameStore ()
383 , _matrixStore()
384 , _floatStore ()
388 ColladaSource::~ColladaSource(void)
392 GeoVectorProperty *
393 ColladaSource::fillProperty(const std::string &semantic)
395 OSG_COLLADA_LOG(("ColladaSource::fillProperty: semantic [%s]\n",
396 semantic.c_str()));
398 GeoVectorPropertyUnrecPtr prop = NULL;
399 domSourceRef source = getDOMElementAs<domSource> ();
400 domSource::domTechnique_commonRef techCom = source ->getTechnique_common();
401 domAccessorRef acc = techCom->getAccessor ();
403 daeURI dataURI = acc->getSource();
404 domFloat_arrayRef dataArray =
405 daeSafeCast<domFloat_array>(dataURI.getElement());
407 if(dataArray == NULL)
409 SWARNING << "ColladaSource::fillProperty: Could not find <float_array> "
410 << "for [" << dataURI.str() << "]." << std::endl;
411 return NULL;
414 const domListOfFloats &data = dataArray->getValue();
416 OSG_ASSERT((_offset + _count * _stride) <= data.getCount());
418 if(semantic == "POSITION")
420 if(_elemSize != 3)
422 SWARNING << "ColladaSource::fillProperty: Unexpected _elemSize ["
423 << _elemSize << "]." << std::endl;
424 return NULL;
427 prop = GeoPnt3fProperty::create();
429 Pnt3f currPnt;
430 UInt32 currIdx = 0;
432 for(UInt32 i = _offset; i < _count * _stride; ++i)
434 if(_strideMap[currIdx] != -1)
435 currPnt[_strideMap[currIdx]] = data[i];
437 ++currIdx;
439 if(currIdx == _stride)
441 prop->push_back(currPnt);
442 currIdx = 0;
446 else
448 OSG_COLLADA_LOG(("ColladaSource::fillProperty: Reading semantic [%s] "
449 "with elemSize [%d] stride [%d] offset [%d] count [%d]\n",
450 semantic.c_str(), _elemSize, _stride, _offset, _count));
452 if(_elemSize == 2)
454 prop = GeoVec2fProperty::create();
456 else if(_elemSize == 3)
458 prop = GeoVec3fProperty::create();
460 else if(_elemSize == 4)
462 prop = GeoVec4fProperty::create();
464 else
466 SWARNING << "ColladaSource::fillProperty: Unhandled element size ["
467 << _elemSize << "] for semantic [" << semantic << "]"
468 << std::endl;
469 return NULL;
472 Vec4f currVec;
473 UInt32 currIdx = 0;
475 for(UInt32 i = _offset; i < _count * _stride; ++i)
477 if(_strideMap[currIdx] != -1)
479 currVec[_strideMap[currIdx]] = data[i];
482 ++currIdx;
484 if(currIdx == _stride)
486 prop->push_back(currVec);
487 currIdx = 0;
492 if(prop != NULL)
494 _propMap.insert(PropertyMap::value_type(semantic, prop));
497 return prop;
500 AnimKeyFrameDataSource *
501 ColladaSource::fillDataSource(const std::string &semantic)
503 AnimKeyFrameDataSourceUnrecPtr retVal = NULL;
504 domSourceRef source = getDOMElementAs<domSource> ();
505 domSource::domTechnique_commonRef techCom = source ->getTechnique_common();
506 domAccessorRef acc = techCom->getAccessor ();
508 daeURI dataURI = acc->getSource();
509 domFloat_arrayRef dataArray =
510 daeSafeCast<domFloat_array>(dataURI.getElement());
512 if(dataArray == NULL)
514 SWARNING << "ColladaSource::fillDataSource: Could not find "
515 << "<float_array> for [" << dataURI.str() << "]."
516 << std::endl;
517 return NULL;
520 const domListOfFloats &data = dataArray->getValue();
522 OSG_ASSERT((_offset + _count * _stride) <= data.getCount());
525 if(_elemSize == 3)
527 AnimVec3fDataSourceUnrecPtr dataSource =
528 AnimVec3fDataSource::create();
530 Vec3f currVal;
531 UInt32 currIdx = 0;
533 for(UInt32 i = _offset; i < _count * _stride; ++i)
535 if(_strideMap[currIdx] != -1)
536 currVal[_strideMap[currIdx]] = data[i];
538 ++currIdx;
540 if(currIdx == _stride)
542 dataSource->editMFValues()->push_back(currVal);
543 currIdx = 0;
547 retVal = dataSource;
549 else if(_elemSize == 4)
551 AnimQuaternionDataSourceUnrecPtr dataSource =
552 AnimQuaternionDataSource::create();
554 Quaternion currVal;
555 UInt32 currIdx = 0;
557 for(UInt32 i = _offset; i < _count * _stride; ++i)
559 if(_strideMap[currIdx] != -1)
560 currVal[_strideMap[currIdx]] = data[i];
562 ++currIdx;
564 if(currIdx == _stride)
566 dataSource->editMFValues()->push_back(currVal);
567 currIdx = 0;
571 retVal = dataSource;
573 else if(_elemSize == 16)
575 AnimMatrixDataSourceUnrecPtr dataSource =
576 AnimMatrixDataSource::create();
578 Matrix currVal;
579 UInt32 currIdx = 0;
580 UInt32 currRowIdx = 0;
581 UInt32 currColIdx = 0;
583 for(UInt32 i = _offset; i < _count * _stride; ++i)
585 if(_strideMap[currIdx] != -1)
586 currVal[currColIdx][currRowIdx] = data[i];
588 ++currIdx;
589 ++currColIdx;
591 if(currColIdx >= 4)
593 currColIdx = 0;
594 ++currRowIdx;
597 if(currIdx == _stride)
599 dataSource->editMFValues()->push_back(currVal);
600 currIdx = 0;
601 currRowIdx = 0;
602 currColIdx = 0;
606 retVal = dataSource;
608 else
610 SWARNING << "ColladaSource::fillDataSource: Unhandled element size ["
611 << _elemSize << "] for semantic [" << semantic << "]"
612 << std::endl;
615 if(retVal != NULL)
617 _dataMap.insert(DataSourceMap::value_type(semantic, retVal));
620 return retVal;
623 void
624 ColladaSource::fillNameStore(void)
626 domSourceRef source = getDOMElementAs<domSource> ();
627 domSource::domTechnique_commonRef techCom = source ->getTechnique_common();
628 domAccessorRef acc = techCom->getAccessor ();
630 daeURI dataURI = acc->getSource();
631 domName_arrayRef nameArray =
632 daeSafeCast<domName_array> (dataURI.getElement());
633 domIDREF_arrayRef idrefArray =
634 daeSafeCast<domIDREF_array>(dataURI.getElement());
636 if(nameArray == NULL && idrefArray == NULL)
638 SWARNING << "ColladaSource::fillNameStore: Could not find <name_array>"
639 << " or <IDREF_array> for [" << dataURI.str() << "]."
640 << std::endl;
641 return;
644 if(nameArray != NULL)
646 std::string currVal;
647 UInt32 currIdx = 0;
648 const domListOfNames &data = nameArray->getValue();
650 for(UInt32 i = _offset; i < _count * _stride; ++i)
652 if(_strideMap[currIdx] != -1)
654 currVal = data[i];
657 ++currIdx;
659 if(currIdx == _stride)
661 _nameStore.push_back(currVal);
662 currIdx = 0;
666 else if(idrefArray != NULL)
668 std::string currVal;
669 UInt32 currIdx = 0;
670 const xsIDREFS &data = idrefArray->getValue();
672 for(UInt32 i = _offset; i < _count * _stride; ++i)
674 if(_strideMap[currIdx] != -1)
676 currVal = data[i].getID();
679 ++currIdx;
681 if(currIdx == _stride)
683 _nameStore.push_back(currVal);
684 currIdx = 0;
690 void
691 ColladaSource::fillMatrixStore(void)
693 domSourceRef source = getDOMElementAs<domSource> ();
694 domSource::domTechnique_commonRef techCom = source ->getTechnique_common();
695 domAccessorRef acc = techCom->getAccessor ();
697 daeURI dataURI = acc->getSource();
698 domFloat_arrayRef dataArray =
699 daeSafeCast<domFloat_array>(dataURI.getElement());
701 if(dataArray == NULL)
703 SWARNING << "ColladaSource::fillMatrixStore: Could not find "
704 << "<float_array> for [" << dataURI.str() << "]."
705 << std::endl;
706 return;
709 Matrix currVal;
710 UInt32 currIdx = 0;
711 UInt32 currRowIdx = 0;
712 UInt32 currColIdx = 0;
713 const domListOfFloats &data = dataArray->getValue();
715 for(UInt32 i = _offset; i < _count * _stride; ++i)
717 if(_strideMap[currIdx] != -1)
719 currVal[currColIdx][currRowIdx] = data[i];
722 ++currIdx;
723 ++currColIdx;
725 if(currColIdx >= 4)
727 currColIdx = 0;
728 ++currRowIdx;
731 if(currIdx == _stride)
733 _matrixStore.push_back(currVal);
734 currIdx = 0;
735 currRowIdx = 0;
736 currColIdx = 0;
741 void
742 ColladaSource::fillFloatStore(void)
744 domSourceRef source = getDOMElementAs<domSource> ();
745 domSource::domTechnique_commonRef techCom = source ->getTechnique_common();
746 domAccessorRef acc = techCom->getAccessor ();
748 daeURI dataURI = acc->getSource();
749 domFloat_arrayRef dataArray =
750 daeSafeCast<domFloat_array>(dataURI.getElement());
752 if(dataArray == NULL)
754 SWARNING << "ColladaSource::fillFloatStore: Could not find "
755 << "<float_array> for [" << dataURI.str() << "]."
756 << std::endl;
757 return;
760 Real32 currVal;
761 UInt32 currIdx = 0;
762 const domListOfFloats &data = dataArray->getValue();
764 for(UInt32 i = _offset; i < _count * _stride; ++i)
766 if(_strideMap[currIdx] != -1)
768 currVal = data[i];
771 ++currIdx;
773 if(currIdx == _stride)
775 _floatStore.push_back(currVal);
776 currIdx = 0;
781 OSG_END_NAMESPACE
783 #endif // OSG_WITH_COLLADA