mirror of
https://github.com/devZoGok/vb01.git
synced 2026-08-26 19:43:30 +00:00
beginning of object transform animation
improved exporter
This commit is contained in:
+2
-2
@@ -13,7 +13,7 @@ namespace vb01{
|
||||
void Animation::update(){
|
||||
}
|
||||
|
||||
Animation::KeyframeGroup* Animation::getKeyframeGroup(Bone *b){
|
||||
Animation::KeyframeGroup* Animation::getKeyframeGroup(Node *b){
|
||||
int id = -1;
|
||||
for(int i = 0;i < keyframeGroups.size(); i++)
|
||||
if(keyframeGroups[i].bone == b){
|
||||
@@ -48,7 +48,7 @@ namespace vb01{
|
||||
return type;
|
||||
}
|
||||
|
||||
KeyframeChannel* Animation::getKeyframeChannel(Bone *bone, KeyframeChannelType type){
|
||||
KeyframeChannel* Animation::getKeyframeChannel(Node *bone, KeyframeChannelType type){
|
||||
KeyframeChannel *k = nullptr;
|
||||
|
||||
KeyframeGroup *group = getKeyframeGroup(bone);
|
||||
|
||||
+6
-5
@@ -1,11 +1,12 @@
|
||||
#ifndef ANIMATION_H
|
||||
#define ANIMATION_H
|
||||
|
||||
#include<string>
|
||||
#include<vector>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace vb01{
|
||||
class Bone;
|
||||
class Node;
|
||||
|
||||
class Animation{
|
||||
public:
|
||||
@@ -35,7 +36,7 @@ namespace vb01{
|
||||
std::vector<Keyframe> keyframes;
|
||||
};
|
||||
|
||||
Bone *bone = nullptr;
|
||||
Node *bone = nullptr;
|
||||
std::vector<KeyframeChannel> keyframeChannels;
|
||||
};
|
||||
|
||||
@@ -43,8 +44,8 @@ namespace vb01{
|
||||
Animation(std::string);
|
||||
~Animation();
|
||||
void update();
|
||||
KeyframeGroup* getKeyframeGroup(Bone *b);
|
||||
KeyframeGroup::KeyframeChannel* getKeyframeChannel(Bone *b, KeyframeGroup::KeyframeChannel::Type);
|
||||
KeyframeGroup* getKeyframeGroup(Node*);
|
||||
KeyframeGroup::KeyframeChannel* getKeyframeChannel(Node*, KeyframeGroup::KeyframeChannel::Type);
|
||||
static KeyframeGroup::KeyframeChannel::Type getKeyframeChannelType(std::string);
|
||||
inline int getNumKeyframeGroups(){return keyframeGroups.size();}
|
||||
inline std::string getName(){return name;}
|
||||
|
||||
+21
-7
@@ -35,17 +35,31 @@ namespace vb01{
|
||||
vector<Keyframe> keyframes;
|
||||
|
||||
Animation *animation = controller->getAnimation(animName);
|
||||
KeyframeGroup *startGroup = animation->getKeyframeGroup(bones[0]);
|
||||
for(int i = 0; i < bones.size(); i++){
|
||||
KeyframeGroup *kg = animation->getKeyframeGroup(bones[i]);
|
||||
|
||||
for(int j = 0 ; j < kg->keyframeChannels.size(); j++){
|
||||
KeyframeChannel ch = kg->keyframeChannels[j];
|
||||
|
||||
Node *controllerNode = controller->getNode();
|
||||
KeyframeGroup *startGroup = nullptr;
|
||||
if(controllerNode){
|
||||
startGroup = animation->getKeyframeGroup(controllerNode);
|
||||
|
||||
for(int j = 0 ; j < startGroup->keyframeChannels.size(); j++){
|
||||
KeyframeChannel ch = startGroup->keyframeChannels[j];
|
||||
|
||||
for(int k = 0; k < ch.keyframes.size(); k++)
|
||||
keyframes.push_back(ch.keyframes[k]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
startGroup = animation->getKeyframeGroup((Node*)bones[0]);
|
||||
for(int i = 0; i < bones.size(); i++){
|
||||
KeyframeGroup *kg = animation->getKeyframeGroup((Node*)bones[i]);
|
||||
|
||||
for(int j = 0 ; j < kg->keyframeChannels.size(); j++){
|
||||
KeyframeChannel ch = kg->keyframeChannels[j];
|
||||
|
||||
for(int k = 0; k < ch.keyframes.size(); k++)
|
||||
keyframes.push_back(ch.keyframes[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return keyframes;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ using namespace std;
|
||||
namespace vb01{
|
||||
void AnimationChannelTest::setUp(){
|
||||
Bone *bone = new Bone("bone", 1, Vector3(0, 0, 0), Quaternion::QUAT_I, Vector3::VEC_IJK);
|
||||
skeleton = new Skeleton();
|
||||
skeleton = new Skeleton(new AnimationController());
|
||||
skeleton->addBone(bone, nullptr);
|
||||
AnimationController *controller = skeleton->getAnimationController();
|
||||
|
||||
|
||||
+23
-8
@@ -5,8 +5,7 @@
|
||||
using namespace std;
|
||||
|
||||
namespace vb01{
|
||||
AnimationController::AnimationController(Skeleton *skeleton){
|
||||
this->skeleton = skeleton;
|
||||
AnimationController::AnimationController(){
|
||||
}
|
||||
|
||||
AnimationController::~AnimationController(){
|
||||
@@ -16,15 +15,21 @@ namespace vb01{
|
||||
for(AnimationChannel *channel : channels){
|
||||
channel->update();
|
||||
|
||||
transformBones(channel);
|
||||
transform(channel);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationController::transformBones(AnimationChannel *channel){
|
||||
void AnimationController::transform(AnimationChannel *channel){
|
||||
Animation *animation = getAnimation(channel->getAnimationName());
|
||||
|
||||
for(Bone *channelBone : channel->getBones()){
|
||||
Animation::KeyframeGroup *keyframeGroup = animation->getKeyframeGroup(channelBone);
|
||||
vector<Node*> transformNodes;
|
||||
if(node)
|
||||
transformNodes.push_back(node);
|
||||
for(Bone *channelBone : channel->getBones())
|
||||
transformNodes.push_back((Node*)channelBone);
|
||||
|
||||
for(Node *transformNode : transformNodes){
|
||||
Animation::KeyframeGroup *keyframeGroup = animation->getKeyframeGroup(transformNode);
|
||||
Vector3 pastPos, nextPos, pastScale, nextScale;
|
||||
Quaternion pastRot, nextRot;
|
||||
Keyframe::Interpolation interp;
|
||||
@@ -35,8 +40,18 @@ namespace vb01{
|
||||
Vector3 currentPos = interpolate(pastPos, nextPos, interp, ratio);
|
||||
Quaternion currentRot = interpolate(pastRot, nextRot, interp, ratio);
|
||||
Vector3 currentScale = interpolate(pastScale, nextScale, interp, ratio);
|
||||
channelBone->setPosePos(currentPos);
|
||||
channelBone->setPoseRot(currentRot);
|
||||
|
||||
if(node && node->getName() == transformNode->getName()){
|
||||
transformNode->setPosition(currentPos);
|
||||
transformNode->setOrientation(currentRot);
|
||||
transformNode->setScale(currentScale);
|
||||
}
|
||||
else{
|
||||
Bone *channelBone = (Bone*)transformNode;
|
||||
channelBone->setPosePos(currentPos);
|
||||
channelBone->setPoseRot(currentRot);
|
||||
channelBone->setPoseScale(currentScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,19 +13,24 @@ namespace vb01{
|
||||
|
||||
class AnimationController{
|
||||
public:
|
||||
AnimationController(Skeleton*);
|
||||
AnimationController();
|
||||
~AnimationController();
|
||||
void update();
|
||||
Animation* getAnimation(std::string);
|
||||
inline std::vector<Animation*> getAnimations(){return animations;}
|
||||
inline void addAnimation(Animation *anim){animations.push_back(anim);}
|
||||
inline void addAnimationChannel(AnimationChannel *channel){channels.push_back(channel);}
|
||||
inline void setSkeleton(Skeleton *sk){this->skeleton = sk;}
|
||||
inline void setNode(Node *node){this->node = node;}
|
||||
inline Skeleton* getSkeleton(){return skeleton;}
|
||||
inline Node* getNode(){return node;}
|
||||
private:
|
||||
Skeleton *skeleton = nullptr;
|
||||
Node *node = nullptr;
|
||||
std::vector<Animation*> animations;
|
||||
std::vector<AnimationChannel*> channels;
|
||||
|
||||
void transformBones(AnimationChannel*);
|
||||
void transform(AnimationChannel*);
|
||||
void prepareAdjacentValues(Vector3&, Vector3&, Quaternion&, Quaternion&, Vector3&, Vector3&, Keyframe::Interpolation&, float&, KeyframeGroup*, AnimationChannel*);
|
||||
Vector3 interpolate(Vector3, Vector3, Keyframe::Interpolation, float);
|
||||
Quaternion interpolate(Quaternion, Quaternion, Keyframe::Interpolation, float);
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace vb01{
|
||||
|
||||
void AnimationControllerTest::setUp(){
|
||||
Node *rootNode = Root::getSingleton()->getRootNode();
|
||||
skeleton = new Skeleton();
|
||||
skeleton = new Skeleton(new AnimationController());
|
||||
Bone *bone = new Bone("bone", 1.f, Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK);
|
||||
skeleton->addBone(bone, (Bone*)rootNode);
|
||||
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
#include "boneTest.h"
|
||||
#include "root.h"
|
||||
#include "skeleton.h"
|
||||
#include "animationController.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -14,7 +15,7 @@ namespace vb01{
|
||||
rootNode->attachChild(modelNodeParent);
|
||||
modelNodeParent->attachChild(modelNode);
|
||||
|
||||
skeleton = new Skeleton();
|
||||
skeleton = new Skeleton(new AnimationController());
|
||||
|
||||
Bone *rootBone = new Bone("rootBone", 1, Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK);
|
||||
Bone *pelvis = new Bone("pelvis", 1, Vector3(0, 2, 0), Quaternion::QUAT_W, Vector3::VEC_IJK);
|
||||
|
||||
+2
-1
@@ -1,12 +1,13 @@
|
||||
#include "ikSolverTest.h"
|
||||
#include "ikSolver.h"
|
||||
#include "skeleton.h"
|
||||
#include "animationController.h"
|
||||
|
||||
namespace vb01{
|
||||
void IkSolverTest::setUp(){
|
||||
rootNode = Root::getSingleton()->getRootNode();
|
||||
|
||||
skeleton = new Skeleton("");
|
||||
skeleton = new Skeleton(new AnimationController());
|
||||
|
||||
Bone *boneA = new Bone("A", 1, Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK);
|
||||
Bone *boneB = new Bone("B", 1, Vector3::VEC_J, Quaternion::QUAT_W, Vector3::VEC_IJK);
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
#include"root.h"
|
||||
#include"node.h"
|
||||
#include"mesh.h"
|
||||
#include"particleEmitter.h"
|
||||
#include"light.h"
|
||||
#include"text.h"
|
||||
#include"material.h"
|
||||
#include"matrix.h"
|
||||
#include<glm.hpp>
|
||||
#include<glm/gtc/matrix_inverse.hpp>
|
||||
#include "root.h"
|
||||
#include "node.h"
|
||||
#include "mesh.h"
|
||||
#include "particleEmitter.h"
|
||||
#include "light.h"
|
||||
#include "text.h"
|
||||
#include "material.h"
|
||||
#include "matrix.h"
|
||||
#include "animationController.h"
|
||||
|
||||
#include <glm.hpp>
|
||||
#include <glm/gtc/matrix_inverse.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace glm;
|
||||
|
||||
namespace vb01{
|
||||
Node::Node(Vector3 pos, Quaternion orientation, Vector3 scale,string name){
|
||||
Node::Node(Vector3 pos, Quaternion orientation, Vector3 scale, string name, AnimationController *controller){
|
||||
this->pos = pos;
|
||||
this->scale = scale;
|
||||
this->orientation = orientation;
|
||||
this->name = name;
|
||||
this->controller = controller;
|
||||
if(this->controller)
|
||||
this->controller->setNode(this);
|
||||
|
||||
globalAxis[0] = Vector3::VEC_I;
|
||||
globalAxis[1] = Vector3::VEC_J;
|
||||
globalAxis[2] = Vector3::VEC_K;
|
||||
@@ -50,6 +56,8 @@ namespace vb01{
|
||||
c->update();
|
||||
for(ParticleEmitter *p : emitters)
|
||||
p->update();
|
||||
if(controller)
|
||||
controller->update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#ifndef NODE_H
|
||||
#define NODE_H
|
||||
|
||||
#include"quaternion.h"
|
||||
#include"vector.h"
|
||||
#include"root.h"
|
||||
#include<vector>
|
||||
#include<string>
|
||||
#include "quaternion.h"
|
||||
#include "vector.h"
|
||||
#include "root.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace vb01{
|
||||
class Mesh;
|
||||
@@ -13,6 +14,7 @@ namespace vb01{
|
||||
class Light;
|
||||
class ParticleEmitter;
|
||||
class Text;
|
||||
class AnimationController;
|
||||
|
||||
class Node{
|
||||
public:
|
||||
@@ -21,7 +23,7 @@ namespace vb01{
|
||||
Quaternion orientation = Quaternion::QUAT_W;
|
||||
};
|
||||
|
||||
Node(Vector3 = Vector3::VEC_ZERO, Quaternion = Quaternion::QUAT_W, Vector3 = Vector3::VEC_IJK, std::string = "");
|
||||
Node(Vector3 = Vector3::VEC_ZERO, Quaternion = Quaternion::QUAT_W, Vector3 = Vector3::VEC_IJK, std::string = "", AnimationController *c = nullptr);
|
||||
virtual ~Node();
|
||||
void attachMesh(Mesh*);
|
||||
void attachParticleEmitter(ParticleEmitter*);
|
||||
@@ -63,10 +65,12 @@ namespace vb01{
|
||||
inline bool isVisible(){return visible;}
|
||||
inline std::string getName(){return name;}
|
||||
inline void setVisible(bool v){this->visible = v;}
|
||||
inline AnimationController* getAnimationController(){return controller;}
|
||||
private:
|
||||
void adjustUp(Vector3);
|
||||
void adjustDir(Vector3);
|
||||
Quaternion adjustRot(std::vector<Node*>, Quaternion, bool);
|
||||
AnimationController *controller = nullptr;
|
||||
protected:
|
||||
void updateShaders();
|
||||
|
||||
|
||||
@@ -11,9 +11,13 @@ def exportData(ob):
|
||||
file.write('rot: ' + str(ob.rotation_quaternion.w) + ' ' + str(ob.rotation_quaternion.x) + ' ' + str(ob.rotation_quaternion.y) + ' ' + str(-ob.rotation_quaternion.z) + '\n')
|
||||
file.write('scale: ' + str(ob.scale.x) + ' ' + str(ob.scale.y) + ' ' + str(ob.scale.z) + '\n')
|
||||
file.write('parent: ' + ('-' if par is None else par.name) + '\n')
|
||||
if(ob.type == "ARMATURE"):
|
||||
|
||||
numAnims = 0
|
||||
if(ob.animation_data is not None and len(ob.animation_data.nla_tracks) > 0):
|
||||
numAnims = len(ob.animation_data.nla_tracks[0].strips)
|
||||
file.write("bones: "+str(len(ob.data.bones)) + ' ' + str(numAnims) + ' ')
|
||||
|
||||
if(ob.type == 'ARMATURE'):
|
||||
file.write('bones: ' + str(len(ob.data.bones)) + ' ' + str(numAnims) + ' \n')
|
||||
|
||||
for bone in ob.data.bones:
|
||||
head = bone.head
|
||||
@@ -38,67 +42,15 @@ def exportData(ob):
|
||||
else:
|
||||
chainLength = ikConstraint.chain_count
|
||||
|
||||
file.write('\n' + bone.name + ': ' + ('None' if bone.parent is None else bone.parent.name) + " " + str(bone.length) + " " + str(head.x) + " " + str(head.y) + " " + str(head.z) + " " + str(xAxis.x) + " " + str(xAxis.y) + " " + str(xAxis.z) + " " + str(yAxis.x) + " " + str(yAxis.y) + " " + str(yAxis.z) + " " + ikTarget + ' ' + str(chainLength) + ' ')
|
||||
file.write(bone.name + ': ' + ('None' if bone.parent is None else bone.parent.name) + " " + str(bone.length) + " " + str(head.x) + " " + str(head.y) + " " + str(head.z) + " " + str(xAxis.x) + " " + str(xAxis.y) + " " + str(xAxis.z) + " " + str(yAxis.x) + " " + str(yAxis.y) + " " + str(yAxis.z) + " " + ikTarget + ' ' + str(chainLength) + ' \n')
|
||||
|
||||
if numAnims > 0:
|
||||
file.write('\nanimations: ' + str(numAnims) + '\n')
|
||||
for nlaStrip in ob.animation_data.nla_tracks[0].strips:
|
||||
start = nlaStrip.frame_start
|
||||
end = nlaStrip.frame_end
|
||||
animName = nlaStrip.name
|
||||
action = bpy.data.actions[animName]
|
||||
numAnimBones = len(action.groups)
|
||||
file.write('animation: ' + animName)
|
||||
file.write('\ngroups: ' + str(numAnimBones))
|
||||
|
||||
print('Exporting animation '+animName+'...\n')
|
||||
|
||||
file.write('\n')
|
||||
|
||||
for group in action.groups:
|
||||
file.write(group.name + ' ' + str(len(group.channels)) + ' ')
|
||||
|
||||
for channel in group.channels:
|
||||
numKeyframes = len(channel.keyframe_points)
|
||||
channelType = getChannelType(channel)
|
||||
file.write(channelType + ' ' + str(numKeyframes) + ' ')
|
||||
|
||||
file.write('\n')
|
||||
|
||||
bone = ob.data.bones[group.name]
|
||||
for channel in group.channels:
|
||||
channelType = getChannelType(channel)
|
||||
|
||||
dotId = channel.data_path.rfind('.') + 1
|
||||
arrInd = channel.array_index
|
||||
coordType = channel.data_path[dotId :]
|
||||
|
||||
for keyframe in channel.keyframe_points:
|
||||
keyframeId = keyframe.co[0]
|
||||
interp = keyframe.interpolation
|
||||
bpy.context.scene.frame_set(int(start) + int(keyframeId))
|
||||
poseBone = ob.pose.bones[group.name]
|
||||
interpInt = - 1
|
||||
|
||||
if interp == 'CONSTANT':
|
||||
interpInt = 0
|
||||
elif interp == 'LINEAR':
|
||||
interpInt = 1
|
||||
elif interp == 'BEZIER':
|
||||
interpInt = 2
|
||||
|
||||
keyframeValue = keyframe.co[1]
|
||||
file.write(str(keyframeValue) + ' ' + str(keyframeId) + ' ' + str(interpInt))
|
||||
if interp == 'BEZIER':
|
||||
file.write(' ' + str(keyframe.handle_left_type) + ' ' + str(keyframe.handle_left.x) + ' ' + str(keyframe.handle_left.y) + ' ')
|
||||
file.write(str(keyframe.handle_right_type) + ' ' + str(keyframe.handle_right.x) + ' ' + str(keyframe.handle_right.y))
|
||||
file.write('\n')
|
||||
|
||||
|
||||
elif(ob.type == 'MESH'):
|
||||
skeletonName = '-'
|
||||
skeleton = ob.modifiers['Armature'].object
|
||||
if(skeleton):
|
||||
skeleton = None
|
||||
if(len(ob.modifiers) > 0 and ob.modifiers['Armature'] and ob.modifiers['Armature'].object):
|
||||
skeleton = ob.modifiers['Armature'].object
|
||||
skeletonName = skeleton.name
|
||||
file.write('skeleton: ' + skeletonName + '\n')
|
||||
mesh = ob.data
|
||||
@@ -113,8 +65,8 @@ def exportData(ob):
|
||||
|
||||
file.write('numElements: ' + str(numVerts) + ' ' + str(numFaces) + ' ' + str(numGroups) + ' ' + str(numShapeKeys) + ' \n')
|
||||
|
||||
file.write('groups:\n')
|
||||
if numGroups > 0:
|
||||
file.write('groups:\n')
|
||||
for group in ob.vertex_groups:
|
||||
file.write(group.name + '\n')
|
||||
|
||||
@@ -192,6 +144,9 @@ def exportData(ob):
|
||||
if(newPos!=mesh.vertices[i].co):
|
||||
file.write('\n'+str(i)+" "+str(newPos.x)+' '+str(newPos.y)+' '+str(newPos.z))
|
||||
'''
|
||||
file.write('animations: ' + str(numAnims) + '\n')
|
||||
if numAnims > 0:
|
||||
readAnimations(ob, numAnims)
|
||||
|
||||
def getChannelType(channel):
|
||||
channelType = ''
|
||||
@@ -209,6 +164,57 @@ def getChannelType(channel):
|
||||
channelType = 'scale_' + coords[arrInd + 1]
|
||||
return channelType
|
||||
|
||||
def readAnimations(ob, numAnims):
|
||||
for nlaStrip in ob.animation_data.nla_tracks[0].strips:
|
||||
start = nlaStrip.frame_start
|
||||
end = nlaStrip.frame_end
|
||||
animName = nlaStrip.name
|
||||
action = bpy.data.actions[animName]
|
||||
numAnimBones = len(action.groups)
|
||||
file.write('animation: ' + animName)
|
||||
file.write('\ngroups: ' + str(numAnimBones))
|
||||
|
||||
print('Exporting animation ' + animName + '...\n')
|
||||
|
||||
file.write('\n')
|
||||
|
||||
for group in action.groups:
|
||||
file.write((ob.name if group.name == 'Object Transforms' else group.name) + ' ' + str(len(group.channels)) + ' ')
|
||||
|
||||
for channel in group.channels:
|
||||
numKeyframes = len(channel.keyframe_points)
|
||||
channelType = getChannelType(channel)
|
||||
file.write(channelType + ' ' + str(numKeyframes) + ' ')
|
||||
|
||||
file.write('\n')
|
||||
|
||||
for channel in group.channels:
|
||||
channelType = getChannelType(channel)
|
||||
|
||||
dotId = channel.data_path.rfind('.') + 1
|
||||
arrInd = channel.array_index
|
||||
coordType = channel.data_path[dotId :]
|
||||
|
||||
for keyframe in channel.keyframe_points:
|
||||
keyframeId = keyframe.co[0]
|
||||
interp = keyframe.interpolation
|
||||
bpy.context.scene.frame_set(int(start) + int(keyframeId))
|
||||
interpInt = - 1
|
||||
|
||||
if interp == 'CONSTANT':
|
||||
interpInt = 0
|
||||
elif interp == 'LINEAR':
|
||||
interpInt = 1
|
||||
elif interp == 'BEZIER':
|
||||
interpInt = 2
|
||||
|
||||
keyframeValue = keyframe.co[1]
|
||||
file.write(str(keyframeValue) + ' ' + str(keyframeId) + ' ' + str(interpInt))
|
||||
if interp == 'BEZIER':
|
||||
file.write(' ' + str(keyframe.handle_left_type) + ' ' + str(keyframe.handle_left.x) + ' ' + str(keyframe.handle_left.y) + ' ')
|
||||
file.write(str(keyframe.handle_right_type) + ' ' + str(keyframe.handle_right.x) + ' ' + str(keyframe.handle_right.y))
|
||||
file.write('\n')
|
||||
|
||||
fl = bpy.data.filepath
|
||||
dotId = 0
|
||||
for i in range(len(fl)):
|
||||
|
||||
+4
-4
@@ -10,9 +10,10 @@ using namespace std;
|
||||
using namespace glm;
|
||||
|
||||
namespace vb01{
|
||||
Skeleton::Skeleton(string name){
|
||||
Skeleton::Skeleton(AnimationController *controller, string name){
|
||||
this->name = name;
|
||||
controller = new AnimationController(this);
|
||||
this->controller = controller;
|
||||
this->controller->setSkeleton(this);
|
||||
}
|
||||
|
||||
void Skeleton::update(){
|
||||
@@ -42,9 +43,8 @@ namespace vb01{
|
||||
|
||||
Bone **boneChain = getIkBoneChain(ikBone);
|
||||
Vector3 boneIkPos[chainLength];
|
||||
for(int i = chainLength - 1; i >= 0; i--){
|
||||
for(int i = chainLength - 1; i >= 0; i--)
|
||||
boneIkPos[i] = subBase->globalToLocalPosition(boneChain[i]->localToGlobalPosition(Vector3::VEC_ZERO));
|
||||
}
|
||||
|
||||
Vector3 targetPos = subBase->globalToLocalPosition(ikTarget->localToGlobalPosition(Vector3::VEC_ZERO));
|
||||
IkSolver::calculateFabrik(chainLength, boneChain, boneIkPos, targetPos);
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ namespace vb01{
|
||||
|
||||
class Skeleton{
|
||||
public:
|
||||
Skeleton(std::string = "");
|
||||
Skeleton(AnimationController*, std::string = "");
|
||||
void update();
|
||||
void addBone(Bone*, Bone*);
|
||||
Bone* getBone(std::string);
|
||||
@@ -23,7 +23,7 @@ namespace vb01{
|
||||
inline int getNumBones(){return bones.size();}
|
||||
private:
|
||||
void solveIk(Bone*);
|
||||
void transformIkChain(int, Bone**, Vector3[], Bone*);
|
||||
void transformIkChain(int, Bone*[], Vector3[], Bone*);
|
||||
Bone** getIkBoneChain(Bone*);
|
||||
|
||||
std::string name;
|
||||
|
||||
+28
-10
@@ -172,8 +172,7 @@ namespace vb01{
|
||||
}
|
||||
}
|
||||
|
||||
void VbModelReader::readAnimations(Skeleton *skeleton, vector<string> &skeletonData, int numAnimations){
|
||||
AnimationController *controller = skeleton->getAnimationController();
|
||||
void VbModelReader::readAnimations(AnimationController *controller, vector<string> &skeletonData, int numAnimations){
|
||||
int animStartLine = 0;
|
||||
|
||||
for(int i = 0; i < numAnimations; i++){
|
||||
@@ -191,7 +190,14 @@ namespace vb01{
|
||||
getLineData(skeletonData[keyframeGroupStartLine], dataLine, 2);
|
||||
|
||||
KeyframeGroup keyframeGroup;
|
||||
keyframeGroup.bone = skeleton->getBone(dataLine[0]);
|
||||
string nodeName = dataLine[0];
|
||||
Node *transformNode = nullptr;
|
||||
if(controller->getSkeleton())
|
||||
transformNode = (Node*)controller->getSkeleton()->getBone(nodeName);
|
||||
if(!transformNode)
|
||||
transformNode = controller->getNode();
|
||||
keyframeGroup.bone = transformNode;
|
||||
|
||||
int numKeyframeChannels = atoi(dataLine[1].c_str());
|
||||
string channelData[2 * numKeyframeChannels];
|
||||
getLineData(skeletonData[keyframeGroupStartLine], channelData, 2 * numKeyframeChannels, 2);
|
||||
@@ -249,16 +255,16 @@ namespace vb01{
|
||||
|
||||
line = skeletonData[boneStartLine + numBones].substr(getCharId(skeletonData[boneStartLine + numBones], ':') + 2);
|
||||
int numAnimations = atoi(line.c_str());
|
||||
int animStartLine = boneStartLine + numBones + 1;
|
||||
|
||||
Skeleton *skeleton = new Skeleton(name);
|
||||
AnimationController *controller = new AnimationController();
|
||||
Skeleton *skeleton = new Skeleton(controller, name);
|
||||
|
||||
vector<string> skeletonSubData = vector<string>(skeletonData.begin() + boneStartLine, skeletonData.begin() + boneStartLine + numBones);
|
||||
createBones(skeleton, skeletonSubData);
|
||||
skeletonSubData.clear();
|
||||
|
||||
skeletonSubData = vector<string>(skeletonData.begin() + animStartLine, skeletonData.end());
|
||||
readAnimations(skeleton, skeletonSubData, numAnimations);
|
||||
skeletonSubData = vector<string>(skeletonData.begin() + (boneStartLine + numBones + 1), skeletonData.end());
|
||||
readAnimations(controller, skeletonSubData, numAnimations);
|
||||
skeletonSubData.clear();
|
||||
|
||||
return skeleton;
|
||||
@@ -399,6 +405,18 @@ namespace vb01{
|
||||
readShapeKeys(shapeKeyStartLine, numShapes);
|
||||
meshSubData.clear();
|
||||
|
||||
AnimationController *controller = new AnimationController();
|
||||
Node *node = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, name, controller);
|
||||
nodes.push_back(node);
|
||||
|
||||
int numAnimLineId = vertexStartLine + numVertices + numFaces * numVertsPerFace + numShapes + 1;
|
||||
int numAnimations = atoi(meshData[numAnimLineId].substr(meshData[numAnimLineId].find_first_of(':') + 1).c_str());
|
||||
meshSubData = vector<string>(meshData.begin() + (numAnimLineId + 1), meshData.end());
|
||||
readAnimations(controller, meshSubData, numAnimations);
|
||||
meshSubData.clear();
|
||||
/*
|
||||
*/
|
||||
|
||||
string skeletonLine = meshData[5];
|
||||
int skeletonLineColonId = getCharId(skeletonLine, ':');
|
||||
string skeletonName = skeletonLine.substr(skeletonLineColonId + 2, string::npos);
|
||||
@@ -410,6 +428,9 @@ namespace vb01{
|
||||
|
||||
Mesh *mesh = new Mesh(vertices, indices, numFaces, groups, numBones, nullptr, numShapes, name);
|
||||
mesh->setSkeleton(skeleton);
|
||||
node->attachMesh(mesh);
|
||||
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
@@ -417,9 +438,6 @@ namespace vb01{
|
||||
Mesh *mesh = readMeshes(meshData);
|
||||
mesh->construct();
|
||||
|
||||
Node *node = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, mesh->getName());
|
||||
node->attachMesh(mesh);
|
||||
nodes.push_back(node);
|
||||
}
|
||||
|
||||
void VbModelReader::readLights(vector<string> &lightData){
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ namespace vb01{
|
||||
void connectNodes();
|
||||
|
||||
void createBones(Skeleton*, std::vector<std::string>&);
|
||||
void readAnimations(Skeleton*, std::vector<std::string>&, int);
|
||||
void readAnimations(AnimationController*, std::vector<std::string>&, int);
|
||||
Skeleton* readSkeleton(std::vector<std::string>&);
|
||||
void readVertices(std::vector<Vector3>&, std::vector<Vector3>&, std::vector<float>&, std::vector<std::string>&, int);
|
||||
void readFaces(std::vector<Vector3>&, std::vector<Vector3>&, std::vector<float>&, std::vector<std::string>&, int, Mesh::Vertex*, u32*);
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace vb01{
|
||||
string yAxisStr = to_string(b.yAxis.x) + " " + to_string(b.yAxis.y) + " " + to_string(b.yAxis.z) + " ";
|
||||
skeletonData.push_back(b.name + ": " + b.parent + " " + headStr + xAxisStr + yAxisStr + b.ikTarget + " " + to_string(b.ikChainLength) + " ");
|
||||
}
|
||||
skeletonData.push_back("animations: 2 ");
|
||||
skeletonData.push_back("animations: 2");
|
||||
skeletonData.push_back("animation: Action");
|
||||
skeletonData.push_back("groups: 2 ");
|
||||
skeletonData.push_back("bipod.L 7 pos_x 2 pos_y 2 pos_z 2 rot_w 2 rot_x 2 rot_y 2 rot_z 2 ");
|
||||
@@ -142,6 +142,7 @@ namespace vb01{
|
||||
|
||||
meshData.push_back(to_string(i) + " " + uvString + tanString + biTanString);
|
||||
}
|
||||
meshData.push_back("animations: 0");
|
||||
}
|
||||
|
||||
void VbModelReaderTest::testReadSkeletons(){
|
||||
|
||||
Reference in New Issue
Block a user