From 7e1575d690ed319ac5f79bba2ab19a516e1a5b84 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Wed, 5 Feb 2020 09:33:59 +0200 Subject: [PATCH] improved particle emitters --- CMakeLists.txt | 3 +- bone.cpp | 5 ++ bone.h | 14 +++++ gui.vert | 8 +-- mesh.cpp | 6 +- mesh.h | 9 +++ model.cpp | 136 +++++++++++++++++++++++++++++++++++++++++++- model.h | 2 +- particle.frag | 1 + particle.vert | 9 ++- particleEmitter.cpp | 18 ++++-- particleEmitter.h | 4 +- ray.cpp | 11 ++-- root.cpp | 55 +++++++++--------- script.py | 48 ++++++++++++++++ skeleton.cpp | 5 ++ skeleton.h | 12 ++++ 17 files changed, 295 insertions(+), 51 deletions(-) create mode 100644 bone.cpp create mode 100644 bone.h create mode 100644 script.py create mode 100644 skeleton.cpp create mode 100644 skeleton.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c1ecc17..ac14b28 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,8 +14,9 @@ set(gui text.cpp rectangle.cpp) set(utils util.cpp) set(math quaternion.cpp vector.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(armature skeleton.cpp bone.cpp) -add_library(vb01 SHARED main.cpp ${render} ${math} ${utils} ${gui}) +add_library(vb01 SHARED main.cpp ${render} ${math} ${utils} ${gui} ${armature}) target_link_libraries(vb01 glfw) target_link_libraries(vb01 glad) target_link_libraries(vb01 assimp) diff --git a/bone.cpp b/bone.cpp new file mode 100644 index 0000000..4cd4fe4 --- /dev/null +++ b/bone.cpp @@ -0,0 +1,5 @@ +#include"bone.h" + +namespace vb01{ + Bone::Bone() : Node(){} +} diff --git a/bone.h b/bone.h new file mode 100644 index 0000000..40d37ec --- /dev/null +++ b/bone.h @@ -0,0 +1,14 @@ +#ifndef BONE_H +#define BONE_H + +#include"node.h" + +namespace vb01{ + class Bone : public Node{ + public: + Bone(); + private: + }; +} + +#endif diff --git a/gui.vert b/gui.vert index 7312e2e..b86ecc6 100755 --- a/gui.vert +++ b/gui.vert @@ -9,9 +9,9 @@ uniform vec2 screen; uniform vec3 pos; void main(){ - float x,y; - x=(aVert.x+pos.x-screen.x*.5)/(screen.x*.5); - y=(screen.y*.5-(aVert.y+pos.y))/(screen.y*.5); - gl_Position=vec4(x,y,pos.z+aVert.z,1); + float x,y; + x=(aVert.x+pos.x-screen.x*.5)/(screen.x*.5); + y=(screen.y*.5-(aVert.y+pos.y))/(screen.y*.5); + gl_Position=vec4(x,y,pos.z+aVert.z,1); texCoords=aTexCoords; } diff --git a/mesh.cpp b/mesh.cpp index 1237781..bc82459 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -1,6 +1,7 @@ #include"root.h" #include"node.h" #include"mesh.h" +#include"skeleton.h" #include #include #include @@ -90,7 +91,8 @@ namespace vb01{ } Vector3 rotAxis=orient.norm().getAxis(); - if(rotAxis==Vector3::VEC_ZERO)rotAxis=Vector3::VEC_I; + if(rotAxis==Vector3::VEC_ZERO) + rotAxis=Vector3::VEC_I; mat4 model=translate(mat4(1.),vec3(pos.x,pos.y,pos.z)); model=rotate(model,orient.norm().getAngle(),vec3(rotAxis.x,rotAxis.y,rotAxis.z)); model=glm::scale(model,vec3(scale.x,scale.y,scale.z)); @@ -104,6 +106,8 @@ namespace vb01{ shader->setMat4(proj,"proj"); shader->setVec3(camPos,"camPos"); shader->setMat4(model,"model"); + if(skeleton){ + } if(material->getType()==Material::MATERIAL_GUI){ shader->setVec2(Vector2((float)width,(float)height),"screen"); if(node) diff --git a/mesh.h b/mesh.h index ed2bae8..e4acfb1 100755 --- a/mesh.h +++ b/mesh.h @@ -9,6 +9,7 @@ namespace vb01{ class Node; + class Skeleton; class Mesh{ public: @@ -16,6 +17,12 @@ namespace vb01{ Vector3 pos,norm; Vector2 texCoords; }; + struct VertexGroup{ + int numVertices=0; + Vertex **vertices=nullptr; + float *weights; + std::string name; + }; Mesh(Vertex*,unsigned int*,int); ~Mesh(); @@ -36,12 +43,14 @@ namespace vb01{ Node *node=nullptr; std::vector meshes; std::string name=""; + Skeleton *skeleton=nullptr; protected: Mesh(); void construct(); bool staticVerts=true,castShadow=false; Vertex *vertices; + VertexGroup groups; unsigned int *indices,VAO,VBO,EBO; int numTris; }; diff --git a/model.cpp b/model.cpp index 1500734..9165de0 100755 --- a/model.cpp +++ b/model.cpp @@ -8,6 +8,7 @@ #include #include #include +#include using namespace std; using namespace Assimp; @@ -59,7 +60,8 @@ namespace vb01{ currentNode->attachMesh(new Mesh(vertices,indices,numTris)); } - Model::Model(string path) : Node(){ + Model::Model(string path,bool b) : Node(){ + if(b){ Importer importer; const aiScene *scene=importer.ReadFile(path,aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenNormals); if(!scene||scene->mFlags&AI_SCENE_FLAGS_INCOMPLETE||!scene->mRootNode){ @@ -67,6 +69,133 @@ namespace vb01{ exit(-1); } processNode(scene->mRootNode,scene,this); + } + else{ + int numTris,numVerts,numGroups,v=0,u=0,vg=0,b=0; + Mesh::Vertex *vertices; + Mesh::VertexGroup *groups=new Mesh::VertexGroup[5]; + unsigned int *indices; + Vector3 *pos,*norm; + + ifstream in(path); + string l; + bool verts=false,uv=false,vertexGroups=false,bones=false; + + while(getline(in,l)){ + if(l.substr(0,8)=="numFaces"){ + numTris=atoi(l.substr(9,string::npos).c_str()); + vertices=new Mesh::Vertex[numTris*3]; + indices=new unsigned int[numTris*3]; + } + else if(l.substr(0,11)=="numVertices"){ + numVerts=atoi(l.substr(12,string::npos).c_str()); + pos=new Vector3[numVerts]; + norm=new Vector3[numVerts]; + } + else if(l.substr(0,9)=="numGroups"){ + numGroups=atoi(l.substr(10,string::npos).c_str()); + groups=new Mesh::VertexGroup[numGroups]; + } + if(l=="vertices:"){ + verts=true; + continue; + } + else if(l=="uv:"){ + verts=false; + uv=true; + continue; + } + else if(l=="groups:"){ + uv=false; + vertexGroups=true; + continue; + } + else if(l=="bones:"){ + vertexGroups=false; + bones=true; + continue; + } + + if(verts||uv||vertexGroups||bones){ + int numCoords=1; + if(verts)numCoords=6; + else if(uv)numCoords=3; + else if(vg)numCoords=3; + else if(groups)numCoords=1; + + int nextSpace=0; + int *spaceIds=new int[numCoords-1]; + for(int i=0;iattachMesh(new Mesh(vertices,indices,numTris)); + } } Model::~Model(){} @@ -76,10 +205,11 @@ namespace vb01{ } void Model::setMaterial(Material *mat){ - for(Node *node : children) + vector descendants; + getDescendants(this,descendants); + for(Node *node : descendants) for(Mesh *mesh : node->getMeshes()) mesh->setMaterial(mat); - this->material=mat; } void Model::setCastShadow(bool castShadow){ diff --git a/model.h b/model.h index dfbc7c5..e322066 100755 --- a/model.h +++ b/model.h @@ -17,7 +17,7 @@ namespace vb01{ class Model : public Node{ public: - Model(std::string); + Model(std::string,bool=true); ~Model(); void update(); void setMaterial(Material*); diff --git a/particle.frag b/particle.frag index ff8de73..510dd0b 100755 --- a/particle.frag +++ b/particle.frag @@ -12,5 +12,6 @@ uniform vec4 color[100]; void main(){ float alpha=texture(tex,texCoords).x; vec4 c=color[id]; + //FragColor=vec4(1,0,0,1); FragColor=vec4(c.x,c.y,c.z,c.w*alpha); } diff --git a/particle.vert b/particle.vert index 9c3e76e..b978d45 100755 --- a/particle.vert +++ b/particle.vert @@ -13,10 +13,13 @@ uniform mat4 model[100]; uniform vec2 size[100]; void main(){ - vec3 camLeft=-vec3(view[0][0],view[1][0],view[2][0]); - vec3 camUp=vec3(view[1][0],view[2][0],view[3][0]); + vec3 camLeft=vec3(view[0][0],view[1][0],view[2][0]); + vec3 camUp=vec3(view[0][1],view[1][1],view[2][1]); + id=gl_InstanceID; vec2 s=size[gl_InstanceID]; - gl_Position=proj*view*model[gl_InstanceID]*vec4(camLeft*s.x*aPos.x+camUp*s.y*aPos.y+camDir*aPos.z,1); + vec3 v=camLeft*s.x*aPos.x+camUp*s.y*aPos.y; + gl_Position=proj*view*model[gl_InstanceID]*vec4(v,1); + //gl_Position=proj*view*model[gl_InstanceID]*vec4(s.x*aPos.x,s.y*aPos.y,aPos.z,1); texCoords=aTexCoords; } diff --git a/particleEmitter.cpp b/particleEmitter.cpp index bf9b5ca..f1b83bf 100755 --- a/particleEmitter.cpp +++ b/particleEmitter.cpp @@ -79,7 +79,7 @@ namespace vb01{ float fov=cam->getFov(),width=root->getWidth(),height=root->getHeight(); float nearPlane=cam->getNearPlane(),farPlane=cam->getFarPlane(); Vector3 pos=node->getPosition(); - Vector3 camDir=cam->getDirection(),up=cam->getUp(),camPos=cam->getPosition(); + Vector3 camDir=cam->getDirection(),up=cam->getUp(),left=cam->getLeft(),camPos=cam->getPosition(); mat4 view=lookAt(vec3(camPos.x,camPos.y,camPos.z),vec3(camPos.x+camDir.x,camPos.y+camDir.y,camPos.z+camDir.z),vec3(up.x,up.y,up.z)); mat4 proj=perspective(radians(fov),width/height,nearPlane,farPlane); @@ -94,12 +94,14 @@ namespace vb01{ if(getTime()-particles[i].time>=particles[i].timeToLive){ particles[i].time=getTime(); float factor=(float)(rand()%100)/100; - float spreadX=(float)(rand()%360)/180*PI,spreadY=(float)(rand()%360)/180*PI; - dir=Vector3(cos(abs(spreadX)>spread?spread:spreadX),sin(abs(spreadY)>spread?spread:spreadY),0); + float s1=float(rand()%(int)spread)/180*PI,s2=float(rand()%360)/180*PI; + Vector3 ra1=(Vector3(0,1,0).cross(dir)).norm(),ra2=dir.norm(); + dir=Quaternion(s1,ra1)*dir; + dir=Quaternion(s2,ra2)*dir; particles[i].timeToLive=s64(1000*((highLife-lowLife)*factor+lowLife)); - particles[i].mat=translate(mat4(1.f),vec3(dir.x,dir.y,dir.z)); + particles[i].mat=mat4(1.f); } - dir=dir.norm()*direction.getLengthSq(); + particles[i].dir=dir.norm()*direction.getLengthSq(); float lifePercentage=(float)(getTime()-particles[i].time)/particles[i].timeToLive; particles[i].color=startColor+(endColor-startColor)*lifePercentage; particles[i].size=startSize+(endSize-startSize)*lifePercentage; @@ -127,4 +129,10 @@ namespace vb01{ glBindVertexArray(VAO); glDrawElementsInstanced(GL_TRIANGLES,6,GL_UNSIGNED_INT,0,numParticles); } + + void ParticleEmitter::setDirection(Vector3 dir){ + this->direction=dir; + for(int i=0;iendSize=size;} inline void setStartColor(Vector4 color){this->startColor=color;} inline void setEndColor(Vector4 color){this->endColor=color;} + inline void setSpread(float s){this->spread=s;} + void setDirection(Vector3 dir); private: struct Vertex{ Vector3 pos; @@ -42,7 +44,7 @@ namespace vb01{ Vector2 startSize=Vector2::VEC_IJ,endSize=Vector2::VEC_IJ; Vector3 direction=Vector3(0,.1,0); Vector4 startColor,endColor; - float spread=0,lowLife=1,highLife=2; + float spread=1,lowLife=1,highLife=2; }; } diff --git a/ray.cpp b/ray.cpp index 6d2d7f0..5614a2e 100644 --- a/ray.cpp +++ b/ray.cpp @@ -54,10 +54,11 @@ namespace vb01{ } void sortResults(std::vector &results){ - for(int i=0;iresults[i2].distance) - swap(results[i],results[i2]); - } + if(!results.empty()) + for(int i=0;iresults[i2].distance) + swap(results[i],results[i2]); + } } } diff --git a/root.cpp b/root.cpp index 767927a..0f89cd5 100755 --- a/root.cpp +++ b/root.cpp @@ -52,8 +52,9 @@ namespace vb01{ } glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); + //glEnable(GL_CULL_FACE); + //glCullFace(GL_BACK); + glDepthMask(GL_TRUE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); @@ -68,11 +69,11 @@ namespace vb01{ glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8,width,height); glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_STENCIL_ATTACHMENT,GL_RENDERBUFFER,RBO); */ - glBindFramebuffer(GL_FRAMEBUFFER,0); if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE) cout<<"Not complete\n"; else cout<<"Complete\n"; + glBindFramebuffer(GL_FRAMEBUFFER,0); guiPlane=new Quad(Vector3(width,height,-1),false); Material *mat=new Material(Material::MATERIAL_GUI); @@ -81,42 +82,42 @@ namespace vb01{ } void Root::update(){ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - - glBindFramebuffer(GL_FRAMEBUFFER,FBO); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + //glBindFramebuffer(GL_FRAMEBUFFER,FBO); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + //glEnable(GL_CULL_FACE); - if(skybox){ - glDepthMask(GL_FALSE); - glCullFace(GL_BACK); - skybox->update(); - glDepthMask(GL_TRUE); - glCullFace(GL_FRONT); - } + if(skybox){ + glDepthMask(GL_FALSE); + //glCullFace(GL_BACK); + skybox->update(); + glDepthMask(GL_TRUE); + //glCullFace(GL_FRONT); + } - rootNode->update(); + rootNode->update(); - glBindFramebuffer(GL_FRAMEBUFFER,0); + //glBindFramebuffer(GL_FRAMEBUFFER,0); - glDisable(GL_CULL_FACE); + //glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); + glDisable(GL_DEPTH_TEST); - guiPlane->update(); - /* - */ - glEnable(GL_DEPTH_TEST); - guiNode->update(); + //guiPlane->update(); + /* + */ + glEnable(GL_DEPTH_TEST); + guiNode->update(); - glfwSwapBuffers(window); - glfwPollEvents(); + glfwSwapBuffers(window); + glfwPollEvents(); } void Root::createSkybox(string textures[6]){ skybox = new Box(Vector3(10,10,10)); - Material *skyboxMat=new Material(Material::Type::MATERIAL_SKYBOX); + Material *skyboxMat=new Material(Material::MATERIAL_SKYBOX); skyboxMat->addDiffuseMap(textures); skybox->setMaterial(skyboxMat); } diff --git a/script.py b/script.py new file mode 100644 index 0000000..9c77a2f --- /dev/null +++ b/script.py @@ -0,0 +1,48 @@ +import sys + +ob=bpy.data.objects['awp'] +mesh=bpy.data.meshes['Cylinder'] + +fl="/home/dominykas/c++/vb01/kek.vb"; +file=open(fl,"w") + +file.write("numFaces:"+str(len(ob.data.polygons))+"\n") +file.write("numVertices:"+str(len(ob.data.vertices))+"\n") +file.write("vertices:\n") + +for vert in ob.data.vertices: + pos=vert.co + norm=vert.normal + file.write(str(pos.x)+" "+str(pos.z)+" "+str(pos.y)+" "+str(norm.x)+" "+str(norm.z)+" "+str(norm.y)+"\n") + +file.write("uv:\n") + +for face in ob.data.polygons: + for vert,loop in zip(face.vertices,face.loop_indices): + uv=mesh.uv_layers[0].data[loop].uv + file.write(str(vert)+" "+str(uv.x)+" "+str(uv.y)+"\n") + +file.write("numGroups:"+str(len(ob.vertex_groups))+"\n") +file.write("groups:\n") +for group in ob.vertex_groups: + file.write(group.name+":\n") + for vert in ob.data.vertices: + for g in vert.groups: + if g.group==group.index: + file.write(str(vert.index)+" "+str(g.weight)+"\n") + +if ob.parent.name=="AWP": + file.write("bones:\n") + armature=ob.parent + for bone in armature.data.bones: + tail=bone.tail + head=bone.head + file.write(bone.name+":\n"+str(head.x)+" "+str(head.y)+" "+str(head.z)+" "+str(tail.x)+" "+str(tail.y)+" "+str(tail.z)+"\n") + + file.write("boneHierarchy:\n") + for bone in armature.data.bones: + file.write(str(len(bone.children))+" ") + for ch in bone.children: + file.write(ch.name+" ") + file.write("\n") +file.close() diff --git a/skeleton.cpp b/skeleton.cpp new file mode 100644 index 0000000..44faddf --- /dev/null +++ b/skeleton.cpp @@ -0,0 +1,5 @@ +#include"skeleton.h" + +namespace vb01{ + Skeleton::Skeleton(){} +} diff --git a/skeleton.h b/skeleton.h new file mode 100644 index 0000000..9a1b56b --- /dev/null +++ b/skeleton.h @@ -0,0 +1,12 @@ +#ifndef SKELETON_H +#define SKELETON_H + +namespace vb01{ + class Skeleton{ + public: + Skeleton(); + private: + }; +} + +#endif