#include"model.h" #include"mesh.h" #include"material.h" #include"vector.h" #include"util.h" #include"bone.h" #include"root.h" #include"skeleton.h" #include"animation.h" #include #include #include #include #include #include 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; vector vertPos,vertNorm; const int numVertsPerFace=3; int numVertPos=0,numFaces=0,vertId=0,faceId=0,groupId=-1,groupVertId=0,numGroups=0,numShapeKeys=0; Mesh::Vertex *vertices; u32 *indices; Mesh::VertexGroup *groups=nullptr; Mesh::ShapeKey *shapeKeys=nullptr; while(getline(in,l)){ int colonId=-1; for(int i=0;igetBone(parName); if(!parent) parent=this; Bone *bone=new Bone(preColon); skeleton->addBone(bone,parent); bone->setPosition(parent->globalToLocalPosition(pos)); bone->lookAt(yAxis,zAxis,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"){ string data[2]; getLineData(postColon,data,2); numVertPos=atoi(data[0].c_str()); numFaces=atoi(data[1].c_str()); meshStage=VERTICES; continue; } else if(preColon=="faces"){ meshStage=FACES; vertices=new Mesh::Vertex[numFaces*numVertsPerFace]; indices=new u32[numFaces*numVertsPerFace]; continue; } else if(preColon=="groups"){ numGroups=atoi(postColon.c_str()); groups=new Mesh::VertexGroup[numGroups]; meshStage=GROUPS; continue; } else if(preColon=="shapeKeys"){ meshStage=SHAPE_KEYS; continue; } switch(meshStage){ { case VERTICES: int numData=6; string data[numData]; getLineData(l,data,numData); Vector3 vp=Vector3(atof(data[0].c_str()),atof(data[2].c_str()),-atof(data[1].c_str())); Vector3 vn=Vector3(atof(data[3].c_str()),atof(data[5].c_str()),-atof(data[4].c_str())); vertPos.push_back(vp); vertNorm.push_back(vn); break; } { case FACES: int numData=9; string data[numData]; getLineData(l,data,numData); u32 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.norm=vertNorm[index]; vert.uv=uv; vert.tan=tan; vert.biTan=biTan; vertices[vertId]=vert; indices[vertId]=vertId; vertId++; break; } { case GROUPS: if(l==""){ meshes.push_back(new Mesh(vertices,indices,numFaces,groups,numGroups,shapeKeys,numShapeKeys,name)); break; } else if(colonId!=-1){ groupId++,groupVertId=0; int numVerts=atoi(postColon.c_str()); groups[groupId].numVertices=numVerts; groups[groupId].name=preColon; if(numVerts>0){ groups[groupId].vertices=new u32[numVerts]; groups[groupId].weights=new float[numVerts]; } } else{ int numData=2,vertId; float weight; string data[numData]; getLineData(l,data,numData); vertId=atoi(data[0].c_str()); weight=atof(data[1].c_str()); groups[groupId].vertices[groupVertId]=vertId; groups[groupId].weights[groupVertId]=weight; groupVertId++; } 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); meshNode->attachMesh(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(){ delete children[0]->getMesh(0)->getMaterial(); vector descendants; getDescendants(this,descendants); for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setMaterial(nullptr); while(!children.empty()){ Node *c=children[children.size()-1]; dettachChild(c); delete c; } } void Model::update(){ 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); for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setMaterial(mat); } void Model::setCastShadow(bool castShadow){ vector descendants; getDescendants(this,descendants); for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setCastShadow(castShadow); this->castShadow=castShadow; } void Model::setReflect(bool reflect){ vector descendants; getDescendants(this,descendants); for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setReflect(reflect); this->reflect=reflect; } void Model::setWireframe(bool wirefame){ vector descendants; getDescendants(this,descendants); for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setWireframe(wirefame); this->wireframe=wireframe; } }