skeleton assignment improvements

This commit is contained in:
devZoGok
2022-03-04 21:26:24 +02:00
parent dae9cd08d7
commit 3f0f1c60d9
4 changed files with 79 additions and 27 deletions
+11 -2
View File
@@ -6,6 +6,7 @@
#include "text.h"
#include "material.h"
#include "matrix.h"
#include "skeleton.h"
#include "animationController.h"
#include <glm.hpp>
@@ -45,15 +46,23 @@ namespace vb01{
if(visible){
for(Light *l : lights)
l->update();
for(Mesh *m : meshes)
m->update();
for(Text *t : texts)
t->update();
for(Node *c : children)
c->update();
for(ParticleEmitter *p : emitters)
p->update();
for(Skeleton *sk : skeletons)
sk->update();
for(Node *c : children)
c->update();
}
for(Driver *driver : drivers)
driver->drive(getDriverValue(driver->getType()));
}
+2
View File
@@ -44,8 +44,10 @@ namespace vb01{
Quaternion globalToLocalOrientation(Quaternion);
Vector3 localToGlobalScale(Vector3);
Vector3 globalToLocalScale(Vector3);
inline Skeleton* getSkeleton(int i){return skeletons[i];}
inline Text* getText(int i){return texts[i];}
inline std::vector<Mesh*>& getMeshes(){return meshes;}
inline std::vector<Skeleton*>& getSkeletons(){return skeletons;}
inline Mesh* getMesh(int i){return meshes[i];}
inline Node* getParent(){return parent;}
inline void setParent(Node *par){this->parent = par;}
+10 -9
View File
@@ -165,8 +165,8 @@ def export(node, parentTag):
norm = vert.normal
vertDataTag = ET.SubElement(meshTag, 'vertdata')
vertDataTag.set('px', str(pos.x))
vertDataTag.set('py', str(pos.y))
vertDataTag.set('pz', str(pos.z))
vertDataTag.set('py', str(pos.z))
vertDataTag.set('pz', str(-pos.y))
vertDataTag.set('nx', str(norm.x))
vertDataTag.set('ny', str(norm.y))
vertDataTag.set('nz', str(norm.z))
@@ -201,11 +201,11 @@ def export(node, parentTag):
vertTag.set('uvx', str(uv.x))
vertTag.set('uvy', str(uv.y))
vertTag.set('tx', str(tan.x))
vertTag.set('ty', str(tan.y))
vertTag.set('tz', str(tan.z))
vertTag.set('ty', str(tan.z))
vertTag.set('tz', str(-tan.y))
vertTag.set('bx', str(bitan.x))
vertTag.set('by', str(bitan.y))
vertTag.set('bz', str(bitan.z))
vertTag.set('by', str(bitan.z))
vertTag.set('bz', str(-bitan.y))
mesh.free_tangents()
@@ -224,8 +224,8 @@ def export(node, parentTag):
pos = vert.co
vertTag = ET.SubElement(shapeKeyTag, 'vert')
vertTag.set('px', str(pos.x))
vertTag.set('py', str(pos.y))
vertTag.set('pz', str(pos.z))
vertTag.set('py', str(pos.z))
vertTag.set('pz', str(-pos.y))
i = i + 1
@@ -233,9 +233,10 @@ def export(node, parentTag):
if(node.modifiers and node.modifiers[armatureMod] and node.modifiers[armatureMod].object):
skeleton = node.modifiers[armatureMod].object
meshTag.set('skeleton', skeleton.name)
meshTag.set('skeleton', skeleton.name + '.' + skeleton.data.name_full)
elif node.type == 'ARMATURE':
skeletonTag = ET.SubElement(nodeTag, 'skeleton')
skeletonTag.set('name', node.data.name_full)
exportBone(node, node.data.bones[0], skeletonTag, True)
elif node.type == 'LIGHT':
lightTag = ET.SubElement(nodeTag, 'light')
+56 -16
View File
@@ -3,6 +3,7 @@
#include "skeleton.h"
#include "bone.h"
#include "vector.h"
#include "animationController.h"
#include <vector>
@@ -16,8 +17,27 @@ namespace vb01{
XMLDocument *doc = new XMLDocument();
doc->LoadFile(path.c_str());
XMLNode *root = doc->FirstChild();
model->attachChild(processNode(model, (XMLElement*)root));
XMLElement *root = doc->FirstChildElement();
for(XMLElement *ch = root->FirstChildElement(); ch; ch = ch->NextSiblingElement())
model->attachChild(processNode(model, ch));
vector<Node*> descendants;
model->getDescendants(descendants);
vector<Mesh*> meshes;
for(Node *desc : descendants)
for(Mesh *m : desc->getMeshes())
if(m->getSkeleton())
meshes.push_back(m);
for(Mesh *m : meshes)
for(Node *desc : descendants)
for(Skeleton *sk : desc->getSkeletons())
if(m->getSkeleton()->getName() == sk->getName()){
delete m->getSkeleton();
m->setSkeleton(sk);
}
}
Mesh* XmlModelReader::processMesh(XMLElement *meshEl){
@@ -50,7 +70,6 @@ namespace vb01{
i = 0;
int numVertices = 3 * atoi(meshEl->Attribute("num_faces"));
int numBones;
Mesh::Vertex *vertices = new Mesh::Vertex[numVertices];
tagName = "vert";
vector<u32> vertIds;
@@ -81,10 +100,10 @@ namespace vb01{
vertex.tan = tan;
vertex.biTan = biTan;
for(int j = 0, boneIndex = 0; j < numBones; j++){
if(weights[id * numBones + j] > 0){
for(int j = 0, boneIndex = 0; j < numVertexGroups; j++){
if(weights[id * numVertexGroups + j] > 0){
vertex.boneIndices[boneIndex] = j;
vertex.weights[boneIndex] = weights[id * numBones + j];
vertex.weights[boneIndex] = weights[id * numVertexGroups + j];
boneIndex++;
}
}
@@ -119,20 +138,38 @@ namespace vb01{
}
}
Mesh *mesh = new Mesh(vertices, indices, numVertices / 3, vertexGroups, numBones, shapeKeys, numShapeKeys);
Mesh *mesh = new Mesh(vertices, indices, numVertices / 3, vertexGroups, numVertexGroups, shapeKeys, numShapeKeys);
mesh->construct();
const char *skeletonName = meshEl->Attribute("skeleton");
if(skeletonName){
int dotId = string(skeletonName).find_first_of(".");
string name = string(skeletonName).substr(dotId + 1, string::npos);
mesh->setSkeleton(new Skeleton(name));
}
return mesh;
}
Skeleton* XmlModelReader::processSkeleton(Node *root, XMLElement *skeletonEl){
XMLElement *rootBoneEl = skeletonEl->FirstChildElement("bone");
Skeleton *skeleton = new Skeleton(nullptr);
skeleton->addBone((Bone*)processNode(root, rootBoneEl, true), (Bone*)root);
Bone *rootBone = (Bone*)processNode(root, rootBoneEl, true);
vector<Node*> bones;
rootBone->getDescendants(bones);
Skeleton *skeleton = new Skeleton(skeletonEl->Attribute("name"));
skeleton->addBone(rootBone, (Bone*)root);
for(Node *bone : bones)
skeleton->addBone((Bone*)bone, (Bone*)bone->getParent());
return skeleton;
}
Node* XmlModelReader::processNode(Node *parent, XMLElement *xmlEl, bool bone){
Node *node = nullptr;
const char *name = xmlEl->Attribute("name");
if(bone){
float headX = atof(xmlEl->Attribute("hx"));
@@ -150,14 +187,14 @@ namespace vb01{
float yAxisZ = atof(xmlEl->Attribute("yaxisz"));
Vector3 yAxis = Vector3(yAxisX, yAxisY, yAxisZ);
string name = xmlEl->Attribute("name");
float length = atof(xmlEl->Attribute("length"));
Vector3 zAxis = xAxis.cross(yAxis).norm();
Vector3 pos = head;
/*
if(!parent){
*/
if(xmlEl->Parent()->ToElement()->Name() == "skeleton"){
parent = model;
swap(pos.y, pos.z);
pos.z = -pos.z;
@@ -167,7 +204,6 @@ namespace vb01{
zAxis.z = -zAxis.z;
}
else
*/
pos = pos + Vector3(0, ((Bone*)parent)->getLength(), 0);
node = new Bone(name, length, pos, Quaternion::QUAT_W, Vector3::VEC_IJK);
@@ -180,21 +216,25 @@ namespace vb01{
((Bone*)node)->setIkChainLength(ikChainLength);
}
}
else
node = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, name);
XMLElement *skeletonTag = xmlEl->FirstChildElement("skeleton");
if(skeletonTag)
processSkeleton(node, skeletonTag);
node->addSkeleton(processSkeleton(node, skeletonTag));
XMLElement *meshTag = xmlEl->FirstChildElement("mesh");
if(meshTag)
processMesh(meshTag);
node->attachMesh(processMesh(meshTag));
XMLElement *lightTag = xmlEl->FirstChildElement("light");
for(XMLElement *el = xmlEl->FirstChildElement("node"); el; el = el->NextSiblingElement())
parent->attachChild(processNode(parent, el, bone));
const char *tagName = (bone ? "bone" : "node");
for(XMLElement *el = xmlEl->FirstChildElement(tagName); el; el = el->NextSiblingElement())
node->attachChild(processNode(node, el, bone));
return node;
}