mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 05:38:56 +00:00
GRIM: Apply animations in priority order.
This commit is contained in:
parent
d1d0dfe909
commit
6a40b43f16
@ -1205,6 +1205,11 @@ void Actor::update() {
|
||||
c->update();
|
||||
}
|
||||
|
||||
for (Common::List<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i) {
|
||||
Costume *c = *i;
|
||||
c->animate();
|
||||
}
|
||||
|
||||
for (Common::List<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i) {
|
||||
Costume *c = *i;
|
||||
c->moveHead(_lookingMode, _lookAtVector, _lookAtRate);
|
||||
|
@ -132,16 +132,24 @@ public:
|
||||
void init();
|
||||
};
|
||||
|
||||
struct AnimationState {
|
||||
KeyframeAnimPtr _keyf;
|
||||
int _time;
|
||||
float _fade;
|
||||
};
|
||||
|
||||
class ModelComponent : public Costume::Component {
|
||||
public:
|
||||
ModelComponent(Costume::Component *parent, int parentID, const char *filename, Costume::Component *prevComponent, tag32 tag);
|
||||
void init();
|
||||
void setKey(int val);
|
||||
void update();
|
||||
void animate();
|
||||
void reset();
|
||||
void resetColormap();
|
||||
void setMatrix(Graphics::Matrix4 matrix) { _matrix = matrix; };
|
||||
void restoreState(SaveGame *state);
|
||||
void addActiveAnimation(AnimationState *anim, int priority1, int priority2);
|
||||
void removeActiveAnimation(AnimationState *anim);
|
||||
~ModelComponent();
|
||||
|
||||
Model::HierNode *getHierarchy() { return _hier; }
|
||||
@ -150,10 +158,17 @@ public:
|
||||
void draw();
|
||||
|
||||
protected:
|
||||
struct AnimationEntry {
|
||||
AnimationState *anim;
|
||||
int priority;
|
||||
bool tagged;
|
||||
};
|
||||
|
||||
Common::String _filename;
|
||||
ObjectPtr<Model> _obj;
|
||||
Model::HierNode *_hier;
|
||||
Graphics::Matrix4 _matrix;
|
||||
Common::List<AnimationEntry> *_activeAnims;
|
||||
};
|
||||
|
||||
class MainModelComponent : public ModelComponent {
|
||||
@ -307,7 +322,7 @@ void SpriteComponent::restoreState(SaveGame *state) {
|
||||
|
||||
ModelComponent::ModelComponent(Costume::Component *p, int parentID, const char *filename, Costume::Component *prevComponent, tag32 t) :
|
||||
Costume::Component(p, parentID, t), _filename(filename),
|
||||
_obj(NULL), _hier(NULL) {
|
||||
_obj(NULL), _hier(NULL), _activeAnims(NULL) {
|
||||
const char *comma = strchr(filename, ',');
|
||||
|
||||
// Can be called with a comma and a numeric parameter afterward, but
|
||||
@ -356,6 +371,10 @@ void ModelComponent::init() {
|
||||
setKey(0);
|
||||
}
|
||||
|
||||
if (!_activeAnims) {
|
||||
_activeAnims = new Common::List<AnimationEntry>();
|
||||
}
|
||||
|
||||
// If we're the child of a mesh component, put our nodes in the
|
||||
// parent object's tree.
|
||||
if (_parent) {
|
||||
@ -383,16 +402,103 @@ void ModelComponent::reset() {
|
||||
_hier->_hierVisible = _visible;
|
||||
}
|
||||
|
||||
// Reset the hierarchy nodes for any keyframe animations (which
|
||||
// are children of this component and therefore get updated later).
|
||||
void ModelComponent::update() {
|
||||
for (int i = 0; i < _obj->getNumNodes(); i++) {
|
||||
_hier[i]._priority = -1;
|
||||
void ModelComponent::addActiveAnimation(AnimationState *anim, int priority1, int priority2)
|
||||
{
|
||||
// Keep the list of animations sorted by priorities in descending order. Because
|
||||
// the animations have two different priorities, we add the animation to the list
|
||||
// with both priorities.
|
||||
Common::List<AnimationEntry>::iterator i;
|
||||
AnimationEntry entry;
|
||||
entry.anim = anim;
|
||||
entry.priority = priority1;
|
||||
entry.tagged = false;
|
||||
for (i = _activeAnims->begin(); i != _activeAnims->end(); ++i) {
|
||||
if (i->priority < entry.priority) {
|
||||
_activeAnims->insert(i, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == _activeAnims->end())
|
||||
_activeAnims->push_back(entry);
|
||||
|
||||
entry.priority = priority2;
|
||||
entry.tagged = true;
|
||||
for (i = _activeAnims->begin(); i != _activeAnims->end(); ++i) {
|
||||
if (i->priority < entry.priority) {
|
||||
_activeAnims->insert(i, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == _activeAnims->end())
|
||||
_activeAnims->push_back(entry);
|
||||
}
|
||||
|
||||
void ModelComponent::removeActiveAnimation(AnimationState *anim)
|
||||
{
|
||||
Common::List<AnimationEntry>::iterator i;
|
||||
for (i = _activeAnims->begin(); i != _activeAnims->end(); ++i) {
|
||||
if (i->anim == anim)
|
||||
i = _activeAnims->erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelComponent::animate() {
|
||||
// First reset the current animation.
|
||||
for (int i = 0; i < getNumNodes(); i++) {
|
||||
_hier[i]._animPos.set(0,0,0);
|
||||
_hier[i]._animPitch = 0;
|
||||
_hier[i]._animYaw = 0;
|
||||
_hier[i]._animRoll = 0;
|
||||
_hier[i]._totalWeight = 0;
|
||||
}
|
||||
|
||||
// Apply animation to each hierarchy node separately.
|
||||
for (int i = 0; i < getNumNodes(); i++) {
|
||||
Graphics::Vector3d tempPos;
|
||||
float tempYaw = 0.0f, tempPitch = 0.0f, tempRoll = 0.0f;
|
||||
float totalWeight = 0.0f;
|
||||
float remainingWeight = 1.0f;
|
||||
int currPriority = -1;
|
||||
|
||||
// The animations are layered so that animations with a higher priority
|
||||
// are played regardless of the blend weights of lower priority animations.
|
||||
// The highest priority layer gets as much weight as it wants, while the
|
||||
// next layer gets the remaining amount and so on.
|
||||
for (Common::List<AnimationEntry>::iterator j = _activeAnims->begin(); j != _activeAnims->end(); ++j) {
|
||||
if (currPriority != j->priority) {
|
||||
currPriority = j->priority;
|
||||
remainingWeight *= 1 - totalWeight;
|
||||
if (remainingWeight <= 0.0f)
|
||||
break;
|
||||
|
||||
float weightFactor = 1.0f;
|
||||
if (totalWeight > 1.0f) {
|
||||
weightFactor = 1.0f / totalWeight;
|
||||
}
|
||||
tempPos += _hier[i]._animPos * weightFactor;
|
||||
tempYaw += _hier[i]._animYaw * weightFactor;
|
||||
tempPitch += _hier[i]._animPitch * weightFactor;
|
||||
tempRoll += _hier[i]._animRoll * weightFactor;
|
||||
_hier[i]._animPos.set(0,0,0);
|
||||
_hier[i]._animYaw = 0.0f;
|
||||
_hier[i]._animPitch = 0.0f;
|
||||
_hier[i]._animRoll = 0.0f;
|
||||
totalWeight = 0.0f;
|
||||
}
|
||||
|
||||
float time = j->anim->_time / 1000.0f;
|
||||
float weight = j->anim->_fade * remainingWeight;
|
||||
j->anim->_keyf->animate(_hier, i, time, weight, j->tagged);
|
||||
totalWeight += weight;
|
||||
}
|
||||
|
||||
float weightFactor = 1.0f;
|
||||
if (totalWeight > 1.0f) {
|
||||
weightFactor = 1.0f / totalWeight;
|
||||
}
|
||||
_hier[i]._animPos = _hier[i]._animPos * weightFactor + tempPos;
|
||||
_hier[i]._animYaw = _hier[i]._animYaw * weightFactor + tempYaw;
|
||||
_hier[i]._animPitch = _hier[i]._animPitch * weightFactor + tempPitch;
|
||||
_hier[i]._animRoll = _hier[i]._animRoll * weightFactor + tempRoll;
|
||||
}
|
||||
}
|
||||
|
||||
@ -423,15 +529,11 @@ void translateObject(Model::HierNode *node, bool reset) {
|
||||
if (reset) {
|
||||
g_driver->translateViewpointFinish();
|
||||
} else {
|
||||
if (node->_totalWeight > 0) {
|
||||
Graphics::Vector3d animPos = node->_pos + node->_animPos / node->_totalWeight;
|
||||
float animPitch = node->_pitch + node->_animPitch / node->_totalWeight;
|
||||
float animYaw = node->_yaw + node->_animYaw / node->_totalWeight;
|
||||
float animRoll = node->_roll + node->_animRoll / node->_totalWeight;
|
||||
g_driver->translateViewpointStart(animPos, animPitch, animYaw, animRoll);
|
||||
} else {
|
||||
g_driver->translateViewpointStart(node->_pos, node->_pitch, node->_yaw, node->_roll);
|
||||
}
|
||||
Graphics::Vector3d animPos = node->_pos + node->_animPos;
|
||||
float animPitch = node->_pitch + node->_animPitch;
|
||||
float animYaw = node->_yaw + node->_animYaw;
|
||||
float animRoll = node->_roll + node->_animRoll;
|
||||
g_driver->translateViewpointStart(animPos, animPitch, animYaw, animRoll);
|
||||
}
|
||||
}
|
||||
|
||||
@ -459,6 +561,7 @@ MainModelComponent::MainModelComponent(Costume::Component *p, int parentID, cons
|
||||
MainModelComponent *mmc = dynamic_cast<MainModelComponent *>(prevComponent);
|
||||
|
||||
if (mmc && mmc->_filename == filename) {
|
||||
_activeAnims = mmc->_activeAnims;
|
||||
_obj = mmc->_obj;
|
||||
_hier = mmc->_hier;
|
||||
_hierShared = true;
|
||||
@ -536,16 +639,17 @@ public:
|
||||
void reset();
|
||||
void saveState(SaveGame *state);
|
||||
void restoreState(SaveGame *state);
|
||||
void activate();
|
||||
void deactivate();
|
||||
~KeyframeComponent() {}
|
||||
|
||||
private:
|
||||
KeyframeAnimPtr _keyf;
|
||||
AnimationState _anim;
|
||||
int _priority1, _priority2;
|
||||
Model::HierNode *_hier;
|
||||
int _numNodes;
|
||||
bool _active;
|
||||
int _repeatMode;
|
||||
int _currTime;
|
||||
Common::String _fname;
|
||||
|
||||
friend class Costume;
|
||||
@ -557,10 +661,10 @@ KeyframeComponent::KeyframeComponent(Costume::Component *p, int parentID, const
|
||||
const char *comma = strchr(filename, ',');
|
||||
if (comma) {
|
||||
Common::String realName(filename, comma);
|
||||
_keyf = g_resourceloader->getKeyframe(realName);
|
||||
_anim._keyf = g_resourceloader->getKeyframe(realName.c_str());
|
||||
sscanf(comma + 1, "%d,%d", &_priority1, &_priority2);
|
||||
} else
|
||||
_keyf = g_resourceloader->getKeyframe(filename);
|
||||
_anim._keyf = g_resourceloader->getKeyframe(filename);
|
||||
}
|
||||
|
||||
void KeyframeComponent::setKey(int val) {
|
||||
@ -570,58 +674,70 @@ void KeyframeComponent::setKey(int val) {
|
||||
case 2:
|
||||
case 3:
|
||||
if (!_active || val != 1) {
|
||||
_active = true;
|
||||
_currTime = -1;
|
||||
if (!_active) {
|
||||
activate();
|
||||
_active = true;
|
||||
}
|
||||
_anim._time = -1;
|
||||
}
|
||||
_repeatMode = val;
|
||||
break;
|
||||
case 5:
|
||||
warning("Key 5 (meaning uncertain) used for keyframe %s", _keyf->getFilename().c_str());
|
||||
warning("Key 5 (meaning uncertain) used for keyframe %s", _anim._keyf->getFilename().c_str());
|
||||
case 4:
|
||||
_active = false;
|
||||
if (_active) {
|
||||
deactivate();
|
||||
_active = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (gDebugLevel == DEBUG_MODEL || gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL)
|
||||
warning("Unknown key %d for keyframe %s", val, _keyf->getFilename().c_str());
|
||||
warning("Unknown key %d for keyframe %s", val, _anim._keyf->getFilename());
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeComponent::reset() {
|
||||
_active = false;
|
||||
if (_active) {
|
||||
deactivate();
|
||||
_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeComponent::update() {
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
if (_currTime < 0) // For first time through
|
||||
_currTime = 0;
|
||||
if (_anim._time < 0) // For first time through
|
||||
_anim._time = 0;
|
||||
else
|
||||
_currTime += g_grim->getFrameTime();
|
||||
_anim._time += g_grim->getFrameTime();
|
||||
|
||||
int animLength = (int)(_keyf->getLength() * 1000);
|
||||
int animLength = (int)(_anim._keyf->getLength() * 1000);
|
||||
|
||||
if (_currTime > animLength) { // What to do at end?
|
||||
if (_anim._time > animLength) { // What to do at end?
|
||||
switch (_repeatMode) {
|
||||
case 0: // Stop
|
||||
case 3: // Fade at end
|
||||
_active = false;
|
||||
if (_active) {
|
||||
deactivate();
|
||||
_active = false;
|
||||
}
|
||||
return;
|
||||
case 1: // Loop
|
||||
do
|
||||
_currTime -= animLength;
|
||||
while (_currTime > animLength);
|
||||
_anim._time -= animLength;
|
||||
while (_anim._time > animLength);
|
||||
break;
|
||||
case 2: // Hold at end
|
||||
_currTime = animLength;
|
||||
_anim._time = animLength;
|
||||
break;
|
||||
default:
|
||||
if (gDebugLevel == DEBUG_MODEL || gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL)
|
||||
warning("Unknown repeat mode %d for keyframe %s", _repeatMode, _keyf->getFilename().c_str());
|
||||
warning("Unknown repeat mode %d for keyframe %s", _repeatMode, _anim._keyf->getFilename());
|
||||
}
|
||||
}
|
||||
|
||||
_keyf->animate(_hier, _numNodes, _currTime / 1000.0f, _priority1, _priority2, _fade);
|
||||
_anim._fade = _fade;
|
||||
}
|
||||
|
||||
void KeyframeComponent::init() {
|
||||
@ -631,7 +747,7 @@ void KeyframeComponent::init() {
|
||||
_numNodes = mc->getNumNodes();
|
||||
} else {
|
||||
if (gDebugLevel == DEBUG_MODEL || gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL)
|
||||
warning("Parent of %s was not a model", _keyf->getFilename().c_str());
|
||||
warning("Parent of %s was not a model", _anim._keyf->getFilename());
|
||||
_hier = NULL;
|
||||
_numNodes = 0;
|
||||
}
|
||||
@ -640,13 +756,28 @@ void KeyframeComponent::init() {
|
||||
void KeyframeComponent::saveState(SaveGame *state) {
|
||||
state->writeLESint32(_active);
|
||||
state->writeLESint32(_repeatMode);
|
||||
state->writeLESint32(_currTime);
|
||||
state->writeLESint32(_anim._time);
|
||||
}
|
||||
|
||||
void KeyframeComponent::restoreState(SaveGame *state) {
|
||||
_active = state->readLESint32();
|
||||
_repeatMode = state->readLESint32();
|
||||
_currTime = state->readLESint32();
|
||||
_anim._time = state->readLESint32();
|
||||
|
||||
if (_active)
|
||||
activate();
|
||||
}
|
||||
|
||||
void KeyframeComponent::activate() {
|
||||
ModelComponent *mc = dynamic_cast<ModelComponent *>(_parent);
|
||||
if (mc)
|
||||
mc->addActiveAnimation(&_anim, _priority1, _priority2);
|
||||
}
|
||||
|
||||
void KeyframeComponent::deactivate() {
|
||||
ModelComponent *mc = dynamic_cast<ModelComponent *>(_parent);
|
||||
if (mc)
|
||||
mc->removeActiveAnimation(&_anim);
|
||||
}
|
||||
|
||||
MeshComponent::MeshComponent(Costume::Component *p, int parentID, const char *name, tag32 t) :
|
||||
@ -1384,16 +1515,19 @@ void Costume::update() {
|
||||
}
|
||||
}
|
||||
|
||||
void Costume::animate() {
|
||||
for (int i = 0; i < _numComponents; i++) {
|
||||
if (_components[i]) {
|
||||
_components[i]->animate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Costume::moveHead(bool lookingMode, const Graphics::Vector3d &lookAt, float rate) {
|
||||
if (_joint1Node) {
|
||||
float step = g_grim->getPerSecond(rate);
|
||||
float yawStep = step;
|
||||
float pitchStep = step / 3.f;
|
||||
|
||||
_joint1Node->_totalWeight = 1;
|
||||
_joint2Node->_totalWeight = 1;
|
||||
_joint3Node->_totalWeight = 1;
|
||||
|
||||
if (!lookingMode) {
|
||||
//animate yaw
|
||||
if (_headYaw > yawStep) {
|
||||
@ -1448,9 +1582,7 @@ void Costume::moveHead(bool lookingMode, const Graphics::Vector3d &lookAt, float
|
||||
float bodyYaw = _matrix._rot.getYaw();
|
||||
p = _joint1Node->_parent;
|
||||
while (p) {
|
||||
bodyYaw += p->_yaw;
|
||||
if (p->_totalWeight > 0)
|
||||
bodyYaw += p->_animYaw / p->_totalWeight;
|
||||
bodyYaw += p->_yaw + p->_animYaw;
|
||||
p = p->_parent;
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
void moveHead(bool lookingMode, const Graphics::Vector3d &lookAt, float rate);
|
||||
|
||||
void update();
|
||||
void animate();
|
||||
void setupTextures();
|
||||
void draw();
|
||||
void setPosRotate(Graphics::Vector3d pos, float pitch, float yaw, float roll);
|
||||
@ -91,6 +92,7 @@ public:
|
||||
virtual void setKey(int) { }
|
||||
virtual void setMapName(char *) { }
|
||||
virtual void update() { }
|
||||
virtual void animate() { }
|
||||
virtual void setupTexture() { }
|
||||
virtual void draw() { }
|
||||
virtual void reset() { }
|
||||
|
@ -489,15 +489,11 @@ void GfxOpenGL::translateViewpointFinish() {
|
||||
}
|
||||
|
||||
void GfxOpenGL::drawHierachyNode(const Model::HierNode *node) {
|
||||
if (node->_totalWeight > 0) {
|
||||
Graphics::Vector3d animPos = node->_pos + node->_animPos / node->_totalWeight;
|
||||
float animPitch = node->_pitch + node->_animPitch / node->_totalWeight;
|
||||
float animYaw = node->_yaw + node->_animYaw / node->_totalWeight;
|
||||
float animRoll = node->_roll + node->_animRoll / node->_totalWeight;
|
||||
translateViewpointStart(animPos, animPitch, animYaw, animRoll);
|
||||
} else {
|
||||
translateViewpointStart(node->_pos, node->_pitch, node->_yaw, node->_roll);
|
||||
}
|
||||
Graphics::Vector3d animPos = node->_pos + node->_animPos;
|
||||
float animPitch = node->_pitch + node->_animPitch;
|
||||
float animYaw = node->_yaw + node->_animYaw;
|
||||
float animRoll = node->_roll + node->_animRoll;
|
||||
translateViewpointStart(animPos, animPitch, animYaw, animRoll);
|
||||
if (node->_hierVisible) {
|
||||
glPushMatrix();
|
||||
glTranslatef(node->_pivot.x(), node->_pivot.y(), node->_pivot.z());
|
||||
|
@ -526,15 +526,11 @@ void GfxTinyGL::translateViewpointFinish() {
|
||||
}
|
||||
|
||||
void GfxTinyGL::drawHierachyNode(const Model::HierNode *node) {
|
||||
if (node->_totalWeight > 0) {
|
||||
Graphics::Vector3d animPos = node->_pos + node->_animPos / node->_totalWeight;
|
||||
float animPitch = node->_pitch + node->_animPitch / node->_totalWeight;
|
||||
float animYaw = node->_yaw + node->_animYaw / node->_totalWeight;
|
||||
float animRoll = node->_roll + node->_animRoll / node->_totalWeight;
|
||||
translateViewpointStart(animPos, animPitch, animYaw, animRoll);
|
||||
} else {
|
||||
translateViewpointStart(node->_pos, node->_pitch, node->_yaw, node->_roll);
|
||||
}
|
||||
Graphics::Vector3d animPos = node->_pos + node->_animPos;
|
||||
float animPitch = node->_pitch + node->_animPitch;
|
||||
float animYaw = node->_yaw + node->_animYaw;
|
||||
float animRoll = node->_roll + node->_animRoll;
|
||||
translateViewpointStart(animPos, animPitch, animYaw, animRoll);
|
||||
if (node->_hierVisible) {
|
||||
tglPushMatrix();
|
||||
tglTranslatef(node->_pivot.x(), node->_pivot.y(), node->_pivot.z());
|
||||
|
@ -149,22 +149,19 @@ KeyframeAnim::~KeyframeAnim() {
|
||||
g_resourceloader->uncacheKeyframe(this);
|
||||
}
|
||||
|
||||
void KeyframeAnim::animate(Model::HierNode *nodes, int num, float time, int priority1, int priority2, float fade) const {
|
||||
void KeyframeAnim::animate(Model::HierNode *nodes, int num, float time, float fade, bool tagged) const {
|
||||
// Without this sending the bread down the tube in "mo" often crashes,
|
||||
// because it goes outside the bounds of the array of the nodes.
|
||||
if (num >= _numJoints)
|
||||
return;
|
||||
|
||||
float frame = time * _fps;
|
||||
|
||||
if (frame > _numFrames)
|
||||
frame = _numFrames;
|
||||
|
||||
// Without this sending the bread down the tube in "mo" often crashes,
|
||||
// because it goes outside the bounds of the array of the nodes.
|
||||
if (_numJoints < num) {
|
||||
num = _numJoints;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (_nodes[i])
|
||||
_nodes[i]->animate(nodes[i], frame, ((_type & nodes[i]._type) != 0 ? priority2 : priority1), fade);
|
||||
}
|
||||
if (_nodes[num] && tagged == ((_type & nodes[num]._type) != 0))
|
||||
_nodes[num]->animate(nodes[num], frame, fade);
|
||||
}
|
||||
|
||||
void KeyframeAnim::KeyframeEntry::loadBinary(const char *&data) {
|
||||
@ -222,11 +219,9 @@ KeyframeAnim::KeyframeNode::~KeyframeNode() {
|
||||
delete[] _entries;
|
||||
}
|
||||
|
||||
void KeyframeAnim::KeyframeNode::animate(Model::HierNode &node, float frame, int priority, float fade) const {
|
||||
void KeyframeAnim::KeyframeNode::animate(Model::HierNode &node, float frame, float fade) const {
|
||||
if (_numEntries == 0)
|
||||
return;
|
||||
if (priority < node._priority)
|
||||
return;
|
||||
|
||||
// Do a binary search for the nearest previous frame
|
||||
// Loop invariant: entries_[low].frame_ <= frame < entries_[high].frame_
|
||||
@ -245,23 +240,6 @@ void KeyframeAnim::KeyframeNode::animate(Model::HierNode &node, float frame, int
|
||||
float yaw = _entries[low]._yaw + dt * _entries[low]._dyaw;
|
||||
float roll = _entries[low]._roll + dt * _entries[low]._droll;
|
||||
|
||||
if (priority > node._priority) {
|
||||
node._priority = priority;
|
||||
if (node._totalWeight > 0) {
|
||||
node._animPos = node._animPos * (1 - fade) / node._totalWeight;
|
||||
node._animPitch = node._animPitch * (1 - fade) / node._totalWeight;
|
||||
node._animYaw = node._animYaw * (1 - fade) / node._totalWeight;
|
||||
node._animRoll = node._animRoll * (1 - fade) / node._totalWeight;
|
||||
node._totalWeight = 1 - fade;
|
||||
} else {
|
||||
node._animPos.set(0,0,0);
|
||||
node._animPitch = 0;
|
||||
node._animYaw = 0;
|
||||
node._animRoll = 0;
|
||||
node._totalWeight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
node._animPos += (pos - node._pos) * fade;
|
||||
|
||||
float dpitch = pitch - node._pitch;
|
||||
@ -284,8 +262,6 @@ void KeyframeAnim::KeyframeNode::animate(Model::HierNode &node, float frame, int
|
||||
while (droll < -180)
|
||||
droll += 360;
|
||||
node._animRoll += droll * fade;
|
||||
|
||||
node._totalWeight += fade;
|
||||
}
|
||||
|
||||
} // end of namespace Grim
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
|
||||
void loadBinary(const char *data, int len);
|
||||
void loadText(TextSplitter &ts);
|
||||
void animate(Model::HierNode *nodes, int num, float time, int priority1 = 1, int priority2 = 5, float fade = 1) const;
|
||||
void animate(Model::HierNode *nodes, int num, float time, float fade, bool tagged) const;
|
||||
|
||||
float getLength() const { return _numFrames / _fps; }
|
||||
const Common::String &getFilename() const { return _fname; }
|
||||
@ -66,7 +66,7 @@ private:
|
||||
void loadText(TextSplitter &ts);
|
||||
~KeyframeNode();
|
||||
|
||||
void animate(Model::HierNode &node, float frame, int priority, float fade) const;
|
||||
void animate(Model::HierNode &node, float frame, float fade) const;
|
||||
|
||||
char _meshName[32];
|
||||
int _numEntries;
|
||||
|
@ -273,8 +273,6 @@ void Model::HierNode::loadBinary(const char *&data, Model::HierNode *hierNodes,
|
||||
_animPitch = 0;
|
||||
_animYaw = 0;
|
||||
_animRoll = 0;
|
||||
_priority = -1;
|
||||
_totalWeight = 0;
|
||||
_sprite = NULL;
|
||||
|
||||
data += 184;
|
||||
@ -393,7 +391,6 @@ void Model::loadText(TextSplitter *ts, CMap *cmap) {
|
||||
_rootHierNode[num]._pivot = Graphics::Vector3d(pivotx, pivoty, pivotz);
|
||||
_rootHierNode[num]._meshVisible = true;
|
||||
_rootHierNode[num]._hierVisible = true;
|
||||
_rootHierNode[num]._totalWeight = 0;
|
||||
_rootHierNode[num]._sprite = NULL;
|
||||
}
|
||||
|
||||
@ -551,18 +548,13 @@ void Model::HierNode::update() {
|
||||
if (!_initialized)
|
||||
return;
|
||||
|
||||
if (_totalWeight > 0) {
|
||||
Graphics::Vector3d animPos = _pos + _animPos / _totalWeight;
|
||||
float animPitch = _pitch + _animPitch / _totalWeight;
|
||||
float animYaw = _yaw + _animYaw / _totalWeight;
|
||||
float animRoll = _roll + _animRoll / _totalWeight;
|
||||
Graphics::Vector3d animPos = _pos + _animPos;
|
||||
float animPitch = _pitch + _animPitch;
|
||||
float animYaw = _yaw + _animYaw;
|
||||
float animRoll = _roll + _animRoll;
|
||||
|
||||
_localMatrix._pos.set(animPos.x(), animPos.y(), animPos.z());
|
||||
_localMatrix._rot.buildFromPitchYawRoll(animPitch, animYaw, animRoll);
|
||||
} else {
|
||||
_localMatrix._pos.set(_pos.x(), _pos.y(), _pos.z());
|
||||
_localMatrix._rot.buildFromPitchYawRoll(_pitch, _yaw, _roll);
|
||||
}
|
||||
_localMatrix._pos.set(animPos.x(), animPos.y(), animPos.z());
|
||||
_localMatrix._rot.buildFromPitchYawRoll(animPitch, animYaw, animRoll);
|
||||
|
||||
_matrix *= _localMatrix;
|
||||
|
||||
|
@ -83,8 +83,6 @@ public:
|
||||
Graphics::Vector3d _animPos;
|
||||
float _animPitch, _animYaw, _animRoll;
|
||||
bool _meshVisible, _hierVisible;
|
||||
int _priority;
|
||||
float _totalWeight;
|
||||
bool _initialized;
|
||||
Graphics::Matrix4 _matrix;
|
||||
Graphics::Matrix4 _localMatrix;
|
||||
|
Loading…
Reference in New Issue
Block a user