From dba02e794428c8ed56a0477ebe74ebb0db980c4a Mon Sep 17 00:00:00 2001 From: devZoGok Date: Thu, 13 Aug 2020 19:50:41 +0300 Subject: [PATCH] readable models via the new reader (verts, faces, bones...) --- CMakeLists.txt | 3 +- mesh.cpp | 2 + model.cpp | 185 ++------------------------------- model.h | 7 +- modelReader.cpp | 255 +--------------------------------------------- modelReader.h | 10 +- script.py | 12 ++- skeleton.cpp | 3 + skeleton.h | 1 + util.cpp | 21 +++- util.h | 2 +- vbModelReader.cpp | 12 +-- vbModelReader.h | 9 +- 13 files changed, 62 insertions(+), 460 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eda3c95..0748dc9 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,10 +14,11 @@ set(gui text.cpp rectangle.cpp) set(utils util.cpp) set(math quaternion.cpp vector.cpp matrix.cpp ray.cpp) set(render waterPlane.cpp particleEmitter.cpp camera.cpp light.cpp material.cpp mesh.cpp model.cpp node.cpp quad.cpp box.cpp root.cpp shader.cpp texture.cpp) +set(model modelReader.cpp assimpModelReader.cpp vbModelReader.cpp) set(anim animationChannel.cpp animation.cpp) set(armature skeleton.cpp bone.cpp) -add_library(vb01 SHARED main.cpp ${render} ${math} ${utils} ${gui} ${armature} ${anim}) +add_library(vb01 SHARED main.cpp ${render} ${math} ${model} ${utils} ${gui} ${armature} ${anim}) target_link_libraries(vb01 glfw) target_link_libraries(vb01 glad) target_link_libraries(vb01 assimp) diff --git a/mesh.cpp b/mesh.cpp index 69e0f91..82a2980 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -175,6 +175,8 @@ namespace vb01{ shader->setMat4(model,"model"); if(skeleton){ + skeleton->update(); + shader->editShader(Shader::VERTEX_SHADER,2,"const int numBones="+to_string(skeleton->getNumBones())+";"); shader->editShader(Shader::VERTEX_SHADER,3,"const int numVertGroups="+to_string(numVertexGroups)+";"); diff --git a/model.cpp b/model.cpp index 1b71c9b..4ec9666 100755 --- a/model.cpp +++ b/model.cpp @@ -7,6 +7,8 @@ #include"root.h" #include"skeleton.h" #include"animation.h" +#include"vbModelReader.h" +#include"assimpModelReader.h" #include #include @@ -18,181 +20,14 @@ using namespace std; using namespace Assimp; namespace vb01{ - void Model::processNode(aiNode *node, const aiScene *scene, Node *currentNode){ - for(int i=0;imNumMeshes;i++){ - aiMesh *mesh=scene->mMeshes[node->mMeshes[i]]; - processMesh(mesh,scene,currentNode); - } - for(int i=0;imNumChildren;i++){ - Node *childNode=new Node(); - currentNode->attachChild(childNode); - processNode(node->mChildren[i],scene,childNode); - } - } - - void Model::processMesh(aiMesh *mesh, const aiScene *scene, Node *currentNode){ - const int numTris=mesh->mNumFaces; - Mesh::Vertex *vertices=new Mesh::Vertex[3*numTris]; - u32 *indices=new u32[3*numTris]; - for(int i=0;i<3*numTris;i++){ - Mesh::Vertex v; - v.pos.x=mesh->mVertices[i].x; - v.pos.y=mesh->mVertices[i].y; - v.pos.z=mesh->mVertices[i].z; - - v.norm.x=mesh->mNormals[i].x; - v.norm.y=mesh->mNormals[i].y; - v.norm.z=mesh->mNormals[i].z; - - v.tan.x=mesh->mTangents[i].x; - v.tan.y=mesh->mTangents[i].y; - v.tan.z=mesh->mTangents[i].z; - - v.biTan.x=mesh->mBitangents[i].x; - v.biTan.y=mesh->mBitangents[i].y; - v.biTan.z=mesh->mBitangents[i].z; - - if(mesh->mTextureCoords[0]){ - v.uv.x=mesh->mTextureCoords[0][i].x; - v.uv.y=mesh->mTextureCoords[0][i].y; - } - else - v.uv=Vector2::VEC_ZERO; - vertices[i]=v; - } - for(int i=0;imFaces[i].mNumIndices; - for(int j=0;jmFaces[i].mIndices[j]; - } - } - //if(mesh->mMaterialIndex>=0){ - // aiMaterial *material=scene->mMaterial[mesh->mMaterialIndex]; - //} - currentNode->attachMesh(new Mesh(vertices,indices,numTris)); - } - - Model::Model(string path,bool b) : Node(){ - Node *rootNode=Root::getSingleton()->getRootNode(); - if(b){ - Importer importer; - const aiScene *scene=importer.ReadFile(path,aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenNormals | aiProcess_CalcTangentSpace); - if(!scene||scene->mFlags&AI_SCENE_FLAGS_INCOMPLETE||!scene->mRootNode){ - cout<<"Failed to load model:"<mRootNode,scene,this); - } - else{ - enum Stage{ARMATURE,MESH}; - - Stage stage; - ifstream in(path); - string l,name=""; - Vector3 localPos=Vector3::VEC_ZERO,localScale=Vector3::VEC_IJK; - Quaternion localRot=Quaternion::QUAT_W; - vector childrenChain; - vector skeletons; - vector meshes; - vector lights; - vector nodes; - - Skeleton *skeleton=nullptr; - string animName=""; - Bone *animBone=nullptr; - - const int numVertsPerFace=3; - int numFaces=0,vertId=0,faceId=0,groupId=0,groupVertId=0,numGroups=0,numShapeKeys=0,numBones=0; - Mesh::Vertex *vertices; - u32 *indices; - vector vertPos,vertNorm; - vector vertWeights; - string *groups=nullptr,*shapeKeys=nullptr; - - while(getline(in,l)){ - int colonId=-1; - for(int i=0;iattachMesh(mesh); - nodes.push_back(meshNode); - for(string line : childrenChain){ - int spaceId=-1; - for(int i=0;igetName()==childName){ - for(Skeleton *sk : skeletons){ - if(sk->getName()==parentName) - mesh->setSkeleton(sk); - } - } - } - } - for(Light *light : lights){ - Node *lightNode=new Node(localPos,localRot,localScale); - lightNode->addLight(light); - nodes.push_back(lightNode); - } - for(string line : childrenChain){ - int spaceId=-1; - for(int i=0;igetMesh(0); - Skeleton *sk0=m0->getSkeleton(); - if(m0->getName()==childName||(sk0&&sk0->getName()==childName)){ - childNode=nodes[i]; - for(int j=0;jgetMesh(0); - Skeleton *sk1=m1->getSkeleton(); - if(m1->getName()==parentName||(sk1&&sk1->getName()==parentName)) - parentNode=nodes[j]; - } - } - } - if(childNode!=parentNode) - parentNode->attachChild(childNode); - } - } + Model::Model(string path) : Node(){ + int dotId = getCharId(path, '.', true); + string extension = path.substr(dotId + 1, string::npos); + ModelReader *modelReader = nullptr; + if(extension == "vb") + modelReader = new VbModelReader(this, path); + else + modelReader = new AssimpModelReader(this, path); } Model::~Model(){ diff --git a/model.h b/model.h index 6be023f..44e27aa 100755 --- a/model.h +++ b/model.h @@ -17,7 +17,7 @@ namespace vb01{ class Model : public Node{ public: - Model(std::string,bool=true); + Model(std::string); ~Model(); void update(); void setMaterial(Material*); @@ -25,11 +25,6 @@ namespace vb01{ void setReflect(bool); void setWireframe(bool); private: - void processNode(aiNode*, const aiScene*, Node*); - void processMesh(aiMesh*, const aiScene*, Node*); -// std::vector processTexture(aiMaterial*, Assimp::aiTextureType); - void processMaterial(); - Material* material; bool castShadow=false,reflect=false,wireframe=false; }; diff --git a/modelReader.cpp b/modelReader.cpp index f99dbfb..ba01250 100644 --- a/modelReader.cpp +++ b/modelReader.cpp @@ -1,265 +1,16 @@ #include"modelReader.h" +#include"model.h" #include #include using namespace std; namespace vb01{ - ModelReader::ModelReader(string path){ + ModelReader::ModelReader(Model *model, string path){ + this->model = model; this->path = path; - - const string meshType = "MESH", skeletonType = "ARMATURE", lightType = "LIGHT"; - vector meshBracketIds, skeletonBracketIds, lightBracketIds; - int curBracketId = -1; - string line; - ifstream file(path); - - for(int i = 0; getline(file, line); i++){ - if(line[0] == '{' || line[0] == '}') - curBracketId = i; - else{ - int colonId = getCharId(':'); - - string type = line.substr(0, colonId - 1); - if(type == meshType) - meshBracketIds.push_back(curBracketId); - else if(type == skeletonType) - skeletonBracketIds.push_back(curBracketId); - else if(type == lightType) - lightBracketIds.push_back(curBracketId); - } - } - - file.close(); - - for(int i = 0; i < meshBracketIds.size() / 2; i++) - readMeshes(meshBracketIds[i * 2], meshBracketIds[i * 2 + 1]); - for(int i = 0; i < skeletonBracketIds.size() / 2; i++) - readSkeletons(skeletonBracketIds[i * 2], skeletonBracketIds[i * 2 + 1]); - for(int i = 0; i < lightBracketIds.size() / 2; i++) - readLights(lightBracketIds[i * 2], lightBracketIds[i * 2 + 1]); } ModelReader::~ModelReader(){ } - - void ModelReader::readSkeletons(int startLine, int endLine){ - /* - if(stage==ARMATURE){ - enum ArmatureStage{BONES,ANIMATIONS}; - - ArmatureStage armatureStage; - - if(preColon=="bones"){ - numBones=atoi(postColon.c_str()); - armatureStage=BONES; - continue; - } - else if(preColon=="animations"){ - armatureStage=ANIMATIONS; - continue; - } - - switch(armatureStage){ - case BONES: - { - int numData=11; - 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())); - Vector3 yAxis=Vector3(atof(data[8].c_str()),atof(data[9].c_str()),atof(data[10].c_str())); - Vector3 zAxis=xAxis.cross(yAxis); - Vector3 pos = head; - - string parName=string(data[0].c_str()); - Node *parent=skeleton->getBone(parName); - if(!parent){ - parent=this; - swap(xAxis.y,xAxis.z); - xAxis.z=-xAxis.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); - skeleton->addBone(bone,(Bone*)parent); - bone->lookAt(zAxis,yAxis,parent); - - break; - } - case ANIMATIONS: - { - if(preColon=="animationName"){ - animName=postColon; - skeleton->addAnimation(new Animation(animName)); - continue; - } - Bone *b=skeleton->getBone(preColon); - if(b){ - animBone=b; - Animation *anim=skeleton->getAnimation(animName); - Animation::KeyframeGroup *group=anim->getKeyframeGroup(animBone); - if(!group){ - Animation::KeyframeGroup kg; - kg.bone=animBone; - anim->addKeyframeGroup(kg); - } - continue; - } - else{ - Animation::KeyframeGroup::Keyframe::Type type; - Animation::KeyframeGroup::Keyframe::Interpolation interp; - if(preColon=="pos_x") - type=Animation::KeyframeGroup::Keyframe::Type::POS_X; - else if(preColon=="pos_y") - type=Animation::KeyframeGroup::Keyframe::Type::POS_Y; - else if(preColon=="pos_z") - type=Animation::KeyframeGroup::Keyframe::Type::POS_Z; - else if(preColon=="rot_w") - type=Animation::KeyframeGroup::Keyframe::Type::ROT_W; - else if(preColon=="rot_x") - type=Animation::KeyframeGroup::Keyframe::Type::ROT_X; - else if(preColon=="rot_y") - type=Animation::KeyframeGroup::Keyframe::Type::ROT_Y; - else if(preColon=="rot_z") - type=Animation::KeyframeGroup::Keyframe::Type::ROT_Z; - else if(l==""){ - skeletons.push_back(skeleton); - break; - } - else{ - int numData=3; - string data[numData]; - - getLineData(l,data,numData); - - float value=atof(data[0].c_str()),frame=atoi(data[1].c_str()); - interp=(Animation::KeyframeGroup::Keyframe::Interpolation)atoi(data[2].c_str()); - - Animation::KeyframeGroup::Keyframe keyframe; - keyframe.type=type; - keyframe.interpolation=interp; - keyframe.value=value; - keyframe.frame=frame; - skeleton->getAnimation(animName)->getKeyframeGroup(animBone)->keyframes.push_back(keyframe); - - } - } - break; - } - } - } - */ - } - - void ModelReader::readMeshes(int startLine, int endLine){ - vector meshData; - readFile(path, meshData, startLine - 4, endLine - 1); - for(String line : meshData){ - int colonId = getCharId(':'); - string preColonSubstring = line.substr(0, colonId - 1); - string postColonSubstring = line.substr(colonId + 1, string::npos); - } - - numFaces=atoi(data[1].c_str()); - numGroups=atoi(data[2].c_str()); - vertices=new Mesh::Vertex[numFaces*numVertsPerFace]; - indices=new u32[numFaces*numVertsPerFace]; - - if(preColon=="vertices"){ - const int numData=4; - string data[numData]; - getLineData(postColon,data,numData); - meshStage=VERTICES; - continue; - } - else if(preColon=="faces"){ - meshStage=FACES; - continue; - } - else if(preColon=="groups"){ - groups=new string[numGroups]; - meshStage=GROUPS; - continue; - } - else if(preColon=="shapeKeys"){ - meshStage=SHAPE_KEYS; - continue; - } - switch(meshStage){ - { - case VERTICES: - int numData = 6 + numBones; - string data[numData]; - getLineData(l,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); - for(int j=0;j 0){ - vert.boneIndices[boneIndex] = j; - vert.weights[boneIndex] = vertWeights[index * numBones + j]; - boneIndex++; - } - } - indices[vertId]=vertId; - vertices[vertId]=vert; - - vertId++; - break; - } - { - case GROUPS: - if(l==""){ - meshes.push_back(new Mesh(vertices,indices,numFaces,groups,numGroups,shapeKeys,numShapeKeys,name)); - break; - } - else{ - groups[groupId]=l; - groupId++; - } - break; - } - { - case SHAPE_KEYS: - if(l==""){ - meshes.push_back(new Mesh(vertices,indices,numFaces,groups,numGroups,shapeKeys,numShapeKeys,name)); - break; - } - break; - } - } - } - - void ModelReader::readLights(int startLine, int endLine){ - - } } diff --git a/modelReader.h b/modelReader.h index 31b0a6f..35e163a 100644 --- a/modelReader.h +++ b/modelReader.h @@ -2,17 +2,15 @@ #define MODEL_READER #include +#include"model.h" namespace vb01{ class ModelReader{ public: - ModelReader(std::string); + protected: + ModelReader(Model*, std::string); ~ModelReader(); - private: - void readSkeletons(int, int); - void readMeshes(int, int); - void readLights(int, int); - + Model *model = nullptr; std::string path; }; } diff --git a/script.py b/script.py index 0663335..be8ae35 100644 --- a/script.py +++ b/script.py @@ -1,14 +1,20 @@ import sys def exportData(ob): - par=ob.parent + par = ob.parent + if(par is not None and par.type == 'ARMATURE'): + while(par is not None): + par = par.parent + file.write('{\n' + ob.type+": "+ob.name+"\n") file.write("pos: "+str(ob.location.x)+" "+str(ob.location.y)+" "+str(ob.location.z)+"\n") file.write("rot: "+str(ob.rotation_quaternion.w)+" "+str(ob.rotation_quaternion.x)+" "+str(ob.rotation_quaternion.y)+" "+str(-ob.rotation_quaternion.z)+"\n") file.write("scale: "+str(ob.scale.x)+" "+str(ob.scale.y)+" "+str(ob.scale.z)+"\n") file.write("parent: "+('-' if par is None else par.name)+"\n") if(ob.type=="ARMATURE"): - file.write("bones: "+str(len(ob.data.bones))) + numAnims=len(ob.animation_data.nla_tracks[0].strips) + file.write("bones: "+str(len(ob.data.bones)) + ' ' + str(numAnims) + ' ') + for bone in ob.data.bones: head=bone.head tail=bone.tail @@ -16,7 +22,6 @@ def exportData(ob): yAxis=bone.y_axis file.write("\n"+bone.name+": "+('None' if bone.parent is None else bone.parent.name)+" "+str(bone.length)+" "+str(head.x)+" "+str(head.y)+" "+str(head.z)+" "+str(xAxis.x)+" "+str(xAxis.y)+" "+str(xAxis.z)+" "+str(yAxis.x)+" "+str(yAxis.y)+" "+str(yAxis.z)+" ") - numAnims=len(ob.animation_data.nla_tracks[0].strips) if numAnims>0: file.write("\nanimations: "+str(numAnims)) for nlaStrip in ob.animation_data.nla_tracks[0].strips: @@ -80,6 +85,7 @@ def exportData(ob): file.write(str(keyframe.handle_right_type)+" "+str(keyframe.handle_right.x)+" "+str(keyframe.handle_right.y)) file.write("\n") elif(ob.type=="MESH"): + file.write('skeleton: ' + ob.modifiers['Armature'].object.name + '\n') mesh=ob.data numFaces=len(mesh.polygons) diff --git a/skeleton.cpp b/skeleton.cpp index 49f52b4..eadfa4a 100644 --- a/skeleton.cpp +++ b/skeleton.cpp @@ -9,6 +9,9 @@ namespace vb01{ this->name=name; } + void Skeleton::update(){ + } + void Skeleton::addBone(Bone *bone, Bone *parent){ parent->attachChild(bone); bone->setSkeleton(this); diff --git a/skeleton.h b/skeleton.h index 728794b..37366db 100644 --- a/skeleton.h +++ b/skeleton.h @@ -11,6 +11,7 @@ namespace vb01{ class Skeleton{ public: Skeleton(std::string=""); + void update(); void addBone(Bone*,Bone*); Bone* getBone(std::string); Animation* getAnimation(std::string); diff --git a/util.cpp b/util.cpp index f143daa..6b902d7 100755 --- a/util.cpp +++ b/util.cpp @@ -34,13 +34,24 @@ namespace vb01{ } } - int getCharId(char ch){ + int getCharId(string line, char ch, bool reverse){ int charId = -1; - for(int i = 0; i < line.length(); i++) - if(line[i] == ch){ - colonId = i; - break; + if(!reverse){ + for(int i = 0; i < line.length(); i++){ + if(line[i] == ch){ + charId = i; + break; + } } + } + else{ + for(int i = line.length() - 1; i >= 0; i--){ + if(line[i] == ch){ + charId = i; + break; + } + } + } return charId; } } diff --git a/util.h b/util.h index d9c18c6..fcde55c 100755 --- a/util.h +++ b/util.h @@ -21,7 +21,7 @@ namespace vb01{ void readFile(std::string, std::vector&, int = 0, int = -1); void getLineData(std::string&, std::string[], int, int = 0); - int getCharId(char); + int getCharId(std::string, char, bool = false); inline s64 getTime(){return s64(std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1));} } diff --git a/vbModelReader.cpp b/vbModelReader.cpp index cbb1272..b38cf10 100644 --- a/vbModelReader.cpp +++ b/vbModelReader.cpp @@ -76,14 +76,14 @@ namespace vb01{ void VbModelReader::readSkeletons(int startLine, int endLine){ vector meshData; readFile(path, meshData, startLine + 1, startLine + 7); - string line = meshData[5]; string name = meshData[0].substr(getCharId(meshData[0], ':') + 2, string::npos); + string line = meshData[5]; string data[3]; getLineData(line, data, 3); int numBones = atoi(data[1].c_str()); int numAnimations = atoi(data[2].c_str()); - int boneStartLine = startLine + 8; + int boneStartLine = startLine + 7; int animationStartLine = boneStartLine + numBones + 1; Skeleton *skeleton = new Skeleton(name); @@ -254,7 +254,7 @@ namespace vb01{ } meshData.clear(); - readFile(path, meshData, faceStartLine, faceStartLine + numFaces); + readFile(path, meshData, faceStartLine, faceStartLine + numFaces * numVertsPerFace); int i = 0; for(string line : meshData){ int numData = 9; @@ -281,10 +281,8 @@ namespace vb01{ } } - vertices[i * numVertsPerFace] = vert; - indices[i * numVertsPerFace] = i * numVertsPerFace; - for(int j = 0; j < numVertsPerFace; j++){ - } + vertices[i] = vert; + indices[i] = i; i++; } diff --git a/vbModelReader.h b/vbModelReader.h index 0061e11..5cc4b7e 100644 --- a/vbModelReader.h +++ b/vbModelReader.h @@ -1,11 +1,13 @@ -#ifndef MODEL_READER -#define MODEL_READER +#ifndef VB_MODEL_READER +#define VB_MODEL_READER -#include #include"modelReader.h" +#include +#include namespace vb01{ class Model; + class Node; class Mesh; class Skeleton; @@ -18,7 +20,6 @@ namespace vb01{ void readMeshes(int, int); void readLights(int, int); - std::string path; std::vector relationships; std::vector skeletons; std::vector meshes;