From 146b267a7262bbc8983b22ebf303ef76d623b162 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Fri, 31 Jul 2020 16:25:01 +0300 Subject: [PATCH] beginning of a model reader --- model.cpp | 226 ----------------------------------------- model.h | 1 - modelReader.cpp | 265 ++++++++++++++++++++++++++++++++++++++++++++++++ modelReader.h | 21 ++++ script.py | 18 ++-- util.cpp | 43 +++++++- util.h | 10 +- 7 files changed, 347 insertions(+), 237 deletions(-) create mode 100644 modelReader.cpp create mode 100644 modelReader.h diff --git a/model.cpp b/model.cpp index d0fbd7a..1b71c9b 100755 --- a/model.cpp +++ b/model.cpp @@ -9,7 +9,6 @@ #include"animation.h" #include -#include #include #include #include @@ -146,211 +145,6 @@ namespace vb01{ continue; } - 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; - } - } - } - else{ - enum MeshStage{VERTICES,FACES,GROUPS,SHAPE_KEYS}; - - MeshStage meshStage; - - if(preColon=="vertices"){ - const int numData=4; - string data[numData]; - getLineData(postColon,data,numData); - numFaces=atoi(data[1].c_str()); - numGroups=atoi(data[2].c_str()); - vertices=new Mesh::Vertex[numFaces*numVertsPerFace]; - indices=new u32[numFaces*numVertsPerFace]; - 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 i=0;i 0){ - vert.boneIndices[boneIndex] = i; - vert.weights[boneIndex] = vertWeights[index * numBones + i]; - 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; - } - } - } } for(Mesh *mesh : meshes){ Node *meshNode=new Node(localPos,localRot,localScale); @@ -421,26 +215,6 @@ namespace vb01{ Node::update(); } - void Model::getLineData(string &line,string data[],int numData,int offset){ - int offsetComma=0,c1=0; - for(int i=0;i descendants; getDescendants(this,descendants); diff --git a/model.h b/model.h index b76ae8d..6be023f 100755 --- a/model.h +++ b/model.h @@ -29,7 +29,6 @@ namespace vb01{ void processMesh(aiMesh*, const aiScene*, Node*); // std::vector processTexture(aiMaterial*, Assimp::aiTextureType); void processMaterial(); - void getLineData(std::string&,std::string[],int,int=0); Material* material; bool castShadow=false,reflect=false,wireframe=false; diff --git a/modelReader.cpp b/modelReader.cpp new file mode 100644 index 0000000..f99dbfb --- /dev/null +++ b/modelReader.cpp @@ -0,0 +1,265 @@ +#include"modelReader.h" +#include +#include + +using namespace std; + +namespace vb01{ + ModelReader::ModelReader(string path){ + 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 new file mode 100644 index 0000000..31b0a6f --- /dev/null +++ b/modelReader.h @@ -0,0 +1,21 @@ +#ifndef MODEL_READER +#define MODEL_READER + +#include + +namespace vb01{ + class ModelReader{ + public: + ModelReader(std::string); + ~ModelReader(); + private: + void readSkeletons(int, int); + void readMeshes(int, int); + void readLights(int, int); + + std::string path; + }; +} + +#endif + diff --git a/script.py b/script.py index a89064b..0663335 100644 --- a/script.py +++ b/script.py @@ -2,7 +2,7 @@ import sys def exportData(ob): par=ob.parent - file.write(ob.type+": "+ob.name+"\n") + 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") @@ -89,7 +89,15 @@ def exportData(ob): #if mesh.shape_keys is not NoneType: #numShapeKeys=len(mesh.shape_keys[0].key_blocks)-1 - file.write("vertices: "+str(numVerts)+" "+str(numFaces)+" "+str(numGroups)+" "+str(numShapeKeys)+" \n") + + file.write("numElements: "+str(numVerts)+" "+str(numFaces)+" "+str(numGroups)+" "+str(numShapeKeys)+" \n") + + if numGroups>0: + file.write('groups:\n') + for group in ob.vertex_groups: + file.write(group.name+'\n') + + file.write("vertices:\n") print('Exporting vertices...\n') for vert in mesh.vertices: pos=vert.co @@ -116,10 +124,6 @@ def exportData(ob): file.write(str(vert)+" "+str(uv.x)+" "+str(uv.y)+" "+str(tan.x)+" "+str(tan.y)+" "+str(tan.z)+" "+str(bitan.x)+" "+str(bitan.y)+" "+str(bitan.z)+" \n") mesh.free_tangents() - if numGroups>0: - file.write('groups:\n') - for group in ob.vertex_groups: - file.write(group.name+'\n') if numShapeKeys>0: file.write('shapeKeys:\n') @@ -194,5 +198,5 @@ for s in selectedObjects: file=open(fl,"w") for ob in selectedObjects: exportData(ob) - file.write("\n") + file.write("}\n") file.close() diff --git a/util.cpp b/util.cpp index 33c2079..f143daa 100755 --- a/util.cpp +++ b/util.cpp @@ -1,5 +1,46 @@ #include"util.h" +#include + +using namespace std; namespace vb01{ - + void readFile(string path, vector &lines, int firstLine, int lastLine){ + string l; + std::ifstream inFile(path); + for(int i = 0; i < lastLine && getline(inFile,l); i++){ + if(i >= firstLine) + lines.push_back(l); + } + inFile.close(); + } + + void getLineData(string &line, string data[], int numData, int offset){ + int offsetComma = 0, c1 = 0; + for(int i = 0; i < line.length() && offsetComma < offset; i++) + if(line.c_str()[i] == ' '){ + c1 = i + 1; + offsetComma++; + } + int c2 = c1; + for(int i = 0; i < numData; i++){ + for(int j = c1; j < line.length(); j++) + if(line.c_str()[j] == ' '){ + c2 = j; + break; + } + data[i] = line.substr(c1, c2 - c1); + c2++; + c1 = c2; + } + } + + int getCharId(char ch){ + int charId = -1; + for(int i = 0; i < line.length(); i++) + if(line[i] == ch){ + colonId = i; + break; + } + return charId; + } } diff --git a/util.h b/util.h index 0b1b99f..d9c18c6 100755 --- a/util.h +++ b/util.h @@ -3,6 +3,8 @@ #include #include +#include +#include namespace vb01{ typedef char s8; @@ -15,9 +17,13 @@ namespace vb01{ typedef unsigned int u32; typedef unsigned long long u64; - static const float PI=4*atan(1); + static const float PI = 4 * atan(1); - inline s64 getTime(){return s64(std::chrono::system_clock::now().time_since_epoch()/std::chrono::milliseconds(1));} + void readFile(std::string, std::vector&, int = 0, int = -1); + void getLineData(std::string&, std::string[], int, int = 0); + int getCharId(char); + + inline s64 getTime(){return s64(std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1));} } #endif