1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2009 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
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. *
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. *
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. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
40 #pragma GCC diagnostic ignored "-Wold-style-cast"
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>
60 ColladaElementRegistrationHelper
ColladaSource::_regHelper(
61 &ColladaSource::create
, "source");
64 ColladaElementTransitPtr
65 ColladaSource::create(daeElement
*elem
, ColladaGlobal
*global
)
67 return ColladaElementTransitPtr(new ColladaSource(elem
, global
));
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",
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();
88 _strideMap
.resize(_stride
, -1);
90 const domParam_Array
¶ms
= acc
->getParam_array();
94 for(UInt32 i
= 0; i
< params
.getCount(); ++i
)
96 if(params
[i
]->getName() == NULL
)
103 std::string paramType
= params
[i
]->getType();
105 if(paramType
== "float")
107 _strideMap
[idx
] = _elemSize
;
111 else if(paramType
== "float4x4")
113 for(UInt32 j
= 0; j
< 16; ++j
)
115 _strideMap
[idx
] = _elemSize
;
120 else if(paramType
== "Name")
122 _strideMap
[idx
] = _elemSize
;
128 SWARNING
<< "ColladaSource::read: Unknown <param> type ["
129 << paramType
<< "], defaulting to elemSize 1"
132 _strideMap
[idx
] = _elemSize
;
139 OSG_COLLADA_LOG(("ColladaSource::read: offset [%d] count [%d] "
140 "stride [%d] elemSize [%d]\n",
141 _offset
, _count
, _stride
, _elemSize
));
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
;
157 retVal
= fillProperty(semantic
);
162 SFATAL
<< "ColladaSource::getProperty: Could not read data for "
163 << "semantic [" << semantic
<< "] from source ["
164 << source
->getId() << "]."
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
;
184 retVal
= fillDataSource(semantic
);
189 SFATAL
<< "ColladaSource::getDataSource: Could not read data for "
190 << "semantic [" << semantic
<< "] from source ["
191 << source
->getId() << "]." << std::endl
;
197 const ColladaSource::NameStore
&
198 ColladaSource::getNameStore(void)
200 if(_nameStore
.empty() == true && _count
> 0)
208 const ColladaSource::MatrixStore
&
209 ColladaSource::getMatrixStore(void)
211 if(_matrixStore
.empty() == true && _count
> 0)
219 const ColladaSource::FloatStore
&
220 ColladaSource::getFloatStore(void)
222 if(_floatStore
.empty() == true && _count
> 0)
231 ColladaSource::getNameValue(UInt32 idx
)
234 getNameValue(idx
, retVal
);
240 ColladaSource::getNameValue(UInt32 idx
, std::string
&nameVal
)
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
;
260 SWARNING
<< "ColladaSource::getNameValue: Unexpected elemSize ["
261 << _elemSize
<< "] != 1." << std::endl
;
264 nameVal
= dataArray
->getValue()[_offset
+ idx
* _stride
];
271 ColladaSource::getFloatValue(UInt32 idx
)
274 getFloatValue(idx
, retVal
);
280 ColladaSource::getFloatValue(UInt32 idx
, Real32
&floatVal
)
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() << "]."
301 SWARNING
<< "ColladaSource::getFloatValue: Unexpected elemSize ["
302 << _elemSize
<< "] != 1." << std::endl
;
305 floatVal
= dataArray
->getValue()[_offset
+ idx
* _stride
];
312 ColladaSource::getMatrixValue(UInt32 idx
)
315 getMatrixValue(idx
, retVal
);
321 ColladaSource::getMatrixValue(UInt32 idx
, Matrix
&matVal
)
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() << "]."
342 SWARNING
<< "ColladaSource::getMatrixValue: Not a matrix <source>, "
343 << "elemSize [" << _elemSize
<< "] != 16" << std::endl
;
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
];
373 ColladaSource::ColladaSource(daeElement
*elem
, ColladaGlobal
*global
)
374 : Inherited (elem
, global
)
388 ColladaSource::~ColladaSource(void)
393 ColladaSource::fillProperty(const std::string
&semantic
)
395 OSG_COLLADA_LOG(("ColladaSource::fillProperty: semantic [%s]\n",
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
;
414 const domListOfFloats
&data
= dataArray
->getValue();
416 OSG_ASSERT((_offset
+ _count
* _stride
) <= data
.getCount());
418 if(semantic
== "POSITION")
422 SWARNING
<< "ColladaSource::fillProperty: Unexpected _elemSize ["
423 << _elemSize
<< "]." << std::endl
;
427 prop
= GeoPnt3fProperty::create();
432 for(UInt32 i
= _offset
; i
< _count
* _stride
; ++i
)
434 if(_strideMap
[currIdx
] != -1)
435 currPnt
[_strideMap
[currIdx
]] = data
[i
];
439 if(currIdx
== _stride
)
441 prop
->push_back(currPnt
);
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
));
454 prop
= GeoVec2fProperty::create();
456 else if(_elemSize
== 3)
458 prop
= GeoVec3fProperty::create();
460 else if(_elemSize
== 4)
462 prop
= GeoVec4fProperty::create();
466 SWARNING
<< "ColladaSource::fillProperty: Unhandled element size ["
467 << _elemSize
<< "] for semantic [" << semantic
<< "]"
475 for(UInt32 i
= _offset
; i
< _count
* _stride
; ++i
)
477 if(_strideMap
[currIdx
] != -1)
479 currVec
[_strideMap
[currIdx
]] = data
[i
];
484 if(currIdx
== _stride
)
486 prop
->push_back(currVec
);
494 _propMap
.insert(PropertyMap::value_type(semantic
, 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() << "]."
520 const domListOfFloats
&data
= dataArray
->getValue();
522 OSG_ASSERT((_offset
+ _count
* _stride
) <= data
.getCount());
527 AnimVec3fDataSourceUnrecPtr dataSource
=
528 AnimVec3fDataSource::create();
533 for(UInt32 i
= _offset
; i
< _count
* _stride
; ++i
)
535 if(_strideMap
[currIdx
] != -1)
536 currVal
[_strideMap
[currIdx
]] = data
[i
];
540 if(currIdx
== _stride
)
542 dataSource
->editMFValues()->push_back(currVal
);
549 else if(_elemSize
== 4)
551 AnimQuaternionDataSourceUnrecPtr dataSource
=
552 AnimQuaternionDataSource::create();
557 for(UInt32 i
= _offset
; i
< _count
* _stride
; ++i
)
559 if(_strideMap
[currIdx
] != -1)
560 currVal
[_strideMap
[currIdx
]] = data
[i
];
564 if(currIdx
== _stride
)
566 dataSource
->editMFValues()->push_back(currVal
);
573 else if(_elemSize
== 16)
575 AnimMatrixDataSourceUnrecPtr dataSource
=
576 AnimMatrixDataSource::create();
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
];
597 if(currIdx
== _stride
)
599 dataSource
->editMFValues()->push_back(currVal
);
610 SWARNING
<< "ColladaSource::fillDataSource: Unhandled element size ["
611 << _elemSize
<< "] for semantic [" << semantic
<< "]"
617 _dataMap
.insert(DataSourceMap::value_type(semantic
, retVal
));
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() << "]."
644 if(nameArray
!= NULL
)
648 const domListOfNames
&data
= nameArray
->getValue();
650 for(UInt32 i
= _offset
; i
< _count
* _stride
; ++i
)
652 if(_strideMap
[currIdx
] != -1)
659 if(currIdx
== _stride
)
661 _nameStore
.push_back(currVal
);
666 else if(idrefArray
!= NULL
)
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();
681 if(currIdx
== _stride
)
683 _nameStore
.push_back(currVal
);
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() << "]."
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
];
731 if(currIdx
== _stride
)
733 _matrixStore
.push_back(currVal
);
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() << "]."
762 const domListOfFloats
&data
= dataArray
->getValue();
764 for(UInt32 i
= _offset
; i
< _count
* _stride
; ++i
)
766 if(_strideMap
[currIdx
] != -1)
773 if(currIdx
== _stride
)
775 _floatStore
.push_back(currVal
);
783 #endif // OSG_WITH_COLLADA