attached objects follow their bones

model space positions are retrieved from bones
supported more than 4 bones
improved global and local orientation methods
improved vector angle method
This commit is contained in:
devZoGok
2021-10-19 19:06:41 +03:00
parent 73f49e91bc
commit 4f4bc88956
14 changed files with 230 additions and 210 deletions
+40 -9
View File
@@ -1,30 +1,61 @@
#include"bone.h"
#include"skeleton.h"
using namespace std;
namespace vb01{
Bone::Bone(string name, Vector3 axis[3], Vector3 pos,Quaternion rot, Vector3 scale) : Node(pos,rot,scale){
Bone::Bone(string name, float length, Vector3 pos,Quaternion rot, Vector3 scale) : Node(pos,rot,scale,name){
this->name=name;
this->restPos=pos;
this->restRot=rot;
this->restScale=scale;
this->length=length;
}
void Bone::lookAt(Vector3 newDir, Vector3 newUp, Node *par){
Node::lookAt(newDir,newUp,par);
for(int i=0;i<3;i++)
this->initAxis[i]=axis[i];
//lookAt(axis[1],axis[2],parent);
this->initAxis[i] = globalAxis[i];
restPos = pos;
restRot = orientation;
restScale = scale;
}
Vector3 Bone::getModelSpacePos(){
Vector3 modelSpacePos = Vector3::VEC_ZERO;
Bone *rootBone = skeleton->getRootBone();
vector<Node*> boneHierarchy = getAncestors(this, rootBone);
while(!boneHierarchy.empty()){
int id = boneHierarchy.size() - 1;
Bone *curBone = ((Bone*)boneHierarchy[id]);
Bone *par = (Bone*)curBone->getParent();
Vector3 axis[]{
curBone != rootBone? par->getInitAxis(0) : Vector3::VEC_I,
curBone != rootBone? par->getInitAxis(1) : Vector3::VEC_J,
curBone != rootBone? par->getInitAxis(2) : Vector3::VEC_K
};
Vector3 rPos = curBone->getRestPos();
modelSpacePos = modelSpacePos + axis[0] * rPos.x + axis[1] * rPos.y + axis[2] * rPos.z;
boneHierarchy.pop_back();
}
return modelSpacePos;
}
void Bone::setPosePos(Vector3 p){
this->posePos=p;
setPosition(restPos+posePos);
Vector3 parentSpacePosePos=parent->globalToLocalPosition(localToGlobalPosition(p));
//setPosition(parentSpacePosePos);
}
void Bone::setPoseRot(Quaternion r){
this->poseRot=r;
setOrientation(poseRot*restRot);
Quaternion parentSpacePoseRot = parent->globalToLocalOrientation(localToGlobalOrientation(r));
setOrientation(parentSpacePoseRot);
}
void Bone::setPoseScale(Vector3 s){
this->poseScale=s;
setScale(restScale+poseScale);
//setScale(restScale+poseScale);
}
}
+9 -2
View File
@@ -5,12 +5,18 @@
#include<string>
namespace vb01{
class Skeleton;
class Bone : public Node{
public:
Bone(std::string,Vector3[3],Vector3=Vector3::VEC_ZERO,Quaternion=Quaternion::QUAT_W,Vector3=Vector3::VEC_ZERO);
Bone(std::string,float,Vector3=Vector3::VEC_ZERO,Quaternion=Quaternion::QUAT_W,Vector3=Vector3::VEC_ZERO);
void setPosePos(Vector3 p);
void setPoseRot(Quaternion r);
void setPoseScale(Vector3 s);
void lookAt(Vector3,Vector3,Node*);
Vector3 getModelSpacePos();
inline float getLength(){return length;}
inline void setSkeleton(Skeleton *sk){this->skeleton = sk;}
inline Vector3 getInitAxis(int i){return initAxis[i];}
inline std::string getName(){return name;}
inline Vector3 getRestPos(){return restPos;}
@@ -20,7 +26,8 @@ namespace vb01{
inline Quaternion getPoseRot(){return poseRot;}
inline Vector3 getPoseScale(){return poseScale;}
private:
std::string name;
float length;
Skeleton *skeleton = nullptr;
Vector3 initAxis[3],restPos,posePos=Vector3::VEC_ZERO,restScale,poseScale=Vector3::VEC_IJK;
Quaternion restRot,poseRot=Quaternion::QUAT_W;
};
+9 -15
View File
@@ -72,11 +72,7 @@ namespace vb01{
glGenBuffers(1,&VBO);
glGenBuffers(1,&EBO);
u32 base=sizeof(float);
u32 size=(14+3*numShapeKeys)*base;
size=sizeof(Vertex);
//size=(18)*sizeof(float)+sizeof(Vector3*);
//cout<<size<<endl;
u32 size=sizeof(Vertex);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
@@ -95,11 +91,9 @@ namespace vb01{
glVertexAttribPointer(4,3,GL_FLOAT,GL_FALSE,size,(void*)(offsetof(Vertex,biTan)));
glEnableVertexAttribArray(4);
glVertexAttribPointer(5,4,GL_FLOAT,GL_FALSE,size,(void*)(offsetof(Vertex,weights)));
//glEnableVertexArrayAttrib(VAO,5);
glEnableVertexAttribArray(5);
//glVertexAttribDivisor(5,1);
for(int i=0;i<numVertexGroups;i++){
}
glVertexAttribPointer(6,4,GL_FLOAT,GL_FALSE,size,(void*)(offsetof(Vertex,boneIndices)));
glEnableVertexAttribArray(6);
}
void Mesh::update(){
@@ -159,11 +153,12 @@ namespace vb01{
glViewport(0,0,root->getWidth(),root->getHeight());
}
Vector3 rotAxis=orient.norm().getAxis();
Vector3 rotAxis=orient.getAxis();
if(rotAxis==Vector3::VEC_ZERO)
rotAxis=Vector3::VEC_I;
mat4 model=translate(mat4(1.),vec3(pos.x,pos.y,pos.z));
model=rotate(model,orient.norm().getAngle(),vec3(rotAxis.x,rotAxis.y,rotAxis.z));
mat4 model = mat4(1.);
model=translate(model,vec3(pos.x,pos.y,pos.z));
model=rotate(model,orient.getAngle(),vec3(rotAxis.x,rotAxis.y,rotAxis.z));
model=glm::scale(model,vec3(scale.x,scale.y,scale.z));
mat4 view=lookAt(vec3(camPos.x,camPos.y,camPos.z),vec3(camPos.x+dir.x,camPos.y+dir.y,camPos.z+dir.z),vec3(up.x,up.y,up.z));
mat4 proj=perspective(radians(fov),width/height,nearPlane,farPlane);
@@ -195,10 +190,9 @@ namespace vb01{
Quaternion poseRot = bone->getPoseRot();
Vector3 trans = boneAxis[0]*posePos.x+boneAxis[1]*posePos.y+boneAxis[2]*posePos.z;
Vector3 scale = bone->getPoseScale();
Vector3 bonePos = (bone->getRestPos());
//bonePos = modelNode->globalToLocalPosition(bonePos);
Vector3 bonePos = bone->getModelSpacePos();
int vertGroupId = -1,parentId = -1;
int vertGroupId = -1, parentId = -1;
for(int j=0;j<numVertexGroups;j++)
if(bone->getName() == vertexGroups[j])
vertGroupId = j;
+2 -1
View File
@@ -21,7 +21,8 @@ namespace vb01{
Vector2 uv;
//Vector4 weights;
//float *weights=nullptr;
float weights[4];
float weights[4]{0,0,0,0};
int boneIndices[4]{-1,-1,-1,-1};
Vector3 *shapeKeyOffsets=nullptr;
};
+19 -46
View File
@@ -103,7 +103,7 @@ namespace vb01{
Bone *animBone=nullptr;
const int numVertsPerFace=3;
int numFaces=0,vertId=0,faceId=0,groupId=0,groupVertId=0,numGroups=0,numShapeKeys=0;
int numFaces=0,vertId=0,faceId=0,groupId=0,groupVertId=0,numGroups=0,numShapeKeys=0,numBones=0;
Mesh::Vertex *vertices;
u32 *indices;
vector<Vector3> vertPos,vertNorm;
@@ -150,7 +150,6 @@ namespace vb01{
enum ArmatureStage{BONES,ANIMATIONS};
ArmatureStage armatureStage;
int numBones=0;
if(preColon=="bones"){
numBones=atoi(postColon.c_str());
@@ -169,11 +168,12 @@ namespace vb01{
string data[numData];
getLineData(postColon,data,numData);
float length=atof(data[0].c_str());
Vector3 pos=Vector3(atof(data[2].c_str()),atof(data[3].c_str()),atof(data[4].c_str()));
Vector3 xAxis=Vector3(atof(data[5].c_str()),atof(data[6].c_str()),atof(data[6].c_str()));
float length = atof(data[1].c_str());
Vector3 head=Vector3(atof(data[2].c_str()),atof(data[3].c_str()),atof(data[4].c_str()));
Vector3 xAxis=Vector3(atof(data[5].c_str()),atof(data[6].c_str()),atof(data[7].c_str()));
Vector3 yAxis=Vector3(atof(data[8].c_str()),atof(data[9].c_str()),atof(data[10].c_str()));
Vector3 zAxis=xAxis.cross(yAxis);
Vector3 pos = head;
string parName=string(data[0].c_str());
Node *parent=skeleton->getBone(parName);
@@ -186,20 +186,12 @@ namespace vb01{
swap(zAxis.y,zAxis.z);
zAxis.z=-zAxis.z;
}
else
pos = pos + Vector3(0,((Bone*)parent)->getLength(),0);
Vector3 parAxis[]={
parent->getLocalAxis(0),
parent->getLocalAxis(1),
parent->getLocalAxis(2)
};
Vector3 boneAxis[3]={
(parAxis[0]*xAxis.x+parAxis[1]*xAxis.y+parAxis[2]*xAxis.z).norm(),
(parAxis[0]*yAxis.x+parAxis[1]*yAxis.y+parAxis[2]*yAxis.z).norm(),
(parAxis[0]*zAxis.x+parAxis[1]*zAxis.y+parAxis[2]*zAxis.z).norm()
};
Bone *bone=new Bone(preColon,boneAxis,pos);
skeleton->addBone(bone,parent);
bone->lookAt(boneAxis[1],boneAxis[2],parent);
Bone *bone=new Bone(preColon,length,pos);
skeleton->addBone(bone,(Bone*)parent);
bone->lookAt(zAxis,yAxis,parent);
break;
}
@@ -297,35 +289,15 @@ namespace vb01{
switch(meshStage){
{
case VERTICES:
int numData=10;
int numData = 6 + numBones;
string data[numData];
getLineData(l,data,numData);
Vector3 vPos=Vector3(atof(data[0].c_str()),atof(data[2].c_str()),-atof(data[1].c_str()));
Vector3 vNorm=Vector3(atof(data[3].c_str()),atof(data[5].c_str()),-atof(data[4].c_str()));
float vWeights[]{
atof(data[6].c_str()),
atof(data[7].c_str()),
atof(data[8].c_str()),
atof(data[9].c_str())
};
vertPos.push_back(vPos);
vertNorm.push_back(vNorm);
for(int i=0;i<4;i++)
vertWeights.push_back(vWeights[i]);
/*
Vector2 vertUv=Vector2(atof(data[5].c_str()),atof(data[6].c_str()));
Vector3 vertTan=Vector3(atof(data[7].c_str()),atof(data[9].c_str()),-atof(data[10].c_str()));
Vector3 vertBitan=Vector3(atof(data[11].c_str()),atof(data[13].c_str()),-atof(data[12].c_str()));
*/
/*
Mesh::Vertex vert;
vert.pos=vertPos;
vert.norm=vertNorm;
vert.uv=vertUv;
vert.tan=vertTan;
vert.biTan=vertBitan;
*/
//vertices[vertId]=vert;
for(int i=0;i<numBones;i++)
vertWeights.push_back(atof(data[6 + i].c_str()));
break;
}
{
@@ -344,11 +316,12 @@ namespace vb01{
vert.tan=tan;
vert.biTan=biTan;
vert.uv=uv;
vert.weights[0]=vertWeights[index*4+0];
vert.weights[1]=vertWeights[index*4+1];
vert.weights[2]=vertWeights[index*4+2];
vert.weights[3]=vertWeights[index*4+3];
for(int i=0;i<numVertsPerFace;i++){
for(int i = 0, boneIndex = 0; i < numBones; i++){
if(vertWeights[index * numBones + i] > 0){
vert.boneIndices[boneIndex] = i;
vert.weights[boneIndex] = vertWeights[index * numBones + i];
boneIndex++;
}
}
indices[vertId]=vertId;
vertices[vertId]=vert;
+104 -102
View File
@@ -18,9 +18,9 @@ namespace vb01{
this->scale=scale;
this->orientation=orientation;
this->name=name;
axis[0]=Vector3::VEC_I;
axis[1]=Vector3::VEC_J;
axis[2]=Vector3::VEC_K;
globalAxis[0]=Vector3::VEC_I;
globalAxis[1]=Vector3::VEC_J;
globalAxis[2]=Vector3::VEC_K;
}
Node::~Node(){
@@ -56,15 +56,17 @@ namespace vb01{
void Node::attachChild(Node *child){
child->setParent(this);
children.push_back(child);
child->updateLocalAxis();
child->updateAxis();
}
void Node::dettachChild(Node *child){
child->setParent(nullptr);
int id=-1;
for(int i=0;i<children.size()&&id==-1;i++)
if(children[i]==child)
for(int i=0;i<children.size();i++)
if(children[i]==child){
id=i;
break;
}
if(id!=-1)
children.erase(children.begin()+id);
}
@@ -101,38 +103,41 @@ namespace vb01{
void Node::lookAt(Vector3 newDir,Vector3 newUp,Node *node){
Vector3 parAxis[]{
node->getLocalAxis(0),
node->getLocalAxis(1),
node->getLocalAxis(2)
node->getGlobalAxis(0),
node->getGlobalAxis(1),
node->getGlobalAxis(2)
};
newDir=parAxis[0]*newDir.x+parAxis[1]*newDir.y+parAxis[2]*newDir.z;
newUp=parAxis[0]*newUp.x+parAxis[1]*newUp.y+parAxis[2]*newUp.z;
/*
*/
float angle=axis[2].getAngleBetween(newDir);
Vector3 rotAxis=axis[2].cross(newDir).norm();
newDir=(parAxis[0]*newDir.x+parAxis[1]*newDir.y+parAxis[2]*newDir.z).norm();
newUp=(parAxis[0]*newUp.x+parAxis[1]*newUp.y+parAxis[2]*newUp.z).norm();
float angle=globalAxis[2].getAngleBetween(newDir);
Vector3 rotAxis=globalAxis[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)));
rotAxis=globalAxis[1];
Quaternion oldRot = node->localToGlobalOrientation(orientation);
Quaternion newRot = node->globalToLocalOrientation(Quaternion(angle,rotAxis));
setOrientation(newRot*oldRot);
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[0][0]=globalAxis[0].x;
mat[1][0]=globalAxis[0].y;
mat[2][0]=globalAxis[0].z;
mat[0][1]=globalAxis[1].x;
mat[1][1]=globalAxis[1].y;
mat[2][1]=globalAxis[1].z;
mat[0][2]=globalAxis[2].x;
mat[1][2]=globalAxis[2].y;
mat[2][2]=globalAxis[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)));
newUp=(globalAxis[0]*nu.x+globalAxis[1]*nu.y).norm();
angle=globalAxis[1].getAngleBetween(newUp);
oldRot = node->localToGlobalOrientation(orientation);
newRot = node->globalToLocalOrientation(Quaternion(angle*(nu.x<0?1:-1),globalAxis[2]));
setOrientation(newRot*oldRot);
}
void Node::getDescendants(Node *node, vector<Node*> &descendants){
@@ -144,92 +149,89 @@ namespace vb01{
}
}
void Node::updateLocalAxis(){
Node *rootNode=Root::getSingleton()->getRootNode(),*ancestor=this;
while(ancestor->getParent())
ancestor=ancestor->getParent();
if(ancestor!=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*> Node::getAncestors(Node *node, Node *topAncestor){
vector<Node*> ancestors;
ancestors.push_back(this);
Node *parent=this->getParent();
Node *parent=node;
if(!topAncestor)
topAncestor = Root::getSingleton()->getRootNode();
while(parent){
ancestors.push_back(parent);
if(parent == topAncestor)
break;
parent=parent->getParent();
}
return ancestors;
}
void Node::updateAxis(){
Vector3 parGlobalAxis[3]{
parent->getGlobalAxis(0),
parent->getGlobalAxis(1),
parent->getGlobalAxis(2)
};
float rotAngle=orientation.getAngle();
Vector3 rotAxis=orientation.getAxis();
Vector3 newAxis=(parGlobalAxis[0]*rotAxis.x+parGlobalAxis[1]*rotAxis.y+parGlobalAxis[2]*rotAxis.z).norm();
Quaternion rotQuat=Quaternion(rotAngle,newAxis);
for(int i=0;i<3;i++)
globalAxis[i] = (rotQuat * parGlobalAxis[i]).norm();
for(Node *ch : children)
ch->updateAxis();
}
Vector3 Node::localToGlobalPosition(Vector3 localPos){
vector<Node*> ancestors=getAncestors(this);
Vector3 origin=Vector3::VEC_ZERO;
while(!ancestors.empty()){
int id=ancestors.size()-1;
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
par?par->getGlobalAxis(0):Vector3::VEC_I,
par?par->getGlobalAxis(1):Vector3::VEC_J,
par?par->getGlobalAxis(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();
}
return origin+axis[0]*localPos.x+axis[1]*localPos.y+axis[2]*localPos.z;
return origin+globalAxis[0]*localPos.x+globalAxis[1]*localPos.y+globalAxis[2]*localPos.z;
}
Vector3 Node::globalToLocalPosition(Vector3 globalPos){
Vector3 origin=globalPos;
vector<Node*> ancestors;
ancestors.push_back(this);
Node *parent=this->getParent();
mat3 mat;
mat[0][0]=globalAxis[0].x;
mat[1][0]=globalAxis[0].y;
mat[2][0]=globalAxis[0].z;
mat[0][1]=globalAxis[1].x;
mat[1][1]=globalAxis[1].y;
mat[2][1]=globalAxis[1].z;
mat[0][2]=globalAxis[2].x;
mat[1][2]=globalAxis[2].y;
mat[2][2]=globalAxis[2].z;
mat=inverse(mat);
while(parent){
ancestors.push_back(parent);
parent=parent->getParent();
}
while(!ancestors.empty()){
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;
vec3 local = vec3(globalPos.x, globalPos.y, globalPos.z) * mat;
return Vector3(local.x, local.y, local.z);
}
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();
}
vector<Node*> ancestors=getAncestors(this);
while(!ancestors.empty()){
int id=ancestors.size()-1;
Quaternion o=ancestors[id]->getOrientation();
Vector3 ancAxis[]{
ancestors[id]->getGlobalAxis(0),
ancestors[id]->getGlobalAxis(1),
ancestors[id]->getGlobalAxis(2)
};
float angle = ancestors[id]->getOrientation().getAngle();
Vector3 axis = ancestors[id]->getOrientation().getAxis();
Quaternion o = Quaternion(angle, (ancAxis[0]*axis.x+ancAxis[1]*axis.y+ancAxis[2]*axis.z).norm());
origin=o*origin;
ancestors.pop_back();
}
@@ -238,19 +240,19 @@ namespace vb01{
Quaternion Node::globalToLocalOrientation(Quaternion globalRot){
Quaternion origin=globalRot;
vector<Node*> ancestors;
ancestors.push_back(this);
Node *parent=this->getParent();
while(parent){
ancestors.push_back(parent);
parent=parent->getParent();
}
vector<Node*> ancestors=getAncestors(this);
while(!ancestors.empty()){
int id=ancestors.size()-1;
Quaternion o=ancestors[id]->getOrientation();
origin=origin*Quaternion(-o.getAngle(),o.getAxis());
Vector3 ancAxis[]{
ancestors[id]->getGlobalAxis(0),
ancestors[id]->getGlobalAxis(1),
ancestors[id]->getGlobalAxis(2)
};
float angle = ancestors[id]->getOrientation().getAngle();
Vector3 axis = ancestors[id]->getOrientation().getAxis();
Quaternion o = Quaternion(-angle, (ancAxis[0]*axis.x+ancAxis[1]*axis.y+ancAxis[2]*axis.z).norm());
origin=origin*o;
ancestors.pop_back();
}
return origin;
@@ -278,6 +280,6 @@ namespace vb01{
void Node::setOrientation(Quaternion q){
this->orientation=q;
updateLocalAxis();
updateAxis();
}
}
+5 -4
View File
@@ -30,10 +30,11 @@ namespace vb01{
void addLight(Light*);
void removeLight(int);
void addText(Text*);
void lookAt(Vector3,Vector3,Node*);
void updateLocalAxis();
virtual void lookAt(Vector3,Vector3,Node*);
void updateAxis();
void setOrientation(Quaternion);
void getDescendants(Node*,std::vector<Node*>&);
std::vector<Node*> getAncestors(Node*, Node *anc = nullptr);
Vector3 localToGlobalPosition(Vector3);
Vector3 globalToLocalPosition(Vector3);
Quaternion localToGlobalOrientation(Quaternion);
@@ -46,7 +47,7 @@ namespace vb01{
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 getGlobalAxis(int i){return globalAxis[i];}
inline Vector3 getPosition(){return pos;}
inline Vector3 getScale(){return scale;}
inline void setPosition(Vector3 pos){this->pos=pos;}
@@ -64,7 +65,7 @@ namespace vb01{
void updateShaders();
bool visible=true;
Vector3 pos,scale,axis[3];
Vector3 pos,scale,globalAxis[3];
Quaternion orientation;
std::vector<Mesh*> meshes;
std::vector<ParticleEmitter*> emitters;
+3 -3
View File
@@ -140,9 +140,9 @@ namespace vb01{
shader->setVec2(endSize,"endSize");
Vector3 nodePos=node->localToGlobalPosition(Vector3::VEC_ZERO);
Vector3 nodeDir=node->getLocalAxis(2);
Vector3 nodeUp=node->getLocalAxis(1);
Vector3 nodeLeft=node->getLocalAxis(0);
Vector3 nodeDir=node->getGlobalAxis(2);
Vector3 nodeUp=node->getGlobalAxis(1);
Vector3 nodeLeft=node->getGlobalAxis(0);
for(int i=0;i<numParticles;i++){
Vector3 dir=particles[i]->dir;
if(getTime()-particles[i]->time>=particles[i]->timeToLive){
+1
View File
@@ -11,6 +11,7 @@ def exportData(ob):
file.write("bones: "+str(len(ob.data.bones)))
for bone in ob.data.bones:
head=bone.head
tail=bone.tail
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)+" ")
+2 -9
View File
@@ -9,17 +9,10 @@ namespace vb01{
this->name=name;
}
void Skeleton::addBone(Bone *bone, Node *parent){
void Skeleton::addBone(Bone *bone, Bone *parent){
parent->attachChild(bone);
bone->setSkeleton(this);
bones.push_back(bone);
Box *box=new Box(Vector3(.1,.1,.1));
Material *mat=new Material();
mat->setTexturingEnabled(false);
mat->setLightingEnabled(false);
mat->setDiffuseColor(Vector4(0,1,0,1));
box->setMaterial(mat);
//bone->attachMesh(box);
}
Bone* Skeleton::getBone(string name){
+1 -1
View File
@@ -11,7 +11,7 @@ namespace vb01{
class Skeleton{
public:
Skeleton(std::string="");
void addBone(Bone*,Node*);
void addBone(Bone*,Bone*);
Bone* getBone(std::string);
Animation* getAnimation(std::string);
inline void addAnimation(Animation *anim){animations.push_back(anim);}
+2
View File
@@ -118,10 +118,12 @@ void main(){
diffuseColor+=light[i].color*(factor*attenuation*coef);
}
/*
for(int i=0;i<numLights;i++){
float shadow=getShadow(i);
diffuseColor*=(1-shadow);
}
*/
if(environmentMapEnabled){
vec3 projDir=normalize(fragPos-camPos);
projDir=reflect(projDir,norm);
+25 -17
View File
@@ -2,6 +2,7 @@
const int numBones=1;
const int numVertGroups=1;
const int numMaxInfluences = 4;
layout (location=0) in vec3 aPos;
layout (location=1) in vec3 aNorm;
@@ -9,7 +10,7 @@ layout (location=2) in vec2 aTexCoords;
layout (location=3) in vec3 aTan;
layout (location=4) in vec3 aBiTan;
layout (location=5) in vec4 aWeight;
//layout (location=5) in float[numVertGroups] aWeight;
layout (location=6) in ivec4 aBoneIndices;
out vec3 fragPos;
out vec3 norm;
@@ -34,37 +35,44 @@ void main(){
if(animated){
for(int i = 0; i < numBones; i++){
Bone bone = bones[i];
float weight = 0;
for(int j = 0; j < numMaxInfluences; j++){
if(bone.vertGroup == aBoneIndices[j])
weight = aWeight[j];
}
while(bone.parent!=-1){
float weight = aWeight[bones[i].vertGroup];
float angle = weight * bone.angle;
vec3 trans = bone.trans;
vec3 axis = bone.rotAxis;
vec3 scale = bone.scale;
vec4 bonePos = vec4(bone.pos,1);
vec4 bonePos = vec4(bone.pos, 1);
float s = sin(angle);
float c = cos(angle);
float oc = 1.0 - c;
mat4 rotMat;
rotMat[0] = vec4(oc * axis.x * axis.x + c,oc * axis.x * axis.y + axis.z * s,oc * axis.z * axis.x - axis.y * s,0.0);
rotMat[1] = vec4(oc * axis.x * axis.y - axis.z * s,oc * axis.y * axis.y + c,oc * axis.y * axis.z + axis.x * s,0.0);
rotMat[2] = vec4(oc * axis.z * axis.x + axis.y * s,oc * axis.y * axis.z - axis.x * s,oc * axis.z * axis.z + c,0.0);
rotMat[3] = vec4(0,0,0,1);
rotMat[0] = vec4(oc * axis.x * axis.x + c,oc * axis.x * axis.y + axis.z * s,oc * axis.z * axis.x - axis.y * s, 0.0);
rotMat[1] = vec4(oc * axis.x * axis.y - axis.z * s,oc * axis.y * axis.y + c,oc * axis.y * axis.z + axis.x * s, 0.0);
rotMat[2] = vec4(oc * axis.z * axis.x + axis.y * s,oc * axis.y * axis.z - axis.x * s,oc * axis.z * axis.z + c, 0.0);
rotMat[3] = vec4(0, 0, 0, 1);
vertPos += -(vertPos - bonePos) + rotMat * (vertPos - bonePos);
vec4 vertToBone = vec4(vertPos.xyz - bonePos.xyz, 1);
vertPos.xyz += -weight * vertToBone.xyz + weight * vec3(scale.x * vertToBone.x, scale.y * vertToBone.y, scale.z * vertToBone.z);
vertPos.xyz = vertPos.xyz + weight * trans;
vertPos.xyz += weight * trans;
bone = bones[bone.parent];
}
}
}
}
gl_Position=proj*view*model*vertPos;
fragPos=vec3(model*vec4(aPos,1));
norm=mat3(transpose(inverse(model)))*aNorm;
tan=mat3(transpose(inverse(model)))*aTan;
biTan=mat3(transpose(inverse(model)))*aBiTan;
texCoords=aTexCoords;
gl_Position = proj * view * model * vertPos;
fragPos = vec3(model * vec4(aPos, 1));
norm = mat3(transpose(inverse(model))) * aNorm;
tan = mat3(transpose(inverse(model))) * aTan;
biTan = mat3(transpose(inverse(model))) * aBiTan;
texCoords = aTexCoords;
}
+8 -1
View File
@@ -43,7 +43,14 @@ namespace vb01{
float getLengthSq(){return x*x+y*y+z*z;}
float getLength(){return std::sqrt(getLengthSq());}
float dot(Vector3 v){return x*v.x+y*v.y+z*v.z;}
float getAngleBetween(Vector3 v){return std::acos(dot(v));}
float getAngleBetween(Vector3 v){
float dotProd = dot(v);
if(dotProd > 1.0)
dotProd = 1.0;
else if(dotProd < -1)
dotProd = -1;
return std::acos(dotProd);
}
float getDistanceFrom(Vector3 v){return (v-*this).getLength();}
Vector3 norm(){return (*this!=Vector3::VEC_ZERO?*this/getLength():Vector3::VEC_ZERO);}
Vector3 cross(Vector3 v){return Vector3(y * v.z - v.y * z, z * v.x - x * v.z, x * v.y - v.x * y);}