mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 03:42:48 +01:00
Change Animator to animate Frames directly instead of Skeleton
This commit is contained in:
parent
3163a5dd57
commit
ec5f1d7b55
@ -3,9 +3,9 @@
|
||||
#include <engine/Animator.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <loaders/LoaderDFF.hpp>
|
||||
#include <queue>
|
||||
|
||||
Animator::Animator(Clump* model, Skeleton* skeleton)
|
||||
: model(model), skeleton(skeleton) {
|
||||
Animator::Animator(Clump* model) : model(model) {
|
||||
}
|
||||
|
||||
void Animator::tick(float dt) {
|
||||
@ -18,21 +18,21 @@ void Animator::tick(float dt) {
|
||||
glm::quat rotation;
|
||||
};
|
||||
|
||||
#if 0
|
||||
// Blend all active animations together
|
||||
std::map<unsigned int, BoneTransform> blendFrames;
|
||||
std::map<ModelFrame*, BoneTransform> blendFrames;
|
||||
#endif
|
||||
|
||||
for (AnimationState& state : animations) {
|
||||
RW_CHECK(state.animation != nullptr,
|
||||
"AnimationState with no animation");
|
||||
if (state.animation == nullptr) continue;
|
||||
|
||||
if (state.boneInstances.size() == 0) {
|
||||
for (unsigned int f = 0; f < model->frames.size(); ++f) {
|
||||
auto bit =
|
||||
state.animation->bones.find(model->frames[f]->getName());
|
||||
if (bit != state.animation->bones.end()) {
|
||||
state.boneInstances.insert({bit->second, {f}});
|
||||
if (state.boneInstances.empty()) {
|
||||
for (const auto& bone : state.animation->bones) {
|
||||
auto frame = model->findFrame(bone.first);
|
||||
if (!frame) {
|
||||
continue;
|
||||
}
|
||||
state.boneInstances.insert({bone.second, frame});
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,23 +72,20 @@ void Animator::tick(float dt) {
|
||||
blendFrames[b.second.frameIndex] = xform;
|
||||
}
|
||||
#else
|
||||
blendFrames[b.second.frameIndex] = xform;
|
||||
b.second->setTranslation(b.second->getDefaultTranslation() +
|
||||
xform.translation);
|
||||
b.second->setRotation(glm::mat3_cast(xform.rotation));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (auto& p : blendFrames) {
|
||||
auto& data = skeleton->getData(p.first);
|
||||
Skeleton::FrameData fd;
|
||||
fd.b = data.a;
|
||||
fd.enabled = data.enabled;
|
||||
|
||||
fd.a.translation = model->frames[p.first]->getDefaultTranslation() +
|
||||
p.second.translation;
|
||||
fd.a.rotation = p.second.rotation;
|
||||
|
||||
skeleton->setData(p.first, fd);
|
||||
p.first->setTranslation(p.first->getDefaultTranslation() +
|
||||
p.second.translation);
|
||||
p.first->setRotation(glm::mat3_cast(p.second.rotation));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Animator::isCompleted(unsigned int slot) const {
|
||||
|
@ -11,8 +11,6 @@
|
||||
class Clump;
|
||||
class ModelFrame;
|
||||
|
||||
class Skeleton;
|
||||
|
||||
/**
|
||||
* @brief calculates animation frame matrices, as well as procedural frame
|
||||
* animation.
|
||||
@ -24,13 +22,6 @@ class Skeleton;
|
||||
* The Animator will blend all active animations together.
|
||||
*/
|
||||
class Animator {
|
||||
/**
|
||||
* @brief Stores data required to animate a model frame
|
||||
*/
|
||||
struct BoneInstanceData {
|
||||
unsigned int frameIndex;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The AnimationState struct stores information about playing
|
||||
* animations
|
||||
@ -43,7 +34,7 @@ class Animator {
|
||||
float speed;
|
||||
/// Automatically restart
|
||||
bool repeat;
|
||||
std::map<AnimationBone*, BoneInstanceData> boneInstances;
|
||||
std::map<AnimationBone*, ModelFrame*> boneInstances;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -51,18 +42,13 @@ class Animator {
|
||||
*/
|
||||
Clump* model;
|
||||
|
||||
/**
|
||||
* @brief Skeleton instance.
|
||||
*/
|
||||
Skeleton* skeleton;
|
||||
|
||||
/**
|
||||
* @brief Currently playing animations
|
||||
*/
|
||||
std::vector<AnimationState> animations;
|
||||
|
||||
public:
|
||||
Animator(Clump* model, Skeleton* skeleton);
|
||||
Animator(Clump* model);
|
||||
|
||||
Animation* getAnimation(unsigned int slot) {
|
||||
if (slot < animations.size()) {
|
||||
|
@ -74,8 +74,7 @@ CharacterObject::CharacterObject(GameWorld* engine, const glm::vec3& pos,
|
||||
setClump(ClumpPtr(info->getModel()->clone()));
|
||||
if (info->getModel()) {
|
||||
setModel(info->getModel());
|
||||
skeleton = new Skeleton;
|
||||
animator = new Animator(getModel(), skeleton);
|
||||
animator = new Animator(getClump().get());
|
||||
|
||||
createActor();
|
||||
}
|
||||
@ -251,10 +250,6 @@ glm::vec3 CharacterObject::updateMovementAnimation(float dt) {
|
||||
rootBone->getInterpolatedKeyframe(animTime + step).position;
|
||||
glm::vec3 d = (b - a);
|
||||
animTranslate.y += d.y;
|
||||
|
||||
Skeleton::FrameData fd = skeleton->getData(root->getIndex());
|
||||
fd.a.translation.y = 0.f;
|
||||
skeleton->setData(root->getIndex(), fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,6 +273,7 @@ void CharacterObject::tick(float dt) {
|
||||
void CharacterObject::setRotation(const glm::quat& orientation) {
|
||||
m_look.x = glm::roll(orientation);
|
||||
rotation = orientation;
|
||||
getClump()->getFrame()->setRotation(glm::mat3_cast(rotation));
|
||||
}
|
||||
|
||||
#include <algorithm>
|
||||
@ -291,15 +287,13 @@ void CharacterObject::changeCharacterModel(const std::string& name) {
|
||||
engine->data->loadTXD(modelName + ".txd");
|
||||
auto newmodel = engine->data->loadClump(modelName + ".dff");
|
||||
|
||||
if (skeleton) {
|
||||
if (animator) {
|
||||
delete animator;
|
||||
delete skeleton;
|
||||
}
|
||||
|
||||
setModel(newmodel);
|
||||
|
||||
skeleton = new Skeleton;
|
||||
animator = new Animator(getModel(), skeleton);
|
||||
animator = new Animator(getClump().get());
|
||||
}
|
||||
|
||||
void CharacterObject::updateCharacter(float dt) {
|
||||
|
@ -14,8 +14,7 @@ CutsceneObject::CutsceneObject(GameWorld *engine, const glm::vec3 &pos,
|
||||
else {
|
||||
setModel(getModelInfo<ClumpModelInfo>()->getModel());
|
||||
}
|
||||
skeleton = new Skeleton;
|
||||
animator = new Animator(getModel(), skeleton);
|
||||
animator = new Animator(getModel());
|
||||
}
|
||||
|
||||
CutsceneObject::~CutsceneObject() {
|
||||
|
@ -17,7 +17,7 @@ BOOST_AUTO_TEST_CASE(test_matrix) {
|
||||
* frame #s. */
|
||||
auto test_model = Global::get().d->loadClump("player.dff");
|
||||
|
||||
Animator animator(test_model, &skeleton);
|
||||
Animator animator(test_model);
|
||||
|
||||
animation.duration = 1.f;
|
||||
animation.bones["player"] = new AnimationBone{
|
||||
@ -35,17 +35,15 @@ BOOST_AUTO_TEST_CASE(test_matrix) {
|
||||
|
||||
animator.tick(0.0f);
|
||||
|
||||
BOOST_CHECK(skeleton.getData(0).a.translation ==
|
||||
glm::vec3(0.f, 0.f, 0.f));
|
||||
BOOST_CHECK(skeleton.getData(0).b.translation ==
|
||||
const auto& root = test_model->findFrame("player");
|
||||
|
||||
BOOST_CHECK(glm::vec3(root->getTransform()[3]) ==
|
||||
glm::vec3(0.f, 0.f, 0.f));
|
||||
|
||||
animator.tick(1.0f);
|
||||
|
||||
BOOST_CHECK(skeleton.getData(0).a.translation ==
|
||||
BOOST_CHECK(glm::vec3(root->getTransform()[3]) ==
|
||||
glm::vec3(0.f, 1.f, 0.f));
|
||||
BOOST_CHECK(skeleton.getData(0).b.translation ==
|
||||
glm::vec3(0.f, 0.f, 0.f));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user