From 33d077bc9474a55abf1dd5403b698b84a8914b0b Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sat, 19 Dec 2020 19:38:55 +0200 Subject: [PATCH] vb model mesh reader test, beginning of skeleton test --- assimpModelReader.cpp | 4 +- mesh.cpp | 11 ++-- mesh.h | 6 ++- vbModelReader.cpp | 95 +++++++++++++++++----------------- vbModelReader.h | 7 +-- vbModelReaderTest.cpp | 117 ++++++++++++++++++++++++++++++++++++------ vbModelReaderTest.h | 30 ++++++++++- vector.h | 2 + 8 files changed, 196 insertions(+), 76 deletions(-) diff --git a/assimpModelReader.cpp b/assimpModelReader.cpp index 0817afa..ea69803 100644 --- a/assimpModelReader.cpp +++ b/assimpModelReader.cpp @@ -71,6 +71,8 @@ namespace vb01{ aiMaterial *material=scene->mMaterial[mesh->mMaterialIndex]; } */ - currentNode->attachMesh(new Mesh(vertices, indices, numTris)); + Mesh *vbMesh = new Mesh(vertices, indices, numTris); + vbMesh ->construct(); + currentNode->attachMesh(vbMesh); } } diff --git a/mesh.cpp b/mesh.cpp index 9fc0af9..24adf70 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -26,7 +26,6 @@ namespace vb01{ this->numShapeKeys = numShapeKeys; this->name = name; - construct(); } Mesh::~Mesh(){ @@ -63,13 +62,13 @@ namespace vb01{ glBindFramebuffer(GL_FRAMEBUFFER, environmentBuffer); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *(environmentMap->getTexture()), 0); - glGenRenderbuffers(1,&RBO); - glBindRenderbuffer(GL_RENDERBUFFER,RBO); - glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8,width,width); - glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_STENCIL_ATTACHMENT,GL_RENDERBUFFER,RBO); + glGenRenderbuffers(1, &RBO); + glBindRenderbuffer(GL_RENDERBUFFER, RBO); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, width); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RBO); if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - cout<<"Not complete\n"; + cout << "Not complete\n"; glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/mesh.h b/mesh.h index 66c4d81..6c633c1 100755 --- a/mesh.h +++ b/mesh.h @@ -28,6 +28,7 @@ namespace vb01{ Mesh(Vertex*, unsigned int*, int, std::string *vg = nullptr, int = 0, std::string *sk = nullptr, int = 0, std::string = ""); ~Mesh(); + void construct(); virtual void update(); void render(); void setMaterial(Material *mat){this->material = mat;} @@ -44,10 +45,12 @@ namespace vb01{ inline Vertex* getVerts(){return vertices;} inline std::string getName(){return name;} inline Skeleton* getSkeleton(){return skeleton;} + inline std::string* getVertexGroups(){return vertexGroups;} + inline int getNumVertexGroups(){return numVertexGroups;} inline unsigned int* getIndices(){return indices;} private: - void initFramebuffer(); void initMesh(); + void initFramebuffer(); void updateSkeleton(Shader*); void updateReflection(Shader*, Vector3, int, int); @@ -61,7 +64,6 @@ namespace vb01{ Skeleton *skeleton = nullptr; protected: Mesh(); - void construct(); bool staticVerts = true, castShadow = false, reflect = false, wireframe = false; Vertex *vertices; diff --git a/vbModelReader.cpp b/vbModelReader.cpp index 78c52b5..2cfd66e 100644 --- a/vbModelReader.cpp +++ b/vbModelReader.cpp @@ -26,13 +26,13 @@ namespace vb01{ for(it = skeletonBracketIds.begin(); it != skeletonBracketIds.end(); ++it){ int key = it->first; readFile(path, data, key, skeletonBracketIds[key]); - readSkeleton(data); + skeletons.push_back(readSkeleton(data)); data.clear(); } for(it = meshBracketIds.begin(); it != meshBracketIds.end(); ++it){ int key = it->first; readFile(path, data, key, meshBracketIds[key]); - readMeshes(data); + buildMesh(data); data.clear(); } for(it = lightBracketIds.begin(); it != lightBracketIds.end(); ++it){ @@ -86,10 +86,9 @@ namespace vb01{ } void VbModelReader::connectNodes(){ - for(string line : relationships){ + for(map::iterator it = relationships.begin(); it != relationships.end(); it++){ Node *child = nullptr, *parent = nullptr; - int spaceId = getCharId(line, ' '); - string childName = line.substr(0, spaceId), parentName = line.substr(spaceId + 1, string::npos); + string childName = it->first, parentName = relationships[childName]; for(Node *node : nodes){ if(node->getName() == childName) child = node; @@ -104,10 +103,10 @@ namespace vb01{ model->attachChild(node); } - void VbModelReader::createBones(Skeleton *skeleton, vector &meshData){ - vector ikRelationships; + void VbModelReader::createBones(Skeleton *skeleton, vector &skeletonData){ + map ikRelationships; - for(string line : meshData){ + for(string line : skeletonData){ int colonId = getCharId(line, ':'); string preColon = line.substr(0, colonId); string postColon = line.substr(colonId + 2); @@ -146,13 +145,13 @@ namespace vb01{ skeleton->addBone(bone, (Bone*)parent); bone->lookAt(zAxis, yAxis, parent); if(ikTarget != "-") - ikRelationships.push_back(preColon + " " + ikTarget); + ikRelationships.emplace(preColon, ikTarget); } - for(string ikRelationship : ikRelationships){ - int spaceId = getCharId(ikRelationship, ' '); - string targetBoneName = ikRelationship.substr(0, spaceId); - string ikTargetBoneName = ikRelationship.substr(spaceId + 1); + map::iterator it; + for(it = ikRelationships.begin(); it != ikRelationships.end(); it++){ + string targetBoneName = it->first; + string ikTargetBoneName = ikRelationships[targetBoneName]; skeleton->getBone(targetBoneName)->setIkTarget(skeleton->getBone(ikTargetBoneName)); } } @@ -218,7 +217,7 @@ namespace vb01{ } } - void VbModelReader::readSkeleton(vector &skeletonData){ + Skeleton* VbModelReader::readSkeleton(vector &skeletonData){ //vector skeletonMetaData(skeletonData.begin() + 1, skeletonData.begin() + 7); string name = skeletonData[0].substr(getCharId(skeletonData[0], ':') + 2, string::npos); string line = skeletonData[5]; @@ -235,27 +234,24 @@ namespace vb01{ int keyframeStartLine = animationStartLine + numAnimations + 1; Skeleton *skeleton = new Skeleton(name); - skeletons.push_back(skeleton); - vector *skeletonSubData = new vector(skeletonData.begin() + boneStartLine, skeletonData.begin() + boneStartLine + numBones); - createBones(skeleton, *skeletonSubData); - skeletonSubData->clear(); - delete skeletonSubData; + vector skeletonSubData = vector(skeletonData.begin() + boneStartLine, skeletonData.begin() + boneStartLine + numBones); + createBones(skeleton, skeletonSubData); + skeletonSubData.clear(); - skeletonSubData = new vector(skeletonData.begin() + animationStartLine, skeletonData.begin() + animationStartLine + numAnimations); - readAnimations(skeleton, *skeletonSubData); - skeletonSubData->clear(); - delete skeletonSubData; + skeletonSubData = vector(skeletonData.begin() + animationStartLine, skeletonData.begin() + animationStartLine + numAnimations); + readAnimations(skeleton, skeletonSubData); + skeletonSubData.clear(); - skeletonSubData = new vector(skeletonData.begin() + keyframeGroupStartLine, skeletonData.begin() + keyframeGroupStartLine + numKeyframeGroups); - readKeyframesGroups(skeleton, *skeletonSubData); - skeletonSubData->clear(); - delete skeletonSubData; + skeletonSubData = vector(skeletonData.begin() + keyframeGroupStartLine, skeletonData.begin() + keyframeGroupStartLine + numKeyframeGroups); + readKeyframesGroups(skeleton, skeletonSubData); + skeletonSubData.clear(); - skeletonSubData = new vector(skeletonData.begin() + keyframeGroupStartLine, skeletonData.end()); - readKeyframes(skeleton, *skeletonSubData); - skeletonSubData->clear(); - delete skeletonSubData; + skeletonSubData = vector(skeletonData.begin() + keyframeGroupStartLine, skeletonData.end()); + readKeyframes(skeleton, skeletonSubData); + skeletonSubData.clear(); + + return skeleton; } void VbModelReader::readVertices( @@ -319,7 +315,6 @@ namespace vb01{ } void VbModelReader::readVertexGroups(string *groups, vector &meshData, int numBones){ - groups = new string[numBones]; for(int i = 0; i < numBones; i++){ groups[i] = meshData[i]; } @@ -330,9 +325,7 @@ namespace vb01{ } } - void VbModelReader::readMeshes(vector &meshData){ - //readFile(path, meshData, startLine + 1, startLine + 8); - + Mesh* VbModelReader::readMeshes(vector &meshData){ string nameLine = meshData[0]; int nameLineColonId = getCharId(nameLine, ':'); string preColonNameLine = nameLine.substr(0, nameLineColonId); @@ -350,7 +343,7 @@ namespace vb01{ string parentLine = meshData[4]; int parentLineColonId = getCharId(parentLine, ':'); string parent = parentLine.substr(parentLineColonId + 2, string::npos); - relationships.push_back(postColonNameLine + " " + parent); + relationships.emplace(name, parent); const int numVertsPerFace = 3; int numVertices = atoi(data[0].c_str()); @@ -368,21 +361,21 @@ namespace vb01{ u32 *indices = new u32[numFaces * numVertsPerFace]; string *groups = new string[numBones]; - vector vertexData(meshData.begin() + vertexStartLine, meshData.begin() + vertexStartLine + numVertices); - readVertices(vertPos, vertNorm, vertWeights, vertexData, numBones); - vertexData.clear(); + vector meshSubData = vector(meshData.begin() + vertexStartLine, meshData.begin() + vertexStartLine + numVertices); + readVertices(vertPos, vertNorm, vertWeights, meshSubData, numBones); + meshSubData.clear(); - vector faceData(meshData.begin() + faceStartLine, meshData.begin() + faceStartLine + numFaces * numVertsPerFace); - readFaces(vertPos, vertNorm, vertWeights, faceData, numBones, vertices, indices); - faceData.clear(); + meshSubData = vector(meshData.begin() + faceStartLine, meshData.begin() + faceStartLine + numFaces * numVertsPerFace); + readFaces(vertPos, vertNorm, vertWeights, meshSubData, numBones, vertices, indices); + meshSubData.clear(); - vector vertexGroupData(meshData.begin() + vertexGroupStartLine, meshData.begin() + vertexGroupStartLine + numBones); - readVertexGroups(groups, vertexGroupData, numBones); - vertexGroupData.clear(); + meshSubData = vector(meshData.begin() + vertexGroupStartLine, meshData.begin() + vertexGroupStartLine + numBones); + readVertexGroups(groups, meshSubData, numBones); + meshSubData.clear(); - vector shapeKeyData(meshData.begin() + shapeKeyStartLine, meshData.begin() + shapeKeyStartLine + numShapes); + meshSubData = vector(meshData.begin() + shapeKeyStartLine, meshData.begin() + shapeKeyStartLine + numShapes); readShapeKeys(shapeKeyStartLine, numShapes); - shapeKeyData.clear(); + meshSubData.clear(); string skeletonLine = meshData[5]; int skeletonLineColonId = getCharId(skeletonLine, ':'); @@ -395,8 +388,14 @@ namespace vb01{ Mesh *mesh = new Mesh(vertices, indices, numFaces, groups, numBones, nullptr, numShapes, name); mesh->setSkeleton(skeleton); + return mesh; + } - Node *node = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, name); + void VbModelReader::buildMesh(vector &meshData){ + Mesh *mesh = readMeshes(meshData); + mesh->construct(); + + Node *node = new Node(Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK, mesh->getName()); node->attachMesh(mesh); nodes.push_back(node); } diff --git a/vbModelReader.h b/vbModelReader.h index 540aa88..b9a82f3 100644 --- a/vbModelReader.h +++ b/vbModelReader.h @@ -28,15 +28,16 @@ namespace vb01{ void readAnimations(Skeleton*, std::vector&); void readKeyframesGroups(Skeleton*, std::vector&); void readKeyframes(Skeleton*, std::vector&); - void readSkeleton(std::vector&); + Skeleton* readSkeleton(std::vector&); void readVertices(std::vector&, std::vector&, std::vector&, std::vector&, int); void readFaces(std::vector&, std::vector&, std::vector&, std::vector&, int, Mesh::Vertex*, u32*); void readVertexGroups(std::string*, std::vector&, int); void readShapeKeys(int, int); - void readMeshes(std::vector&); + void buildMesh(std::vector&); + Mesh* readMeshes(std::vector&); void readLights(std::vector&); - std::vector relationships; + std::map relationships; std::vector skeletons; std::vector meshes; std::vector nodes; diff --git a/vbModelReaderTest.cpp b/vbModelReaderTest.cpp index c18d180..72c2df5 100644 --- a/vbModelReaderTest.cpp +++ b/vbModelReaderTest.cpp @@ -1,5 +1,6 @@ #include "vbModelReaderTest.h" #include "vbModelReader.h" +#include "skeleton.h" using namespace std; @@ -19,35 +20,121 @@ namespace vb01{ } void VbModelReaderTest::setupSkeleton(){ + bones = vector({ + Bone("", "", Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(0, 0, 0), "", 0) + }); + skeletonParent = "-"; + + animations = vector({ + }); + + 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) + " 1 "); + 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: 1"); + skeletonData.push_back("animation: Action 3 bipod bipod.R bipod.L "); + skeletonData.push_back("bipod: 3 pos_x 3 pos_y 3 pos_z 3 rot_w 3 rot_x 3 rot_y 3 rot_z "); } void VbModelReaderTest::setupMesh(){ - meshData.push_back("MESH: mg42"); + meshName = "mg42"; + meshParent = "-"; + skeletonName = "MG42"; + + vertPos = vector({Vector3(0, 1, 2), Vector3(1, 1, 2), Vector3(2, 1, 2)}); + vertNorm = vector({Vector3(3, 4, 5), Vector3(3, 4, 5), Vector3(3, 4, 5)}); + vertUv = vector({Vector2(1, 1), Vector2(1, 0), Vector2(0, 0)}); + vertexGroups = vector({"clip", "trigger"}); + vertTan = vector({Vector3(1, 2, 3), Vector3(1, 2, 3), Vector3(1, 2, 3)}); + vertBiTan = vector({Vector3(3, 2, 1), Vector3(3, 2, 1), Vector3(3, 2, 1)}); + vertWeights = vector>({ + vector({1, 0.5}), + vector({1, 0.5}), + vector({1, 0.5}) + }); + + int numVerts = vertPos.size(); + int numFaces = numVerts / 3; + int numVertexGroups = vertexGroups.size(); + int numShapeKeys = 0; + + 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: -"); - meshData.push_back("skeleton: MG42"); - meshData.push_back("numElements: 3 1 2 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:"); - meshData.push_back("clip"); - meshData.push_back("trigger"); + for(string group : vertexGroups) + meshData.push_back(group); meshData.push_back("vertices:"); - meshData.push_back("0 1 2 3 4 5 1 0.5 "); - meshData.push_back("1 1 2 3 4 5 1 0.5 "); - meshData.push_back("2 1 2 3 4 5 1 0.5 "); + 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:"); - meshData.push_back("0 1 1 1 2 3 3 2 1"); - meshData.push_back("1 0 0 1 2 3 3 2 1"); - meshData.push_back("2 1 0 1 2 3 3 2 1"); + 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); + } } void VbModelReaderTest::testReadSkeletons(){ + //Skeleton *skeleton = modelReader->readSkeleton(skeletonData); } void VbModelReaderTest::testReadMeshes(){ - modelReader->readMeshes(meshData); - Mesh *mesh = modelReader->meshes[0]; - CPPUNIT_ASSERT(mesh->getName() == "mg42"); + 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]); + } } } diff --git a/vbModelReaderTest.h b/vbModelReaderTest.h index 8a2c8f9..4d53209 100644 --- a/vbModelReaderTest.h +++ b/vbModelReaderTest.h @@ -6,9 +6,15 @@ #include #include +#include "vector.h" +#include "animation.h" + namespace vb01{ class VbModelReader; + class VbModelReaderTest; + typedef VbModelReaderTest vbReader; + class VbModelReaderTest : public CppUnit::TestFixture{ CPPUNIT_TEST_SUITE(VbModelReaderTest); CPPUNIT_TEST(testReadSkeletons); @@ -27,9 +33,31 @@ namespace vb01{ 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; + }; + VbModelReader *modelReader = nullptr; + std::string meshName, skeletonName, meshParent, skeletonParent; + std::vector vertexGroups; + std::vector vertPos, vertNorm, vertTan, vertBiTan; + std::vector vertUv; std::vector skeletonData, meshData; - int numBones = 0; + std::vector bones; + std::vector> vertWeights; + std::vector animations; }; } diff --git a/vector.h b/vector.h index f980579..2c9665f 100755 --- a/vector.h +++ b/vector.h @@ -65,6 +65,8 @@ namespace vb01{ this->x = x; this->y = y; } + bool operator!=(const Vector2 &v){return x != v.x || y != v.y;} + bool operator==(const Vector2 &v){return x == v.x && y == v.y;} Vector2 operator-(const Vector2 &v){return Vector2(x - v.x, y - v.y);} Vector2 operator+(const Vector2 &v){return Vector2(x + v.x, y + v.y);} templateVector2 operator+(T s){return Vector2(x + s, y + s);}