mirror of
https://github.com/devZoGok/vb01.git
synced 2026-08-26 19:43:30 +00:00
improved skeleton loading
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
#include "cameraTest.h"
|
||||
#include "nodeTest.h"
|
||||
#include "boneTest.h"
|
||||
#include "vbModelReaderTest.h"
|
||||
#include "animationChannelTest.h"
|
||||
#include "shaderTest.h"
|
||||
#include "particleEmitterTest.h"
|
||||
@@ -20,7 +19,6 @@ int main(){
|
||||
runner.addTest(CameraTest::suite());
|
||||
runner.addTest(NodeTest::suite());
|
||||
runner.addTest(BoneTest::suite());
|
||||
runner.addTest(VbModelReaderTest::suite());
|
||||
runner.addTest(AnimationChannelTest::suite());
|
||||
runner.addTest(ShaderTest::suite());
|
||||
runner.addTest(ParticleEmitterTest::suite());
|
||||
|
||||
@@ -30,16 +30,18 @@ namespace vb01{
|
||||
Node::~Node(){
|
||||
for(Mesh *m : meshes)
|
||||
delete m;
|
||||
|
||||
for(Light *l : lights)
|
||||
delete l;
|
||||
|
||||
for(ParticleEmitter *p : emitters)
|
||||
delete p;
|
||||
|
||||
for(Text *t : texts)
|
||||
delete t;
|
||||
for(Node *c : children){
|
||||
//dettachChild(c);
|
||||
|
||||
for(Node *c : children)
|
||||
delete c;
|
||||
}
|
||||
}
|
||||
|
||||
void Node::update(){
|
||||
@@ -69,6 +71,7 @@ namespace vb01{
|
||||
|
||||
float Node::getDriverValue(Driver::VariableType type){
|
||||
float driverValue;
|
||||
|
||||
switch(type){
|
||||
case Driver::POS_X:
|
||||
driverValue = pos.x;
|
||||
@@ -101,6 +104,7 @@ namespace vb01{
|
||||
driverValue = scale.z;
|
||||
break;
|
||||
}
|
||||
|
||||
return driverValue;
|
||||
}
|
||||
|
||||
@@ -113,11 +117,13 @@ namespace vb01{
|
||||
void Node::dettachChild(Node *child){
|
||||
child->setParent(nullptr);
|
||||
int id = -1;
|
||||
|
||||
for(int i = 0; i < children.size(); i++)
|
||||
if(children[i] == child){
|
||||
id = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if(id != -1)
|
||||
children.erase(children.begin() + id);
|
||||
}
|
||||
@@ -168,6 +174,7 @@ namespace vb01{
|
||||
void Node::adjustDir(Vector3 newDir){
|
||||
float angle = Vector3(0, 0, 1).getAngleBetween(newDir);
|
||||
Vector3 rotAxis = Vector3(0, 0, 1).cross(newDir).norm();
|
||||
|
||||
if(rotAxis == Vector3::VEC_ZERO)
|
||||
rotAxis = Vector3::VEC_I;
|
||||
|
||||
@@ -175,39 +182,21 @@ namespace vb01{
|
||||
}
|
||||
|
||||
void Node::adjustUp(Vector3 newUp){
|
||||
Vector3 xDir =
|
||||
parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_I)) -
|
||||
parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_ZERO));
|
||||
Vector3 xDir = orientation * Vector3(1, 0, 0),
|
||||
yDir = orientation * Vector3(0, 1, 0),
|
||||
zDir = orientation * Vector3(0, 0, 1);
|
||||
newUp = Vector3(newUp.x, newUp.y, 0).norm();
|
||||
|
||||
Vector3 yDir =
|
||||
parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_J)) -
|
||||
parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_ZERO));
|
||||
|
||||
Vector3 zDir = xDir.cross(yDir).norm();
|
||||
|
||||
mat3 mat;
|
||||
mat[0][0] = xDir.x;
|
||||
mat[1][0] = xDir.y;
|
||||
mat[2][0] = xDir.z;
|
||||
mat[0][1] = yDir.x;
|
||||
mat[1][1] = yDir.y;
|
||||
mat[2][1] = yDir.z;
|
||||
mat[0][2] = zDir.x;
|
||||
mat[1][2] = zDir.y;
|
||||
mat[2][2] = zDir.z;
|
||||
|
||||
vec3 nu = vec3(newUp.x, newUp.y, newUp.z) * inverse(mat);
|
||||
newUp = (xDir * nu.x + yDir * nu.y).norm();
|
||||
if(newUp != Vector3::VEC_ZERO){
|
||||
float angle = yDir.getAngleBetween(newUp);
|
||||
|
||||
setOrientation(Quaternion(angle * (nu.x < 0 ? 1 : -1), zDir) * orientation);
|
||||
setOrientation(Quaternion(angle * (newUp.x < 0 ? 1 : -1), zDir) * orientation);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::getDescendants(vector<Node*> &descendants){
|
||||
for(Node *child : getChildren()){
|
||||
descendants.push_back(child);
|
||||
|
||||
if(!child->getChildren().empty())
|
||||
child->getDescendants(descendants);
|
||||
}
|
||||
@@ -216,20 +205,24 @@ namespace vb01{
|
||||
vector<Node*> Node::getAncestors(Node *topAncestor){
|
||||
vector<Node*> ancestors;
|
||||
Node *parent = this;
|
||||
|
||||
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)
|
||||
parent ? parent->getGlobalAxis(0) : Vector3::VEC_I,
|
||||
parent ? parent->getGlobalAxis(1) : Vector3::VEC_J,
|
||||
parent ? parent->getGlobalAxis(2) : Vector3::VEC_K
|
||||
};
|
||||
|
||||
float rotAngle = orientation.getAngle();
|
||||
@@ -256,6 +249,7 @@ namespace vb01{
|
||||
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();
|
||||
@@ -320,17 +314,13 @@ namespace vb01{
|
||||
|
||||
Quaternion Node::localToGlobalOrientation(Quaternion localRot){
|
||||
vector<Node*> ancestors = getAncestors();
|
||||
|
||||
Quaternion origin = adjustRot(ancestors, Quaternion::QUAT_W, true);
|
||||
|
||||
return localRot * origin;
|
||||
}
|
||||
|
||||
Quaternion Node::globalToLocalOrientation(Quaternion globalRot){
|
||||
vector<Node*> ancestors = getAncestors();
|
||||
|
||||
Quaternion origin = adjustRot(ancestors, globalRot, false);
|
||||
|
||||
return origin;
|
||||
}
|
||||
|
||||
@@ -344,6 +334,7 @@ namespace vb01{
|
||||
|
||||
for(Node *n : descendants){
|
||||
vector<Mesh*> meshes = n->getMeshes();
|
||||
|
||||
for(Mesh *m : meshes){
|
||||
Material *mat = m->getMaterial();
|
||||
int numLights = root->getNumLights();
|
||||
@@ -363,6 +354,7 @@ namespace vb01{
|
||||
void Node::animate(float value, KeyframeChannel keyframeChannel){
|
||||
Vector3 newPos = pos, newScale = scale;
|
||||
Quaternion newRot = orientation;
|
||||
|
||||
switch(keyframeChannel.type){
|
||||
case KeyframeChannel::POS_X:
|
||||
newPos.x = value;
|
||||
@@ -395,6 +387,7 @@ namespace vb01{
|
||||
newScale.z = value;
|
||||
break;
|
||||
}
|
||||
|
||||
setPosition(newPos);
|
||||
setOrientation(newRot);
|
||||
setScale(newScale);
|
||||
|
||||
@@ -220,6 +220,7 @@ namespace vb01{
|
||||
Vector3(0, -1, -.4).norm(),
|
||||
Vector3(1, 1, 1).norm()
|
||||
};
|
||||
|
||||
int numDirs = sizeof(dir) / sizeof(Vector3);
|
||||
|
||||
for(int i = 0; i < numDirs; i++){
|
||||
@@ -234,6 +235,13 @@ namespace vb01{
|
||||
lookNode->lookAt(dir[i]);
|
||||
CPPUNIT_ASSERT(lookNode->getGlobalAxis(2).getAngleBetween(rotQuat * dir[i]) < maxAngle);
|
||||
}
|
||||
|
||||
for(int i = 0; i < numDirs; i++){
|
||||
lookNodeParent->dettachChild(lookNode);
|
||||
lookNode->lookAt(dir[i]);
|
||||
lookNodeParent->attachChild(lookNode);
|
||||
CPPUNIT_ASSERT(lookNode->getGlobalAxis(2).getAngleBetween(rotQuat * dir[i]) < maxAngle);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeTest::testAdjustUp(){
|
||||
@@ -256,6 +264,7 @@ namespace vb01{
|
||||
Vector3 upClamped = Vector3(up[i].x, up[i].y, 0).norm();
|
||||
CPPUNIT_ASSERT(lookNode->getGlobalAxis(1).getAngleBetween(upClamped) < maxAngle);
|
||||
}
|
||||
|
||||
lookNode->setOrientation(Quaternion::QUAT_W);
|
||||
lookNode->lookAt(Vector3::VEC_K, Vector3::VEC_K);
|
||||
CPPUNIT_ASSERT(lookNode->getGlobalAxis(1) == Vector3::VEC_J);
|
||||
@@ -268,5 +277,13 @@ namespace vb01{
|
||||
Vector3 upClamped = Vector3(up[i].x, up[i].y, 0).norm();
|
||||
CPPUNIT_ASSERT(lookNode->getGlobalAxis(1).getAngleBetween(rotQuat * upClamped) < maxAngle);
|
||||
}
|
||||
|
||||
for(int i = 0; i < numDirs; i++){
|
||||
lookNodeParent->dettachChild(lookNode);
|
||||
lookNode->lookAt(Vector3::VEC_K, up[i]);
|
||||
lookNodeParent->attachChild(lookNode);
|
||||
Vector3 upClamped = Vector3(up[i].x, up[i].y, 0).norm();
|
||||
CPPUNIT_ASSERT(lookNode->getGlobalAxis(1).getAngleBetween(rotQuat * upClamped) < maxAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
-17
@@ -172,29 +172,37 @@ namespace vb01{
|
||||
const char *name = xmlEl->Attribute("name");
|
||||
|
||||
if(bone){
|
||||
float headX = atof(xmlEl->Attribute("hx"));
|
||||
float headY = atof(xmlEl->Attribute("hy"));
|
||||
float headZ = atof(xmlEl->Attribute("hz"));
|
||||
Vector3 head = Vector3(headX, headY, headZ);
|
||||
float components[]{
|
||||
atof(xmlEl->Attribute("hx")),
|
||||
atof(xmlEl->Attribute("hy")),
|
||||
atof(xmlEl->Attribute("hz")),
|
||||
atof(xmlEl->Attribute("xaxisx")),
|
||||
atof(xmlEl->Attribute("xaxisy")),
|
||||
atof(xmlEl->Attribute("xaxisz")),
|
||||
atof(xmlEl->Attribute("yaxisx")),
|
||||
atof(xmlEl->Attribute("yaxisy")),
|
||||
atof(xmlEl->Attribute("yaxisz"))
|
||||
};
|
||||
|
||||
float xAxisX = atof(xmlEl->Attribute("xaxisx"));
|
||||
float xAxisY = atof(xmlEl->Attribute("xaxisy"));
|
||||
float xAxisZ = atof(xmlEl->Attribute("xaxisz"));
|
||||
Vector3 xAxis = Vector3(xAxisX, xAxisY, xAxisZ);
|
||||
|
||||
float yAxisX = atof(xmlEl->Attribute("yaxisx"));
|
||||
float yAxisY = atof(xmlEl->Attribute("yaxisy"));
|
||||
float yAxisZ = atof(xmlEl->Attribute("yaxisz"));
|
||||
Vector3 yAxis = Vector3(yAxisX, yAxisY, yAxisZ);
|
||||
float eps = pow(10, -2);
|
||||
|
||||
for(int i = 0; i < 9; i++){
|
||||
if(fabs(components[i]) < eps)
|
||||
components[i] = 0;
|
||||
}
|
||||
/*
|
||||
else if(fabs(components[i]) > 1.0)
|
||||
components[i] = 1.0;
|
||||
*/
|
||||
|
||||
Vector3 head = Vector3(components[0], components[1], components[2]);
|
||||
Vector3 xAxis = Vector3(components[3], components[4], components[5]);
|
||||
Vector3 yAxis = Vector3(components[6], components[7], components[8]);
|
||||
float length = atof(xmlEl->Attribute("length"));
|
||||
|
||||
Vector3 zAxis = xAxis.cross(yAxis).norm();
|
||||
Vector3 pos = head;
|
||||
|
||||
/*
|
||||
*/
|
||||
if(xmlEl->Parent()->ToElement()->Name() == "skeleton"){
|
||||
if(strcmp(xmlEl->Parent()->ToElement()->Name(), "skeleton") == 0){
|
||||
parent = model;
|
||||
swap(pos.y, pos.z);
|
||||
pos.z = -pos.z;
|
||||
|
||||
Reference in New Issue
Block a user