1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2010 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 #include "OSGOgreSkeletonReader.h"
40 #include "OSGOgreLog.h"
42 #include "OSGAnimKeyFrameTemplate.h"
43 #include "OSGAnimTargetAttachment.h"
44 #include "OSGConceptPropertyChecks.h"
45 #include "OSGNameAttachment.h"
46 #include "OSGQuaternion.h"
47 #include "OSGSkeleton.h"
48 #include "OSGSkeletonOgreJoint.h"
49 #include "OSGVector.h"
54 const std::string
OgreSkeletonReader::_versionString ("[Serializer_v1.10]");
55 const std::size_t OgreSkeletonReader::_boneLengthNoScale (_chunkHeaderSize
+ 1 * sizeof(UInt16
) + 7 * sizeof(Real32
));
56 const std::size_t OgreSkeletonReader::_keyFrameLengthNoScale(_chunkHeaderSize
+ 8 * sizeof(Real32
));
59 OgreSkeletonReader::OgreSkeletonReader( std::istream
&is
,
60 const OgreOptions
&options
)
69 OgreSkeletonReader::~OgreSkeletonReader(void)
74 OgreSkeletonReader::read(void)
76 OSG_OGRE_LOG(("OgreSkeletonReader::read\n"));
78 UInt16 headerId
= readUInt16(_is
);
82 if(headerId
== CHUNK_HEADER
)
84 std::string version
= readString(_is
);
86 if(version
== _versionString
)
92 SWARNING
<< "OgreSkeletonReader::read: Unsupported version '"
93 << version
<< "'." << std::endl
;
98 SWARNING
<< "OgreSkeletonReader::read: Unrecognized file header."
104 SWARNING
<< "OgreSkeletonReader::read: Bad stream."
110 OgreSkeletonReader::getSkeleton(void)
116 OgreSkeletonReader::getGlobals(void)
122 OgreSkeletonReader::readContent(void)
124 OSG_OGRE_LOG(("OgreSkeletonReader::readContent\n"));
126 JointNodeStore joints
;
132 readChunkHeader(_is
);
134 switch(_header
.chunkId
)
140 case CHUNK_BONE_PARENT
:
141 readBoneParent(joints
);
144 case CHUNK_ANIMATION
:
145 readAnimation(joints
);
148 case CHUNK_ANIMATION_LINK
:
153 OSG_OGRE_LOG(("OgreSkeletonReader::readContent: Unknown chunkId '0x%x'\n",
161 skip(_is
, -_chunkHeaderSize
);
166 calcInvBindMatrices(joints
);
168 // construct skeleton
169 _skel
= Skeleton::create();
171 JointNodeStore::const_iterator jIt
= joints
.begin();
172 JointNodeStore::const_iterator jEnd
= joints
.end ();
174 for(; jIt
!= jEnd
; ++jIt
)
176 if((*jIt
) != NULL
&& (*jIt
)->getParent() == NULL
)
178 #ifndef OSG_OGRE_SILENT
179 SkeletonOgreJoint
* joint
=
180 dynamic_cast<SkeletonOgreJoint
*>((*jIt
)->getCore());
183 OSG_OGRE_LOG(("OgreSkeletonReader::readContent: "
184 "adding root joint id '%u'\n", joint
->getJointId()));
186 _skel
->editMFRoots()->push_back(*jIt
);
192 OgreSkeletonReader::readBone(JointNodeStore
&joints
)
194 std::string boneName
= readString(_is
);
195 UInt16 boneId
= readUInt16(_is
);
198 Vec3f
scale(1.f
, 1.f
, 1.f
);
200 translate
[0] = readReal32(_is
);
201 translate
[1] = readReal32(_is
);
202 translate
[2] = readReal32(_is
);
204 rotate
[0] = readReal32(_is
);
205 rotate
[1] = readReal32(_is
);
206 rotate
[2] = readReal32(_is
);
207 rotate
[3] = readReal32(_is
);
210 if(_header
.chunkSize
> _boneLengthNoScale
)
212 scale
[0] = readReal32(_is
);
213 scale
[1] = readReal32(_is
);
214 scale
[2] = readReal32(_is
);
219 rotate
.getValueAsAxisDeg(axis
, angle
);
221 OSG_OGRE_LOG(("OgreSkeletonReader::readBone: boneName '%s' "
222 "boneId '%u' translate '(%f %f %f)' rotate '(%f %f %f %f)' "
223 "scale '(%f %f %f)'\n",
224 boneName
.c_str(), boneId
, translate
[0], translate
[1], translate
[2],
225 axis
[0], axis
[1], axis
[2], angle
, scale
[0], scale
[1], scale
[2]));
227 SkeletonOgreJointUnrecPtr joint
= SkeletonOgreJoint::create();
228 NodeUnrecPtr jointN
= makeNodeFor(joint
);
229 joint
->setJointId(boneId
);
230 joint
->setTranslate(translate
);
231 joint
->setScale (scale
);
232 joint
->setRotate (rotate
);
234 setTargetId(joint
, boneName
);
235 setName (jointN
, boneName
);
237 if(boneId
>= joints
.size())
238 joints
.resize(boneId
+ 1, NULL
);
240 joints
[boneId
] = jointN
;
244 OgreSkeletonReader::readBoneParent(JointNodeStore
&joints
)
246 UInt16 boneId
= readUInt16(_is
);
247 UInt16 parentId
= readUInt16(_is
);
249 OSG_OGRE_LOG(("OgreSkeletonReader::readBoneParent: "
250 "boneId '%u' parentId '%u'\n", boneId
, parentId
));
252 joints
[parentId
]->addChild(joints
[boneId
]);
256 OgreSkeletonReader::readAnimation(JointNodeStore
&joints
)
258 if(_options
.getLoadAnimations() == true)
260 std::string animName
= readString(_is
);
261 Real32 animLen
= readReal32(_is
);
263 osgSinkUnusedWarning(animLen
);
265 OSG_OGRE_LOG(("OgreSkeletonReader::readAnimation: "
266 "animName '%s' animLen '%f'\n", animName
.c_str(), animLen
));
268 AnimTemplateUnrecPtr animTmpl
= AnimKeyFrameTemplate::create();
269 animTmpl
->setName(animName
);
275 readChunkHeader(_is
);
277 switch(_header
.chunkId
)
279 case CHUNK_ANIMATION_TRACK
:
280 readAnimationTrack(joints
, animTmpl
);
290 skip(_is
, -_chunkHeaderSize
);
296 _globals
= GlobalsAttachment::create();
298 _globals
->editMFElements()->push_back(animTmpl
);
302 skip(_is
, _header
.chunkSize
- _chunkHeaderSize
);
307 OgreSkeletonReader::readAnimationTrack(JointNodeStore
&joints
,
308 AnimTemplate
*animTmpl
)
310 UInt16 boneId
= readUInt16(_is
);
312 std::string boneName
;
313 getTargetId(joints
[boneId
]->getCore(), boneName
);
315 // OSG_OGRE_LOG(("OgreSkeletonReader::readAnimationTrack: boneId '%u' boneName '%s'\n",
316 // boneId, boneName.c_str()));
318 AnimVec3fDataSourceUnrecPtr translateSrc
= AnimVec3fDataSource ::create();
319 AnimVec3fDataSourceUnrecPtr scaleSrc
= AnimVec3fDataSource ::create();
320 AnimQuaternionDataSourceUnrecPtr rotateSrc
= AnimQuaternionDataSource::create();
322 translateSrc
->editMFInterpolationModes()->push_back(AnimKeyFrameDataSource::IM_Linear
);
323 scaleSrc
->editMFInterpolationModes()->push_back(AnimKeyFrameDataSource::IM_Linear
);
324 rotateSrc
->editMFInterpolationModes()->push_back(AnimKeyFrameDataSource::IM_Linear
);
330 readChunkHeader(_is
);
332 switch(_header
.chunkId
)
334 case CHUNK_ANIMATION_TRACK_KEYFRAME
:
335 readAnimationTrackKeyFrame(translateSrc
, scaleSrc
, rotateSrc
);
345 skip(_is
, -_chunkHeaderSize
);
350 if(translateSrc
->getMFInValues()->empty() == false)
352 animTmpl
->editMFSources ()->push_back(translateSrc
);
353 animTmpl
->editMFTargetIds()->push_back(boneName
+ ".offsetTranslate");
356 if(scaleSrc
->getMFInValues()->empty() == false)
358 animTmpl
->editMFSources ()->push_back(scaleSrc
);
359 animTmpl
->editMFTargetIds()->push_back(boneName
+ ".offsetScale");
362 if(rotateSrc
->getMFInValues()->empty() == false)
364 animTmpl
->editMFSources ()->push_back(rotateSrc
);
365 animTmpl
->editMFTargetIds()->push_back(boneName
+ ".offsetRotate");
370 OgreSkeletonReader::readAnimationTrackKeyFrame(AnimVec3fDataSource
*translateSrc
,
371 AnimVec3fDataSource
*scaleSrc
,
372 AnimQuaternionDataSource
*rotateSrc
)
374 Real32 time
= readReal32(_is
);
377 Vec3f
scale(1.f
, 1.f
, 1.f
);
378 bool hasScale
= false;
380 rotate
[0] = readReal32(_is
);
381 rotate
[1] = readReal32(_is
);
382 rotate
[2] = readReal32(_is
);
383 rotate
[3] = readReal32(_is
);
386 translate
[0] = readReal32(_is
);
387 translate
[1] = readReal32(_is
);
388 translate
[2] = readReal32(_is
);
390 if(_header
.chunkSize
> _keyFrameLengthNoScale
)
394 scale
[0] = readReal32(_is
);
395 scale
[1] = readReal32(_is
);
396 scale
[2] = readReal32(_is
);
401 rotate
.getValueAsAxisDeg(axis
, angle
);
403 // OSG_OGRE_LOG(("OgreSkeletonReader::readAnimationTrackKeyFrame: "
404 // "time '%f' rotate '(%f %f %f %f)' translate '(%f %f %f)' "
405 // "scale '(%f %f %f)'\n",
406 // time, axis[0], axis[1], axis[2], angle,
407 // translate[0], translate[1], translate[2],
408 // scale[0], scale[1], scale[2]));
410 translateSrc
->editMFInValues()->push_back(time
);
411 translateSrc
->editMFValues ()->push_back(translate
);
415 scaleSrc
->editMFInValues()->push_back(time
);
416 scaleSrc
->editMFValues ()->push_back(scale
);
419 rotateSrc
->editMFInValues()->push_back(time
);
420 rotateSrc
->editMFValues ()->push_back(rotate
);
424 OgreSkeletonReader::readAnimationLink(void)
426 std::string skelName
= readString(_is
);
427 Real32 scale
= readReal32(_is
);
429 osgSinkUnusedWarning(skelName
);
430 osgSinkUnusedWarning(scale
);
432 OSG_OGRE_LOG(("OgreSkeletonReader::readAnimationLink "
433 "skelName '%s' scale '%f'\n", skelName
.c_str(), scale
));
437 OgreSkeletonReader::calcInvBindMatrices(JointNodeStore
&joints
)
439 OSG_OGRE_LOG(("OgreSkeletonReader::calcInvBindMatrices\n"));
441 JointNodeStore::iterator jIt
= joints
.begin();
442 JointNodeStore::iterator jEnd
= joints
.end ();
444 for(; jIt
!= jEnd
; ++jIt
)
446 if((*jIt
) != NULL
&& (*jIt
)->getParent() == NULL
)
448 calcInvBindMatrix(*jIt
, Vec3f(0.f
, 0.f
, 0.f
),
449 Vec3f(1.f
, 1.f
, 1.f
),
450 Quaternion::identity());
456 OgreSkeletonReader::calcInvBindMatrix(Node
*node
,
457 Vec3f parentTranslate
,
459 Quaternion parentRotate
)
461 SkeletonOgreJoint
*joint
= dynamic_cast<SkeletonOgreJoint
*>(node
->getCore());
463 Quaternion
rotate(parentRotate
);
464 Vec3f
scale (parentScale
);
469 rotate
.mult(joint
->getRotate());
471 scale
[0] *= joint
->getScale()[0];
472 scale
[1] *= joint
->getScale()[1];
473 scale
[2] *= joint
->getScale()[2];
475 translate
= joint
->getTranslate();
476 translate
[0] *= parentScale
[0];
477 translate
[1] *= parentScale
[1];
478 translate
[2] *= parentScale
[2];
480 parentRotate
.multVec(translate
, translate
);
482 translate
+= parentTranslate
;
484 joint
->setInvBindTranslate(-translate
);
485 joint
->setInvBindScale (Vec3f(1.f
/scale
[0], 1.f
/scale
[1], 1.f
/scale
[2]));
486 joint
->setInvBindRotate (rotate
.inverse());
490 joint
->getInvBindRotate().getValueAsAxisDeg(axis
, angle
);
493 Node::MFChildrenType::const_iterator cIt
= node
->getMFChildren()->begin();
494 Node::MFChildrenType::const_iterator cEnd
= node
->getMFChildren()->end ();
496 for(; cIt
!= cEnd
; ++cIt
)
498 calcInvBindMatrix(*cIt
, translate
, scale
, rotate
);