readable .vb format

This commit is contained in:
devZoGok
2021-10-19 19:06:41 +03:00
parent a13d4f1244
commit 3753d08ca5
27 changed files with 783 additions and 274 deletions
+2 -1
View File
@@ -14,9 +14,10 @@ set(gui text.cpp rectangle.cpp)
set(utils util.cpp)
set(math quaternion.cpp vector.cpp matrix.cpp ray.cpp)
set(render waterPlane.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 animationChannel.cpp animation.cpp)
set(armature skeleton.cpp bone.cpp)
add_library(vb01 SHARED main.cpp ${render} ${math} ${utils} ${gui} ${armature})
add_library(vb01 SHARED main.cpp ${render} ${math} ${utils} ${gui} ${armature} ${anim})
target_link_libraries(vb01 glfw)
target_link_libraries(vb01 glad)
target_link_libraries(vb01 assimp)
+25
View File
@@ -0,0 +1,25 @@
#include"animation.h"
using namespace std;
namespace vb01{
Animation::Animation(string name){
this->name=name;
}
Animation::~Animation(){
}
void Animation::update(){
}
Animation::KeyframeGroup* Animation::getKeyframeGroup(Bone *b){
int id=-1;
for(int i=0;i<keyframeGroups.size();i++)
if(keyframeGroups[i].bone==b){
id=i;
break;
}
return id>-1?&(keyframeGroups[id]):nullptr;
}
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef ANIMATION_H
#define ANIMATION_H
#include<string>
#include<vector>
namespace vb01{
class Bone;
class Animation{
public:
struct KeyframeGroup{
struct Keyframe{
enum Type{
POS_X,
POS_Y,
POS_Z,
ROT_W,
ROT_X,
ROT_Y,
ROT_Z,
SCALE_X,
SCALE_Y,
SCALE_Z
};
enum Interpolation{CONSTANT,LINEAR,BEZIER};
Type type;
Interpolation interpolation;
float value;
int frame;
};
Bone *bone=nullptr;
std::vector<Keyframe> keyframes;
};
Animation(std::string);
~Animation();
void update();
KeyframeGroup* getKeyframeGroup(Bone *b);
inline std::string getName(){return name;}
inline void addKeyframeGroup(KeyframeGroup k){keyframeGroups.push_back(k);}
private:
std::string name;
std::vector<KeyframeGroup> keyframeGroups;
};
}
#endif
View File
+14
View File
@@ -0,0 +1,14 @@
#ifndef ANIMATION_CHANNEL_H
#define ANIMATION_CHANNEL_H
namespace vb01{
class AnimationChannel{
public:
AnimationChannel();
~AnimationChannel();
void update();
private:
};
}
#endif
+12
View File
@@ -0,0 +1,12 @@
#include "animationController.h"
namespace vb01{
AnimationController::AnimationController(){
}
AnimationController::~AnimationController(){
}
void AnimationController::update(){
}
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef ANIMATION_CONTROLLER_H
#define ANIMATION_CONTROLLER_H
#include<string>
namespace vb01{
class AnimationController{
public:
AnimationController();
~AnimationController();
void update();
private:
protected:
void onAnimationEnd(std::string){}
void onAnimationStart(std::string){}
};
}
#endif
+5 -1
View File
@@ -1,5 +1,9 @@
#include"bone.h"
using namespace std;
namespace vb01{
Bone::Bone() : Node(){}
Bone::Bone(string name, Vector3 pos) : Node(pos){
this->name=name;
}
}
+5 -1
View File
@@ -2,12 +2,16 @@
#define BONE_H
#include"node.h"
#include<string>
namespace vb01{
class Bone : public Node{
public:
Bone();
Bone(std::string,Vector3=Vector3::VEC_ZERO);
std::string getName(){return name;}
private:
std::string name;
Vector3 yAxis,zAxis;
};
}
+1 -1
View File
@@ -64,7 +64,7 @@ namespace vb01{
Vertex v;
v.pos=pos[data[3*i]];
v.norm=norm[data[3*i+1]];
v.texCoords=tex[data[3*i+2]];
v.uv=tex[data[3*i+2]];
vertices[i]=v;
indices[i]=i;
}
+2 -2
View File
@@ -87,8 +87,8 @@ namespace vb01{
for(Mesh *mesh : meshes){
Material *mat=mesh->getMaterial();
if(n->isVisible()&&mat&&mat->isLightingEnabled()){
Vector3 pos=n->getWorldPosition();
Quaternion rot=n->getWorldOrientation();
Vector3 pos=n->localToGlobalPosition(Vector3::VEC_ZERO);
Quaternion rot=n->localToGlobalOrientation(Quaternion::QUAT_W);
Vector3 rotAxis=rot.norm().getAxis();
if(rotAxis==Vector3::VEC_ZERO)
+9
View File
@@ -139,13 +139,16 @@ namespace vb01{
int newRows=dim[0]-1,newColumns=dim[1]-1;
float **matrix=new float*[dim[0]];
bool offsetRows=false,offsetColumns=false;
for(int i=0;i<dim[1];i++){
matrix[i]=new float[dim[1]];
for(int j=0;j<dim[1];j++)
if(i!=row&&j!=column){
int a=offsetRows&&i!=0?i-1:i,b=offsetColumns&&j!=0?j-1:j;
matrix[a][b]=this->matrix[i][j];
}
else if(i==row) offsetRows=true;
else if(j==column) offsetColumns=true;
}
@@ -155,11 +158,17 @@ namespace vb01{
void Matrix::invert(){
transpose();
float **matrix=new float*[dim[0]];
for(int i=0;i<dim[0];i++){
matrix[i]=new float[dim[1]];
for(int j=0;j<dim[1];j++)
matrix[i][j]=getCofactor(i,j);
}
for(int i=0;i<dim[0];i++)
delete this->matrix[i];
delete[] this->matrix;
this->matrix=matrix;
*this/getDeterminant();
}
+31 -8
View File
@@ -18,10 +18,15 @@ namespace vb01{
}
Mesh::Mesh(Vertex *vertices, unsigned int *indices,int numTris){
Mesh::Mesh(Vertex *vertices,unsigned int *indices,int numTris,VertexGroup *vertexGroups,int numVertexGroups,ShapeKey *shapeKeys,int numShapeKeys,string name){
this->vertices=vertices;
this->indices=indices;
this->numTris=numTris;
this->groups=vertexGroups;
this->numVertexGroups=numVertexGroups;
this->shapeKeys=shapeKeys;
this->numShapeKeys=numShapeKeys;
this->name=name;
construct();
}
@@ -77,7 +82,7 @@ namespace vb01{
glEnableVertexAttribArray(0);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(Vertex),(void*)(offsetof(Vertex,norm)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,sizeof(Vertex),(void*)(offsetof(Vertex,texCoords)));
glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,sizeof(Vertex),(void*)(offsetof(Vertex,uv)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(3,3,GL_FLOAT,GL_FALSE,sizeof(Vertex),(void*)(offsetof(Vertex,tan)));
glEnableVertexAttribArray(3);
@@ -94,10 +99,8 @@ namespace vb01{
Quaternion orient=Quaternion::QUAT_W;
if(node){
Node::Transform t=node->getWorldTransform();
pos=t.position;
orient=t.orientation;
pos=node->localToGlobalPosition(Vector3::VEC_ZERO);
orient=node->localToGlobalOrientation(Quaternion::QUAT_W);
camPos=cam->getPosition();
}
@@ -120,8 +123,8 @@ namespace vb01{
for(Node *n : descendants){
for(Mesh *m : n->getMeshes())
if(m!=this){
Vector3 position=n->getWorldPosition();
Quaternion rotation=n->getWorldOrientation();
Vector3 position=n->localToGlobalPosition(Vector3::VEC_ZERO);
Quaternion rotation=n->localToGlobalOrientation(Quaternion::QUAT_W);
Vector3 rotAxis=rotation.norm().getAxis();
if(rotAxis==Vector3::VEC_ZERO)
@@ -188,4 +191,24 @@ namespace vb01{
glPolygonMode(GL_FRONT_AND_BACK,wireframe?GL_LINE:GL_FILL);
glDrawElements(GL_TRIANGLES,3*numTris,GL_UNSIGNED_INT,0);
}
Mesh::VertexGroup& Mesh::getVertexGroup(string name){
int id=-1;
for(int i=0;i<numVertexGroups;i++)
if(groups[i].name==name){
id=i;
break;
}
return groups[id];
}
Mesh::ShapeKey& Mesh::getShapeKey(string name){
int id=-1;
for(int i=0;i<numVertexGroups;i++)
if(shapeKeys[i].name==name){
id=i;
break;
}
return shapeKeys[id];
}
}
+18 -6
View File
@@ -18,30 +18,41 @@ namespace vb01{
public:
struct Vertex{
Vector3 pos,tan,biTan,norm;
Vector2 texCoords;
Vector2 uv;
};
struct VertexGroup{
int numVertices=0;
int numVertices;
u32 *vertices=nullptr;
float *weights=nullptr;
std::string name;
};
struct ShapeKey{
int numVertices;
Vertex **vertices=nullptr;
float *weights;
Vector3 *offsets=nullptr;
std::string name;
};
Mesh(Vertex*,unsigned int*,int);
Mesh(Vertex*,unsigned int*,int,VertexGroup *groups=nullptr,int=0,ShapeKey *keys=nullptr,int=0,std::string="");
~Mesh();
virtual void update();
void render();
void setMaterial(Material *mat){this->material=mat;}
VertexGroup& getVertexGroup(std::string);
ShapeKey& getShapeKey(std::string);
inline void setNode(Node *node){this->node=node;}
inline void setCastShadow(bool castShadow){this->castShadow=castShadow;}
inline void setReflect(bool r){this->reflect=r;}
inline void setWireframe(bool w){this->wireframe=w;}
inline void setSkeleton(Skeleton *sk){this->skeleton=sk;}
inline Node* getNode(){return node;}
inline Material* getMaterial(){return material;}
inline std::vector<Mesh*>& getMeshes(){return meshes;}
inline bool isCastShadow(){return castShadow;}
inline int getNumVerts(){return 3*numTris;}
inline Vertex* getVerts(){return vertices;}
inline std::string getName(){return name;}
inline Skeleton* getSkeleton(){return skeleton;}
inline unsigned int* getIndices(){return indices;}
private:
Shader *environmentShader=nullptr;
@@ -59,9 +70,10 @@ namespace vb01{
bool staticVerts=true,castShadow=false,reflect=false,wireframe=false;
Vertex *vertices;
VertexGroup groups;
VertexGroup *groups;
ShapeKey *shapeKeys;
unsigned int *indices,VAO,VBO,EBO;
int numTris;
int numTris,numVertexGroups=0,numShapeKeys=0;
};
}
+324 -109
View File
@@ -3,6 +3,11 @@
#include"material.h"
#include"vector.h"
#include"util.h"
#include"bone.h"
#include"root.h"
#include"skeleton.h"
#include"animation.h"
#include<vector>
#include<iostream>
#include<Importer.hpp>
@@ -49,11 +54,11 @@ namespace vb01{
v.biTan.z=mesh->mBitangents[i].z;
if(mesh->mTextureCoords[0]){
v.texCoords.x=mesh->mTextureCoords[0][i].x;
v.texCoords.y=mesh->mTextureCoords[0][i].y;
v.uv.x=mesh->mTextureCoords[0][i].x;
v.uv.y=mesh->mTextureCoords[0][i].y;
}
else
v.texCoords=Vector2::VEC_ZERO;
v.uv=Vector2::VEC_ZERO;
vertices[i]=v;
}
for(int i=0;i<numTris;i++){
@@ -69,6 +74,7 @@ namespace vb01{
}
Model::Model(string path,bool b) : Node(){
Node *rootNode=Root::getSingleton()->getRootNode();
if(b){
Importer importer;
const aiScene *scene=importer.ReadFile(path,aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenNormals | aiProcess_CalcTangentSpace);
@@ -79,130 +85,319 @@ namespace vb01{
processNode(scene->mRootNode,scene,this);
}
else{
int numTris,numVerts,numGroups,v=0,u=0,vg=0,b=0;
Mesh::Vertex *vertices;
Mesh::VertexGroup *groups=new Mesh::VertexGroup[5];
unsigned int *indices;
Vector3 *pos,*norm;
enum Stage{ARMATURE,MESH};
Stage stage;
ifstream in(path);
string l;
bool verts=false,uv=false,vertexGroups=false,bones=false;
string l,name="";
Vector3 localPos=Vector3::VEC_ZERO,localScale=Vector3::VEC_IJK;
Quaternion localRot=Quaternion::QUAT_W;
vector<string> childrenChain;
vector<Skeleton*> skeletons;
vector<Mesh*> meshes;
vector<Light*> lights;
vector<Node*> nodes;
Skeleton *skeleton=nullptr;
string animName="";
Bone *animBone=nullptr;
vector<Vector3> vertPos,vertNorm;
const int numVertsPerFace=3;
int numVertPos=0,numFaces=0,vertId=0,faceId=0,groupId=-1,groupVertId=0,numGroups=0,numShapeKeys=0;
Mesh::Vertex *vertices;
u32 *indices;
Mesh::VertexGroup *groups=nullptr;
Mesh::ShapeKey *shapeKeys=nullptr;
while(getline(in,l)){
if(l.substr(0,8)=="numFaces"){
numTris=atoi(l.substr(9,string::npos).c_str());
vertices=new Mesh::Vertex[numTris*3];
indices=new unsigned int[numTris*3];
}
else if(l.substr(0,11)=="numVertices"){
numVerts=atoi(l.substr(12,string::npos).c_str());
pos=new Vector3[numVerts];
norm=new Vector3[numVerts];
}
else if(l.substr(0,9)=="numGroups"){
numGroups=atoi(l.substr(10,string::npos).c_str());
groups=new Mesh::VertexGroup[numGroups];
}
if(l=="vertices:"){
verts=true;
int colonId=-1;
for(int i=0;i<l.length();i++)
if(l[i]==':'){
colonId=i;
break;
}
string preColon=l.substr(0,colonId);
string postColon=l.length()==colonId+1?"":l.substr(colonId+2,string::npos);
if(preColon=="ARMATURE"){
stage=ARMATURE;
skeleton=new Skeleton(postColon);
name=postColon;
continue;
}
else if(l=="uv:"){
verts=false;
uv=true;
else if(preColon=="MESH"){
stage=MESH;
name=postColon;
continue;
}
else if(l=="groups:"){
uv=false;
vertexGroups=true;
else if(preColon=="pos"){
continue;
}
else if(l=="bones:"){
vertexGroups=false;
bones=true;
else if(preColon=="rot"){
continue;
}
if(verts||uv||vertexGroups||bones){
int numCoords=1;
if(verts)numCoords=6;
else if(uv)numCoords=3;
else if(vg)numCoords=3;
else if(groups)numCoords=1;
int nextSpace=0;
int *spaceIds=new int[numCoords-1];
for(int i=0;i<l.length();i++)
if(l.c_str()[i]==' '){
spaceIds[nextSpace]=i;
nextSpace++;
else if(preColon=="scale"){
continue;
}
else if(preColon=="parent"){
childrenChain.push_back(name+" "+postColon);
continue;
}
if(stage==ARMATURE){
enum ArmatureStage{BONES,ANIMATIONS};
ArmatureStage armatureStage;
int numBones=0;
if(preColon=="bones"){
numBones=atoi(postColon.c_str());
armatureStage=BONES;
continue;
}
else if(preColon=="animations"){
armatureStage=ANIMATIONS;
continue;
}
switch(armatureStage){
case BONES:
{
int numData=11;
string data[numData];
getLineData(postColon,data,numData);
float length=atof(data[0].c_str());
Vector3 pos=Vector3(atof(data[2].c_str()),atof(data[4].c_str()),-atof(data[3].c_str()));
Vector3 xAxis=Vector3(atof(data[5].c_str()),atof(data[7].c_str()),-atof(data[6].c_str())),yAxis=Vector3(atof(data[8].c_str()),atof(data[10].c_str()),-atof(data[9].c_str())),zAxis=xAxis.cross(yAxis);
string parName=string(data[0].c_str());
Node *parent=skeleton->getBone(parName);
if(!parent)
parent=this;
Bone *bone=new Bone(preColon);
skeleton->addBone(bone,parent);
bone->setPosition(parent->globalToLocalPosition(pos));
bone->lookAt(yAxis,zAxis,parent);
break;
}
float *coords=new float[numCoords];
for(int i=0;i<numCoords;i++){
int firstChar,lastChar;
if(i==0)
firstChar=0,lastChar=spaceIds[i];
else if(i==numCoords-1)
firstChar=spaceIds[i-1],lastChar=string::npos;
else
firstChar=spaceIds[i-1],lastChar=spaceIds[i]-spaceIds[i-1];
coords[i]=atof(l.substr(firstChar,lastChar).c_str());
}
if(verts){
pos[v]=Vector3(coords[0],coords[1],coords[2]);
norm[v]=Vector3(coords[3],coords[4],coords[5]);
//Vector2 uv=Vector2(coords[6],coords[7]);
//vertices[v].pos=pos;
//vertices[v].norm=norm;
//vertices[v].texCoords=uv;
v++;
}
else if(uv){
int id=(int)coords[0];
Vector2 uv=Vector2(coords[1],coords[2]);
vertices[u].pos=pos[id];
vertices[u].norm=norm[id];
vertices[u].texCoords=uv;
indices[u]=u;
u++;
}
else if(vertexGroups){
if(l.c_str()[l.length()-1]==':'){
numCoords=1;
groups[vg].vertices=new Mesh::Vertex*;
groups[vg].weights=new float;
groups[vg].name=l.c_str()[l.length()-1];
vg++;
}
else{
numCoords=2;
int *ids=new int,numVerts=0;
for(int i=0;i<3*numTris;i++){
if(vertices[i].pos==pos[(int)coords[0]]){
ids[numVerts]=i;
numVerts++;
case ANIMATIONS:
{
if(preColon=="animationName"){
animName=postColon;
skeleton->addAnimation(new Animation(animName));
continue;
}
Bone *b=skeleton->getBone(preColon);
if(b){
animBone=b;
Animation *anim=skeleton->getAnimation(animName);
Animation::KeyframeGroup *group=anim->getKeyframeGroup(animBone);
if(!group){
Animation::KeyframeGroup kg;
kg.bone=animBone;
anim->addKeyframeGroup(kg);
}
continue;
}
else{
Animation::KeyframeGroup::Keyframe::Type type;
Animation::KeyframeGroup::Keyframe::Interpolation interp;
if(preColon=="pos_x")
type=Animation::KeyframeGroup::Keyframe::Type::POS_X;
else if(preColon=="pos_y")
type=Animation::KeyframeGroup::Keyframe::Type::POS_Y;
else if(preColon=="pos_z")
type=Animation::KeyframeGroup::Keyframe::Type::POS_Z;
else if(preColon=="rot_w")
type=Animation::KeyframeGroup::Keyframe::Type::ROT_W;
else if(preColon=="rot_x")
type=Animation::KeyframeGroup::Keyframe::Type::ROT_X;
else if(preColon=="rot_y")
type=Animation::KeyframeGroup::Keyframe::Type::ROT_Y;
else if(preColon=="rot_z")
type=Animation::KeyframeGroup::Keyframe::Type::ROT_Z;
else if(l==""){
skeletons.push_back(skeleton);
break;
}
else{
int numData=3;
string data[numData];
getLineData(l,data,numData);
float value=atof(data[0].c_str()),frame=atoi(data[1].c_str());
interp=(Animation::KeyframeGroup::Keyframe::Interpolation)atoi(data[2].c_str());
Animation::KeyframeGroup::Keyframe keyframe;
keyframe.type=type;
keyframe.interpolation=interp;
keyframe.value=value;
keyframe.frame=frame;
skeleton->getAnimation(animName)->getKeyframeGroup(animBone)->keyframes.push_back(keyframe);
}
}
for(int i=0;i<3*numTris;i++)
for(int j=0;j<numVerts;j++){
groups[vg].vertices[groups[vg].numVertices]=&(vertices[ids[j]]);
groups[vg].weights[ids[j]]=coords[1];
}
groups[vg].numVertices++;
delete[] ids;
break;
}
}
else if(bones){
b++;
}
else{
enum MeshStage{VERTICES,FACES,GROUPS,SHAPE_KEYS};
MeshStage meshStage;
if(preColon=="vertices"){
string data[2];
getLineData(postColon,data,2);
numVertPos=atoi(data[0].c_str());
numFaces=atoi(data[1].c_str());
meshStage=VERTICES;
continue;
}
else if(preColon=="faces"){
meshStage=FACES;
vertices=new Mesh::Vertex[numFaces*numVertsPerFace];
indices=new u32[numFaces*numVertsPerFace];
continue;
}
else if(preColon=="groups"){
numGroups=atoi(postColon.c_str());
groups=new Mesh::VertexGroup[numGroups];
meshStage=GROUPS;
continue;
}
else if(preColon=="shapeKeys"){
meshStage=SHAPE_KEYS;
continue;
}
switch(meshStage){
{
case VERTICES:
int numData=6;
string data[numData];
getLineData(l,data,numData);
Vector3 vp=Vector3(atof(data[0].c_str()),atof(data[2].c_str()),-atof(data[1].c_str()));
Vector3 vn=Vector3(atof(data[3].c_str()),atof(data[5].c_str()),-atof(data[4].c_str()));
vertPos.push_back(vp);
vertNorm.push_back(vn);
break;
}
{
case FACES:
int numData=9;
string data[numData];
getLineData(l,data,numData);
u32 index=atoi(data[0].c_str());
Vector2 uv=Vector2(atof(data[1].c_str()),atof(data[2].c_str()));
Vector3 tan=Vector3(atof(data[3].c_str()),atof(data[5].c_str()),-atof(data[4].c_str()));
Vector3 biTan=Vector3(atof(data[6].c_str()),atof(data[8].c_str()),-atof(data[7].c_str()));
/*
*/
Mesh::Vertex vert;
vert.pos=vertPos[index];
vert.norm=vertNorm[index];
vert.uv=uv;
vert.tan=tan;
vert.biTan=biTan;
vertices[vertId]=vert;
indices[vertId]=vertId;
vertId++;
break;
}
{
case GROUPS:
if(l==""){
meshes.push_back(new Mesh(vertices,indices,numFaces,groups,numGroups,shapeKeys,numShapeKeys,name));
break;
}
else if(colonId!=-1){
groupId++,groupVertId=0;
int numVerts=atoi(postColon.c_str());
groups[groupId].numVertices=numVerts;
groups[groupId].name=preColon;
if(numVerts>0){
groups[groupId].vertices=new u32[numVerts];
groups[groupId].weights=new float[numVerts];
}
}
else{
int numData=2,vertId;
float weight;
string data[numData];
getLineData(l,data,numData);
vertId=atoi(data[0].c_str());
weight=atof(data[1].c_str());
groups[groupId].vertices[groupVertId]=vertId;
groups[groupId].weights[groupVertId]=weight;
groupVertId++;
}
break;
}
{
case SHAPE_KEYS:
if(l==""){
meshes.push_back(new Mesh(vertices,indices,numFaces,groups,numGroups,shapeKeys,numShapeKeys,name));
break;
}
break;
}
}
delete[] coords;
}
}
delete[] pos;
delete[] norm;
attachChild(new Node());
children[0]->attachMesh(new Mesh(vertices,indices,numTris));
for(Mesh *mesh : meshes){
Node *meshNode=new Node(localPos,localRot,localScale);
meshNode->attachMesh(mesh);
nodes.push_back(meshNode);
for(string line : childrenChain){
int spaceId=-1;
for(int i=0;i<line.length();i++)
if(line[i]==' ')
spaceId=i;
string childName=line.substr(0,spaceId),parentName=line.substr(spaceId+1,string::npos);
if(mesh->getName()==childName){
for(Skeleton *sk : skeletons){
if(sk->getName()==parentName)
mesh->setSkeleton(sk);
}
}
}
}
for(Light *light : lights){
Node *lightNode=new Node(localPos,localRot,localScale);
lightNode->addLight(light);
nodes.push_back(lightNode);
}
for(string line : childrenChain){
int spaceId=-1;
for(int i=0;i<line.length();i++)
if(line[i]==' ')
spaceId=i;
string childName=line.substr(0,spaceId),parentName=line.substr(spaceId+1,string::npos);
Node *childNode=nullptr,*parentNode=this;
for(int i=0;i<nodes.size();i++){
Mesh *m0=nodes[i]->getMesh(0);
Skeleton *sk0=m0->getSkeleton();
if(m0->getName()==childName||(sk0&&sk0->getName()==childName)){
childNode=nodes[i];
for(int j=0;j<nodes.size();j++){
Mesh *m1=nodes[j]->getMesh(0);
Skeleton *sk1=m1->getSkeleton();
if(m1->getName()==parentName||(sk1&&sk1->getName()==parentName))
parentNode=nodes[j];
}
}
}
if(childNode!=parentNode)
parentNode->attachChild(childNode);
}
}
}
@@ -226,6 +421,26 @@ namespace vb01{
Node::update();
}
void Model::getLineData(string &line,string data[],int numData,int offset){
int offsetComma=0,c1=0;
for(int i=0;i<line.length()&&offsetComma<offset;i++)
if(line.c_str()[i]==' '){
c1=i+1;
offsetComma++;
}
int c2=c1;
for(int i=0;i<numData;i++){
for(int j=c1;j<line.length();j++)
if(line.c_str()[j]==' '){
c2=j;
break;
}
data[i]=line.substr(c1,c2-c1);
c2++;
c1=c2;
}
}
void Model::setMaterial(Material *mat){
vector<Node*> descendants;
getDescendants(this,descendants);
+1
View File
@@ -29,6 +29,7 @@ namespace vb01{
void processMesh(aiMesh*, const aiScene*, Node*);
// std::vector<Texture*> processTexture(aiMaterial*, Assimp::aiTextureType);
void processMaterial();
void getLineData(std::string&,std::string[],int,int=0);
Material* material;
bool castShadow=false,reflect=false,wireframe=false;
+124 -88
View File
@@ -6,14 +6,21 @@
#include"text.h"
#include"material.h"
#include"matrix.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){
Node::Node(Vector3 pos, Quaternion orientation, Vector3 scale,string name){
this->pos=pos;
this->scale=scale;
this->orientation=orientation;
this->name=name;
axis[0]=Vector3::VEC_I;
axis[1]=Vector3::VEC_J;
axis[2]=Vector3::VEC_K;
}
Node::~Node(){
@@ -49,6 +56,7 @@ namespace vb01{
void Node::attachChild(Node *child){
child->setParent(this);
children.push_back(child);
child->updateLocalAxis();
}
void Node::dettachChild(Node *child){
@@ -91,15 +99,33 @@ namespace vb01{
text->setNode(this);
}
void Node::lookAt(Vector3 newDir,Vector3 upDir){
Vector3 dir=getLocalAxis(2).norm(),newDirLocal=globalToLocal(newDir.norm()),upDirLocal=globalToLocal(upDir.norm());
float angle=dir.getAngleBetween(newDirLocal);
Vector3 rotAxis=dir.cross(newDirLocal);
orientation=Quaternion(angle,rotAxis)*orientation;
Vector3 up=getLocalAxis(1).norm();
angle=up.getAngleBetween(upDirLocal);
rotAxis=up.cross(upDirLocal);
orientation=Quaternion(angle,rotAxis.norm())*orientation;
void Node::lookAt(Vector3 newDir,Vector3 newUp,Node *node){
newDir=node->localToGlobalPosition(newDir);
newUp=node->localToGlobalPosition(newUp);
float angle=axis[2].getAngleBetween(newDir);
Vector3 rotAxis=axis[2].cross(newDir).norm();
if(rotAxis==Vector3::VEC_ZERO)
rotAxis=axis[1];
//setOrientation((Quaternion(angle,rotAxis)*(orientation)));
setOrientation(node->globalToLocalOrientation(Quaternion(angle,rotAxis)*node->localToGlobalOrientation(orientation)));
mat3 mat;
mat[0][0]=axis[0].x;
mat[1][0]=axis[0].y;
mat[2][0]=axis[0].z;
mat[0][1]=axis[1].x;
mat[1][1]=axis[1].y;
mat[2][1]=axis[1].z;
mat[0][2]=axis[2].x;
mat[1][2]=axis[2].y;
mat[2][2]=axis[2].z;
mat=inverse(mat);
vec3 nu=vec3(newUp.x,newUp.y,newUp.z)*mat;
newUp=(axis[0]*nu.x+axis[1]*nu.y).norm();
angle=axis[1].getAngleBetween(newUp);
//setOrientation((Quaternion(angle*(nu.x<0?1:-1),axis[2])*(orientation)));
setOrientation(node->globalToLocalOrientation(Quaternion(angle*(nu.x<0?1:-1),axis[2])*node->localToGlobalOrientation(orientation)));
//setOrientation(node->globalToLocalOrientation(Quaternion(angle,axis[2])*node->localToGlobalOrientation(orientation)));
}
void Node::getDescendants(Node *node, vector<Node*> &descendants){
@@ -111,111 +137,116 @@ namespace vb01{
}
}
Node::Transform Node::getWorldTransform(){
Transform t;
Vector3 scale=Vector3::VEC_IJK;
Quaternion orient=Quaternion::QUAT_W;
Vector3 origin=Vector3::VEC_ZERO,axis[]={Vector3::VEC_I,Vector3::VEC_J,Vector3::VEC_K};
void Node::updateLocalAxis(){
Node *rootNode=Root::getSingleton()->getRootNode(),*par=this;
while(par->getParent())
par=par->getParent();
if(par!=rootNode)
return;
Vector3 parAxis[3]={
parent->getLocalAxis(0),
parent->getLocalAxis(1),
parent->getLocalAxis(2)
};
for(int i=0;i<3;i++)
axis[i]=(orientation*parAxis[i]).norm();
for(Node *ch : children)
ch->updateLocalAxis();
}
Vector3 Node::localToGlobalPosition(Vector3 localPos){
Vector3 origin=Vector3::VEC_ZERO;
vector<Node*> ancestors;
ancestors.push_back(this);
Node *parent=this->getParent();
while(parent){
ancestors.push_back(parent);
parent=parent->getParent();
}
while(!ancestors.empty()){
int id=ancestors.size()-1;
Quaternion o=ancestors[id]->getOrientation();
Vector3 p=ancestors[id]->getPosition(),s=ancestors[id]->getScale();
origin=origin+axis[0]*p.x*s.x+axis[1]*p.y*s.y+axis[2]*p.z*s.z;
orient=o*orient;
scale=s;
for(int i=0;i<3;i++)
axis[i]=orient*axis[i];
Node *par=ancestors[id]->getParent();
Vector3 parAxis[]={
par?par->getLocalAxis(0):Vector3::VEC_I,
par?par->getLocalAxis(1):Vector3::VEC_J,
par?par->getLocalAxis(2):Vector3::VEC_K
};
Vector3 p=ancestors[id]->getPosition();
origin=origin+parAxis[0]*p.x+parAxis[1]*p.y+parAxis[2]*p.z;
ancestors.pop_back();
}
t.position=origin,t.orientation=orient,t.scale=scale;
return t;
return origin+axis[0]*localPos.x+axis[1]*localPos.y+axis[2]*localPos.z;
}
Vector3 Node::getLocalAxis(int i){
Transform t;
Vector3 pos=Vector3::VEC_ZERO,scale=Vector3::VEC_IJK;
Quaternion orient=Quaternion::QUAT_W;
Vector3 origin=Vector3::VEC_ZERO,axis[]={Vector3::VEC_I,Vector3::VEC_J,Vector3::VEC_K};
Vector3 Node::globalToLocalPosition(Vector3 globalPos){
Vector3 origin=globalPos;
vector<Node*> ancestors;
ancestors.push_back(this);
Node *parent=this->getParent();
while(parent){
ancestors.push_back(parent);
parent=parent->getParent();
}
while(!ancestors.empty()){
int id=ancestors.size()-1;
Quaternion o=ancestors[id]->getOrientation();
Vector3 p=ancestors[id]->getPosition(),s=ancestors[id]->getScale();
origin=origin+axis[0]*p.x*s.x+axis[1]*p.y*s.y+axis[2]*p.z*s.z;
orient=o*orient;
scale=s;
for(int i=0;i<3;i++)
axis[i]=orient*axis[i];
ancestors.pop_back();
int id=0;
Node *par=ancestors[id]->getParent();
Vector3 parAxis[]={
par?par->getLocalAxis(0):Vector3::VEC_I,
par?par->getLocalAxis(1):Vector3::VEC_J,
par?par->getLocalAxis(2):Vector3::VEC_K
};
Vector3 p=ancestors[id]->getPosition();
origin=origin-parAxis[0]*p.x-parAxis[1]*p.y-parAxis[2]*p.z;
ancestors.erase(ancestors.begin());
}
//return origin+axis[0]*localPos.x+axis[1]*localPos.y+axis[2]*localPos.z;
return origin;
}
Quaternion Node::localToGlobalOrientation(Quaternion localRot){
Quaternion origin=Quaternion::QUAT_W;
vector<Node*> ancestors;
ancestors.push_back(this);
Node *parent=this->getParent();
while(parent){
ancestors.push_back(parent);
parent=parent->getParent();
}
return axis[i];
while(!ancestors.empty()){
int id=ancestors.size()-1;
Quaternion o=ancestors[id]->getOrientation();
origin=o*origin;
ancestors.pop_back();
}
return localRot*origin;
}
Vector3 Node::localToGlobal(Vector3 p0){
Vector3 dir=getLocalAxis(2),up=getLocalAxis(1),left=getLocalAxis(0);
float **mat=new float*[3];
for(int i=0;i<3;i++)
mat[i]=new float[3];
Quaternion Node::globalToLocalOrientation(Quaternion globalRot){
Quaternion origin=globalRot;
vector<Node*> ancestors;
ancestors.push_back(this);
Node *parent=this->getParent();
mat[0][0]=left.x;
mat[1][0]=left.y;
mat[2][0]=left.z;
mat[0][1]=up.x;
mat[1][1]=up.y;
mat[2][1]=up.z;
mat[0][2]=dir.x;
mat[1][2]=dir.y;
mat[2][2]=dir.z;
while(parent){
ancestors.push_back(parent);
parent=parent->getParent();
}
Vector3 p=Matrix(mat,3,3)*p0;
for(int i=0;i<3;i++)
delete[] mat[i];
delete[] mat;
return p;
}
Vector3 Node::globalToLocal(Vector3 p0){
Vector3 dir=getLocalAxis(2),up=getLocalAxis(1),left=getLocalAxis(0);
float **mat=new float*[3];
for(int i=0;i<3;i++)
mat[i]=new float[3];
mat[0][0]=left.x;
mat[1][0]=left.y;
mat[2][0]=left.z;
mat[0][1]=up.x;
mat[1][1]=up.y;
mat[2][1]=up.z;
mat[0][2]=dir.x;
mat[1][2]=dir.y;
mat[2][2]=dir.z;
Matrix m(mat,3,3);
m.invert();
Vector3 p=m*p0;
for(int i=0;i<3;i++)
delete[] mat[i];
delete[] mat;
return p;
while(!ancestors.empty()){
int id=ancestors.size()-1;
Quaternion o=ancestors[id]->getOrientation();
origin=origin*Quaternion(-o.getAngle(),o.getAxis());
ancestors.pop_back();
}
return origin;
}
void Node::updateShaders(){
@@ -236,4 +267,9 @@ namespace vb01{
}
}
}
void Node::setOrientation(Quaternion q){
this->orientation=q;
updateLocalAxis();
}
}
+18 -14
View File
@@ -4,6 +4,7 @@
#include"quaternion.h"
#include"vector.h"
#include<vector>
#include<string>
namespace vb01{
class Mesh;
@@ -15,11 +16,11 @@ namespace vb01{
class Node{
public:
struct Transform{
Vector3 position,scale;
Quaternion orientation;
Vector3 position=Vector3::VEC_ZERO,scale=Vector3::VEC_IJK;
Quaternion orientation=Quaternion::QUAT_W;
};
Node(Vector3=Vector3::VEC_ZERO,Quaternion=Quaternion::QUAT_W,Vector3=Vector3::VEC_IJK);
Node(Vector3=Vector3::VEC_ZERO,Quaternion=Quaternion::QUAT_W,Vector3=Vector3::VEC_IJK,std::string="");
virtual ~Node();
void attachMesh(Mesh*);
void attachParticleEmitter(ParticleEmitter*);
@@ -29,20 +30,23 @@ namespace vb01{
void addLight(Light*);
void removeLight(int);
void addText(Text*);
void lookAt(Vector3,Vector3);
Transform getWorldTransform();
Vector3 getLocalAxis(int);
Vector3 localToGlobal(Vector3);
Vector3 globalToLocal(Vector3);
void lookAt(Vector3,Vector3,Node*);
void updateLocalAxis();
void setOrientation(Quaternion);
void getDescendants(Node*,std::vector<Node*>&);
Vector3 localToGlobalPosition(Vector3);
Vector3 globalToLocalPosition(Vector3);
Quaternion localToGlobalOrientation(Quaternion);
Quaternion globalToLocalOrientation(Quaternion);
Vector3 localToGlobalScale(Vector3);
Vector3 globalToLocalScale(Vector3);
inline Text* getText(int i){return texts[i];}
inline Vector3 getWorldPosition(){return getWorldTransform().position;}
inline Quaternion getWorldOrientation(){return getWorldTransform().orientation;}
inline Vector3 getWorldScale(){return getWorldTransform().scale;}
inline std::vector<Mesh*>& getMeshes(){return meshes;}
inline Mesh* getMesh(int i){return meshes[i];}
inline Node* getParent(){return parent;}
inline void setParent(Node *par){this->parent=par;}
inline Node* getChild(int i){return children[i];}
inline Vector3 getLocalAxis(int i){return axis[i];}
inline Vector3 getPosition(){return pos;}
inline Vector3 getScale(){return scale;}
inline void setPosition(Vector3 pos){this->pos=pos;}
@@ -53,21 +57,21 @@ namespace vb01{
inline int getNumLights(){return lights.size();}
inline int getNumChildren(){return children.size();}
inline Quaternion getOrientation(){return orientation;}
inline void setOrientation(Quaternion q){this->orientation=q;}
inline bool isVisible(){return visible;}
inline std::string getName(){return name;}
inline void setVisible(bool v){this->visible=v;}
void getDescendants(Node*,std::vector<Node*>&);
protected:
void updateShaders();
bool visible=true;
Vector3 pos,scale;
Vector3 pos,scale,axis[3];
Quaternion orientation;
std::vector<Mesh*> meshes;
std::vector<ParticleEmitter*> emitters;
std::vector<Node*> children;
std::vector<Light*> lights;
std::vector<Text*> texts;
std::string name;
Node *parent=nullptr;
};
}
+1 -1
View File
@@ -139,7 +139,7 @@ namespace vb01{
shader->setVec2(startSize,"startSize");
shader->setVec2(endSize,"endSize");
Vector3 nodePos=node->getWorldTransform().position;
Vector3 nodePos=node->localToGlobalPosition(Vector3::VEC_ZERO);
Vector3 nodeDir=node->getLocalAxis(2);
Vector3 nodeUp=node->getLocalAxis(1);
Vector3 nodeLeft=node->getLocalAxis(0);
+6 -6
View File
@@ -36,22 +36,22 @@ namespace vb01{
v6.pos=Vector3(size.x,0,0);
}
v1.norm=Vector3(0,0,-1);
v1.texCoords=Vector2(1,1);
v1.uv=Vector2(1,1);
v2.norm=Vector3(0,0,-1);
v2.texCoords=Vector2(0,1);
v2.uv=Vector2(0,1);
v3.norm=Vector3(0,0,-1);
v3.texCoords=Vector2(0,0);
v3.uv=Vector2(0,0);
v4.norm=Vector3(0,0,-1);
v4.texCoords=Vector2(0,0);
v4.uv=Vector2(0,0);
v5.norm=Vector3(0,0,-1);
v5.texCoords=Vector2(1,0);
v5.uv=Vector2(1,0);
v6.norm=Vector3(0,0,-1);
v6.texCoords=Vector2(1,1);
v6.uv=Vector2(1,1);
indices[0]=0;
indices[1]=1;
+1
View File
@@ -50,6 +50,7 @@ namespace vb01{
}
inline Quaternion norm(){return *this/getLength();}
inline Quaternion recip(){return conj()/getLengthSq();}
inline Quaternion invert(){return conj()/(getLengthSq());}
inline float getLengthSq(){return w*w+x*x+y*y+z*z;}
inline float getLength(){return std::sqrt(getLengthSq());}
+2 -2
View File
@@ -7,8 +7,8 @@ using namespace std;
namespace vb01{
void retrieveCollisions(Vector3 rayPos, Vector3 rayDir,Node *node,std::vector<CollisionResult> &results, const float rayLength){
Vector3 pos=node->getWorldPosition();
Quaternion rot=node->getWorldOrientation();
Vector3 pos=node->localToGlobalPosition(Vector3::VEC_ZERO);
Quaternion rot=node->localToGlobalOrientation(Quaternion::QUAT_W);
for(Mesh *m : node->getMeshes()){
const int numVerts=m->getNumVerts();
Mesh::Vertex *vertices=m->getVerts();
+2 -2
View File
@@ -31,7 +31,7 @@ namespace vb01{
camera=new Camera();
}
void Root::start(int width,int height){
void Root::start(int width,int height,string name){
this->width=width;
this->height=height;
@@ -39,7 +39,7 @@ namespace vb01{
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
window=glfwCreateWindow(width,height,"KEK",NULL,NULL);
window=glfwCreateWindow(width,height,name.c_str(),NULL,NULL);
if(window==NULL){
std::cout<<"Failed to load window.\n";
exit(-1);
+1 -1
View File
@@ -20,7 +20,7 @@ namespace vb01{
class Root{
public:
void update();
void start(int,int);
void start(int,int,std::string);
inline Camera* getCamera(){return camera;}
inline Node* getRootNode(){return rootNode;}
inline Node* getGuiNode(){return guiNode;}
+63 -29
View File
@@ -2,25 +2,18 @@ import sys
def exportData(ob):
par=ob.parent
file.write(ob.name+"\n")
file.write(ob.type+": "+ob.name+"\n")
file.write("pos: "+str(ob.location.x)+" "+str(ob.location.y)+" "+str(ob.location.z)+"\n")
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: "+('None' if par is None else par.name)+"\n")
file.write("parent: "+('-' if par is None else par.name)+"\n")
if(ob.type=="ARMATURE"):
file.write("bones: "+str(len(ob.data.bones)))
for bone in ob.data.bones:
tail=bone.tail
head=bone.head
file.write("\n"+bone.name+": "+str(head.x)+" "+str(head.y)+" "+str(head.z)+" "+str(tail.x)+" "+str(tail.y)+" "+str(tail.z))
file.write("\nboneHierarchy:")
for bone in ob.data.bones:
numChildren=len(bone.children)
if numChildren>0:
file.write('\n'+bone.name+' '+str(numChildren)+':')
for ch in bone.children:
file.write(' '+ch.name)
xAxis=bone.x_axis
yAxis=bone.y_axis
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)+" ")
numAnims=len(ob.animation_data.nla_tracks[0].strips)
if numAnims>0:
@@ -29,7 +22,7 @@ def exportData(ob):
animName=nlaStrip.name
action=bpy.data.actions[animName]
numAnimBones=len(action.groups)
file.write("\n"+animName+": "+str(numAnimBones)+"\n")
file.write("\nanimationName: "+animName+"\n")
print('Exporting animation '+animName+'...\n')
for group in action.groups:
@@ -56,13 +49,22 @@ def exportData(ob):
file.write("rot_"+coords[arrInd])
elif coordType=="scale":
file.write("scale_"+coords[arrInd+1])
file.write(' '+str(numKeyframes)+':\n')
file.write(': '+str(numKeyframes)+'\n')
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
if bpy.context.scene.frame_current>end:
bpy.context.scene.frame_current=bpy.context.scene.frame_current-1
if coordType=="location":
@@ -71,7 +73,7 @@ def exportData(ob):
file.write(str(poseBone.rotation_quaternion[arrInd]))
elif coordType=="scale":
file.write(str(poseBone.scale[arrInd]))
file.write(" "+str(keyframeId)+" "+interp)
file.write(" "+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))
@@ -86,31 +88,56 @@ def exportData(ob):
#if mesh.shape_keys is not NoneType:
#numShapeKeys=len(mesh.shape_keys[0].key_blocks)-1
file.write("vertices: "+str(numVerts)+","+str(numFaces)+"\n")
file.write("vertices: "+str(numVerts)+" "+str(numFaces)+" \n")
print('Exporting vertices...\n')
for vert in mesh.vertices:
pos=vert.co
norm=vert.normal
file.write(str(pos.x)+" "+str(pos.y)+" "+str(pos.z)+" "+str(norm.x)+" "+str(norm.y)+" "+str(norm.z)+"\n")
file.write("uv:\n")
print('Exporting texture coordinates...\n')
file.write(str(pos.x)+" "+str(pos.y)+" "+str(pos.z)+" "+str(norm.x)+" "+str(norm.y)+" "+str(norm.z)+" \n")
'''
for face in mesh.polygons:
for vert,loop in zip(face.vertices,face.loop_indices):
uv=mesh.uv_layers[0].data[loop].uv
file.write(str(vert)+" "+str(uv.x)+" "+str(uv.y)+"\n")
for vert,loop in zip(face.vertices,mesh.loops):
pos=mesh.vertices[vert].co
norm=mesh.vertices[vert].normal
uv=mesh.uv_layers[0].data[loop.index].uv
tan=loop.tangent
bitan=loop.bitangent
file.write(str(pos.x)+" "+str(pos.y)+" "+str(pos.z)+" "+str(norm.x)+" "+str(norm.y)+" "+str(norm.z)+str(uv.x)+" "+str(uv.y)+" "+str(tan.x)+" "+str(tan.y)+" "+str(tan.z)+" "+str(bitan.x)+" "+str(bitan.y)+" "+str(bitan.z)+" \n")
'''
file.write("faces:\n")
print('Exporting faces...\n')
mesh.calc_tangents()
for face in mesh.polygons:
for vert,loopInd in zip(face.vertices,face.loop_indices):
uv=mesh.uv_layers[0].data[loopInd].uv
loop=mesh.loops[loopInd]
tan=loop.tangent
bitan=loop.bitangent
file.write(str(vert)+" "+str(uv.x)+" "+str(uv.y)+" "+str(tan.x)+" "+str(tan.y)+" "+str(tan.z)+" "+str(bitan.x)+" "+str(bitan.y)+" "+str(bitan.z)+" \n")
mesh.free_tangents()
if numGroups>0:
groupVerts=[]
file.write("groups: "+str(numGroups)+"\n")
print('Exporting vertex groups...\n')
for group in ob.vertex_groups:
file.write(group.name+":\n")
for i in range(0,numGroups):
groupVerts.append([])
for vert in mesh.vertices:
for g in vert.groups:
if g.group==ob.vertex_groups[i].index:
groupVerts[i].append(vert.index)
for i in range(0,numGroups):
group=ob.vertex_groups[i]
file.write(group.name+": "+str(len(groupVerts[i]))+"\n")
for vert in mesh.vertices:
for g in vert.groups:
if g.group==group.index:
file.write(str(vert.index)+" "+str(g.weight)+"\n")
file.write(str(vert.index)+" "+str(g.weight)+" \n")
if numShapeKeys>0:
file.write('shape keys:\n')
file.write('shapeKeys:\n')
print('Exporting shape keys...\n')
for shape_key in mesh.shape_keys.key_blocks:
if shape_key.name=='Basis':
@@ -120,7 +147,14 @@ def exportData(ob):
if(newPos!=mesh.vertices[i].co):
file.write('\n'+str(i)+" "+str(newPos.x)+' '+str(newPos.y)+' '+str(newPos.z))
fl="/home/dominykas/c++/vb01/kek.vb";
fl=bpy.data.filepath
dotId=0
for i in range(len(fl)):
if(fl[i]=='.'):
dotId=i
break
fl=fl[0:dotId]+".vb"
objects=[]
selectedObjects=bpy.context.selected_objects
+31 -1
View File
@@ -1,5 +1,35 @@
#include"skeleton.h"
#include"animation.h"
using namespace std;
namespace vb01{
Skeleton::Skeleton(){}
Skeleton::Skeleton(string name){
this->name=name;
}
void Skeleton::addBone(Bone *bone, Node *parent){
parent->attachChild(bone);
bones.push_back(bone);
}
Bone* Skeleton::getBone(string name){
Bone *bone=nullptr;
for(Bone *b : bones)
if(b->getName()==name){
bone=b;
break;
}
return bone;
}
Animation* Skeleton::getAnimation(string name){
Animation *anim=nullptr;
for(Animation *a : animations)
if(a->getName()==name){
anim=a;
break;
}
return anim;
}
}
+17 -1
View File
@@ -1,11 +1,27 @@
#ifndef SKELETON_H
#define SKELETON_H
#include<vector>
#include<string>
#include"bone.h"
namespace vb01{
class Animation;
class Skeleton{
public:
Skeleton();
Skeleton(std::string="");
void addBone(Bone*,Node*);
Bone* getBone(std::string);
Animation* getAnimation(std::string);
inline void addAnimation(Animation *anim){animations.push_back(anim);}
inline Bone* getBone(int i){return bones[i];}
inline std::vector<Bone*>& getBones(){return bones;}
inline std::string getName(){return name;}
private:
std::string name;
std::vector<Bone*> bones;
std::vector<Animation*> animations;
};
}