mirror of
https://github.com/devZoGok/vb01.git
synced 2026-08-26 19:43:30 +00:00
corrected shape key reading
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
#ifndef DRIVER_H
|
#ifndef DRIVER_H
|
||||||
#define DRIVER
|
#define DRIVER_H
|
||||||
|
|
||||||
#include "keyframeChannel.h"
|
#include "keyframeChannel.h"
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user