mirror of
https://github.com/ApfelTeeSaft/vb01.git
synced 2026-08-26 19:33:45 +00:00
reading animations
This commit is contained in:
+1
-1
@@ -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)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "animatable.h"
|
||||
|
||||
namespace vb01{
|
||||
using namespace std;
|
||||
|
||||
Animatable::Animatable(string name){
|
||||
this->name = name;
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;}
|
||||
|
||||
@@ -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)];
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace vb01{
|
||||
class Texture;
|
||||
class Skeleton;
|
||||
|
||||
class Mesh : public Animatable{
|
||||
class Mesh{
|
||||
public:
|
||||
struct ShapeKey : public Animatable{
|
||||
std::string name;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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]);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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*);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user