From 8551823dd8c50854db77802fe1898db30e43243f Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sun, 13 Mar 2022 08:02:01 +0200 Subject: [PATCH] corrected shape key reading --- driver.h | 2 +- script.py | 1 + xmlModelReader.cpp | 57 +++++++++++++++++++++++++++++++--------------- xmlModelReader.h | 7 +++++- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/driver.h b/driver.h index 67f6064..2eb15db 100644 --- a/driver.h +++ b/driver.h @@ -1,5 +1,5 @@ #ifndef DRIVER_H -#define DRIVER +#define DRIVER_H #include "keyframeChannel.h" diff --git a/script.py b/script.py index 0c172ec..2d9c9ad 100644 --- a/script.py +++ b/script.py @@ -133,6 +133,7 @@ def readDriver(node, channel, tag): target = driver.variables[0].targets[0]; driverTag = ET.SubElement(tag, 'driver') + driverTag.set('type', target.transform_type) driverTag.set('obj', target.id.name) if(target.bone_target): diff --git a/xmlModelReader.cpp b/xmlModelReader.cpp index de119f2..eb97d60 100644 --- a/xmlModelReader.cpp +++ b/xmlModelReader.cpp @@ -27,6 +27,8 @@ namespace vb01{ vector descendants; model->getDescendants(descendants); + setupDrivers(descendants); + vector meshes; for(Node *desc : descendants) @@ -43,6 +45,18 @@ namespace vb01{ } } + void XmlModelReader::setupDrivers(vector descendants){ + for(pair 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){ vector vertPos, vertNorm; vector weights; @@ -127,18 +141,23 @@ namespace vb01{ shapeKeys[i].maxValue = atof(shapeKeyEl->Attribute("max")); 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 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 posY = atof(vertEl->Attribute("py")); float posZ = atof(vertEl->Attribute("pz")); 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); @@ -155,11 +174,10 @@ namespace vb01{ return mesh; } - Animation* XmlModelReader::processAnimation(XMLElement *animationEl, vector animatables){ - string name = animationEl->Attribute("name"); - Animation *animation = new Animation(name); + vector XmlModelReader::processKeyframeChannells(XMLElement *containerTag){ + vector keyframeChannels; - for(XMLElement *channelEl = animationEl->FirstChildElement("channel"); channelEl; channelEl = channelEl->NextSiblingElement()){ + for(XMLElement *channelEl = containerTag->FirstChildElement("channel"); channelEl; channelEl = channelEl->NextSiblingElement()){ vector keyframes; for(XMLElement *keyframeEl = channelEl->FirstChildElement("keyframe"); keyframeEl; keyframeEl = keyframeEl->NextSiblingElement()){ @@ -177,32 +195,35 @@ namespace vb01{ string typeStr = channelEl->Attribute("type"); KeyframeChannel::Type type = KeyframeChannel::getKeyframeChannelType(typeStr); string channelName = channelEl->Attribute("name"); - KeyframeChannel channel = KeyframeChannel::createKeyframeChannel(type, channelName, keyframes); - animation->addKeyframeChannel(channel); + keyframeChannels.push_back(KeyframeChannel::createKeyframeChannel(type, channelName, keyframes)); } - return animation; + return keyframeChannels; } void XmlModelReader::processAnimations(XMLElement *animContainer, vector animatables){ AnimationController *animController = AnimationController::getSingleton(); const char *animTag = "animation"; - for(XMLElement *animEl = animContainer->FirstChildElement(animTag); animEl && strcmp(animEl->Name(), animTag) == 0; animEl = animEl->NextSiblingElement()) - animController->addAnimation(processAnimation(animEl, animatables)); + for(XMLElement *animEl = animContainer->FirstChildElement(animTag); animEl && strcmp(animEl->Name(), animTag) == 0; animEl = animEl->NextSiblingElement()){ + string name = animEl->Attribute("name"); + Animation *animation = new Animation(name); + animation->addKeyframeChannels(processKeyframeChannells(animEl)); + animController->addAnimation(animation); + } } Skeleton* XmlModelReader::processSkeleton(Node *root, XMLElement *skeletonEl){ XMLElement *rootBoneEl = skeletonEl->FirstChildElement("bone"); Bone *rootBone = (Bone*)processNode(root, rootBoneEl, true); - vector bones; + root->attachChild(rootBone); + Skeleton *skeleton = new Skeleton(skeletonEl->Attribute("name")); + + vector bones = vector{rootBone}; 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()); + skeleton->addBone((Bone*)bone, nullptr); processAnimations(skeletonEl, vector(bones.begin(), bones.end())); diff --git a/xmlModelReader.h b/xmlModelReader.h index 2ddd7ed..45501d5 100644 --- a/xmlModelReader.h +++ b/xmlModelReader.h @@ -4,6 +4,7 @@ #include "modelReader.h" #include +#include namespace tinyxml2{ class XMLElement; @@ -15,6 +16,7 @@ namespace vb01{ class Skeleton; class Animatable; class Animation; + class Driver; class XmlModelReader : public ModelReader{ public: @@ -22,9 +24,12 @@ namespace vb01{ private: Node* processNode(Node*, tinyxml2::XMLElement*, bool = false); Mesh* processMesh(tinyxml2::XMLElement*); - Animation* processAnimation(tinyxml2::XMLElement*, std::vector); + std::vector processKeyframeChannells(tinyxml2::XMLElement*); void processAnimations(tinyxml2::XMLElement*, std::vector); Skeleton* processSkeleton(Node*, tinyxml2::XMLElement*); + void setupDrivers(std::vector); + + std::vector> driversByNodeNames; }; }