corrected shape key reading

This commit is contained in:
devZoGok
2022-03-13 08:02:01 +02:00
parent fa1d0d277c
commit 8551823dd8
4 changed files with 47 additions and 20 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
#ifndef DRIVER_H #ifndef DRIVER_H
#define DRIVER #define DRIVER_H
#include "keyframeChannel.h" #include "keyframeChannel.h"
+1
View File
@@ -133,6 +133,7 @@ def readDriver(node, channel, tag):
target = driver.variables[0].targets[0]; target = driver.variables[0].targets[0];
driverTag = ET.SubElement(tag, 'driver') driverTag = ET.SubElement(tag, 'driver')
driverTag.set('type', target.transform_type)
driverTag.set('obj', target.id.name) driverTag.set('obj', target.id.name)
if(target.bone_target): if(target.bone_target):
+39 -18
View File
@@ -27,6 +27,8 @@ namespace vb01{
vector<Node*> descendants; vector<Node*> descendants;
model->getDescendants(descendants); model->getDescendants(descendants);
setupDrivers(descendants);
vector<Mesh*> meshes; vector<Mesh*> meshes;
for(Node *desc : descendants) for(Node *desc : descendants)
@@ -43,6 +45,18 @@ namespace vb01{
} }
} }
void XmlModelReader::setupDrivers(vector<Node*> descendants){
for(pair<string, Driver*> pair : driversByNodeNames){
for(Node *desc : descendants){
int dotId = pair.first.find_first_of(".");
string driverNodeName = (dotId == string::npos ? pair.first : pair.first.substr(dotId + 1));
if(driverNodeName == desc->getName())
desc->addDriver(pair.second);
}
}
}
Mesh* XmlModelReader::processMesh(XMLElement *meshEl){ Mesh* XmlModelReader::processMesh(XMLElement *meshEl){
vector<Vector3> vertPos, vertNorm; vector<Vector3> vertPos, vertNorm;
vector<float> weights; vector<float> weights;
@@ -127,18 +141,23 @@ namespace vb01{
shapeKeys[i].maxValue = atof(shapeKeyEl->Attribute("max")); shapeKeys[i].maxValue = atof(shapeKeyEl->Attribute("max"));
XMLElement *driverEl = shapeKeyEl->FirstChildElement("driver"); XMLElement *driverEl = shapeKeyEl->FirstChildElement("driver");
KeyframeChannel channel = processKeyframeChannells(driverEl)[0];
const char *nodeName = driverEl->Attribute("obj");
const char *boneName = driverEl->Attribute("bone");
Driver::VariableType type = Driver::getDriverVariableType(driverEl->Attribute("type"));
driversByNodeNames.push_back(make_pair(string(nodeName) + (boneName ? "." + string(boneName) : ""), new Driver(&shapeKeys[i], channel, type)));
vector<Vector3> shapeKeyPos; vector<Vector3> shapeKeyPos;
for(XMLElement *vertEl = shapeKeyEl->FirstChildElement(tagName); vertEl; vertEl = vertEl->NextSiblingElement()){ for(XMLElement *vertEl = shapeKeyEl->FirstChildElement("vert"); vertEl; vertEl = vertEl->NextSiblingElement()){
float posX = atof(vertEl->Attribute("px")); float posX = atof(vertEl->Attribute("px"));
float posY = atof(vertEl->Attribute("py")); float posY = atof(vertEl->Attribute("py"));
float posZ = atof(vertEl->Attribute("pz")); float posZ = atof(vertEl->Attribute("pz"));
shapeKeyPos.push_back(Vector3(posX, posY, posZ)); shapeKeyPos.push_back(Vector3(posX, posY, posZ));
for(int j = 0; j < numVertices; j++)
vertices[j].shapeKeyOffsets[i] = shapeKeyPos[vertIds[j]] - vertPos[vertIds[j]];
} }
for(int j = 0; j < numVertices; j++)
vertices[j].shapeKeyOffsets[i] = shapeKeyPos[vertIds[j]] - vertPos[vertIds[j]];
} }
Mesh *mesh = new Mesh(vertices, indices, numVertices / 3, vertexGroups, numVertexGroups, shapeKeys, numShapeKeys); Mesh *mesh = new Mesh(vertices, indices, numVertices / 3, vertexGroups, numVertexGroups, shapeKeys, numShapeKeys);
@@ -155,11 +174,10 @@ namespace vb01{
return mesh; return mesh;
} }
Animation* XmlModelReader::processAnimation(XMLElement *animationEl, vector<Animatable*> animatables){ vector<KeyframeChannel> XmlModelReader::processKeyframeChannells(XMLElement *containerTag){
string name = animationEl->Attribute("name"); vector<KeyframeChannel> keyframeChannels;
Animation *animation = new Animation(name);
for(XMLElement *channelEl = animationEl->FirstChildElement("channel"); channelEl; channelEl = channelEl->NextSiblingElement()){ for(XMLElement *channelEl = containerTag->FirstChildElement("channel"); channelEl; channelEl = channelEl->NextSiblingElement()){
vector<Keyframe> keyframes; vector<Keyframe> keyframes;
for(XMLElement *keyframeEl = channelEl->FirstChildElement("keyframe"); keyframeEl; keyframeEl = keyframeEl->NextSiblingElement()){ for(XMLElement *keyframeEl = channelEl->FirstChildElement("keyframe"); keyframeEl; keyframeEl = keyframeEl->NextSiblingElement()){
@@ -177,32 +195,35 @@ namespace vb01{
string typeStr = channelEl->Attribute("type"); string typeStr = channelEl->Attribute("type");
KeyframeChannel::Type type = KeyframeChannel::getKeyframeChannelType(typeStr); KeyframeChannel::Type type = KeyframeChannel::getKeyframeChannelType(typeStr);
string channelName = channelEl->Attribute("name"); string channelName = channelEl->Attribute("name");
KeyframeChannel channel = KeyframeChannel::createKeyframeChannel(type, channelName, keyframes); keyframeChannels.push_back(KeyframeChannel::createKeyframeChannel(type, channelName, keyframes));
animation->addKeyframeChannel(channel);
} }
return animation; return keyframeChannels;
} }
void XmlModelReader::processAnimations(XMLElement *animContainer, vector<Animatable*> animatables){ void XmlModelReader::processAnimations(XMLElement *animContainer, vector<Animatable*> animatables){
AnimationController *animController = AnimationController::getSingleton(); AnimationController *animController = AnimationController::getSingleton();
const char *animTag = "animation"; const char *animTag = "animation";
for(XMLElement *animEl = animContainer->FirstChildElement(animTag); animEl && strcmp(animEl->Name(), animTag) == 0; animEl = animEl->NextSiblingElement()) for(XMLElement *animEl = animContainer->FirstChildElement(animTag); animEl && strcmp(animEl->Name(), animTag) == 0; animEl = animEl->NextSiblingElement()){
animController->addAnimation(processAnimation(animEl, animatables)); string name = animEl->Attribute("name");
Animation *animation = new Animation(name);
animation->addKeyframeChannels(processKeyframeChannells(animEl));
animController->addAnimation(animation);
}
} }
Skeleton* XmlModelReader::processSkeleton(Node *root, XMLElement *skeletonEl){ Skeleton* XmlModelReader::processSkeleton(Node *root, XMLElement *skeletonEl){
XMLElement *rootBoneEl = skeletonEl->FirstChildElement("bone"); XMLElement *rootBoneEl = skeletonEl->FirstChildElement("bone");
Bone *rootBone = (Bone*)processNode(root, rootBoneEl, true); Bone *rootBone = (Bone*)processNode(root, rootBoneEl, true);
vector<Node*> bones; root->attachChild(rootBone);
Skeleton *skeleton = new Skeleton(skeletonEl->Attribute("name"));
vector<Node*> bones = vector<Node*>{rootBone};
rootBone->getDescendants(bones); rootBone->getDescendants(bones);
Skeleton *skeleton = new Skeleton(skeletonEl->Attribute("name"));
skeleton->addBone(rootBone, (Bone*)root);
for(Node *bone : bones) for(Node *bone : bones)
skeleton->addBone((Bone*)bone, (Bone*)bone->getParent()); skeleton->addBone((Bone*)bone, nullptr);
processAnimations(skeletonEl, vector<Animatable*>(bones.begin(), bones.end())); processAnimations(skeletonEl, vector<Animatable*>(bones.begin(), bones.end()));
+6 -1
View File
@@ -4,6 +4,7 @@
#include "modelReader.h" #include "modelReader.h"
#include <vector> #include <vector>
#include <utility>
namespace tinyxml2{ namespace tinyxml2{
class XMLElement; class XMLElement;
@@ -15,6 +16,7 @@ namespace vb01{
class Skeleton; class Skeleton;
class Animatable; class Animatable;
class Animation; class Animation;
class Driver;
class XmlModelReader : public ModelReader{ class XmlModelReader : public ModelReader{
public: public:
@@ -22,9 +24,12 @@ namespace vb01{
private: private:
Node* processNode(Node*, tinyxml2::XMLElement*, bool = false); Node* processNode(Node*, tinyxml2::XMLElement*, bool = false);
Mesh* processMesh(tinyxml2::XMLElement*); Mesh* processMesh(tinyxml2::XMLElement*);
Animation* processAnimation(tinyxml2::XMLElement*, std::vector<Animatable*>); std::vector<KeyframeChannel> processKeyframeChannells(tinyxml2::XMLElement*);
void processAnimations(tinyxml2::XMLElement*, std::vector<Animatable*>); void processAnimations(tinyxml2::XMLElement*, std::vector<Animatable*>);
Skeleton* processSkeleton(Node*, tinyxml2::XMLElement*); Skeleton* processSkeleton(Node*, tinyxml2::XMLElement*);
void setupDrivers(std::vector<Node*>);
std::vector<std::pair<std::string, Driver*>> driversByNodeNames;
}; };
} }