From fcc81ec62eab7ed2a57cd5994b8ecfb4bcf0f9db Mon Sep 17 00:00:00 2001 From: xemuth Date: Sat, 22 Aug 2020 15:56:20 +0000 Subject: [PATCH] SurfaceCtrl: Now using assimp to perform model loading, It work well. Note that you need to use USEMALLOC flag :( git-svn-id: svn://ultimatepp.org/upp/trunk@14876 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- bazaar/SurfaceCtrl/Mesh.h | 7 ++ bazaar/SurfaceCtrl/Object3D.cpp | 133 ++++++++++++++++++++++++-- bazaar/SurfaceCtrl/Object3D.h | 54 ++++++----- bazaar/SurfaceCtrl/Object3DProvider.h | 9 +- bazaar/SurfaceCtrl/STLLoader.h | 2 + bazaar/SurfaceCtrl/SurfaceCtrl.cpp | 38 -------- bazaar/SurfaceCtrl/SurfaceCtrl.upp | 3 +- 7 files changed, 171 insertions(+), 75 deletions(-) diff --git a/bazaar/SurfaceCtrl/Mesh.h b/bazaar/SurfaceCtrl/Mesh.h index 3b3cc3275..598cf04ee 100644 --- a/bazaar/SurfaceCtrl/Mesh.h +++ b/bazaar/SurfaceCtrl/Mesh.h @@ -43,6 +43,8 @@ class Mesh : public Moveable{ GLuint colorsVBO = 0; GLuint texCoordsVBO = 0; + Material material; //The material object is a representation of material property of the object (it change how light affect it) + /** All stuff about texture @@ -54,6 +56,8 @@ class Mesh : public Moveable{ name = obj.name; loaded = obj.loaded; + material = obj.material; + vertices = pick(obj.vertices); normals = pick(obj.normals); colors = pick(obj.colors); @@ -79,6 +83,7 @@ class Mesh : public Moveable{ name = obj.name; loaded = obj.loaded; + material = obj.material; vertices.Append(obj.vertices); normals.Append(obj.normals); colors.Append(obj.colors); @@ -97,6 +102,8 @@ class Mesh : public Moveable{ } } + Material& GetMaterial(){return material;} + void SetName(const Upp::String& n){name = n;} Upp::String GetName()const noexcept{return name;} diff --git a/bazaar/SurfaceCtrl/Object3D.cpp b/bazaar/SurfaceCtrl/Object3D.cpp index 0e047a7d2..242b1de51 100644 --- a/bazaar/SurfaceCtrl/Object3D.cpp +++ b/bazaar/SurfaceCtrl/Object3D.cpp @@ -1,12 +1,13 @@ #include "Object3D.h" #include + namespace Upp{ int Object3D::GlobalID = 0; Object3D& Object3D::operator=(Object3D&& obj){ meshes = pick(obj.meshes); - material = obj.material; //The material object is a representation of material property of the object (it change how light affect it) + drawType = obj.drawType; lineColor = obj.lineColor; lineOpacity = obj.lineOpacity; lineWidth = obj.lineWidth; @@ -20,7 +21,6 @@ Object3D& Object3D::operator=(Object3D&& obj){ boundingBox = obj.boundingBox; showBoundingBox = obj.showBoundingBox; transform = obj.transform; - DrawType = obj.DrawType; obj.moved = true; obj.loaded = false; return *this; @@ -29,7 +29,7 @@ Object3D& Object3D::operator=(Object3D&& obj){ Object3D& Object3D::operator=(const Object3D& obj){ meshes.Append(obj.meshes); - material = obj.material; //The material object is a representation of material property of the object (it change how light affect it) + drawType = obj.drawType; lineColor = obj.lineColor; lineOpacity = obj.lineOpacity; lineWidth = obj.lineWidth; @@ -43,7 +43,6 @@ Object3D& Object3D::operator=(const Object3D& obj){ boundingBox = obj.boundingBox; showBoundingBox = obj.showBoundingBox; transform = obj.transform; - DrawType = obj.DrawType; return *this; } @@ -51,7 +50,7 @@ Object3D& Object3D::operator=(const Object3D& obj){ Object3D::~Object3D(){ Unload(); } - +/* bool Object3D::LoadObj(const String& FileObj){ Color color = Gray(); if(OBJLoader::LoadOBJ(FileObj,meshes)){ @@ -82,7 +81,126 @@ bool Object3D::LoadStl(const String& StlFile, Color color){ return true; } return false; +}*/ + + +/** + LoadModel load multiple kind of object file using Assimp lib, you can specify some custom + load routine by editing pFlags, if pFlags = 0 then SurfaceCtrl default behavior about + assimp will be used +**/ +bool Object3D::LoadModel(const String& Filename, Color color, unsigned int pFlags ){ + Unload(); + bool Ret = false; + if( pFlags == 0){ + pFlags = aiProcess_JoinIdenticalVertices |// join identical vertices/ optimize indexing + aiProcess_ValidateDataStructure | // perform a full validation of the loader's output + aiProcess_ImproveCacheLocality | // improve the cache locality of the output vertices + aiProcess_RemoveRedundantMaterials |// remove redundant materials + aiProcess_GenUVCoords | // convert spherical, cylindrical, box and planar mapping to proper UVs + aiProcess_TransformUVCoords | // pre-process UV transformations (scaling, translation ...) + aiProcess_FindInstances | // search for instanced meshes and remove them by references to one master + aiProcess_LimitBoneWeights | // limit bone weights to 4 per vertex + aiProcess_OptimizeMeshes | // join small meshes, if possible; + aiProcess_PreTransformVertices | + aiProcess_GenSmoothNormals | // generate smooth normal vectors if not existing + aiProcess_SplitLargeMeshes | // split large, unrenderable meshes into sub-meshes + aiProcess_Triangulate | // triangulate polygons with more than 3 edges + aiProcess_ConvertToLeftHanded | // convert everything to D3D left handed space + aiProcess_SortByPType; + } + + Assimp::Importer Importer; + const aiScene* pScene = Importer.ReadFile(Filename.ToStd().c_str(),pFlags); + if(pScene){ + Ret = InitFromScene(pScene, Filename); + if(Ret){ + glm::vec3 col(color.GetR()/255.0f, color.GetG()/255.0f, color.GetB()/255.0f); + for(Mesh& m : meshes){ + Vector& color = m.GetColors(); + for(unsigned int e = 0; e < (m.GetVertices().GetCount()/3) ; e++){ + color << col.x << col.y << col.z; + } + } + Load(); + } + }else { + LOG(Format("Error parsing '%s': '%s'\n", Filename, String(Importer.GetErrorString()))); + } + return Ret; } + +/* + Assimp loading function +*/ +bool Object3D::InitFromScene(const aiScene* pScene, const String& Filename){ + meshes.AddN(pScene->mNumMeshes); + //Add Texture vector init here + + // Initialise les maillages de la scène, un par un + for (unsigned int i = 0 ; i < meshes.GetCount() ; i++) { + const aiMesh* paiMesh = pScene->mMeshes[i]; + InitMesh(i, paiMesh); + } + return InitMaterials(pScene, Filename); +} +void Object3D::InitMesh(unsigned int Index, const aiMesh* paiMesh){ + //For texture / material data + //meshes[Index].MaterialIndex = paiMesh->mMaterialIndex; + + Vector& vertices = meshes[Index].GetVertices(); + Vector& normals = meshes[Index].GetNormals(); + Vector& textCoords = meshes[Index].GetTexCoords(); + + struct Vertex : public Moveable{ + float pos[3]; + float normals[3]; + float texCoords[2]; + + Vertex(float x, float y, float z, float n1 , float n2, float n3, float tc1 , float tc2){ + pos[0] = x; pos[1] = y; pos[2] = z; + normals[0] = n1; normals[1] = n2; normals[2] = n3; + texCoords[0] = tc1; texCoords[1] = tc2; + } + }; + + Vector dummyVertices; + Vector dummyIndices; + + const aiVector3D Zero3D(0.0f, 0.0f, 0.0f); + + for (unsigned int i = 0 ; i < paiMesh->mNumVertices ; i++) { + const aiVector3D* pPos = &(paiMesh->mVertices[i]); + const aiVector3D* pNormal = (&(paiMesh->mNormals[i]))? &(paiMesh->mNormals[i]) : &Zero3D; + + glm::vec3 norm(pNormal->x , pNormal->y , pNormal->z); + norm = glm::abs(norm) * -1.0f; + + const aiVector3D* pTexCoord = paiMesh->HasTextureCoords(0) ? &(paiMesh->mTextureCoords[0][i]) : &Zero3D; + + //dummyVertices << Vertex( pPos->x , pPos->y , pPos->z , pNormal->x , pNormal->y , pNormal->z , pTexCoord->x , pTexCoord->y); + dummyVertices << Vertex( pPos->x , pPos->y , pPos->z , norm.x , norm.y , norm.z , pTexCoord->x , pTexCoord->y); + } + + for (unsigned int i = 0 ; i < paiMesh->mNumFaces ; i++) { + const aiFace& Face = paiMesh->mFaces[i]; + ASSERT_(Face.mNumIndices == 3, "Face in Assimp strucure do not contain 3 points !"); + dummyIndices << Face.mIndices[0] << Face.mIndices[1] << Face.mIndices[2]; + } + for(unsigned int i = 0 ; i < dummyIndices.GetCount(); i++){ + Vertex& vertex = dummyVertices[dummyIndices[i]]; + vertices << vertex.pos[0] << vertex.pos[1] << vertex.pos[2]; + normals << vertex.normals[0] << vertex.normals[1] << vertex.normals[2]; + textCoords << vertex.texCoords[0] << vertex.texCoords[1]; + } +} +bool Object3D::InitMaterials(const aiScene* pScene, const String& Filename){ + //TODO + return true; +} + + + bool Object3D::LoadSurface(Surface& surface, Color color){ Mesh& mesh = meshes.Create(); glm::vec3 col( color.GetR()/255.0f, color.GetG()/255.0f, color.GetB()/255.0f); @@ -367,6 +485,7 @@ Vector Object3D::ReadVertices(int MeshNo, unsigned int SurfaceNumber, int } } void Object3D::Draw(glm::mat4 projectionMatrix, glm::mat4 viewMatrix,glm::vec3 viewPosition)noexcept{ + if(showMesh){ if(NoLight.IsLinked() && Light.IsLinked()){ OpenGLProgram& prog = (showLight)? Light : NoLight; @@ -381,6 +500,7 @@ void Object3D::Draw(glm::mat4 projectionMatrix, glm::mat4 viewMatrix,glm::vec3 v } } + prog.SetMat4("ViewMatrix", viewMatrix); prog.SetMat4("ProjectionMatrix", projectionMatrix); prog.SetMat4("ModelMatrix", transform.GetModelMatrix()); @@ -388,7 +508,7 @@ void Object3D::Draw(glm::mat4 projectionMatrix, glm::mat4 viewMatrix,glm::vec3 v for(Mesh& m : meshes){ glBindVertexArray(m.GetVAO()); - glDrawArrays(((prog.ContainTCS()) ? GL_PATCHES : DrawType), 0, m.GetVertices().GetCount()/3); + glDrawArrays(((prog.ContainTCS()) ? GL_PATCHES : drawType), 0, m.GetVertices().GetCount()/3); } }else{ ONCELOCK{ @@ -444,5 +564,6 @@ void Object3D::Draw(glm::mat4 projectionMatrix, glm::mat4 viewMatrix,glm::vec3 v } } } + } } \ No newline at end of file diff --git a/bazaar/SurfaceCtrl/Object3D.h b/bazaar/SurfaceCtrl/Object3D.h index e2790fbd5..a354725c1 100644 --- a/bazaar/SurfaceCtrl/Object3D.h +++ b/bazaar/SurfaceCtrl/Object3D.h @@ -3,14 +3,13 @@ #include #include #include +#include #include "Transform.h" #include "Shader.h" #include "BoundingBox.h" #include "Mesh.h" -#include "STLLoader.h" -#include "OBJLoader.h" namespace Upp{ enum DrawType { DT_TRIANGLE, DT_QUAD }; /* @@ -44,12 +43,12 @@ class Object3D : public Upp::Moveable{ private: static int GlobalID; int ID; + Vector meshes; + bool loaded = false; bool moved = false; - - Material material; //The material object is a representation of material property of the object (it change how light affect it) - + Color lineColor = Black(); float lineOpacity = 0.5f; float lineWidth = 1.0f; @@ -58,6 +57,8 @@ class Object3D : public Upp::Moveable{ float normalOpacity = 0.5f; float normalLenght = 1.0f; + GLenum drawType = GL_TRIANGLES; + OpenGLProgram NoLight; //The program will draw figure without light OpenGLProgram Line; //THe program will draw figure line OpenGLProgram Normal; //The program will draw Normal @@ -72,11 +73,17 @@ class Object3D : public Upp::Moveable{ bool showBoundingBox = false; Transform transform; + Material material; //The material object is a representation of material property of the object (it change how light affect it) - GLenum DrawType = GL_TRIANGLES; - bool UpdateBuffer(GLuint buffer, int SurfaceCount , int SurfaceNumber,int count , const float * data)noexcept; Vector ReadBuffer(GLuint buffer, int SurfaceCount , int SurfaceNumber,int count)noexcept; + + /* + Assimp loading function + */ + bool InitFromScene(const aiScene* pScene, const String& Filename); + void InitMesh(unsigned int Index, const aiMesh* paiMesh); + bool InitMaterials(const aiScene* pScene, const String& Filename); public: Object3D():ID(GlobalID++){} //move will prevent your object to be deleted (from OpenGL perspective) @@ -89,30 +96,26 @@ class Object3D : public Upp::Moveable{ Object3D& operator=(const Object3D& obj); ~Object3D(); - bool LoadObj(const String& FileObj); - bool LoadStl(const String& StlFile, Upp::Color = Green()); + /** + LoadModel load multiple kind of object file using Assimp lib, you can specify some custom + load routine by editing pFlags, if pFlags = 0 then SurfaceCtrl default behavior about + assimp will be used + **/ + bool LoadModel(const String& FileObj, Color color = Gray(), unsigned int pFlags = 0); + + /*bool LoadObj(const String& FileObj); + bool LoadStl(const String& StlFile, Upp::Color = Green());*/ bool LoadSurface(Surface& surface, Upp::Color = Green()); Surface GetSurface(); int GetID()const {return ID;} const Upp::Vector& GetMeshes() const noexcept{return meshes;} - - Upp::Vector& GetVerticesData(int MeshNo = 0){if(MeshNo < meshes.GetCount()){return meshes[MeshNo].GetVertices();}else if(meshes.GetCount() > 0){return meshes[0].GetVertices();}else{throw Exc(Format(t_("Object3D '%i' don't have any meshes, vertices data can't be retrieve\n"), ID));}} - Upp::Vector& GetNormalsData(int MeshNo = 0){if(MeshNo < meshes.GetCount()){return meshes[MeshNo].GetNormals();}else if(meshes.GetCount() > 0){return meshes[0].GetNormals();}else{throw Exc(Format(t_("Object3D '%i' don't have any meshes, normals data can't be retrieve\n"), ID));}} - Upp::Vector& GetColorsData(int MeshNo = 0){if(MeshNo < meshes.GetCount()){return meshes[MeshNo].GetColors();}else if(meshes.GetCount() > 0){return meshes[0].GetColors();}else{throw Exc(Format(t_("Object3D '%i' don't have any meshes, colors data can't be retrieve\n"), ID));}} - Upp::Vector& GetTexturesData(int MeshNo = 0){if(MeshNo < meshes.GetCount()){return meshes[MeshNo].GetTexCoords();}else if(meshes.GetCount() > 0){return meshes[0].GetTexCoords();}else{throw Exc(Format(t_("Object3D '%i' don't have any meshes, textures coordinates data can't be retrieve\n"), ID));}} - - //Create a mesh if no mesh exist - Object3D& AddVerticesData(const Upp::Vector& data, int MeshNo = 0)noexcept{if(meshes.GetCount() == 0 && MeshNo == 0)meshes.Create(); if(MeshNo < meshes.GetCount()){meshes[MeshNo].GetVertices().Append(data);} return *this;} - Object3D& AddNormalsData(const Upp::Vector& data, int MeshNo = 0)noexcept{if(meshes.GetCount() == 0 && MeshNo == 0)meshes.Create(); if(MeshNo < meshes.GetCount()){meshes[MeshNo].GetNormals().Append(data);} return *this;} - Object3D& AddColorsData(const Upp::Vector& data, int MeshNo = 0)noexcept{if(meshes.GetCount() == 0 && MeshNo == 0)meshes.Create(); if(MeshNo < meshes.GetCount()){meshes[MeshNo].GetColors().Append(data);} return *this;} - Object3D& AddTexturesData(const Upp::Vector& data, int MeshNo = 0)noexcept{if(meshes.GetCount() == 0 && MeshNo == 0)meshes.Create(); if(MeshNo < meshes.GetCount()){meshes[MeshNo].GetTexCoords().Append(data);} return *this;} - + Mesh& CreateMeshes()noexcept{return meshes.Add();} + bool Load(); //Load all data in graphic memory It's called automaticly by using Load function, but you must call it if you set manually all data Object3D& Unload(); - Object3D& SetDrawType(GLenum dt)noexcept{DrawType = dt; return *this;} Object3D& ShowMesh(bool b = true)noexcept{showMesh = b; return *this;} Object3D& ShowMeshLine(bool b = true)noexcept{showMeshLine = b; return *this;} Object3D& ShowMeshNormal(bool b = true)noexcept{showMeshNormal = b; return *this;} @@ -125,20 +128,19 @@ class Object3D : public Upp::Moveable{ bool GetShowLight()const noexcept{return showLight;} bool GetShowBoundingBox()const noexcept{return showBoundingBox;} + Object3D& SetDrawType(GLenum drawtype)noexcept{drawType = drawtype;return *this;} Object3D& SetLineColor(Color color)noexcept{lineColor = color; return *this;} Object3D& SetNormalColor(Color color)noexcept{normalColor = color; return *this;} Object3D& SetLineOpacity(float opacity)noexcept{lineOpacity = opacity; if(lineOpacity < 0) lineOpacity =0; if(lineOpacity> 1.0f) lineOpacity = 1.0f; return *this;} Object3D& SetLineWidth(float width)noexcept{lineWidth = width; if(lineWidth < 1) lineWidth = 1.0f; return *this;} Object3D& SetNormalOpacity(float opacity)noexcept{normalOpacity = opacity; if(normalOpacity < 0) normalOpacity =0; if(normalOpacity> 1.0f) normalOpacity = 1.0f; return *this;} + GLenum GetDrawType()const noexcept{return drawType;} Upp::Color GetLineColor()const noexcept{return lineColor;} Upp::Color GetNormalColor()const noexcept{return normalColor;} float GetNormalOpcaity()const noexcept{return normalOpacity;} float GetLineOpcaity()const noexcept{return lineOpacity;} float GetLineWidth()const noexcept{return lineWidth;} - GLenum GetDrawType()const noexcept{return DrawType;} - - Material& GetMaterial(){return material;} - + Transform& GetTransform()noexcept{return transform;} const Transform& GetTransform()const noexcept{return transform;} diff --git a/bazaar/SurfaceCtrl/Object3DProvider.h b/bazaar/SurfaceCtrl/Object3DProvider.h index 237cff28e..5668a9f86 100644 --- a/bazaar/SurfaceCtrl/Object3DProvider.h +++ b/bazaar/SurfaceCtrl/Object3DProvider.h @@ -183,11 +183,12 @@ class Object3DProvider { Object3D End(){ normalData.Append(Vector(vertexData.GetCount())); Object3D buffered; - buffered.AddVerticesData(vertexData); - buffered.AddNormalsData(normalData); - buffered.AddColorsData(colorData); - buffered.Load(); + Mesh& m = buffered.CreateMeshes(); + m.GetVertices().Append(vertexData); + m.GetNormals().Append(normalData); + m.GetColors().Append(colorData); + buffered.Load(); buffered.SetDrawType(DrawType); buffered.ShowLight(false); buffered.ShowMeshLine(false); diff --git a/bazaar/SurfaceCtrl/STLLoader.h b/bazaar/SurfaceCtrl/STLLoader.h index 13714e8e5..75eff791f 100644 --- a/bazaar/SurfaceCtrl/STLLoader.h +++ b/bazaar/SurfaceCtrl/STLLoader.h @@ -1,6 +1,8 @@ #ifndef _SurfaceCtrl_STLLoader_h_ #define _SurfaceCtrl_STLLoader_h_ #include + + namespace Upp{ #define LLOG(x) LOG(x) diff --git a/bazaar/SurfaceCtrl/SurfaceCtrl.cpp b/bazaar/SurfaceCtrl/SurfaceCtrl.cpp index 15d5c14bd..7e5a21788 100644 --- a/bazaar/SurfaceCtrl/SurfaceCtrl.cpp +++ b/bazaar/SurfaceCtrl/SurfaceCtrl.cpp @@ -387,44 +387,6 @@ bool SurfaceCtrl::Key(dword key,int count){ Cout() << "Right vector : "<< camera.GetTransform().GetRight().x << "," << camera.GetTransform().GetRight().y << "," << camera.GetTransform().GetRight().z << EOL; Cout() << "Front vector : "<< camera.GetTransform().GetFront().x << "," << camera.GetTransform().GetFront().y << "," << camera.GetTransform().GetFront().z << EOL; } - /* - Material change - */ - if(key == K_U){ //Increase diffuse - if(allObjects.GetCount() > 0){ - allObjects[0].GetMaterial().SetDiffuse(allObjects[0].GetMaterial().GetDiffuse() + glm::vec3(0.1f,0.1f,0.1f)); - } - } - if(key == K_I){ //decrease diffuse - if(allObjects.GetCount() > 0){ - allObjects[0].GetMaterial().SetDiffuse(allObjects[0].GetMaterial().GetDiffuse() - glm::vec3(0.1f,0.1f,0.1f)); - } - } - if(key == K_J){ //Increase specular - if(allObjects.GetCount() > 0){ - allObjects[0].GetMaterial().SetSpecular(allObjects[0].GetMaterial().GetSpecular() + glm::vec3(0.1f,0.1f,0.1f)); - LOG(allObjects[0].GetMaterial().GetSpecular().x + AsString(" ") + allObjects[0].GetMaterial().GetSpecular().y + AsString(" ") + allObjects[0].GetMaterial().GetSpecular().z); - } - } - if(key == K_K){ //decrease specular - if(allObjects.GetCount() > 0){ - allObjects[0].GetMaterial().SetSpecular(allObjects[0].GetMaterial().GetSpecular() - glm::vec3(0.1f,0.1f,0.1f)); - LOG( AsString(allObjects[0].GetMaterial().GetSpecular().x) + " " + AsString(allObjects[0].GetMaterial().GetSpecular().y) + " " + AsString(allObjects[0].GetMaterial().GetSpecular().z)); - } - } - if(key == K_Y){ //Increase Shininess - if(allObjects.GetCount() > 0){ - allObjects[0].GetMaterial().SetShininess(allObjects[0].GetMaterial().GetShininess() + 0.1f); - LOG(allObjects[0].GetMaterial().GetShininess()); - } - } - if(key == K_H){ //decrease Shininess - if(allObjects.GetCount() > 0){ - allObjects[0].GetMaterial().SetShininess(allObjects[0].GetMaterial().GetShininess() - 0.1f); - LOG(allObjects[0].GetMaterial().GetShininess()); - } - } - if(key == K_ESCAPE){ //removing all selection ClearSelectedObject(); camera.SetFocus(glm::vec3(0.0f,0.0f,0.0f)); diff --git a/bazaar/SurfaceCtrl/SurfaceCtrl.upp b/bazaar/SurfaceCtrl/SurfaceCtrl.upp index f7d03abe6..f354673f7 100644 --- a/bazaar/SurfaceCtrl/SurfaceCtrl.upp +++ b/bazaar/SurfaceCtrl/SurfaceCtrl.upp @@ -2,7 +2,8 @@ description "\377B113,255,200"; uses Surface, - GLCtrl_glad; + GLCtrl_glad, + plugin/assimp; file SurfaceCtrl.h,