mirror of
https://github.com/ApfelTeeSaft/vb01.git
synced 2026-08-26 19:33:45 +00:00
model reader deletion
This commit is contained in:
@@ -85,7 +85,6 @@ if(BUILD_TESTS)
|
||||
|
||||
set(RENDER_TEST nodeTest.cpp cameraTest.cpp shaderTest.cpp particleEmitterTest.cpp)
|
||||
set(ARMATURE_TEST boneTest.cpp ikSolverTest.cpp)
|
||||
set(MODEL_TEST vbModelReaderTest.cpp)
|
||||
set(ANIMATION_TEST animationChannelTest.cpp)
|
||||
set(TEST_SRC main.cpp ${LIB_SRC} ${RENDER_TEST} ${ARMATURE_TEST} ${ANIMATION_TEST})
|
||||
|
||||
|
||||
@@ -1,631 +0,0 @@
|
||||
#include "vbModelReader.h"
|
||||
#include "util.h"
|
||||
#include "vector.h"
|
||||
#include "light.h"
|
||||
#include "mesh.h"
|
||||
#include "skeleton.h"
|
||||
#include "bone.h"
|
||||
#include "model.h"
|
||||
#include "animation.h"
|
||||
#include "animationController.h"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace vb01{
|
||||
VbModelReader::VbModelReader(Model *model, string path) : ModelReader(model, path){
|
||||
this->path = path;
|
||||
this->model = model;
|
||||
|
||||
map<int, int> meshBracketIds, skeletonBracketIds, lightBracketIds;
|
||||
getObjectBounds(meshBracketIds, skeletonBracketIds, lightBracketIds);
|
||||
|
||||
map<int, int>::iterator it;
|
||||
vector<string> data;
|
||||
for(it = skeletonBracketIds.begin(); it != skeletonBracketIds.end(); ++it){
|
||||
int key = it->first;
|
||||
readFile(path, data, key + 1, skeletonBracketIds[key]);
|
||||
skeletons.push_back(readSkeleton(data));
|
||||
data.clear();
|
||||
}
|
||||
for(it = meshBracketIds.begin(); it != meshBracketIds.end(); ++it){
|
||||
int key = it->first;
|
||||
readFile(path, data, key + 1, meshBracketIds[key]);
|
||||
buildMesh(data);
|
||||
data.clear();
|
||||
}
|
||||
for(it = lightBracketIds.begin(); it != lightBracketIds.end(); ++it){
|
||||
int key = it->first;
|
||||
readFile(path, data, key + 1, lightBracketIds[key]);
|
||||
readLights(data);
|
||||
data.clear();
|
||||
}
|
||||
|
||||
connectNodes();
|
||||
setupDrivers();
|
||||
}
|
||||
|
||||
VbModelReader::~VbModelReader(){
|
||||
}
|
||||
|
||||
void VbModelReader::getObjectBounds(map<int, int> &meshBracketIds, map<int, int> &skeletonBracketIds, map<int, int> &lightBracketIds){
|
||||
const string meshType = "MESH", skeletonType = "ARMATURE", lightType = "LIGHT";
|
||||
|
||||
int lineIndex = 0, leftBracket = -1, rightBracket = -1;
|
||||
string line, type;
|
||||
ifstream file(path);
|
||||
|
||||
while(getline(file, line)){
|
||||
if(line[0] == '{'){
|
||||
leftBracket = lineIndex;
|
||||
|
||||
getline(file, line);
|
||||
lineIndex++;
|
||||
|
||||
int colonId = getCharId(line, ':');
|
||||
type = line.substr(0, colonId);
|
||||
}
|
||||
else if(line[0] == '}')
|
||||
rightBracket = lineIndex;
|
||||
|
||||
if(leftBracket != -1 && rightBracket != -1){
|
||||
if(type == meshType)
|
||||
meshBracketIds.emplace(leftBracket, rightBracket);
|
||||
else if(type == skeletonType)
|
||||
skeletonBracketIds.emplace(leftBracket, rightBracket);
|
||||
else if(type == lightType)
|
||||
lightBracketIds.emplace(leftBracket, rightBracket);
|
||||
|
||||
leftBracket = -1, rightBracket = -1;
|
||||
}
|
||||
|
||||
lineIndex++;
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
void VbModelReader::connectNodes(){
|
||||
for(map<string, string>::iterator it = relationships.begin(); it != relationships.end(); it++){
|
||||
Node *child = nullptr, *parent = nullptr;
|
||||
string childName = it->first, parentName = relationships[childName];
|
||||
for(Node *node : nodes){
|
||||
if(node->getName() == childName)
|
||||
child = node;
|
||||
else if(node->getName() == parentName)
|
||||
parent = node;
|
||||
}
|
||||
if(parent)
|
||||
parent->attachChild(child);
|
||||
}
|
||||
for(Node *node : nodes)
|
||||
if(!node->getParent())
|
||||
model->attachChild(node);
|
||||
}
|
||||
|
||||
void VbModelReader::setupDrivers(){
|
||||
int i = 0;
|
||||
for(string *data : driverSetups){
|
||||
Skeleton *drivingSkeleton = nullptr, *drivenSkeleton = nullptr;
|
||||
Mesh *drivenMesh = nullptr;
|
||||
|
||||
for(Skeleton *sk : skeletons){
|
||||
if(data[0] == sk->getName())
|
||||
drivingSkeleton = sk;
|
||||
if(data[2] == sk->getName())
|
||||
drivenSkeleton = sk;
|
||||
}
|
||||
for(Mesh *m : meshes)
|
||||
if(data[2] == m->getName())
|
||||
drivenMesh = m;
|
||||
|
||||
Animatable *animatable = nullptr;
|
||||
if(drivenSkeleton){
|
||||
for(Bone *bone : drivenSkeleton->getBones())
|
||||
if(bone->getName() == data[3])
|
||||
animatable = bone;
|
||||
}
|
||||
else if(drivenMesh){
|
||||
int numShapeKeys = drivenMesh->getNumShapeKeys();
|
||||
for(int i = 0; i < numShapeKeys; i++){
|
||||
Mesh::ShapeKey &shapeKey = drivenMesh->getShapeKey(i);
|
||||
if(shapeKey.name == data[3])
|
||||
animatable = &shapeKey;
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(Node *node : nodes)
|
||||
if(node->getName() == data[2])
|
||||
animatable = node;
|
||||
}
|
||||
|
||||
if(drivingSkeleton){
|
||||
for(Bone *bone : drivingSkeleton->getBones())
|
||||
if(bone->getName() == data[1])
|
||||
bone->addDriver(drivers[i]);
|
||||
}
|
||||
else{
|
||||
for(Node *node : nodes)
|
||||
if(node->getName() == data[0])
|
||||
node->addDriver(drivers[i]);
|
||||
}
|
||||
|
||||
KeyframeChannel &keyframeChannel = drivers[i]->getKeyframeChannel();
|
||||
keyframeChannel.animatable = animatable;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
for(string *data : driverSetups)
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void VbModelReader::createBones(Skeleton *skeleton, vector<string> &skeletonData){
|
||||
map<string, string> ikRelationships;
|
||||
|
||||
for(string line : skeletonData){
|
||||
int colonId = getCharId(line, ':');
|
||||
string preColon = line.substr(0, colonId);
|
||||
string postColon = line.substr(colonId + 2);
|
||||
|
||||
const int numData = 13;
|
||||
string data[numData];
|
||||
getLineData(postColon, data, numData);
|
||||
|
||||
float length = atof(data[1].c_str());
|
||||
Vector3 head = Vector3(atof(data[2].c_str()), atof(data[3].c_str()), atof(data[4].c_str()));
|
||||
Vector3 xAxis = Vector3(atof(data[5].c_str()), atof(data[6].c_str()), atof(data[7].c_str())).norm();
|
||||
Vector3 yAxis = Vector3(atof(data[8].c_str()), atof(data[9].c_str()), atof(data[10].c_str())).norm();
|
||||
|
||||
float eps = pow(10, -2);
|
||||
if(fabs(xAxis.x) < eps)
|
||||
xAxis.x = 0;
|
||||
if(fabs(xAxis.y) < eps)
|
||||
xAxis.y = 0;
|
||||
if(fabs(xAxis.z) < eps)
|
||||
xAxis.z = 0;
|
||||
if(fabs(yAxis.x) < eps)
|
||||
yAxis.x = 0;
|
||||
if(fabs(yAxis.y) < eps)
|
||||
yAxis.y = 0;
|
||||
if(fabs(yAxis.z) < eps)
|
||||
yAxis.z = 0;
|
||||
|
||||
string ikTarget = data[11].c_str();
|
||||
int ikChainLength = atoi(data[12].c_str());
|
||||
Vector3 zAxis = xAxis.cross(yAxis).norm();
|
||||
Vector3 pos = head;
|
||||
|
||||
string parName = string(data[0].c_str());
|
||||
Node *parent = skeleton->getBone(parName);
|
||||
if(!parent){
|
||||
parent = model;
|
||||
swap(pos.y, pos.z);
|
||||
pos.z = -pos.z;
|
||||
swap(yAxis.y, yAxis.z);
|
||||
yAxis.z = -yAxis.z;
|
||||
swap(zAxis.y, zAxis.z);
|
||||
zAxis.z = -zAxis.z;
|
||||
}
|
||||
else
|
||||
pos = pos + Vector3(0, ((Bone*)parent)->getLength(), 0);
|
||||
|
||||
Bone *bone = new Bone(preColon, length, pos);
|
||||
bone->setIkChainLength(ikChainLength);
|
||||
skeleton->addBone(bone, (Bone*)parent);
|
||||
bone->lookAt(zAxis, yAxis);
|
||||
if(ikTarget != "-")
|
||||
ikRelationships.emplace(preColon, ikTarget);
|
||||
}
|
||||
|
||||
map<string, string>::iterator it;
|
||||
for(it = ikRelationships.begin(); it != ikRelationships.end(); it++){
|
||||
string targetBoneName = it->first;
|
||||
string ikTargetBoneName = ikRelationships[targetBoneName];
|
||||
skeleton->getBone(targetBoneName)->setIkTarget(ikTargetBoneName);
|
||||
}
|
||||
}
|
||||
|
||||
KeyframeChannel VbModelReader::readKeyframeChannel(Animatable *animatable, vector<string> &animationData, int &keyframeChannelStartLine){
|
||||
string channelData[3];
|
||||
getLineData(animationData[keyframeChannelStartLine], channelData, 3);
|
||||
|
||||
string animatableName = channelData[0], typeStr = channelData[1];
|
||||
int numKeyframes = atoi(channelData[2].c_str());
|
||||
int keyframeStartLine = keyframeChannelStartLine + 1;
|
||||
|
||||
KeyframeChannel keyframeChannel;
|
||||
if(currentSkeleton)
|
||||
keyframeChannel.animatable = currentSkeleton->getBone(animatableName);
|
||||
else if(currentLight)
|
||||
keyframeChannel.animatable = ((Node*)animatable)->getLight(0);
|
||||
else
|
||||
keyframeChannel.animatable = animatable;
|
||||
keyframeChannel.type = KeyframeChannel::getKeyframeChannelType(typeStr);
|
||||
|
||||
for(int k = 0; k < numKeyframes; k++){
|
||||
string keyframeLine = animationData[keyframeStartLine + k];
|
||||
string keyframeData[7];
|
||||
getLineData(keyframeLine, keyframeData, 7);
|
||||
|
||||
Keyframe keyframe;
|
||||
keyframe.value = atof(keyframeData[0].c_str());
|
||||
keyframe.frame = atof(keyframeData[1].c_str());
|
||||
keyframe.interpolation = (KeyframeInterpolation)atoi(keyframeData[2].c_str());
|
||||
keyframe.leftHandleValue = atof(keyframeData[3].c_str());
|
||||
keyframe.leftHandleFrame = atof(keyframeData[4].c_str());
|
||||
keyframe.rightHandleValue = atof(keyframeData[5].c_str());
|
||||
keyframe.rightHandleFrame = atof(keyframeData[6].c_str());
|
||||
|
||||
keyframeChannel.keyframes.push_back(keyframe);
|
||||
}
|
||||
|
||||
keyframeChannelStartLine += numKeyframes + 1;
|
||||
|
||||
return keyframeChannel;
|
||||
}
|
||||
|
||||
void VbModelReader::readAnimations(Animatable *animatable, vector<string> &animationData){
|
||||
int numAnimations = atoi(animationData[0].substr(animationData[0].find_first_of(':') + 2).c_str());
|
||||
int animStartLine = 1;
|
||||
|
||||
for(int i = 0; i < numAnimations; i++){
|
||||
string animLine = animationData[animStartLine];
|
||||
string data[2];
|
||||
getLineData(animLine.substr(animLine.find_first_of(':') + 2), data, 2);
|
||||
currentAnim = data[0];
|
||||
|
||||
Animation *animation = new Animation(currentAnim);
|
||||
AnimationController::getSingleton()->addAnimation(animation);
|
||||
|
||||
int numKeyframeChannels = atoi(data[1].c_str());
|
||||
int keyframeChannelStartLine = animStartLine + 1;
|
||||
for(int j = 0; j < numKeyframeChannels; j++)
|
||||
animation->addKeyframeChannel(readKeyframeChannel(animatable, animationData, keyframeChannelStartLine));
|
||||
|
||||
animStartLine = keyframeChannelStartLine;
|
||||
}
|
||||
}
|
||||
|
||||
void VbModelReader::readDrivers(vector<string> &meshData, string objectName){
|
||||
int numDrivers = atoi(meshData[0].substr(meshData[0].find_first_of(':') + 1).c_str());
|
||||
int driverStartLine = 1;
|
||||
const int numData = 3;
|
||||
|
||||
for(int i = 0; i < numDrivers; i++){
|
||||
string data[numData];
|
||||
getLineData(meshData[driverStartLine], data, numData);
|
||||
bool driverIsBone = (data[numData - 1] != "");
|
||||
Driver::VariableType type = Driver::getDriverVariableType(driverIsBone ? data[numData - 1] : data[numData - 2]);
|
||||
|
||||
int keyframeChannelStartLine = driverStartLine + 1;
|
||||
string drivingNode = data[0];
|
||||
string drivingBone = (driverIsBone ? data[1] : "");
|
||||
string drivenAnimatable = objectName;
|
||||
string channelData[1];
|
||||
getLineData(meshData[keyframeChannelStartLine], channelData, 1);
|
||||
string drivenSubAnimatable = channelData[0];
|
||||
|
||||
string *driverSetup = new string[4]{drivingNode, drivingBone, drivenAnimatable, drivenSubAnimatable};
|
||||
driverSetups.push_back(driverSetup);
|
||||
|
||||
KeyframeChannel keyframeChannel = readKeyframeChannel(nullptr, meshData, keyframeChannelStartLine);
|
||||
|
||||
drivers.push_back(new Driver(keyframeChannel, type));
|
||||
|
||||
driverStartLine += 2 + keyframeChannel.keyframes.size();
|
||||
}
|
||||
}
|
||||
|
||||
Skeleton* VbModelReader::readSkeleton(vector<string> &skeletonData){
|
||||
string name = skeletonData[0].substr(getCharId(skeletonData[0], ':') + 2);
|
||||
string line = skeletonData[5];
|
||||
string data[3];
|
||||
getLineData(line, data, 3);
|
||||
|
||||
int boneStartLine = 6;
|
||||
int numBones = atoi(data[1].c_str());
|
||||
int animationStartLine = boneStartLine + numBones;
|
||||
int driverStartLine = findDriverStartLine(skeletonData, animationStartLine);
|
||||
|
||||
Skeleton *skeleton = new Skeleton(name);
|
||||
currentSkeleton = skeleton;
|
||||
|
||||
vector<string> skeletonSubData = vector<string>(skeletonData.begin() + boneStartLine, skeletonData.begin() + boneStartLine + numBones);
|
||||
createBones(skeleton, skeletonSubData);
|
||||
skeletonSubData.clear();
|
||||
|
||||
skeletonSubData = vector<string>(skeletonData.begin() + animationStartLine, skeletonData.begin() + driverStartLine);
|
||||
readAnimations(nullptr, skeletonSubData);
|
||||
skeletonSubData.clear();
|
||||
|
||||
skeletonSubData = vector<string>(skeletonData.begin() + driverStartLine, skeletonData.end());
|
||||
readDrivers(skeletonSubData, name);
|
||||
skeletonSubData.clear();
|
||||
|
||||
currentSkeleton = nullptr;
|
||||
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
void VbModelReader::readVertices(
|
||||
vector<Vector3> &vertPos,
|
||||
vector<Vector3> &vertNorm,
|
||||
vector<float> &vertWeights,
|
||||
vector<string> &meshData,
|
||||
int numBones
|
||||
){
|
||||
for(string line : meshData){
|
||||
int numData = 6 + numBones;
|
||||
string *data = new string[numData];
|
||||
getLineData(line, data, numData);
|
||||
Vector3 vPos = Vector3(atof(data[0].c_str()), atof(data[2].c_str()), -atof(data[1].c_str()));
|
||||
Vector3 vNorm = Vector3(atof(data[3].c_str()), atof(data[5].c_str()), -atof(data[4].c_str()));
|
||||
vertPos.push_back(vPos);
|
||||
vertNorm.push_back(vNorm);
|
||||
|
||||
float *weightCoefs = new float[numBones];
|
||||
for(int i = 0; i < numBones; i++)
|
||||
weightCoefs[i] = atof(data[6 + i].c_str());
|
||||
delete[] data;
|
||||
|
||||
int numPosWeights = 0;
|
||||
float sumWeightCoefs = 0;
|
||||
for(int i = 0; i < numBones; i++)
|
||||
if(weightCoefs[i] > 0){
|
||||
sumWeightCoefs += weightCoefs[i];
|
||||
}
|
||||
|
||||
float root = 1. / sumWeightCoefs;
|
||||
for(int i = 0; i < numBones; i++)
|
||||
vertWeights.push_back(root * weightCoefs[i]);
|
||||
delete[] weightCoefs;
|
||||
}
|
||||
}
|
||||
|
||||
void VbModelReader::readFaces(
|
||||
vector<Vector3> &vertPos,
|
||||
vector<Vector3> &vertNorm,
|
||||
vector<u32> &vertIds,
|
||||
vector<float> &vertWeights,
|
||||
vector<string> &meshData,
|
||||
int numBones,
|
||||
Mesh::Vertex *vertices,
|
||||
u32 *indices
|
||||
){
|
||||
for(int i = 0; i < meshData.size(); i++){
|
||||
const int numData = 9;
|
||||
string data[numData];
|
||||
getLineData(meshData[i], data, numData);
|
||||
int index = atoi(data[0].c_str());
|
||||
|
||||
Vector2 uv = Vector2(atof(data[1].c_str()), atof(data[2].c_str()));
|
||||
Vector3 tan = Vector3(atof(data[3].c_str()), atof(data[5].c_str()), -atof(data[4].c_str()));
|
||||
Vector3 biTan = Vector3(atof(data[6].c_str()), atof(data[8].c_str()), -atof(data[7].c_str()));
|
||||
|
||||
Mesh::Vertex vert;
|
||||
vert.pos = vertPos[index];
|
||||
vert.tan = tan;
|
||||
vert.biTan = biTan;
|
||||
vert.norm = tan.cross(biTan);
|
||||
vert.uv = uv;
|
||||
|
||||
for(int j = 0, boneIndex = 0; j < numBones; j++){
|
||||
if(vertWeights[index * numBones + j] > 0){
|
||||
vert.boneIndices[boneIndex] = j;
|
||||
vert.weights[boneIndex] = vertWeights[index * numBones + j];
|
||||
boneIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
vertIds.push_back(index);
|
||||
vertices[i] = vert;
|
||||
indices[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
void VbModelReader::readVertexGroups(string *groups, vector<string> &meshData, int numBones){
|
||||
for(int i = 0; i < numBones; i++){
|
||||
groups[i] = meshData[i];
|
||||
}
|
||||
}
|
||||
|
||||
void VbModelReader::readShapeKeys(Mesh::Vertex *vertices, vector<u32> &vertIds, vector<string> &meshData, Mesh::ShapeKey *shapeKeys, int numShapes, int numVertPos){
|
||||
int shapeKeyStartLine = 0;
|
||||
|
||||
for(int i = 0; i < numShapes; i++){
|
||||
string line = meshData[shapeKeyStartLine];
|
||||
int colonId = line.find_first_of(':');
|
||||
Mesh::ShapeKey shapeKey;
|
||||
shapeKey.name = line.substr(0, colonId);
|
||||
string data[2];
|
||||
getLineData(line.substr(colonId + 2), data, 2);
|
||||
shapeKey.minValue = atof(data[0].c_str());
|
||||
shapeKey.value = shapeKey.minValue;
|
||||
shapeKey.maxValue = atof(data[1].c_str());
|
||||
shapeKeys[i] = shapeKey;
|
||||
|
||||
Vector3 *shapeKeyVertPos = new Vector3[numVertPos];
|
||||
|
||||
for(int j = 0; j < numVertPos; j++){
|
||||
string line = meshData[shapeKeyStartLine + 1 + j];
|
||||
string dataLine[3];
|
||||
getLineData(line, dataLine, 3);
|
||||
shapeKeyVertPos[j] = Vector3(atof(dataLine[0].c_str()), atof(dataLine[2].c_str()), -atof(dataLine[1].c_str()));
|
||||
}
|
||||
|
||||
for(int j = 0; j < vertIds.size(); j++){
|
||||
Vector3 offset = shapeKeyVertPos[vertIds[j]] - vertices[j].pos;
|
||||
vertices[j].shapeKeyOffsets[i] = (offset);
|
||||
}
|
||||
|
||||
delete[] shapeKeyVertPos;
|
||||
|
||||
|
||||
shapeKeyStartLine = shapeKeyStartLine + numVertPos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
Mesh* VbModelReader::readMeshes(vector<string> &meshData){
|
||||
string nameLine = meshData[0];
|
||||
int nameLineColonId = getCharId(nameLine, ':');
|
||||
string preColonNameLine = nameLine.substr(0, nameLineColonId);
|
||||
string postColonNameLine = nameLine.substr(nameLineColonId + 2, string::npos);
|
||||
|
||||
string numElementsLine = meshData[6];
|
||||
int numElementsColonId = getCharId(numElementsLine, ':');
|
||||
string numElementsPreColon = numElementsLine.substr(0, numElementsColonId);
|
||||
string numElementsPostColon = numElementsLine.substr(numElementsColonId + 2, string::npos);
|
||||
|
||||
string data[4];
|
||||
getLineData(numElementsPostColon, data, 4);
|
||||
string name = postColonNameLine;
|
||||
|
||||
string parentLine = meshData[4];
|
||||
int parentLineColonId = getCharId(parentLine, ':');
|
||||
string parent = parentLine.substr(parentLineColonId + 2, string::npos);
|
||||
relationships.emplace(name, parent);
|
||||
|
||||
const int numVertsPerFace = 3;
|
||||
int numVertices = atoi(data[0].c_str());
|
||||
int numFaces = atoi(data[1].c_str());
|
||||
int numBones = atoi(data[2].c_str());
|
||||
int numShapes = atoi(data[3].c_str());
|
||||
int vertexGroupStartLine = 8;
|
||||
int vertexStartLine = vertexGroupStartLine + numBones + 1;
|
||||
int faceStartLine = vertexStartLine + numVertices + 1;
|
||||
int shapeKeyStartLine = faceStartLine + numFaces * numVertsPerFace + 1;
|
||||
int animationStartLine = shapeKeyStartLine + numShapes * (1 + numVertices);
|
||||
int driverStartLine = findDriverStartLine(meshData, animationStartLine);
|
||||
|
||||
vector<Vector3> vertPos, vertNorm;
|
||||
vector<float> vertWeights;
|
||||
vector<u32> vertIds;
|
||||
Mesh::Vertex *vertices = new Mesh::Vertex[numFaces * numVertsPerFace];
|
||||
u32 *indices = new u32[numFaces * numVertsPerFace];
|
||||
string *groups = new string[numBones];
|
||||
Mesh::ShapeKey *shapeKeys = new Mesh::ShapeKey[numShapes];
|
||||
|
||||
vector<string> meshSubData = vector<string>(meshData.begin() + vertexStartLine, meshData.begin() + vertexStartLine + numVertices);
|
||||
readVertices(vertPos, vertNorm, vertWeights, meshSubData, numBones);
|
||||
meshSubData.clear();
|
||||
|
||||
meshSubData = vector<string>(meshData.begin() + faceStartLine, meshData.begin() + faceStartLine + numFaces * numVertsPerFace);
|
||||
readFaces(vertPos, vertNorm, vertIds, vertWeights, meshSubData, numBones, vertices, indices);
|
||||
meshSubData.clear();
|
||||
vertPos.clear();
|
||||
vertNorm.clear();
|
||||
vertWeights.clear();
|
||||
|
||||
meshSubData = vector<string>(meshData.begin() + vertexGroupStartLine, meshData.begin() + vertexGroupStartLine + numBones);
|
||||
readVertexGroups(groups, meshSubData, numBones);
|
||||
meshSubData.clear();
|
||||
|
||||
meshSubData = vector<string>(meshData.begin() + shapeKeyStartLine, meshData.begin() + (shapeKeyStartLine + numShapes * (1 + numVertices)));
|
||||
readShapeKeys(vertices, vertIds, meshSubData, shapeKeys, numShapes, numVertices);
|
||||
meshSubData.clear();
|
||||
|
||||
getLineData(meshData[1].substr(meshData[1].find_first_of(':') + 2), data, 3);
|
||||
Vector3 pos = Vector3(atof(data[0].c_str()), atof(data[2].c_str()), -atof(data[1].c_str()));
|
||||
getLineData(meshData[2].substr(meshData[2].find_first_of(':') + 2), data, 4);
|
||||
Quaternion rot = Quaternion(atof(data[0].c_str()), atof(data[1].c_str()), atof(data[3].c_str()), -atof(data[2].c_str()));
|
||||
getLineData(meshData[3].substr(meshData[3].find_first_of(':') + 2), data, 3);
|
||||
Vector3 scale = Vector3(atof(data[0].c_str()), atof(data[1].c_str()), atof(data[2].c_str()));
|
||||
|
||||
Node *node = new Node(pos, rot, scale, name);
|
||||
nodes.push_back(node);
|
||||
|
||||
meshSubData = vector<string>(meshData.begin() + animationStartLine, meshData.begin() + driverStartLine);
|
||||
readAnimations(node, meshSubData);
|
||||
meshSubData.clear();
|
||||
|
||||
meshSubData = vector<string>(meshData.begin() + driverStartLine, meshData.end());
|
||||
readDrivers(meshSubData, name);
|
||||
meshSubData.clear();
|
||||
|
||||
string skeletonLine = meshData[5];
|
||||
int skeletonLineColonId = getCharId(skeletonLine, ':');
|
||||
string skeletonName = skeletonLine.substr(skeletonLineColonId + 2, string::npos);
|
||||
|
||||
Skeleton *skeleton = nullptr;
|
||||
for(Skeleton *sk : skeletons)
|
||||
if(sk->getName() == skeletonName)
|
||||
skeleton = sk;
|
||||
|
||||
Mesh *mesh = new Mesh(vertices, indices, numFaces, groups, numBones, shapeKeys, numShapes, name);
|
||||
meshes.push_back(mesh);
|
||||
mesh->setSkeleton(skeleton);
|
||||
node->attachMesh(mesh);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
void VbModelReader::buildMesh(vector<string> &meshData){
|
||||
Mesh *mesh = readMeshes(meshData);
|
||||
mesh->construct();
|
||||
|
||||
}
|
||||
|
||||
void VbModelReader::readLights(vector<string> &lightData){
|
||||
string name = lightData[0].substr(lightData[0].find_first_of(':') + 2);
|
||||
string data[4];
|
||||
getLineData(lightData[1].substr(lightData[1].find_first_of(':') + 2), data, 3);
|
||||
Vector3 pos = Vector3(atof(data[0].c_str()), atof(data[1].c_str()), atof(data[2].c_str()));
|
||||
getLineData(lightData[2].substr(lightData[2].find_first_of(':') + 2), data, 4);
|
||||
Quaternion rot = Quaternion(atof(data[0].c_str()), atof(data[1].c_str()), atof(data[2].c_str()), atof(data[3].c_str()));
|
||||
getLineData(lightData[3].substr(lightData[3].find_first_of(':') + 2), data, 3);
|
||||
Vector3 scale = Vector3(atof(data[0].c_str()), atof(data[1].c_str()) + 2, atof(data[2].c_str()));
|
||||
string parent = lightData[4].substr(lightData[4].find_first_of(':') + 2);
|
||||
relationships.emplace(name, parent);
|
||||
|
||||
string typeStr = lightData[5].substr(lightData[5].find_first_of(':') + 2);
|
||||
Light::Type type;
|
||||
if(typeStr == "POINT")
|
||||
type = Light::POINT;
|
||||
else if(typeStr == "SUN")
|
||||
type = Light::DIRECTIONAL;
|
||||
else if(typeStr == "SPOT")
|
||||
type = Light::SPOT;
|
||||
else if(typeStr == "AREA")
|
||||
type = Light::AMBIENT;
|
||||
getLineData(lightData[6].substr(lightData[6].find_first_of(':') + 2), data, 3);
|
||||
Vector3 color = Vector3(atof(data[0].c_str()), atof(data[1].c_str()), atof(data[2].c_str()));
|
||||
float outerAngle = atof(lightData[7].substr(lightData[7].find_first_of(':') + 2).c_str());
|
||||
float innerAngle = atof(lightData[8].substr(lightData[8].find_first_of(':') + 2).c_str());
|
||||
|
||||
Light *light = new Light(type, name);
|
||||
light->setColor(color);
|
||||
light->setOuterAngle(outerAngle);
|
||||
light->setInnerAngle(innerAngle);
|
||||
currentLight = light;
|
||||
|
||||
Node *node = new Node(pos, rot, scale, name);
|
||||
node->addLight(light);
|
||||
nodes.push_back(node);
|
||||
|
||||
int animationStartLine = 9;
|
||||
int driverStartLine = findDriverStartLine(lightData, animationStartLine);
|
||||
vector<string> lightSubData = vector<string>(lightData.begin() + animationStartLine, lightData.begin() + driverStartLine);
|
||||
readAnimations(node, lightSubData);
|
||||
lightSubData.clear();
|
||||
|
||||
lightSubData = vector<string>(lightData.begin() + driverStartLine, lightData.end());
|
||||
readDrivers(lightSubData, name);
|
||||
lightSubData.clear();
|
||||
|
||||
currentLight = nullptr;
|
||||
}
|
||||
|
||||
int VbModelReader::findDriverStartLine(vector<string> &data, int animationStartLine){
|
||||
int driverStartLine = animationStartLine;
|
||||
for(int i = animationStartLine; i < data.size(); i++)
|
||||
if(data[i].find_first_of(':') != -1 && data[i].substr(0, data[i].length() - 1) == "drivers: "){
|
||||
driverStartLine = i;
|
||||
break;
|
||||
}
|
||||
return driverStartLine;
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
#ifndef VB_MODEL_READER
|
||||
#define VB_MODEL_READER
|
||||
|
||||
#include "modelReader.h"
|
||||
#include "util.h"
|
||||
#include "mesh.h"
|
||||
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
|
||||
namespace vb01{
|
||||
class Model;
|
||||
class Node;
|
||||
class Skeleton;
|
||||
class Driver;
|
||||
|
||||
class VbModelReader : public ModelReader{
|
||||
public:
|
||||
VbModelReader(){}
|
||||
VbModelReader(Model*, std::string);
|
||||
~VbModelReader();
|
||||
private:
|
||||
void getObjectBounds(std::map<int, int>&, std::map<int, int>&, std::map<int, int>&);
|
||||
void connectNodes();
|
||||
void setupDrivers();
|
||||
int findDriverStartLine(std::vector<std::string>&, int);
|
||||
void createBones(Skeleton*, std::vector<std::string>&);
|
||||
KeyframeChannel readKeyframeChannel(Animatable*, std::vector<std::string>&, int&);
|
||||
void readAnimations(Animatable*, std::vector<std::string>&);
|
||||
Skeleton* readSkeleton(std::vector<std::string>&);
|
||||
void readVertices(std::vector<Vector3>&, std::vector<Vector3>&, std::vector<float>&, std::vector<std::string>&, int);
|
||||
void readFaces(std::vector<Vector3>&, std::vector<Vector3>&, std::vector<u32>&, std::vector<float>&, std::vector<std::string>&, int, Mesh::Vertex*, u32*);
|
||||
void readVertexGroups(std::string*, std::vector<std::string>&, int);
|
||||
void readShapeKeys(Mesh::Vertex*, std::vector<u32>&, std::vector<std::string>&, Mesh::ShapeKey*, int, int);
|
||||
void readDrivers(std::vector<std::string>&, std::string);
|
||||
void buildMesh(std::vector<std::string>&);
|
||||
Mesh* readMeshes(std::vector<std::string>&);
|
||||
void readLights(std::vector<std::string>&);
|
||||
|
||||
std::vector<Driver*> drivers;
|
||||
std::map<std::string, std::string> relationships;
|
||||
std::vector<std::string*> driverSetups;
|
||||
Skeleton *currentSkeleton = nullptr;
|
||||
Light *currentLight = nullptr;
|
||||
std::vector<Skeleton*> skeletons;
|
||||
std::vector<Mesh*> meshes;
|
||||
std::vector<Node*> nodes;
|
||||
std::string currentAnim = "";
|
||||
|
||||
friend class VbModelReaderTest;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
#include "vbModelReaderTest.h"
|
||||
#include "vbModelReader.h"
|
||||
#include "skeleton.h"
|
||||
#include "animationController.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace vb01{
|
||||
VbModelReaderTest::VbModelReaderTest(){}
|
||||
|
||||
VbModelReaderTest::~VbModelReaderTest(){}
|
||||
|
||||
void VbModelReaderTest::setUp(){
|
||||
rootNode = Root::getSingleton()->getRootNode();
|
||||
modelReader = new VbModelReader();
|
||||
setupSkeleton();
|
||||
setupMesh();
|
||||
}
|
||||
|
||||
void VbModelReaderTest::tearDown(){
|
||||
delete modelReader;
|
||||
}
|
||||
|
||||
void VbModelReaderTest::setupSkeleton(){
|
||||
model = new Model();
|
||||
rootNode->attachChild(model);
|
||||
modelReader->model = model;
|
||||
|
||||
bones = vector<vbReader::Bone>({
|
||||
Bone("bipod", "-", Vector3(0, 0, 0), Vector3(1, 0, 0), Vector3(0, 1, 0), "", 0),
|
||||
Bone("bipod.L", "bipod", Vector3(1, 0, 2), Vector3(1, 0, 0), Vector3(0, 0, -1), "", 0),
|
||||
Bone("bipod.R", "bipod", Vector3(-1, 0, 2), Vector3(-1, 0, 0), Vector3(0, 0, -1), "", 0),
|
||||
Bone("opening", "-", Vector3(0, 0, 2), Vector3(-1, 0, 0), Vector3(0, 0, -1), "", 0)
|
||||
});
|
||||
skeletonParent = "-";
|
||||
|
||||
int numBones = bones.size();
|
||||
|
||||
skeletonData.push_back("ARMATURE: MG42");
|
||||
skeletonData.push_back("pos: 0.0 0.0 0.0");
|
||||
skeletonData.push_back("rot: 1.0 0.0 0.0 -0.0");
|
||||
skeletonData.push_back("scale: 1.0 1.0 1.0");
|
||||
skeletonData.push_back("parent: " + skeletonParent);
|
||||
skeletonData.push_back("bones: " + to_string(numBones) + " ");
|
||||
for(vbReader::Bone b : bones){
|
||||
string headStr = to_string(b.head.x) + " " + to_string(b.head.y) + " " + to_string(b.head.z) + " ";
|
||||
string xAxisStr = to_string(b.xAxis.x) + " " + to_string(b.xAxis.y) + " " + to_string(b.xAxis.z) + " ";
|
||||
string yAxisStr = to_string(b.yAxis.x) + " " + to_string(b.yAxis.y) + " " + to_string(b.yAxis.z) + " ";
|
||||
skeletonData.push_back(b.name + ": " + b.parent + " " + headStr + xAxisStr + yAxisStr + b.ikTarget + " " + to_string(b.ikChainLength) + " ");
|
||||
}
|
||||
skeletonData.push_back("animations: 2");
|
||||
skeletonData.push_back("animation: Action 13 ");
|
||||
skeletonData.push_back("bipod.L pos_x 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("0 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.L pos_y 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("0 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.L pos_z 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("0 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.L rot_w 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("0 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.L rot_x 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("0 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.L rot_y 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("0 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.L rot_z 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("0 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.R pos_x 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("10 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.R pos_y 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("10 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.R pos_z 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("10 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.R rot_w 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("10 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.R rot_x 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("10 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("bipod.R rot_y 2 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("10 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("animation: open 2 ");
|
||||
skeletonData.push_back("opening rot_w 2 ");
|
||||
skeletonData.push_back("1 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("0 10 2 1 1 1 1 ");
|
||||
skeletonData.push_back("opening rot_x 1 ");
|
||||
skeletonData.push_back("0 1 2 1 1 1 1 ");
|
||||
skeletonData.push_back("drivers: 0");
|
||||
}
|
||||
|
||||
void VbModelReaderTest::setupMesh(){
|
||||
meshName = "mg42";
|
||||
meshParent = "-";
|
||||
skeletonName = "MG42";
|
||||
|
||||
vertPos = vector<Vector3>({Vector3(0, 1, 2), Vector3(1, 1, 2), Vector3(2, 1, 2)});
|
||||
vertNorm = vector<Vector3>({Vector3(3, 4, 5), Vector3(3, 4, 5), Vector3(3, 4, 5)});
|
||||
vertUv = vector<Vector2>({Vector2(1, 1), Vector2(1, 0), Vector2(0, 0)});
|
||||
vertexGroups = vector<string>({"clip", "trigger"});
|
||||
vertTan = vector<Vector3>({Vector3(1, 2, 3), Vector3(1, 2, 3), Vector3(1, 2, 3)});
|
||||
vertBiTan = vector<Vector3>({Vector3(3, 2, 1), Vector3(3, 2, 1), Vector3(3, 2, 1)});
|
||||
vertWeights = vector<vector<float>>({
|
||||
vector<float>({1, 0.5}),
|
||||
vector<float>({1, 0.5}),
|
||||
vector<float>({1, 0.5})
|
||||
});
|
||||
|
||||
int numVerts = vertPos.size();
|
||||
int numFaces = numVerts / 3;
|
||||
int numVertexGroups = vertexGroups.size();
|
||||
int numShapeKeys = 1;
|
||||
|
||||
meshData.push_back("MESH: " + meshName);
|
||||
meshData.push_back("pos: 0.0 0.0 0.0");
|
||||
meshData.push_back("rot: 1.0 0.0 0.0 -0.0");
|
||||
meshData.push_back("scale: 1.0 1.0 1.0");
|
||||
meshData.push_back("parent: " + meshParent);
|
||||
meshData.push_back("skeleton: " + skeletonName);
|
||||
meshData.push_back("numElements: " + to_string(numVerts) + " " + to_string(numFaces) + " " + to_string(numVertexGroups) + " " + to_string(numShapeKeys) + " ");
|
||||
meshData.push_back("groups:");
|
||||
for(string group : vertexGroups)
|
||||
meshData.push_back(group);
|
||||
meshData.push_back("vertices:");
|
||||
for(int i = 0; i < vertPos.size(); i++){
|
||||
Vector3 pos = vertPos[i];
|
||||
Vector3 norm = vertNorm[i];
|
||||
string posString = to_string(pos.x) + " " + to_string(pos.y) + " " + to_string(pos.z) + " ";
|
||||
string normString = to_string(norm.x) + " " + to_string(norm.y) + " " + to_string(norm.z) + " ";
|
||||
string weightsString = "";
|
||||
for(int j = 0; j < numVertexGroups; j++)
|
||||
weightsString += to_string(vertWeights[i][j]) + " ";
|
||||
|
||||
meshData.push_back(posString + normString + weightsString);
|
||||
}
|
||||
meshData.push_back("faces:");
|
||||
for(int i = 0; i < vertPos.size(); i++){
|
||||
Vector2 uv = vertUv[i];
|
||||
Vector3 tan = vertTan[i];
|
||||
Vector3 biTan = vertBiTan[i];
|
||||
string uvString = to_string(uv.x) + " " + to_string(uv.y) + " ";
|
||||
string tanString = to_string(tan.x) + " " + to_string(tan.y) + " " + to_string(tan.z) + " ";
|
||||
string biTanString = to_string(biTan.x) + " " + to_string(biTan.y) + " " + to_string(biTan.z) + " ";
|
||||
|
||||
meshData.push_back(to_string(i) + " " + uvString + tanString + biTanString);
|
||||
}
|
||||
meshData.push_back("shapeKeys: 0");
|
||||
meshData.push_back("Key 1: 0 1 ");
|
||||
for(int i = 0; i < vertPos.size(); i++){
|
||||
Vector3 pos = vertPos[i];
|
||||
string posString = to_string(pos.x) + " " + to_string(pos.y) + " " + to_string(pos.z) + " ";
|
||||
meshData.push_back(posString);
|
||||
}
|
||||
meshData.push_back("animations: 0");
|
||||
meshData.push_back("drivers: 0");
|
||||
}
|
||||
|
||||
void VbModelReaderTest::testReadSkeletons(){
|
||||
Skeleton *skeleton = modelReader->readSkeleton(skeletonData);
|
||||
int numBones = skeleton->getNumBones();
|
||||
for(int i = 0; i < numBones; i++){
|
||||
CPPUNIT_ASSERT(skeleton->getBone(i)->getName() == bones[i].name);
|
||||
|
||||
vb01::Bone *parent = (vb01::Bone*)skeleton->getBone(i)->getParent();
|
||||
if(parent->getName() != "")
|
||||
CPPUNIT_ASSERT(parent->getName() == bones[i].parent);
|
||||
else
|
||||
CPPUNIT_ASSERT(bones[i].parent == "-");
|
||||
}
|
||||
AnimationController *controller = AnimationController::getSingleton();
|
||||
string animNames[]{"Action", "open"};
|
||||
CPPUNIT_ASSERT(controller->getAnimation(animNames[0]));
|
||||
CPPUNIT_ASSERT(controller->getAnimation(animNames[1]));
|
||||
Animation *animation = controller->getAnimation(animNames[0]);
|
||||
|
||||
const vector<KeyframeChannel> &keyframeChannels = animation->getKeyframeChannels();
|
||||
vector<KeyframeChannel> leftBipodChannels, rightBipodChannels;
|
||||
for(KeyframeChannel ch : keyframeChannels){
|
||||
vb01::Bone *bone = (vb01::Bone*)ch.animatable;
|
||||
if(bone->getName() == "bipod.L")
|
||||
leftBipodChannels.push_back(ch);
|
||||
else if(bone->getName() == "bipod.R")
|
||||
rightBipodChannels.push_back(ch);
|
||||
}
|
||||
CPPUNIT_ASSERT(!leftBipodChannels.empty());
|
||||
CPPUNIT_ASSERT(!rightBipodChannels.empty());
|
||||
for(KeyframeChannel keyframeChannel : leftBipodChannels)
|
||||
CPPUNIT_ASSERT(keyframeChannel.keyframes.size() == 2);
|
||||
for(KeyframeChannel keyframeChannel : rightBipodChannels)
|
||||
CPPUNIT_ASSERT(keyframeChannel.keyframes.size() == 2);
|
||||
|
||||
Keyframe lastRightBipodKeyframe = animation->getKeyframeChannel(skeleton->getBone("bipod.R"), KeyframeChannelType::ROT_Y)->keyframes[1];
|
||||
CPPUNIT_ASSERT(lastRightBipodKeyframe.value == 10);
|
||||
CPPUNIT_ASSERT(lastRightBipodKeyframe.frame == 10);
|
||||
CPPUNIT_ASSERT(lastRightBipodKeyframe.interpolation == KeyframeInterpolation::BEZIER);
|
||||
}
|
||||
|
||||
void VbModelReaderTest::testReadMeshes(){
|
||||
Mesh *mesh = modelReader->readMeshes(meshData);
|
||||
Mesh::Vertex *vertices = mesh->getVerts();
|
||||
u32 *indices = mesh->getIndices();
|
||||
Skeleton *skeleton = mesh->getSkeleton();
|
||||
|
||||
CPPUNIT_ASSERT(mesh->getName() == meshName);
|
||||
if(skeleton)
|
||||
CPPUNIT_ASSERT(mesh->getSkeleton()->getName() == skeletonName);
|
||||
else
|
||||
CPPUNIT_ASSERT(!mesh->getSkeleton());
|
||||
|
||||
for(int i = 0; i < mesh->getNumVerts(); i++){
|
||||
Mesh::Vertex vert = vertices[i];
|
||||
Vector3 pos = vertPos[i], norm = vertNorm[i], tan = vertTan[i], biTan = vertBiTan[i];
|
||||
Vector2 uv = vertUv[i];
|
||||
|
||||
CPPUNIT_ASSERT(vert.pos == Vector3(pos.x, pos.z, -pos.y));
|
||||
CPPUNIT_ASSERT(vert.norm == Vector3(norm.x, norm.z, -norm.y));
|
||||
CPPUNIT_ASSERT(vert.tan == Vector3(tan.x, tan.z, -tan.y));
|
||||
CPPUNIT_ASSERT(vert.biTan == Vector3(biTan.x, biTan.z, -biTan.y));
|
||||
CPPUNIT_ASSERT(vert.uv == uv);
|
||||
CPPUNIT_ASSERT(indices[i] == i);
|
||||
}
|
||||
|
||||
for(int i = 0; i < mesh->getNumVertexGroups(); i++){
|
||||
CPPUNIT_ASSERT(mesh->getVertexGroups()[i] == vertexGroups[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
#ifndef VB_MODEL_READER_TEST
|
||||
#define VB_MODEL_READER_TEST
|
||||
|
||||
#include <cppunit/TestFixture.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "vector.h"
|
||||
#include "animation.h"
|
||||
#include "model.h"
|
||||
|
||||
namespace vb01{
|
||||
class VbModelReader;
|
||||
|
||||
class VbModelReaderTest;
|
||||
typedef VbModelReaderTest vbReader;
|
||||
|
||||
class VbModelReaderTest : public CppUnit::TestFixture{
|
||||
CPPUNIT_TEST_SUITE(VbModelReaderTest);
|
||||
CPPUNIT_TEST(testReadSkeletons);
|
||||
CPPUNIT_TEST(testReadMeshes);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
VbModelReaderTest();
|
||||
~VbModelReaderTest();
|
||||
void setUp();
|
||||
void tearDown();
|
||||
private:
|
||||
void setupSkeleton();
|
||||
void testReadSkeletons();
|
||||
void setupMesh();
|
||||
void testReadMeshes();
|
||||
void testReadLights();
|
||||
|
||||
struct Bone{
|
||||
Bone(std::string name, std::string parent, Vector3 head, Vector3 xAxis, Vector3 yAxis, std::string ikTarget, int ikChainLength){
|
||||
this->name = name;
|
||||
this->parent = parent;
|
||||
this->head = head;
|
||||
this->xAxis = xAxis;
|
||||
this->yAxis = yAxis;
|
||||
this->ikTarget = ikTarget;
|
||||
this->ikChainLength = ikChainLength;
|
||||
}
|
||||
|
||||
std::string name, parent, ikTarget;
|
||||
Vector3 head, xAxis, yAxis;
|
||||
int ikChainLength;
|
||||
};
|
||||
|
||||
Node *rootNode = nullptr;
|
||||
VbModelReader *modelReader = nullptr;
|
||||
Model *model = nullptr;
|
||||
std::string meshName, skeletonName, meshParent, skeletonParent;
|
||||
std::vector<std::string> vertexGroups;
|
||||
std::vector<Vector3> vertPos, vertNorm, vertTan, vertBiTan;
|
||||
std::vector<Vector2> vertUv;
|
||||
std::vector<std::string> skeletonData, meshData;
|
||||
std::vector<vbReader::Bone> bones;
|
||||
std::vector<std::vector<float>> vertWeights;
|
||||
std::vector<Animation> animations;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user