reading animations

This commit is contained in:
devZoGok
2022-03-09 21:04:45 +02:00
parent e23ee52257
commit 8936266dcb
19 changed files with 132 additions and 56 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ set(GUI text.cpp)
set(UTILS util.cpp)
set(MATH quaternion.cpp vector.cpp matrix.cpp ray.cpp)
set(RENDER lineRenderer.cpp particleEmitter.cpp camera.cpp light.cpp material.cpp mesh.cpp model.cpp node.cpp quad.cpp box.cpp root.cpp shader.cpp texture.cpp)
set(ANIM animationController.cpp animationChannel.cpp animation.cpp animatable.h keyframeChannel.cpp driver.cpp)
set(ANIM animationController.cpp animationChannel.cpp animation.cpp animatable.cpp keyframeChannel.cpp driver.cpp)
set(ARMATURE skeleton.cpp bone.cpp ikSolver.cpp)
set(ASSET_READERS abstractAssetReader.cpp imageReader.cpp fontReader.cpp modelReader.cpp assimpModelReader.cpp vbModelReader.cpp xmlModelReader.cpp)
set(ASSET_MANAGER assetManager.cpp textAsset.h imageAsset.h modelAsset.h fontAsset.h)
+9
View File
@@ -0,0 +1,9 @@
#include "animatable.h"
namespace vb01{
using namespace std;
Animatable::Animatable(string name){
this->name = name;
}
}
+4 -1
View File
@@ -6,8 +6,11 @@
namespace vb01{
class Animatable{
public:
Animatable(){}
Animatable(std::string = "");
virtual void animate(float, KeyframeChannel){}
inline std::string getName(){return name;}
protected:
std::string name;
};
}
+3
View File
@@ -35,6 +35,7 @@ namespace vb01{
Animation *animation = controller->getAnimation(animName);
const vector<KeyframeChannel> &keyframeChannels = animation->getKeyframeChannels();
for(KeyframeChannel ch : keyframeChannels)
for(Keyframe k : ch.keyframes)
keyframes.push_back(k);
@@ -48,6 +49,7 @@ namespace vb01{
for(int i = 0; i < keyframes.size(); i++){
int curFrameNum = keyframes[i].frame;
if(maxKeyframeNum < curFrameNum)
maxKeyframeNum = curFrameNum;
}
@@ -61,6 +63,7 @@ namespace vb01{
for(int i = 0; i < keyframes.size(); i++){
int curFrameNum = keyframes[i].frame;
if(minKeyframeNum > curFrameNum)
minKeyframeNum = curFrameNum;
}
-1
View File
@@ -27,7 +27,6 @@ namespace vb01{
inline void setIkFromTail(bool ikFromTail){this->ikFromTail = ikFromTail;}
inline void setSkeleton(Skeleton *sk){this->skeleton = sk;}
inline Vector3 getInitAxis(int i){return initAxis[i];}
inline std::string getName(){return name;}
inline Vector3 getRestPos(){return restPos;}
inline Quaternion getRestRot(){return restRot;}
inline Vector3 getRestScale(){return restScale;}
+21
View File
@@ -5,6 +5,7 @@ using namespace std;
namespace vb01{
float KeyframeChannel::interpolate(Keyframe pastKeyframe, Keyframe nextKeyframe, float ratio){
float currentValue;
switch(pastKeyframe.interpolation){
case Keyframe::CONSTANT:
currentValue = pastKeyframe.value;
@@ -17,12 +18,14 @@ namespace vb01{
currentValue = interpolateBezier(points, ratio);
break;
}
return currentValue;
}
float KeyframeChannel::interpolateBezier(vector<float> points, float ratio){
int numPoints = points.size();
vector<float> newPoints;
for(int i = 0; i < numPoints - 1; i++)
newPoints.push_back(points[i] + (points[i + 1] - points[i]) * ratio);
@@ -34,6 +37,7 @@ namespace vb01{
KeyframeChannelType KeyframeChannel::getKeyframeChannelType(string typeString){
KeyframeChannelType type;
if(typeString == "pos_x")
type = KeyframeChannelType::POS_X;
else if(typeString == "pos_y")
@@ -66,17 +70,34 @@ namespace vb01{
type = KeyframeChannelType::SHAPE_KEY_VALUE;
else if(typeString == "shape_key_max")
type = KeyframeChannelType::SHAPE_KEY_MAX;
return type;
}
Keyframe::Interpolation KeyframeChannel::getKeyframeInterpolationType(string interpString){
Keyframe::Interpolation interpolation;
if(interpString == "BEZIER")
interpolation = Keyframe::Interpolation::BEZIER;
else if(interpString == "LINEAR")
interpolation = Keyframe::Interpolation::LINEAR;
else if(interpString == "CONSTANT")
interpolation = Keyframe::Interpolation::CONSTANT;
return interpolation;
}
Keyframe KeyframeChannel::findKeyframe(float time, KeyframeChannel keyframeChannel, bool last){
int pastKeyframeId = -1;
for(int i = 0; i < keyframeChannel.keyframes.size(); i++){
Keyframe keyframe = keyframeChannel.keyframes[i];
if(time >= keyframe.frame){
pastKeyframeId = i;
}
}
return keyframeChannel.keyframes[pastKeyframeId + (last ? 0 : 1)];
}
+1
View File
@@ -68,6 +68,7 @@ namespace vb01{
std::vector<Keyframe> keyframes;
static float interpolateBezier(std::vector<float>, float);
static Keyframe::Interpolation getKeyframeInterpolationType(std::string);
static KeyframeChannel::Type getKeyframeChannelType(std::string);
static float interpolate(Keyframe, Keyframe, float);
static Keyframe findKeyframe(float, KeyframeChannel, bool);
+1 -1
View File
@@ -15,7 +15,7 @@ using namespace glm;
using namespace std;
namespace vb01{
Light::Light(Type t){
Light::Light(Type t, string name) : Animatable(name){
this->type = t;
initDepthMap();
+1 -1
View File
@@ -17,7 +17,7 @@ namespace vb01{
public:
enum Type{POINT, DIRECTIONAL, SPOT, AMBIENT};
Light(Type);
Light(Type, std::string = "");
~Light();
void update();
inline void setNode(Node *node){this->node = node;}
+22 -31
View File
@@ -15,6 +15,21 @@ namespace vb01{
class Material : public Animatable{
public:
struct Uniform : public Animatable{
enum Type{
INT,
BOOL,
FLOAT,
VECTOR_2,
VECTOR_3,
VECTOR_4,
TEXTURE
};
Uniform(std::string name, Type type) : Animatable(name){
this->name = name;
this->type = type;
}
void animate(float val, KeyframeChannel channel){
switch(channel.type){
case KeyframeChannel::UNIFORM_1:
@@ -32,16 +47,6 @@ namespace vb01{
}
}
enum Type{
INT,
BOOL,
FLOAT,
VECTOR_2,
VECTOR_3,
VECTOR_4,
TEXTURE
};
std::string name;
Type type;
@@ -55,10 +60,8 @@ namespace vb01{
struct IntUniform : public Uniform{
int value;
IntUniform(std::string name, int value){
this->name = name;
IntUniform(std::string name, int value) : Uniform(name, Uniform::INT){
this->value = value;
this->type = Uniform::INT;
}
void animateComponent1(float val){value = (int)val;}
@@ -67,10 +70,8 @@ namespace vb01{
struct BoolUniform : public Uniform{
bool value;
BoolUniform(std::string name, bool value){
this->name = name;
BoolUniform(std::string name, bool value) : Uniform(name, Uniform::BOOL){
this->value = value;
this->type = Uniform::BOOL;
}
void animateComponent1(float val){value = (bool)val;}
@@ -79,10 +80,8 @@ namespace vb01{
struct FloatUniform : public Uniform{
float value;
FloatUniform(std::string name, float value){
this->name = name;
FloatUniform(std::string name, float value) : Uniform(name, Uniform::FLOAT){
this->value = value;
this->type = Uniform::FLOAT;
}
void animateComponent1(float val){value = val;}
@@ -91,10 +90,8 @@ namespace vb01{
struct Vector2Uniform : public Uniform{
Vector2 value;
Vector2Uniform(std::string name, Vector2 value){
this->name = name;
Vector2Uniform(std::string name, Vector2 value) : Uniform(name, Uniform::VECTOR_2){
this->value = value;
this->type = Uniform::VECTOR_2;
}
void animateComponent1(float val){value.x = val;}
@@ -105,10 +102,8 @@ namespace vb01{
struct Vector3Uniform : public Uniform{
Vector3 value;
Vector3Uniform(std::string name, Vector3 value){
this->name = name;
Vector3Uniform(std::string name, Vector3 value) : Uniform(name, Uniform::VECTOR_3){
this->value = value;
this->type = Uniform::VECTOR_3;
}
void animateComponent1(float val){value.x = val;}
@@ -121,10 +116,8 @@ namespace vb01{
struct Vector4Uniform : public Uniform{
Vector4 value;
Vector4Uniform(std::string name, Vector4 value){
this->name = name;
Vector4Uniform(std::string name, Vector4 value) : Uniform(name, Uniform::VECTOR_4){
this->value = value;
this->type = Uniform::VECTOR_4;
}
void animateComponent1(float val){value.x = val;}
@@ -140,11 +133,9 @@ namespace vb01{
Texture *value = nullptr;
bool animatable = false;
TextureUniform(std::string name, Texture *value, bool animatable){
this->name = name;
TextureUniform(std::string name, Texture *value, bool animatable) : Uniform(name, Uniform::TEXTURE){
this->value = value;
this->animatable = animatable;
this->type = Uniform::TEXTURE;
}
};
+1 -1
View File
@@ -33,7 +33,7 @@ namespace vb01{
Mesh::Mesh(){}
Mesh::Mesh(Vertex *vertices, unsigned int *indices, int numTris, string *vertexGroups, int numVertexGroups, ShapeKey *shapeKeys, int numShapeKeys, string name) : Animatable(){
Mesh::Mesh(Vertex *vertices, unsigned int *indices, int numTris, string *vertexGroups, int numVertexGroups, ShapeKey *shapeKeys, int numShapeKeys, string name){
this->vertices = vertices;
this->indices = indices;
this->numTris = numTris;
+1 -1
View File
@@ -14,7 +14,7 @@ namespace vb01{
class Texture;
class Skeleton;
class Mesh : public Animatable{
class Mesh{
public:
struct ShapeKey : public Animatable{
std::string name;
+1 -2
View File
@@ -16,11 +16,10 @@ using namespace std;
using namespace glm;
namespace vb01{
Node::Node(Vector3 pos, Quaternion orientation, Vector3 scale, string name) : Animatable(){
Node::Node(Vector3 pos, Quaternion orientation, Vector3 scale, string name) : Animatable(name){
this->pos = pos;
this->scale = scale;
this->orientation = orientation;
this->name = name;
globalAxis[0] = Vector3::VEC_I;
globalAxis[1] = Vector3::VEC_J;
-2
View File
@@ -64,7 +64,6 @@ namespace vb01{
inline int getNumChildren(){return children.size();}
inline Quaternion getOrientation(){return orientation;}
inline bool isVisible(){return visible;}
inline std::string getName(){return name;}
inline void setVisible(bool v){this->visible = v;}
inline void addDriver(Driver *d){drivers.push_back(d);}
private:
@@ -87,7 +86,6 @@ namespace vb01{
std::vector<Light*> lights;
std::vector<Text*> texts;
std::vector<Skeleton*> skeletons;
std::string name;
Node *parent = nullptr;
};
}
+4 -4
View File
@@ -15,7 +15,7 @@
using namespace std;
namespace vb01{
Texture::Texture(int width, int height, bool shadowMap){
Texture::Texture(int width, int height, bool shadowMap) : Animatable(){
this->width = width;
this->height = height;
texture = new u32;
@@ -42,7 +42,7 @@ namespace vb01{
}
}
Texture::Texture(string paths[], int numPaths, bool cubemap, int mipmapLevel, bool flip){
Texture::Texture(string paths[], int numPaths, bool cubemap, int mipmapLevel, bool flip, string name) : Animatable(name){
this->cubemap = cubemap;
this->paths = new string[numPaths];
@@ -86,7 +86,7 @@ namespace vb01{
}
}
Texture::Texture(int width, bool depth, int mipmapLevel){
Texture::Texture(int width, bool depth, int mipmapLevel, string name) : Animatable(name){
this->width = width;
this->mipmapLevel = mipmapLevel;
this->cubemap = true;
@@ -127,7 +127,7 @@ namespace vb01{
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
Texture::Texture(FT_Face face){
Texture::Texture(FT_Face face) : Animatable(){
texture = new u32;
glGenTextures(1, &texture[0]);
+2 -2
View File
@@ -14,8 +14,8 @@ namespace vb01{
public:
~Texture();
Texture(int, int, bool = true);
Texture(std::string[], int, bool, int = 0, bool = false);
Texture(int, bool = true, int = 0);
Texture(std::string[], int, bool, int = 0, bool = false, std::string = "");
Texture(int, bool = true, int = 0, std::string = "");
Texture(FT_Face);
void select(int = 0, int = 0);
void update(int = 0);
+1 -1
View File
@@ -596,7 +596,7 @@ namespace vb01{
float outerAngle = atof(lightData[7].substr(lightData[7].find_first_of(':') + 2).c_str());
float innerAngle = atof(lightData[8].substr(lightData[8].find_first_of(':') + 2).c_str());
Light *light = new Light(type);
Light *light = new Light(type, name);
light->setColor(color);
light->setOuterAngle(outerAngle);
light->setInnerAngle(innerAngle);
+53 -6
View File
@@ -2,8 +2,11 @@
#include "mesh.h"
#include "skeleton.h"
#include "bone.h"
#include "animation.h"
#include "vector.h"
#include "animationController.h"
#include "animatable.h"
#include "keyframeChannel.h"
#include <vector>
@@ -152,6 +155,51 @@ namespace vb01{
return mesh;
}
Animation* XmlModelReader::processAnimation(XMLElement *animationEl, vector<Animatable*> animatables){
string name = animationEl->Attribute("name");
Animation *animation = new Animation(name);
for(XMLElement *channelEl = animationEl->FirstChildElement("channel"); channelEl; channelEl = channelEl->NextSiblingElement()){
vector<Keyframe> keyframes;
for(XMLElement *keyframeEl = channelEl->FirstChildElement("keyframe"); keyframeEl; keyframeEl = keyframeEl->NextSiblingElement()){
string interpString = keyframeEl->Attribute("interpolation");
Keyframe::Interpolation interpolation = KeyframeChannel::getKeyframeInterpolationType(interpString);
float frame = atof(keyframeEl->Attribute("frame"));
float value = atof(keyframeEl->Attribute("value"));
float leftFrame = atof(keyframeEl->Attribute("lefthandleframe"));
float leftValue = atof(keyframeEl->Attribute("lefthandlevalue"));
float rightFrame = atof(keyframeEl->Attribute("righthandleframe"));
float rightValue = atof(keyframeEl->Attribute("righthandlevalue"));
keyframes.push_back(KeyframeChannel::createKeyframe(interpolation, value, frame, leftValue, leftFrame, rightValue, rightFrame));
}
string typeStr = channelEl->Attribute("type");
KeyframeChannel::Type type = KeyframeChannel::getKeyframeChannelType(typeStr);
Animatable *animatable;
string name = channelEl->Attribute("name");
for(Animatable *an : animatables)
if(an->getName() == name){
animatable = an;
break;
}
KeyframeChannel channel = KeyframeChannel::createKeyframeChannel(type, animatable, keyframes);
animation->addKeyframeChannel(channel);
}
return animation;
}
void XmlModelReader::processAnimations(XMLElement *animContainer, vector<Animatable*> animatables){
AnimationController *animController = AnimationController::getSingleton();
const char *animTag = "animation";
for(XMLElement *animEl = animContainer->FirstChildElement(animTag); animEl && strcmp(animEl->Name(), animTag) == 0; animEl = animEl->NextSiblingElement())
animController->addAnimation(processAnimation(animEl, animatables));
}
Skeleton* XmlModelReader::processSkeleton(Node *root, XMLElement *skeletonEl){
XMLElement *rootBoneEl = skeletonEl->FirstChildElement("bone");
Bone *rootBone = (Bone*)processNode(root, rootBoneEl, true);
@@ -164,6 +212,8 @@ namespace vb01{
for(Node *bone : bones)
skeleton->addBone((Bone*)bone, (Bone*)bone->getParent());
processAnimations(skeletonEl, vector<Animatable*>(bones.begin(), bones.end()));
return skeleton;
}
@@ -186,14 +236,9 @@ namespace vb01{
float eps = pow(10, -2);
for(int i = 0; i < 9; i++){
for(int i = 0; i < 9; i++)
if(fabs(components[i]) < eps)
components[i] = 0;
}
/*
else if(fabs(components[i]) > 1.0)
components[i] = 1.0;
*/
Vector3 head = Vector3(components[0], components[1], components[2]);
Vector3 xAxis = Vector3(components[3], components[4], components[5]);
@@ -239,6 +284,8 @@ namespace vb01{
XMLElement *lightTag = xmlEl->FirstChildElement("light");
processAnimations(xmlEl, vector<Animatable*>{node});
const char *tagName = (bone ? "bone" : "node");
for(XMLElement *el = xmlEl->FirstChildElement(tagName); el; el = el->NextSiblingElement())
+6 -1
View File
@@ -3,6 +3,8 @@
#include "modelReader.h"
#include <vector>
namespace tinyxml2{
class XMLElement;
}
@@ -11,7 +13,8 @@ namespace vb01{
class Node;
class Mesh;
class Skeleton;
class Bone;
class Animatable;
class Animation;
class XmlModelReader : public ModelReader{
public:
@@ -19,6 +22,8 @@ namespace vb01{
private:
Node* processNode(Node*, tinyxml2::XMLElement*, bool = false);
Mesh* processMesh(tinyxml2::XMLElement*);
Animation* processAnimation(tinyxml2::XMLElement*, std::vector<Animatable*>);
void processAnimations(tinyxml2::XMLElement*, std::vector<Animatable*>);
Skeleton* processSkeleton(Node*, tinyxml2::XMLElement*);
};
}