Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "engines/stark/model/skeleton_anim.h"
00024
00025 #include "engines/stark/services/archiveloader.h"
00026
00027 namespace Stark {
00028
00029 SkeletonAnim::SkeletonAnim() :
00030 _id(0),
00031 _ver(0),
00032 _u1(0),
00033 _u2(0),
00034 _time(0) {
00035 }
00036
00037 void SkeletonAnim::createFromStream(ArchiveReadStream *stream) {
00038 _id = stream->readUint32LE();
00039 _ver = stream->readUint32LE();
00040 if (_ver == 3) {
00041 _u1 = 0;
00042 _time = stream->readUint32LE();
00043 _u2 = stream->readUint32LE();
00044 } else {
00045 _u1 = stream->readUint32LE();
00046 _u2 = stream->readUint32LE();
00047 _time = stream->readUint32LE();
00048 }
00049 if (_u2 != 0xdeadbabe) {
00050 error("Wrong magic while reading animation");
00051 }
00052
00053 uint32 num = stream->readUint32LE();
00054 _boneAnims.resize(num);
00055 for (uint32 i = 0; i < num; ++i) {
00056 uint32 bone = stream->readUint32LE();
00057 uint32 numKeys = stream->readUint32LE();
00058
00059 BoneAnim &boneAnim = _boneAnims[bone];
00060 boneAnim._keys.resize(numKeys);
00061 for (uint32 j = 0; j < numKeys; ++j) {
00062 AnimKey &key = boneAnim._keys[j];
00063 key._time = stream->readUint32LE();
00064 key._rot = stream->readQuaternion();
00065 key._pos = stream->readVector3();
00066 }
00067 }
00068 }
00069
00070 void SkeletonAnim::getCoordForBone(uint32 time, int boneIdx, Math::Vector3d &pos, Math::Quaternion &rot) const {
00071 const Common::Array<AnimKey> &keys = _boneAnims[boneIdx]._keys;
00072
00073 if (keys.size() == 1) {
00074
00075 pos = keys[0]._pos;
00076 rot = keys[0]._rot;
00077
00078 return;
00079 }
00080
00081 for (Common::Array<AnimKey>::const_iterator it = keys.begin(); it < keys.end(); ++it) {
00082 if (it->_time > time) {
00083
00084 const AnimKey *a = it;
00085 --it;
00086 const AnimKey *b = it;
00087
00088 float t = (float)(time - b->_time) / (float)(a->_time - b->_time);
00089
00090 pos = b->_pos + (a->_pos - b->_pos) * t;
00091 rot = b->_rot.slerpQuat(a->_rot, t);
00092
00093 return;
00094 } else if (it->_time == time || it == keys.end() - 1){
00095
00096
00097 const AnimKey *key = it;
00098 pos = key->_pos;
00099 rot = key->_rot;
00100 if (it == keys.end() - 1) {
00101 warning("Unable to find keyframe for bone '%d' at %d ms, using default", boneIdx, time);
00102 }
00103 return;
00104 }
00105 }
00106 }
00107
00108 }