mirror of
https://github.com/devZoGok/vb01.git
synced 2026-08-26 19:43:30 +00:00
readable .vb format
This commit is contained in:
+2
-1
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef ANIMATION_CHANNEL_H
|
||||
#define ANIMATION_CHANNEL_H
|
||||
|
||||
namespace vb01{
|
||||
class AnimationChannel{
|
||||
public:
|
||||
AnimationChannel();
|
||||
~AnimationChannel();
|
||||
void update();
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "animationController.h"
|
||||
|
||||
namespace vb01{
|
||||
AnimationController::AnimationController(){
|
||||
}
|
||||
|
||||
AnimationController::~AnimationController(){
|
||||
}
|
||||
|
||||
void AnimationController::update(){
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;}
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user