Clean up the code to be not everything in hpp files.
This commit is contained in:
parent
a1c8208b47
commit
6d21b7f163
6 changed files with 308 additions and 264 deletions
|
|
@ -1 +1,84 @@
|
|||
#include "animation.hpp"
|
||||
#include "model.hpp"
|
||||
#include "assimp_glm_helpers.hpp"
|
||||
|
||||
Animation::Animation(const std::string& animationPath, Model *model) {
|
||||
Assimp::Importer importer;
|
||||
|
||||
const aiScene* scene = importer.ReadFile(animationPath, aiProcess_Triangulate);
|
||||
dbc::check(scene != nullptr, $F("Scene for animation {} failed to load.", animationPath));
|
||||
dbc::check(scene->mRootNode, $F("Scene {} doesn't have a root node.", animationPath));
|
||||
|
||||
auto animation = scene->mAnimations[0];
|
||||
$duration = animation->mDuration;
|
||||
$ticks_per_sec = animation->mTicksPerSecond;
|
||||
aiMatrix4x4 globalTransformation = scene->mRootNode->mTransformation;
|
||||
globalTransformation = globalTransformation.Inverse();
|
||||
ReadHierarchyData($root_node, scene->mRootNode);
|
||||
ReadMissingBones(animation, *model);
|
||||
}
|
||||
|
||||
Bone* Animation::FindBone(const std::string& name) {
|
||||
auto iter = std::find_if($bones.begin(), $bones.end(),
|
||||
[&](const auto& bone) {
|
||||
return bone.GetBoneName() == name;
|
||||
}
|
||||
);
|
||||
|
||||
return iter == $bones.end() ? nullptr : &(*iter);
|
||||
}
|
||||
|
||||
float Animation::GetTicksPerSecond() {
|
||||
return $ticks_per_sec;
|
||||
}
|
||||
|
||||
float Animation::GetDuration() {
|
||||
return $duration;
|
||||
}
|
||||
|
||||
const AssimpNodeData& Animation::GetRootNode() {
|
||||
return $root_node;
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, BoneInfo>& Animation::GetBoneIDMap()
|
||||
{
|
||||
return $bone_info_map;
|
||||
}
|
||||
|
||||
void Animation::ReadMissingBones(const aiAnimation* animation, Model& model) {
|
||||
// this code is weird as hell
|
||||
int size = animation->mNumChannels;
|
||||
auto& boneInfoMap = model.bone_info_map;
|
||||
int& boneCount = model.bone_counter;
|
||||
|
||||
for(int i = 0; i < size; i++) {
|
||||
auto channel = animation->mChannels[i];
|
||||
std::string boneName = channel->mNodeName.data;
|
||||
|
||||
if(!boneInfoMap.contains(boneName)) {
|
||||
boneInfoMap[boneName].id = boneCount;
|
||||
boneCount++;
|
||||
}
|
||||
|
||||
dbc::check(boneCount < MAX_BONES, "Too many bones!");
|
||||
|
||||
$bones.emplace_back(boneName,
|
||||
boneInfoMap[boneName].id, channel);
|
||||
}
|
||||
|
||||
$bone_info_map = boneInfoMap;
|
||||
}
|
||||
|
||||
void Animation::ReadHierarchyData(AssimpNodeData& dest, const aiNode* src) {
|
||||
dbc::check(src != nullptr, "aiNode src is null?!");
|
||||
|
||||
dest.name = src->mName.data;
|
||||
dest.transformation = AssimpGLMHelpers::ConvertMatrixToGLMFormat(src->mTransformation);
|
||||
dest.children_count = src->mNumChildren;
|
||||
|
||||
for(size_t i = 0; i < src->mNumChildren; i++) {
|
||||
AssimpNodeData newData;
|
||||
ReadHierarchyData(newData, src->mChildren[i]);
|
||||
dest.children.push_back(newData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
#include <functional>
|
||||
#include "animdata.hpp"
|
||||
#include "bone.hpp"
|
||||
#include "model.hpp"
|
||||
#include "assimp_glm_helpers.hpp"
|
||||
|
||||
struct Bone;
|
||||
|
||||
|
|
@ -28,88 +26,21 @@ struct Animation {
|
|||
|
||||
Animation() = default;
|
||||
|
||||
Animation(const std::string& animationPath, Model *model) {
|
||||
Assimp::Importer importer;
|
||||
Animation(const std::string& animationPath, Model *model);
|
||||
|
||||
const aiScene* scene = importer.ReadFile(animationPath, aiProcess_Triangulate);
|
||||
dbc::check(scene != nullptr, $F("Scene for animation {} failed to load.", animationPath));
|
||||
dbc::check(scene->mRootNode, $F("Scene {} doesn't have a root node.", animationPath));
|
||||
~Animation() {}
|
||||
|
||||
auto animation = scene->mAnimations[0];
|
||||
$duration = animation->mDuration;
|
||||
$ticks_per_sec = animation->mTicksPerSecond;
|
||||
aiMatrix4x4 globalTransformation = scene->mRootNode->mTransformation;
|
||||
globalTransformation = globalTransformation.Inverse();
|
||||
ReadHierarchyData($root_node, scene->mRootNode);
|
||||
ReadMissingBones(animation, *model);
|
||||
}
|
||||
Bone* FindBone(const std::string& name);
|
||||
|
||||
~Animation() {
|
||||
}
|
||||
float GetTicksPerSecond();
|
||||
|
||||
float GetDuration();
|
||||
|
||||
Bone* FindBone(const std::string& name) {
|
||||
auto iter = std::find_if($bones.begin(), $bones.end(),
|
||||
[&](const auto& bone) {
|
||||
return bone.GetBoneName() == name;
|
||||
}
|
||||
);
|
||||
const AssimpNodeData& GetRootNode();
|
||||
|
||||
return iter == $bones.end() ? nullptr : &(*iter);
|
||||
}
|
||||
const std::unordered_map<std::string, BoneInfo>& GetBoneIDMap();
|
||||
|
||||
float GetTicksPerSecond() {
|
||||
return $ticks_per_sec;
|
||||
}
|
||||
void ReadMissingBones(const aiAnimation* animation, Model& model);
|
||||
|
||||
float GetDuration() {
|
||||
return $duration;
|
||||
}
|
||||
|
||||
const AssimpNodeData& GetRootNode() {
|
||||
return $root_node;
|
||||
}
|
||||
|
||||
const std::unordered_map<std::string, BoneInfo>& GetBoneIDMap()
|
||||
{
|
||||
return $bone_info_map;
|
||||
}
|
||||
|
||||
void ReadMissingBones(const aiAnimation* animation, Model& model) {
|
||||
// this code is weird as hell
|
||||
int size = animation->mNumChannels;
|
||||
auto& boneInfoMap = model.bone_info_map;
|
||||
int& boneCount = model.bone_counter;
|
||||
|
||||
for(int i = 0; i < size; i++) {
|
||||
auto channel = animation->mChannels[i];
|
||||
std::string boneName = channel->mNodeName.data;
|
||||
|
||||
if(!boneInfoMap.contains(boneName)) {
|
||||
boneInfoMap[boneName].id = boneCount;
|
||||
boneCount++;
|
||||
}
|
||||
|
||||
dbc::check(boneCount < MAX_BONES, "Too many bones!");
|
||||
|
||||
$bones.emplace_back(boneName,
|
||||
boneInfoMap[boneName].id, channel);
|
||||
}
|
||||
|
||||
$bone_info_map = boneInfoMap;
|
||||
}
|
||||
|
||||
void ReadHierarchyData(AssimpNodeData& dest, const aiNode* src) {
|
||||
dbc::check(src != nullptr, "aiNode src is null?!");
|
||||
|
||||
dest.name = src->mName.data;
|
||||
dest.transformation = AssimpGLMHelpers::ConvertMatrixToGLMFormat(src->mTransformation);
|
||||
dest.children_count = src->mNumChildren;
|
||||
|
||||
for(size_t i = 0; i < src->mNumChildren; i++) {
|
||||
AssimpNodeData newData;
|
||||
ReadHierarchyData(newData, src->mChildren[i]);
|
||||
dest.children.push_back(newData);
|
||||
}
|
||||
}
|
||||
void ReadHierarchyData(AssimpNodeData& dest, const aiNode* src);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1 +1,57 @@
|
|||
#include "animator.hpp"
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/Importer.hpp>
|
||||
#include "bone.hpp"
|
||||
|
||||
Animator::Animator(Animation* animation) :
|
||||
$current_animation(animation)
|
||||
{
|
||||
$final_bone_matrices.reserve(MAX_BONES);
|
||||
|
||||
for(size_t i = 0; i < MAX_BONES; i++) {
|
||||
$final_bone_matrices.push_back(glm::mat4(1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::UpdateAnimation(float current_time) {
|
||||
if($current_animation) {
|
||||
$current_time = $current_animation->GetTicksPerSecond() * current_time;
|
||||
$current_time = fmod($current_time, $current_animation->GetDuration());
|
||||
CalculateBoneTransform(&$current_animation->GetRootNode(), glm::mat4(1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::PlayAnimation(Animation* animation) {
|
||||
$current_animation = animation;
|
||||
$current_time = 0.0f;
|
||||
}
|
||||
|
||||
void Animator::CalculateBoneTransform(const AssimpNodeData* node, glm::mat4 parentTransform) {
|
||||
std::string node_name = node->name;
|
||||
glm::mat4 node_transform = node->transformation;
|
||||
|
||||
Bone *bone = $current_animation->FindBone(node_name);
|
||||
|
||||
if(bone) {
|
||||
bone->Update($current_time);
|
||||
node_transform = bone->GetLocalTransform();
|
||||
}
|
||||
|
||||
glm::mat4 global_transformation = parentTransform * node_transform;
|
||||
|
||||
auto bone_map = $current_animation->GetBoneIDMap();
|
||||
|
||||
if(bone_map.contains(node_name)) {
|
||||
auto& bone_info = bone_map[node_name];
|
||||
|
||||
$final_bone_matrices[bone_info.id] = global_transformation * bone_info.offset;
|
||||
}
|
||||
|
||||
for(int i = 0; i < node->children_count; i++) {
|
||||
CalculateBoneTransform(&node->children[i], global_transformation);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<glm::mat4>& Animator::GetFinalBoneMatrices() {
|
||||
return $final_bone_matrices;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,72 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/Importer.hpp>
|
||||
#include "animation.hpp"
|
||||
#include "bone.hpp"
|
||||
|
||||
struct Bone;
|
||||
|
||||
struct Animator {
|
||||
std::vector<glm::mat4> $final_bone_matrices;
|
||||
Animation* $current_animation = nullptr;
|
||||
float $current_time = 0.0f;
|
||||
|
||||
Animator(Animation* animation) :
|
||||
$current_animation(animation)
|
||||
{
|
||||
$final_bone_matrices.reserve(MAX_BONES);
|
||||
Animator(Animation* animation);
|
||||
|
||||
for(size_t i = 0; i < MAX_BONES; i++) {
|
||||
$final_bone_matrices.push_back(glm::mat4(1.0f));
|
||||
}
|
||||
}
|
||||
void UpdateAnimation(float current_time);
|
||||
|
||||
void UpdateAnimation(float current_time) {
|
||||
if($current_animation) {
|
||||
$current_time = $current_animation->GetTicksPerSecond() * current_time;
|
||||
$current_time = fmod($current_time, $current_animation->GetDuration());
|
||||
CalculateBoneTransform(&$current_animation->GetRootNode(), glm::mat4(1.0f));
|
||||
}
|
||||
}
|
||||
void PlayAnimation(Animation* animation);
|
||||
|
||||
void PlayAnimation(Animation* animation) {
|
||||
$current_animation = animation;
|
||||
$current_time = 0.0f;
|
||||
}
|
||||
|
||||
void CalculateBoneTransform(const AssimpNodeData* node, glm::mat4 parentTransform) {
|
||||
std::string node_name = node->name;
|
||||
glm::mat4 node_transform = node->transformation;
|
||||
|
||||
Bone *bone = $current_animation->FindBone(node_name);
|
||||
|
||||
if(bone) {
|
||||
bone->Update($current_time);
|
||||
node_transform = bone->GetLocalTransform();
|
||||
}
|
||||
|
||||
glm::mat4 global_transformation = parentTransform * node_transform;
|
||||
|
||||
auto bone_map = $current_animation->GetBoneIDMap();
|
||||
|
||||
if(bone_map.contains(node_name)) {
|
||||
auto& bone_info = bone_map[node_name];
|
||||
|
||||
$final_bone_matrices[bone_info.id] = global_transformation * bone_info.offset;
|
||||
}
|
||||
|
||||
for(int i = 0; i < node->children_count; i++) {
|
||||
CalculateBoneTransform(&node->children[i], global_transformation);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<glm::mat4>& GetFinalBoneMatrices() {
|
||||
return $final_bone_matrices;
|
||||
}
|
||||
void CalculateBoneTransform(const AssimpNodeData* node, glm::mat4 parentTransform);
|
||||
|
||||
std::vector<glm::mat4>& GetFinalBoneMatrices();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1 +1,144 @@
|
|||
#include "bone.hpp"
|
||||
#include "assimp_glm_helpers.hpp"
|
||||
|
||||
Bone::Bone(const std::string& name, int ID, const aiNodeAnim* channel) :
|
||||
$name(name),
|
||||
$id(ID)
|
||||
{
|
||||
$num_positions = channel->mNumPositionKeys;
|
||||
|
||||
for(size_t pos_i = 0; pos_i < $num_positions; pos_i++) {
|
||||
const auto& ai_position = channel->mPositionKeys[pos_i];
|
||||
auto position = AssimpGLMHelpers::GetGLMVec(ai_position.mValue);
|
||||
$positions.emplace_back(position, ai_position.mTime);
|
||||
}
|
||||
|
||||
$num_rotations = channel->mNumRotationKeys;
|
||||
for(size_t rot_i = 0; rot_i < $num_rotations; rot_i++) {
|
||||
const auto& ai_orientation = channel->mRotationKeys[rot_i];
|
||||
auto orientation = AssimpGLMHelpers::GetGLMQuat(ai_orientation.mValue);
|
||||
|
||||
$rotations.emplace_back(orientation, ai_orientation.mTime);
|
||||
}
|
||||
|
||||
$num_scalings = channel->mNumScalingKeys;
|
||||
for(size_t key_i = 0; key_i < $num_scalings; key_i++) {
|
||||
const auto& ai_scale = channel->mScalingKeys[key_i];
|
||||
auto scale = AssimpGLMHelpers::GetGLMVec(ai_scale.mValue);
|
||||
$scales.emplace_back(scale, ai_scale.mTime);
|
||||
}
|
||||
}
|
||||
|
||||
void Bone::Update(float animationTime) {
|
||||
glm::mat4 translation = InterpolatPosition(animationTime);
|
||||
glm::mat4 rotation = InterpolateRotation(animationTime);
|
||||
glm::mat4 scale = InterpolateScaling(animationTime);
|
||||
$local_transform = translation * rotation * scale;
|
||||
}
|
||||
|
||||
glm::mat4 Bone::GetLocalTransform() {
|
||||
return $local_transform;
|
||||
}
|
||||
|
||||
std::string Bone::GetBoneName() const {
|
||||
return $name;
|
||||
}
|
||||
|
||||
int Bone::GetBoneId() {
|
||||
return $id;
|
||||
}
|
||||
|
||||
int Bone::GetPositionIndex(float animationTime) {
|
||||
for(size_t index = 0; index < $num_positions - 1; ++index) {
|
||||
auto ts = $positions[index + 1].timeStamp;
|
||||
|
||||
if(animationTime < ts) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
dbc::sentinel("Failed to find an animation position");
|
||||
}
|
||||
|
||||
int Bone::GetRotationIndex(float animationTime) {
|
||||
for(size_t index = 0; index < $num_rotations - 1; ++index) {
|
||||
auto ts = $rotations[index + 1].timeStamp;
|
||||
|
||||
if(animationTime < ts) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
dbc::sentinel("Failed to find an animation rotation");
|
||||
}
|
||||
|
||||
int Bone::GetScaleIndex(float animationTime) {
|
||||
for(size_t index = 0; index < $num_scalings - 1; ++index) {
|
||||
auto ts = $scales[index + 1].timeStamp;
|
||||
if(animationTime < ts) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
dbc::sentinel("Failed to find an animation scale");
|
||||
}
|
||||
|
||||
float Bone::GetScaleFactor(float lastTimeStamp, float nextTimeStamp, float animationTime) {
|
||||
float scaleFactor = 0.0f;
|
||||
float midWayLength = animationTime - lastTimeStamp;
|
||||
float framesDiff = nextTimeStamp - lastTimeStamp;
|
||||
scaleFactor = midWayLength / framesDiff;
|
||||
return scaleFactor;
|
||||
}
|
||||
|
||||
glm::mat4 Bone::InterpolatPosition(float animationTime) {
|
||||
if($num_positions == 1) {
|
||||
return glm::translate(glm::mat4(1.0f), $positions[0].position);
|
||||
}
|
||||
|
||||
int p0Index = GetPositionIndex(animationTime);
|
||||
auto& p0 = $positions[p0Index];
|
||||
auto& p1 = $positions[p0Index + 1];
|
||||
|
||||
float scaleFactor = GetScaleFactor(
|
||||
p0.timeStamp, p1.timeStamp, animationTime);
|
||||
|
||||
glm::vec3 finalPosition = glm::mix(p0.position,
|
||||
p1.position, scaleFactor);
|
||||
|
||||
return glm::translate(glm::mat4(1.0f), finalPosition);
|
||||
}
|
||||
|
||||
glm::mat4 Bone::InterpolateRotation(float animationTime) {
|
||||
if($num_rotations == 1) {
|
||||
auto rotation = glm::normalize($rotations[0].orientation);
|
||||
return glm::toMat4(rotation);
|
||||
}
|
||||
|
||||
int p0Index = GetRotationIndex(animationTime);
|
||||
auto& p0 = $rotations[p0Index];
|
||||
auto& p1 = $rotations[p0Index + 1];
|
||||
|
||||
float scaleFactor = GetScaleFactor(
|
||||
p0.timeStamp, p1.timeStamp, animationTime);
|
||||
|
||||
glm::quat finalRotation = glm::slerp(
|
||||
p0.orientation, p1.orientation, scaleFactor);
|
||||
|
||||
return glm::toMat4(finalRotation);
|
||||
}
|
||||
|
||||
glm::mat4 Bone::InterpolateScaling(float animationTime) {
|
||||
if($num_scalings == 1) {
|
||||
return glm::scale(glm::mat4(1.0f), $scales[0].scale);
|
||||
}
|
||||
|
||||
int p0Index = GetScaleIndex(animationTime);
|
||||
|
||||
auto& p0 = $scales[p0Index];
|
||||
auto& p1 = $scales[p0Index + 1];
|
||||
float scaleFactor = GetScaleFactor(
|
||||
p0.timeStamp, p1.timeStamp, animationTime);
|
||||
|
||||
glm::vec3 finalScale = glm::mix(p0.scale, p1.scale, scaleFactor);
|
||||
|
||||
return glm::scale(glm::mat4(1.0f), finalScale);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include <glm/glm.hpp>
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include "assimp_glm_helpers.hpp"
|
||||
#include <string>
|
||||
|
||||
struct KeyPosition {
|
||||
|
|
@ -40,145 +39,27 @@ struct Bone
|
|||
std::string $name{};
|
||||
int $id = 0;
|
||||
|
||||
Bone(const std::string& name, int ID, const aiNodeAnim* channel) :
|
||||
$name(name),
|
||||
$id(ID)
|
||||
{
|
||||
$num_positions = channel->mNumPositionKeys;
|
||||
Bone(const std::string& name, int ID, const aiNodeAnim* channel);
|
||||
|
||||
for(size_t pos_i = 0; pos_i < $num_positions; pos_i++) {
|
||||
const auto& ai_position = channel->mPositionKeys[pos_i];
|
||||
auto position = AssimpGLMHelpers::GetGLMVec(ai_position.mValue);
|
||||
$positions.emplace_back(position, ai_position.mTime);
|
||||
}
|
||||
void Update(float animationTime);
|
||||
|
||||
$num_rotations = channel->mNumRotationKeys;
|
||||
for(size_t rot_i = 0; rot_i < $num_rotations; rot_i++) {
|
||||
const auto& ai_orientation = channel->mRotationKeys[rot_i];
|
||||
auto orientation = AssimpGLMHelpers::GetGLMQuat(ai_orientation.mValue);
|
||||
glm::mat4 GetLocalTransform();
|
||||
|
||||
$rotations.emplace_back(orientation, ai_orientation.mTime);
|
||||
}
|
||||
std::string GetBoneName() const;
|
||||
|
||||
$num_scalings = channel->mNumScalingKeys;
|
||||
for(size_t key_i = 0; key_i < $num_scalings; key_i++) {
|
||||
const auto& ai_scale = channel->mScalingKeys[key_i];
|
||||
auto scale = AssimpGLMHelpers::GetGLMVec(ai_scale.mValue);
|
||||
$scales.emplace_back(scale, ai_scale.mTime);
|
||||
}
|
||||
}
|
||||
int GetBoneId();
|
||||
|
||||
void Update(float animationTime) {
|
||||
glm::mat4 translation = InterpolatPosition(animationTime);
|
||||
glm::mat4 rotation = InterpolateRotation(animationTime);
|
||||
glm::mat4 scale = InterpolateScaling(animationTime);
|
||||
$local_transform = translation * rotation * scale;
|
||||
}
|
||||
int GetPositionIndex(float animationTime);
|
||||
|
||||
glm::mat4 GetLocalTransform() {
|
||||
return $local_transform;
|
||||
}
|
||||
int GetRotationIndex(float animationTime);
|
||||
|
||||
std::string GetBoneName() const {
|
||||
return $name;
|
||||
}
|
||||
int GetScaleIndex(float animationTime);
|
||||
|
||||
int GetBoneId() {
|
||||
return $id;
|
||||
}
|
||||
float GetScaleFactor(float lastTimeStamp, float nextTimeStamp, float animationTime);
|
||||
|
||||
int GetPositionIndex(float animationTime) {
|
||||
for(size_t index = 0; index < $num_positions - 1; ++index) {
|
||||
auto ts = $positions[index + 1].timeStamp;
|
||||
glm::mat4 InterpolatPosition(float animationTime);
|
||||
|
||||
if(animationTime < ts) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
glm::mat4 InterpolateRotation(float animationTime);
|
||||
|
||||
dbc::sentinel("Failed to find an animation position");
|
||||
}
|
||||
|
||||
int GetRotationIndex(float animationTime) {
|
||||
for(size_t index = 0; index < $num_rotations - 1; ++index) {
|
||||
auto ts = $rotations[index + 1].timeStamp;
|
||||
|
||||
if(animationTime < ts) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
dbc::sentinel("Failed to find an animation rotation");
|
||||
}
|
||||
|
||||
int GetScaleIndex(float animationTime) {
|
||||
for(size_t index = 0; index < $num_scalings - 1; ++index) {
|
||||
auto ts = $scales[index + 1].timeStamp;
|
||||
if(animationTime < ts) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
dbc::sentinel("Failed to find an animation scale");
|
||||
}
|
||||
|
||||
float GetScaleFactor(float lastTimeStamp, float nextTimeStamp, float animationTime) {
|
||||
float scaleFactor = 0.0f;
|
||||
float midWayLength = animationTime - lastTimeStamp;
|
||||
float framesDiff = nextTimeStamp - lastTimeStamp;
|
||||
scaleFactor = midWayLength / framesDiff;
|
||||
return scaleFactor;
|
||||
}
|
||||
|
||||
glm::mat4 InterpolatPosition(float animationTime) {
|
||||
if($num_positions == 1) {
|
||||
return glm::translate(glm::mat4(1.0f), $positions[0].position);
|
||||
}
|
||||
|
||||
int p0Index = GetPositionIndex(animationTime);
|
||||
auto& p0 = $positions[p0Index];
|
||||
auto& p1 = $positions[p0Index + 1];
|
||||
|
||||
float scaleFactor = GetScaleFactor(
|
||||
p0.timeStamp, p1.timeStamp, animationTime);
|
||||
|
||||
glm::vec3 finalPosition = glm::mix(p0.position,
|
||||
p1.position, scaleFactor);
|
||||
|
||||
return glm::translate(glm::mat4(1.0f), finalPosition);
|
||||
}
|
||||
|
||||
glm::mat4 InterpolateRotation(float animationTime) {
|
||||
if($num_rotations == 1) {
|
||||
auto rotation = glm::normalize($rotations[0].orientation);
|
||||
return glm::toMat4(rotation);
|
||||
}
|
||||
|
||||
int p0Index = GetRotationIndex(animationTime);
|
||||
auto& p0 = $rotations[p0Index];
|
||||
auto& p1 = $rotations[p0Index + 1];
|
||||
|
||||
float scaleFactor = GetScaleFactor(
|
||||
p0.timeStamp, p1.timeStamp, animationTime);
|
||||
|
||||
glm::quat finalRotation = glm::slerp(
|
||||
p0.orientation, p1.orientation, scaleFactor);
|
||||
|
||||
return glm::toMat4(finalRotation);
|
||||
}
|
||||
|
||||
glm::mat4 InterpolateScaling(float animationTime) {
|
||||
if($num_scalings == 1) {
|
||||
return glm::scale(glm::mat4(1.0f), $scales[0].scale);
|
||||
}
|
||||
|
||||
int p0Index = GetScaleIndex(animationTime);
|
||||
|
||||
auto& p0 = $scales[p0Index];
|
||||
auto& p1 = $scales[p0Index + 1];
|
||||
float scaleFactor = GetScaleFactor(
|
||||
p0.timeStamp, p1.timeStamp, animationTime);
|
||||
|
||||
glm::vec3 finalScale = glm::mix(p0.scale, p1.scale, scaleFactor);
|
||||
|
||||
return glm::scale(glm::mat4(1.0f), finalScale);
|
||||
}
|
||||
glm::mat4 InterpolateScaling(float animationTime);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue