mirror of
https://github.com/ApfelTeeSaft/vb01.git
synced 2026-08-26 19:33:45 +00:00
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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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){
|
||||
|
||||
@@ -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
@@ -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
@@ -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);}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);}
|
||||
|
||||
Reference in New Issue
Block a user