GRIM: Apply animations in priority order.

This commit is contained in:
Joni Vähämäki 2011-05-24 19:47:39 +03:00
parent d1d0dfe909
commit 6a40b43f16
9 changed files with 215 additions and 118 deletions

View file

@ -1205,6 +1205,11 @@ void Actor::update() {
c->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) { for (Common::List<Costume *>::iterator i = _costumeStack.begin(); i != _costumeStack.end(); ++i) {
Costume *c = *i; Costume *c = *i;
c->moveHead(_lookingMode, _lookAtVector, _lookAtRate); c->moveHead(_lookingMode, _lookAtVector, _lookAtRate);

View file

@ -132,16 +132,24 @@ public:
void init(); void init();
}; };
struct AnimationState {
KeyframeAnimPtr _keyf;
int _time;
float _fade;
};
class ModelComponent : public Costume::Component { class ModelComponent : public Costume::Component {
public: public:
ModelComponent(Costume::Component *parent, int parentID, const char *filename, Costume::Component *prevComponent, tag32 tag); ModelComponent(Costume::Component *parent, int parentID, const char *filename, Costume::Component *prevComponent, tag32 tag);
void init(); void init();
void setKey(int val); void setKey(int val);
void update(); void animate();
void reset(); void reset();
void resetColormap(); void resetColormap();
void setMatrix(Graphics::Matrix4 matrix) { _matrix = matrix; }; void setMatrix(Graphics::Matrix4 matrix) { _matrix = matrix; };
void restoreState(SaveGame *state); void restoreState(SaveGame *state);
void addActiveAnimation(AnimationState *anim, int priority1, int priority2);
void removeActiveAnimation(AnimationState *anim);
~ModelComponent(); ~ModelComponent();
Model::HierNode *getHierarchy() { return _hier; } Model::HierNode *getHierarchy() { return _hier; }
@ -150,10 +158,17 @@ public:
void draw(); void draw();
protected: protected:
struct AnimationEntry {
AnimationState *anim;
int priority;
bool tagged;
};
Common::String _filename; Common::String _filename;
ObjectPtr<Model> _obj; ObjectPtr<Model> _obj;
Model::HierNode *_hier; Model::HierNode *_hier;
Graphics::Matrix4 _matrix; Graphics::Matrix4 _matrix;
Common::List<AnimationEntry> *_activeAnims;
}; };
class MainModelComponent : public ModelComponent { 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) : ModelComponent::ModelComponent(Costume::Component *p, int parentID, const char *filename, Costume::Component *prevComponent, tag32 t) :
Costume::Component(p, parentID, t), _filename(filename), Costume::Component(p, parentID, t), _filename(filename),
_obj(NULL), _hier(NULL) { _obj(NULL), _hier(NULL), _activeAnims(NULL) {
const char *comma = strchr(filename, ','); const char *comma = strchr(filename, ',');
// Can be called with a comma and a numeric parameter afterward, but // Can be called with a comma and a numeric parameter afterward, but
@ -356,6 +371,10 @@ void ModelComponent::init() {
setKey(0); setKey(0);
} }
if (!_activeAnims) {
_activeAnims = new Common::List<AnimationEntry>();
}
// If we're the child of a mesh component, put our nodes in the // If we're the child of a mesh component, put our nodes in the
// parent object's tree. // parent object's tree.
if (_parent) { if (_parent) {
@ -383,16 +402,103 @@ void ModelComponent::reset() {
_hier->_hierVisible = _visible; _hier->_hierVisible = _visible;
} }
// Reset the hierarchy nodes for any keyframe animations (which void ModelComponent::addActiveAnimation(AnimationState *anim, int priority1, int priority2)
// are children of this component and therefore get updated later). {
void ModelComponent::update() { // Keep the list of animations sorted by priorities in descending order. Because
for (int i = 0; i < _obj->getNumNodes(); i++) { // the animations have two different priorities, we add the animation to the list
_hier[i]._priority = -1; // 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]._animPos.set(0,0,0);
_hier[i]._animPitch = 0; _hier[i]._animPitch = 0;
_hier[i]._animYaw = 0; _hier[i]._animYaw = 0;
_hier[i]._animRoll = 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) { if (reset) {
g_driver->translateViewpointFinish(); g_driver->translateViewpointFinish();
} else { } else {
if (node->_totalWeight > 0) { Graphics::Vector3d animPos = node->_pos + node->_animPos;
Graphics::Vector3d animPos = node->_pos + node->_animPos / node->_totalWeight; float animPitch = node->_pitch + node->_animPitch;
float animPitch = node->_pitch + node->_animPitch / node->_totalWeight; float animYaw = node->_yaw + node->_animYaw;
float animYaw = node->_yaw + node->_animYaw / node->_totalWeight; float animRoll = node->_roll + node->_animRoll;
float animRoll = node->_roll + node->_animRoll / node->_totalWeight; g_driver->translateViewpointStart(animPos, animPitch, animYaw, animRoll);
g_driver->translateViewpointStart(animPos, animPitch, animYaw, animRoll);
} else {
g_driver->translateViewpointStart(node->_pos, node->_pitch, node->_yaw, node->_roll);
}
} }
} }
@ -459,6 +561,7 @@ MainModelComponent::MainModelComponent(Costume::Component *p, int parentID, cons
MainModelComponent *mmc = dynamic_cast<MainModelComponent *>(prevComponent); MainModelComponent *mmc = dynamic_cast<MainModelComponent *>(prevComponent);
if (mmc && mmc->_filename == filename) { if (mmc && mmc->_filename == filename) {
_activeAnims = mmc->_activeAnims;
_obj = mmc->_obj; _obj = mmc->_obj;
_hier = mmc->_hier; _hier = mmc->_hier;
_hierShared = true; _hierShared = true;
@ -536,16 +639,17 @@ public:
void reset(); void reset();
void saveState(SaveGame *state); void saveState(SaveGame *state);
void restoreState(SaveGame *state); void restoreState(SaveGame *state);
void activate();
void deactivate();
~KeyframeComponent() {} ~KeyframeComponent() {}
private: private:
KeyframeAnimPtr _keyf; AnimationState _anim;
int _priority1, _priority2; int _priority1, _priority2;
Model::HierNode *_hier; Model::HierNode *_hier;
int _numNodes; int _numNodes;
bool _active; bool _active;
int _repeatMode; int _repeatMode;
int _currTime;
Common::String _fname; Common::String _fname;
friend class Costume; friend class Costume;
@ -557,10 +661,10 @@ KeyframeComponent::KeyframeComponent(Costume::Component *p, int parentID, const
const char *comma = strchr(filename, ','); const char *comma = strchr(filename, ',');
if (comma) { if (comma) {
Common::String realName(filename, 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); sscanf(comma + 1, "%d,%d", &_priority1, &_priority2);
} else } else
_keyf = g_resourceloader->getKeyframe(filename); _anim._keyf = g_resourceloader->getKeyframe(filename);
} }
void KeyframeComponent::setKey(int val) { void KeyframeComponent::setKey(int val) {
@ -570,58 +674,70 @@ void KeyframeComponent::setKey(int val) {
case 2: case 2:
case 3: case 3:
if (!_active || val != 1) { if (!_active || val != 1) {
_active = true; if (!_active) {
_currTime = -1; activate();
_active = true;
}
_anim._time = -1;
} }
_repeatMode = val; _repeatMode = val;
break; break;
case 5: 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: case 4:
_active = false; if (_active) {
deactivate();
_active = false;
}
break; break;
default: default:
if (gDebugLevel == DEBUG_MODEL || gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL) 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() { void KeyframeComponent::reset() {
_active = false; if (_active) {
deactivate();
_active = false;
}
} }
void KeyframeComponent::update() { void KeyframeComponent::update() {
if (!_active) if (!_active)
return; return;
if (_currTime < 0) // For first time through if (_anim._time < 0) // For first time through
_currTime = 0; _anim._time = 0;
else 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) { switch (_repeatMode) {
case 0: // Stop case 0: // Stop
case 3: // Fade at end case 3: // Fade at end
_active = false; if (_active) {
deactivate();
_active = false;
}
return; return;
case 1: // Loop case 1: // Loop
do do
_currTime -= animLength; _anim._time -= animLength;
while (_currTime > animLength); while (_anim._time > animLength);
break; break;
case 2: // Hold at end case 2: // Hold at end
_currTime = animLength; _anim._time = animLength;
break; break;
default: default:
if (gDebugLevel == DEBUG_MODEL || gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL) 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() { void KeyframeComponent::init() {
@ -631,7 +747,7 @@ void KeyframeComponent::init() {
_numNodes = mc->getNumNodes(); _numNodes = mc->getNumNodes();
} else { } else {
if (gDebugLevel == DEBUG_MODEL || gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL) 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; _hier = NULL;
_numNodes = 0; _numNodes = 0;
} }
@ -640,13 +756,28 @@ void KeyframeComponent::init() {
void KeyframeComponent::saveState(SaveGame *state) { void KeyframeComponent::saveState(SaveGame *state) {
state->writeLESint32(_active); state->writeLESint32(_active);
state->writeLESint32(_repeatMode); state->writeLESint32(_repeatMode);
state->writeLESint32(_currTime); state->writeLESint32(_anim._time);
} }
void KeyframeComponent::restoreState(SaveGame *state) { void KeyframeComponent::restoreState(SaveGame *state) {
_active = state->readLESint32(); _active = state->readLESint32();
_repeatMode = 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) : 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) { void Costume::moveHead(bool lookingMode, const Graphics::Vector3d &lookAt, float rate) {
if (_joint1Node) { if (_joint1Node) {
float step = g_grim->getPerSecond(rate); float step = g_grim->getPerSecond(rate);
float yawStep = step; float yawStep = step;
float pitchStep = step / 3.f; float pitchStep = step / 3.f;
_joint1Node->_totalWeight = 1;
_joint2Node->_totalWeight = 1;
_joint3Node->_totalWeight = 1;
if (!lookingMode) { if (!lookingMode) {
//animate yaw //animate yaw
if (_headYaw > yawStep) { if (_headYaw > yawStep) {
@ -1448,9 +1582,7 @@ void Costume::moveHead(bool lookingMode, const Graphics::Vector3d &lookAt, float
float bodyYaw = _matrix._rot.getYaw(); float bodyYaw = _matrix._rot.getYaw();
p = _joint1Node->_parent; p = _joint1Node->_parent;
while (p) { while (p) {
bodyYaw += p->_yaw; bodyYaw += p->_yaw + p->_animYaw;
if (p->_totalWeight > 0)
bodyYaw += p->_animYaw / p->_totalWeight;
p = p->_parent; p = p->_parent;
} }

View file

@ -67,6 +67,7 @@ public:
void moveHead(bool lookingMode, const Graphics::Vector3d &lookAt, float rate); void moveHead(bool lookingMode, const Graphics::Vector3d &lookAt, float rate);
void update(); void update();
void animate();
void setupTextures(); void setupTextures();
void draw(); void draw();
void setPosRotate(Graphics::Vector3d pos, float pitch, float yaw, float roll); void setPosRotate(Graphics::Vector3d pos, float pitch, float yaw, float roll);
@ -91,6 +92,7 @@ public:
virtual void setKey(int) { } virtual void setKey(int) { }
virtual void setMapName(char *) { } virtual void setMapName(char *) { }
virtual void update() { } virtual void update() { }
virtual void animate() { }
virtual void setupTexture() { } virtual void setupTexture() { }
virtual void draw() { } virtual void draw() { }
virtual void reset() { } virtual void reset() { }

View file

@ -489,15 +489,11 @@ void GfxOpenGL::translateViewpointFinish() {
} }
void GfxOpenGL::drawHierachyNode(const Model::HierNode *node) { void GfxOpenGL::drawHierachyNode(const Model::HierNode *node) {
if (node->_totalWeight > 0) { Graphics::Vector3d animPos = node->_pos + node->_animPos;
Graphics::Vector3d animPos = node->_pos + node->_animPos / node->_totalWeight; float animPitch = node->_pitch + node->_animPitch;
float animPitch = node->_pitch + node->_animPitch / node->_totalWeight; float animYaw = node->_yaw + node->_animYaw;
float animYaw = node->_yaw + node->_animYaw / node->_totalWeight; float animRoll = node->_roll + node->_animRoll;
float animRoll = node->_roll + node->_animRoll / node->_totalWeight; translateViewpointStart(animPos, animPitch, animYaw, animRoll);
translateViewpointStart(animPos, animPitch, animYaw, animRoll);
} else {
translateViewpointStart(node->_pos, node->_pitch, node->_yaw, node->_roll);
}
if (node->_hierVisible) { if (node->_hierVisible) {
glPushMatrix(); glPushMatrix();
glTranslatef(node->_pivot.x(), node->_pivot.y(), node->_pivot.z()); glTranslatef(node->_pivot.x(), node->_pivot.y(), node->_pivot.z());

View file

@ -526,15 +526,11 @@ void GfxTinyGL::translateViewpointFinish() {
} }
void GfxTinyGL::drawHierachyNode(const Model::HierNode *node) { void GfxTinyGL::drawHierachyNode(const Model::HierNode *node) {
if (node->_totalWeight > 0) { Graphics::Vector3d animPos = node->_pos + node->_animPos;
Graphics::Vector3d animPos = node->_pos + node->_animPos / node->_totalWeight; float animPitch = node->_pitch + node->_animPitch;
float animPitch = node->_pitch + node->_animPitch / node->_totalWeight; float animYaw = node->_yaw + node->_animYaw;
float animYaw = node->_yaw + node->_animYaw / node->_totalWeight; float animRoll = node->_roll + node->_animRoll;
float animRoll = node->_roll + node->_animRoll / node->_totalWeight; translateViewpointStart(animPos, animPitch, animYaw, animRoll);
translateViewpointStart(animPos, animPitch, animYaw, animRoll);
} else {
translateViewpointStart(node->_pos, node->_pitch, node->_yaw, node->_roll);
}
if (node->_hierVisible) { if (node->_hierVisible) {
tglPushMatrix(); tglPushMatrix();
tglTranslatef(node->_pivot.x(), node->_pivot.y(), node->_pivot.z()); tglTranslatef(node->_pivot.x(), node->_pivot.y(), node->_pivot.z());

View file

@ -149,22 +149,19 @@ KeyframeAnim::~KeyframeAnim() {
g_resourceloader->uncacheKeyframe(this); 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; float frame = time * _fps;
if (frame > _numFrames) if (frame > _numFrames)
frame = _numFrames; frame = _numFrames;
// Without this sending the bread down the tube in "mo" often crashes, if (_nodes[num] && tagged == ((_type & nodes[num]._type) != 0))
// because it goes outside the bounds of the array of the nodes. _nodes[num]->animate(nodes[num], frame, fade);
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);
}
} }
void KeyframeAnim::KeyframeEntry::loadBinary(const char *&data) { void KeyframeAnim::KeyframeEntry::loadBinary(const char *&data) {
@ -222,11 +219,9 @@ KeyframeAnim::KeyframeNode::~KeyframeNode() {
delete[] _entries; 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) if (_numEntries == 0)
return; return;
if (priority < node._priority)
return;
// Do a binary search for the nearest previous frame // Do a binary search for the nearest previous frame
// Loop invariant: entries_[low].frame_ <= frame < entries_[high].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 yaw = _entries[low]._yaw + dt * _entries[low]._dyaw;
float roll = _entries[low]._roll + dt * _entries[low]._droll; 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; node._animPos += (pos - node._pos) * fade;
float dpitch = pitch - node._pitch; float dpitch = pitch - node._pitch;
@ -284,8 +262,6 @@ void KeyframeAnim::KeyframeNode::animate(Model::HierNode &node, float frame, int
while (droll < -180) while (droll < -180)
droll += 360; droll += 360;
node._animRoll += droll * fade; node._animRoll += droll * fade;
node._totalWeight += fade;
} }
} // end of namespace Grim } // end of namespace Grim

View file

@ -34,7 +34,7 @@ public:
void loadBinary(const char *data, int len); void loadBinary(const char *data, int len);
void loadText(TextSplitter &ts); 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; } float getLength() const { return _numFrames / _fps; }
const Common::String &getFilename() const { return _fname; } const Common::String &getFilename() const { return _fname; }
@ -66,7 +66,7 @@ private:
void loadText(TextSplitter &ts); void loadText(TextSplitter &ts);
~KeyframeNode(); ~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]; char _meshName[32];
int _numEntries; int _numEntries;

View file

@ -273,8 +273,6 @@ void Model::HierNode::loadBinary(const char *&data, Model::HierNode *hierNodes,
_animPitch = 0; _animPitch = 0;
_animYaw = 0; _animYaw = 0;
_animRoll = 0; _animRoll = 0;
_priority = -1;
_totalWeight = 0;
_sprite = NULL; _sprite = NULL;
data += 184; data += 184;
@ -393,7 +391,6 @@ void Model::loadText(TextSplitter *ts, CMap *cmap) {
_rootHierNode[num]._pivot = Graphics::Vector3d(pivotx, pivoty, pivotz); _rootHierNode[num]._pivot = Graphics::Vector3d(pivotx, pivoty, pivotz);
_rootHierNode[num]._meshVisible = true; _rootHierNode[num]._meshVisible = true;
_rootHierNode[num]._hierVisible = true; _rootHierNode[num]._hierVisible = true;
_rootHierNode[num]._totalWeight = 0;
_rootHierNode[num]._sprite = NULL; _rootHierNode[num]._sprite = NULL;
} }
@ -551,18 +548,13 @@ void Model::HierNode::update() {
if (!_initialized) if (!_initialized)
return; return;
if (_totalWeight > 0) { Graphics::Vector3d animPos = _pos + _animPos;
Graphics::Vector3d animPos = _pos + _animPos / _totalWeight; float animPitch = _pitch + _animPitch;
float animPitch = _pitch + _animPitch / _totalWeight; float animYaw = _yaw + _animYaw;
float animYaw = _yaw + _animYaw / _totalWeight; float animRoll = _roll + _animRoll;
float animRoll = _roll + _animRoll / _totalWeight;
_localMatrix._pos.set(animPos.x(), animPos.y(), animPos.z()); _localMatrix._pos.set(animPos.x(), animPos.y(), animPos.z());
_localMatrix._rot.buildFromPitchYawRoll(animPitch, animYaw, animRoll); _localMatrix._rot.buildFromPitchYawRoll(animPitch, animYaw, animRoll);
} else {
_localMatrix._pos.set(_pos.x(), _pos.y(), _pos.z());
_localMatrix._rot.buildFromPitchYawRoll(_pitch, _yaw, _roll);
}
_matrix *= _localMatrix; _matrix *= _localMatrix;

View file

@ -83,8 +83,6 @@ public:
Graphics::Vector3d _animPos; Graphics::Vector3d _animPos;
float _animPitch, _animYaw, _animRoll; float _animPitch, _animYaw, _animRoll;
bool _meshVisible, _hierVisible; bool _meshVisible, _hierVisible;
int _priority;
float _totalWeight;
bool _initialized; bool _initialized;
Graphics::Matrix4 _matrix; Graphics::Matrix4 _matrix;
Graphics::Matrix4 _localMatrix; Graphics::Matrix4 _localMatrix;