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
This commit is contained in:
xemuth 2020-08-22 15:56:20 +00:00
parent d175fbfb3f
commit fcc81ec62e
7 changed files with 171 additions and 75 deletions

View file

@ -43,6 +43,8 @@ class Mesh : public Moveable<Mesh>{
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<Mesh>{
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<Mesh>{
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<Mesh>{
}
}
Material& GetMaterial(){return material;}
void SetName(const Upp::String& n){name = n;}
Upp::String GetName()const noexcept{return name;}

View file

@ -1,12 +1,13 @@
#include "Object3D.h"
#include <Surface/Surface.h>
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<float>& 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<float>& vertices = meshes[Index].GetVertices();
Vector<float>& normals = meshes[Index].GetNormals();
Vector<float>& textCoords = meshes[Index].GetTexCoords();
struct Vertex : public Moveable<Vertex>{
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<Vertex> dummyVertices;
Vector<float> 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<float> 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
}
}
}
}
}

View file

@ -3,14 +3,13 @@
#include <Core/Core.h>
#include <GLCtrl_glad/GLCtrl_glad.h>
#include <Surface/Surface.h>
#include <plugin/assimp/assimp.h>
#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<Object3D>{
private:
static int GlobalID;
int ID;
Vector<Mesh> 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<Object3D>{
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<Object3D>{
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<float> 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>{
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<Mesh>& GetMeshes() const noexcept{return meshes;}
Upp::Vector<float>& 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<float>& 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<float>& 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<float>& 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<float>& 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<float>& 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<float>& 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<float>& 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<Object3D>{
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;}

View file

@ -183,11 +183,12 @@ class Object3DProvider {
Object3D End(){
normalData.Append(Vector<float>(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);

View file

@ -1,6 +1,8 @@
#ifndef _SurfaceCtrl_STLLoader_h_
#define _SurfaceCtrl_STLLoader_h_
#include <Core/Core.h>
namespace Upp{
#define LLOG(x) LOG(x)

View file

@ -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));

View file

@ -2,7 +2,8 @@ description "\377B113,255,200";
uses
Surface,
GLCtrl_glad;
GLCtrl_glad,
plugin/assimp;
file
SurfaceCtrl.h,