mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-11 05:36:12 +00:00
EMI: Move methods that require animation state information from AnimationEmi to AnimationStateEmi.
This commit is contained in:
parent
af7bc0679c
commit
eb26094de1
@ -59,117 +59,6 @@ AnimationEmi::~AnimationEmi() {
|
||||
delete[] _bones;
|
||||
}
|
||||
|
||||
void AnimationEmi::computeWeights(const Skeleton *skel, float weight) {
|
||||
if (weight <= 0.0f)
|
||||
return;
|
||||
|
||||
for (int bone = 0; bone < _numBones; ++bone) {
|
||||
Bone &curBone = _bones[bone];
|
||||
Joint *target = skel->getJointNamed(curBone._boneName);
|
||||
if (!target) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AnimationLayer *layer = skel->getLayer(curBone._priority);
|
||||
int jointIndex = skel->getJointIndex(target);
|
||||
JointAnimation &jointAnim = layer->_jointAnims[jointIndex];
|
||||
|
||||
if (curBone._rotations) {
|
||||
jointAnim._rotWeight += weight;
|
||||
}
|
||||
if (curBone._translations) {
|
||||
jointAnim._transWeight += weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationEmi::animate(const Skeleton *skel, float time, bool loop, float weight) {
|
||||
if (weight <= 0.0f)
|
||||
return;
|
||||
|
||||
for (int bone = 0; bone < _numBones; ++bone) {
|
||||
Bone &curBone = _bones[bone];
|
||||
Joint *target = skel->getJointNamed(curBone._boneName);
|
||||
if (!target) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AnimationLayer *layer = skel->getLayer(curBone._priority);
|
||||
int jointIndex = skel->getJointIndex(target);
|
||||
JointAnimation &jointAnim = layer->_jointAnims[jointIndex];
|
||||
|
||||
if (curBone._rotations) {
|
||||
int keyfIdx = -1;
|
||||
Math::Quaternion quat;
|
||||
|
||||
// Normalize the weight so that the sum of applied weights will equal 1.
|
||||
float normalizedRotWeight = weight;
|
||||
if (jointAnim._rotWeight > 1.0f) {
|
||||
// Note: Division by unnormalized sum of weights.
|
||||
normalizedRotWeight = weight / jointAnim._rotWeight;
|
||||
}
|
||||
|
||||
for (int curKeyFrame = 0; curKeyFrame < curBone._count; curKeyFrame++) {
|
||||
if (curBone._rotations[curKeyFrame]._time >= time) {
|
||||
keyfIdx = curKeyFrame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyfIdx == 0) {
|
||||
quat = curBone._rotations[0]._quat;
|
||||
} else if (keyfIdx != -1) {
|
||||
float timeDelta = curBone._rotations[keyfIdx]._time - curBone._rotations[keyfIdx - 1]._time;
|
||||
float interpVal = (time - curBone._rotations[keyfIdx - 1]._time) / timeDelta;
|
||||
|
||||
quat = curBone._rotations[keyfIdx - 1]._quat.slerpQuat(curBone._rotations[keyfIdx]._quat, interpVal);
|
||||
} else {
|
||||
quat = curBone._rotations[curBone._count - 1]._quat;
|
||||
}
|
||||
|
||||
Math::Quaternion &quatFinal = jointAnim._quat;
|
||||
quat = target->_quat.inverse() * quat;
|
||||
quat = quatFinal * quat;
|
||||
quatFinal = quatFinal.slerpQuat(quat, normalizedRotWeight);
|
||||
}
|
||||
|
||||
if (curBone._translations) {
|
||||
int keyfIdx = -1;
|
||||
Math::Vector3d vec;
|
||||
|
||||
// Normalize the weight so that the sum of applied weights will equal 1.
|
||||
float normalizedTransWeight = weight;
|
||||
if (jointAnim._rotWeight > 1.0f) {
|
||||
// Note: Division by unnormalized sum of weights.
|
||||
normalizedTransWeight = weight / jointAnim._transWeight;
|
||||
}
|
||||
|
||||
for (int curKeyFrame = 0; curKeyFrame < curBone._count; curKeyFrame++) {
|
||||
if (curBone._translations[curKeyFrame]._time >= time) {
|
||||
keyfIdx = curKeyFrame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyfIdx == 0) {
|
||||
vec = curBone._translations[0]._vec;
|
||||
} else if (keyfIdx != -1) {
|
||||
float timeDelta = curBone._translations[keyfIdx]._time - curBone._translations[keyfIdx - 1]._time;
|
||||
float interpVal = (time - curBone._translations[keyfIdx - 1]._time) / timeDelta;
|
||||
|
||||
vec = curBone._translations[keyfIdx - 1]._vec +
|
||||
(curBone._translations[keyfIdx]._vec - curBone._translations[keyfIdx - 1]._vec) * interpVal;
|
||||
} else {
|
||||
vec = curBone._translations[curBone._count - 1]._vec;
|
||||
}
|
||||
|
||||
Math::Vector3d &posFinal = jointAnim._pos;
|
||||
vec = vec - target->_relMatrix.getPosition();
|
||||
posFinal = posFinal + vec * normalizedTransWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Bone::loadBinary(Common::SeekableReadStream *data) {
|
||||
uint32 len = data->readUint32LE();
|
||||
char *inString = new char[len];
|
||||
@ -277,6 +166,121 @@ void AnimationStateEmi::update(uint time) {
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationStateEmi::computeWeights() {
|
||||
if (_fade <= 0.0f)
|
||||
return;
|
||||
|
||||
for (int bone = 0; bone < _anim->_numBones; ++bone) {
|
||||
Bone &curBone = _anim->_bones[bone];
|
||||
Joint *target = _skel->getJointNamed(curBone._boneName);
|
||||
if (!target) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AnimationLayer *layer = _skel->getLayer(curBone._priority);
|
||||
int jointIndex = _skel->getJointIndex(target);
|
||||
JointAnimation &jointAnim = layer->_jointAnims[jointIndex];
|
||||
|
||||
if (curBone._rotations) {
|
||||
jointAnim._rotWeight += _fade;
|
||||
}
|
||||
if (curBone._translations) {
|
||||
jointAnim._transWeight += _fade;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationStateEmi::animate() {
|
||||
if (_fade <= 0.0f)
|
||||
return;
|
||||
|
||||
for (int bone = 0; bone < _anim->_numBones; ++bone) {
|
||||
Bone &curBone = _anim->_bones[bone];
|
||||
Joint *target = _skel->getJointNamed(curBone._boneName);
|
||||
if (!target) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AnimationLayer *layer = _skel->getLayer(curBone._priority);
|
||||
int jointIndex = _skel->getJointIndex(target);
|
||||
JointAnimation &jointAnim = layer->_jointAnims[jointIndex];
|
||||
|
||||
if (curBone._rotations) {
|
||||
int keyfIdx = -1;
|
||||
Math::Quaternion quat;
|
||||
|
||||
// Normalize the weight so that the sum of applied weights will equal 1.
|
||||
float normalizedRotWeight = _fade;
|
||||
if (jointAnim._rotWeight > 1.0f) {
|
||||
// Note: Division by unnormalized sum of weights.
|
||||
normalizedRotWeight = _fade / jointAnim._rotWeight;
|
||||
}
|
||||
|
||||
for (int curKeyFrame = 0; curKeyFrame < curBone._count; curKeyFrame++) {
|
||||
if (curBone._rotations[curKeyFrame]._time >= _time) {
|
||||
keyfIdx = curKeyFrame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyfIdx == 0) {
|
||||
quat = curBone._rotations[0]._quat;
|
||||
}
|
||||
else if (keyfIdx != -1) {
|
||||
float timeDelta = curBone._rotations[keyfIdx]._time - curBone._rotations[keyfIdx - 1]._time;
|
||||
float interpVal = (_time - curBone._rotations[keyfIdx - 1]._time) / timeDelta;
|
||||
|
||||
quat = curBone._rotations[keyfIdx - 1]._quat.slerpQuat(curBone._rotations[keyfIdx]._quat, interpVal);
|
||||
}
|
||||
else {
|
||||
quat = curBone._rotations[curBone._count - 1]._quat;
|
||||
}
|
||||
|
||||
Math::Quaternion &quatFinal = jointAnim._quat;
|
||||
quat = target->_quat.inverse() * quat;
|
||||
quat = quatFinal * quat;
|
||||
quatFinal = quatFinal.slerpQuat(quat, normalizedRotWeight);
|
||||
}
|
||||
|
||||
if (curBone._translations) {
|
||||
int keyfIdx = -1;
|
||||
Math::Vector3d vec;
|
||||
|
||||
// Normalize the weight so that the sum of applied weights will equal 1.
|
||||
float normalizedTransWeight = _fade;
|
||||
if (jointAnim._rotWeight > 1.0f) {
|
||||
// Note: Division by unnormalized sum of weights.
|
||||
normalizedTransWeight = _fade / jointAnim._transWeight;
|
||||
}
|
||||
|
||||
for (int curKeyFrame = 0; curKeyFrame < curBone._count; curKeyFrame++) {
|
||||
if (curBone._translations[curKeyFrame]._time >= _time) {
|
||||
keyfIdx = curKeyFrame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyfIdx == 0) {
|
||||
vec = curBone._translations[0]._vec;
|
||||
}
|
||||
else if (keyfIdx != -1) {
|
||||
float timeDelta = curBone._translations[keyfIdx]._time - curBone._translations[keyfIdx - 1]._time;
|
||||
float interpVal = (_time - curBone._translations[keyfIdx - 1]._time) / timeDelta;
|
||||
|
||||
vec = curBone._translations[keyfIdx - 1]._vec +
|
||||
(curBone._translations[keyfIdx]._vec - curBone._translations[keyfIdx - 1]._vec) * interpVal;
|
||||
}
|
||||
else {
|
||||
vec = curBone._translations[curBone._count - 1]._vec;
|
||||
}
|
||||
|
||||
Math::Vector3d &posFinal = jointAnim._pos;
|
||||
vec = vec - target->_relMatrix.getPosition();
|
||||
posFinal = posFinal + vec * normalizedTransWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationStateEmi::play() {
|
||||
if (!_active) {
|
||||
_time = 0.f;
|
||||
|
@ -67,8 +67,6 @@ public:
|
||||
AnimationEmi(const Common::String &filename, Common::SeekableReadStream *data);
|
||||
~AnimationEmi();
|
||||
|
||||
void computeWeights(const Skeleton *skel, float weight);
|
||||
void animate(const Skeleton *skel, float delta, bool loop, float weight);
|
||||
const Common::String &getFilename() const { return _fname; }
|
||||
};
|
||||
|
||||
@ -77,9 +75,9 @@ public:
|
||||
AnimationStateEmi(const Common::String &anim);
|
||||
~AnimationStateEmi();
|
||||
|
||||
void activate();
|
||||
void deactivate();
|
||||
void update(uint time);
|
||||
void computeWeights();
|
||||
void animate();
|
||||
void play();
|
||||
void stop();
|
||||
void setPaused(bool paused);
|
||||
@ -91,6 +89,9 @@ public:
|
||||
void restoreState(SaveGame *state);
|
||||
|
||||
private:
|
||||
void activate();
|
||||
void deactivate();
|
||||
|
||||
friend class Skeleton;
|
||||
|
||||
Skeleton *_skel;
|
||||
|
@ -129,12 +129,12 @@ void Skeleton::commitAnim() {
|
||||
// animation layers. The sums must be pre-computed in order to be able to normalize the blend
|
||||
// weights properly in the next step.
|
||||
for (Common::List<AnimationStateEmi*>::iterator j = _activeAnims.begin(); j != _activeAnims.end(); ++j) {
|
||||
(*j)->_anim->computeWeights(this, (*j)->_fade);
|
||||
(*j)->computeWeights();
|
||||
}
|
||||
|
||||
// Now make a second pass over the animations to actually accumulate animation to layers.
|
||||
for (Common::List<AnimationStateEmi*>::iterator j = _activeAnims.begin(); j != _activeAnims.end(); ++j) {
|
||||
(*j)->_anim->animate(this, (*j)->_time, (*j)->_looping, (*j)->_fade);
|
||||
(*j)->animate();
|
||||
}
|
||||
|
||||
// Blend the layers together in priority order to produce the final result. Highest priority
|
||||
|
Loading…
x
Reference in New Issue
Block a user