From 2c54a551b4a007d79a9f7a4367e019f11bc94f7b Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Thu, 12 Dec 2013 21:04:07 +0100 Subject: [PATCH] [DEV] transfer special game element in the local lib --- ege/Light.cpp | 59 ++ ege/Light.h | 61 ++ ege/Material.cpp | 76 ++ ege/Material.h | 69 ++ ege/physicsShape/PhysicsBox.cpp | 23 + ege/physicsShape/PhysicsBox.h | 44 + ege/physicsShape/PhysicsCapsule.cpp | 28 + ege/physicsShape/PhysicsCapsule.h | 52 ++ ege/physicsShape/PhysicsCone.cpp | 28 + ege/physicsShape/PhysicsCone.h | 52 ++ ege/physicsShape/PhysicsConvexHull.cpp | 44 + ege/physicsShape/PhysicsConvexHull.h | 52 ++ ege/physicsShape/PhysicsCylinder.cpp | 22 + ege/physicsShape/PhysicsCylinder.h | 45 + ege/physicsShape/PhysicsShape.cpp | 57 ++ ege/physicsShape/PhysicsShape.h | 135 +++ ege/physicsShape/PhysicsSphere.cpp | 25 + ege/physicsShape/PhysicsSphere.h | 43 + ege/resources/Mesh.cpp | 1038 ++++++++++++++++++++++++ ege/resources/Mesh.h | 169 ++++ ege/widget/Mesh.cpp | 133 +++ ege/widget/Mesh.h | 74 ++ 22 files changed, 2329 insertions(+) create mode 100644 ege/Light.cpp create mode 100644 ege/Light.h create mode 100644 ege/Material.cpp create mode 100644 ege/Material.h create mode 100644 ege/physicsShape/PhysicsBox.cpp create mode 100644 ege/physicsShape/PhysicsBox.h create mode 100644 ege/physicsShape/PhysicsCapsule.cpp create mode 100644 ege/physicsShape/PhysicsCapsule.h create mode 100644 ege/physicsShape/PhysicsCone.cpp create mode 100644 ege/physicsShape/PhysicsCone.h create mode 100644 ege/physicsShape/PhysicsConvexHull.cpp create mode 100644 ege/physicsShape/PhysicsConvexHull.h create mode 100644 ege/physicsShape/PhysicsCylinder.cpp create mode 100644 ege/physicsShape/PhysicsCylinder.h create mode 100644 ege/physicsShape/PhysicsShape.cpp create mode 100644 ege/physicsShape/PhysicsShape.h create mode 100644 ege/physicsShape/PhysicsSphere.cpp create mode 100644 ege/physicsShape/PhysicsSphere.h create mode 100644 ege/resources/Mesh.cpp create mode 100644 ege/resources/Mesh.h create mode 100644 ege/widget/Mesh.cpp create mode 100644 ege/widget/Mesh.h diff --git a/ege/Light.cpp b/ege/Light.cpp new file mode 100644 index 0000000..b985dd0 --- /dev/null +++ b/ege/Light.cpp @@ -0,0 +1,59 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#include +#include + +ewol::Light::Light(void) : + m_direction(0,0,0), + m_halfplane(0,0,0), + m_ambientColor(0,0,0,0), + m_diffuseColor(0,0,0,0), + m_specularColor(0,0,0,0), + m_GL_direction(0), + m_GL_halfplane(0), + m_GL_ambientColor(0), + m_GL_diffuseColor(0), + m_GL_specularColor(0) { + // nothing to do else ... +} + +ewol::Light::~Light(void) { + +} + +void ewol::Light::link(ewol::Program* _prog, const std::string& _baseName) { + if (NULL == _prog) { + return; + } + m_GL_direction = _prog->getUniform(_baseName+".direction"); + m_GL_halfplane = _prog->getUniform(_baseName+".halfplane"); + m_GL_ambientColor = _prog->getUniform(_baseName+".ambientColor"); + m_GL_diffuseColor = _prog->getUniform(_baseName+".diffuseColor"); + m_GL_specularColor = _prog->getUniform(_baseName+".specularColor"); +} + +void ewol::Light::draw(ewol::Program* _prog) { + _prog->uniform3(m_GL_direction, m_direction); + _prog->uniform3(m_GL_halfplane, m_halfplane); + _prog->uniform4(m_GL_ambientColor, m_ambientColor); + _prog->uniform4(m_GL_diffuseColor, m_diffuseColor); + _prog->uniform4(m_GL_specularColor, m_specularColor); +} + +etk::CCout& ewol::operator <<(etk::CCout& _os, const ewol::Light& _obj) { + _os << "light:{"; + _os << "dir=" << _obj.m_direction; + _os << " halfplan=" << _obj.m_halfplane; + _os << " color:{ anbiant=" << _obj.m_ambientColor; + _os << " diffuse=" << _obj.m_diffuseColor; + _os << " specular=" << _obj.m_specularColor; + _os << "}}"; + return _os; +} + diff --git a/ege/Light.h b/ege/Light.h new file mode 100644 index 0000000..ed7b116 --- /dev/null +++ b/ege/Light.h @@ -0,0 +1,61 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __EWOL_LIGHT_H__ +#define __EWOL_LIGHT_H__ + +#include +#include +#include +#include + +namespace ewol { + class Light { + private: + // values + vec3 m_direction; + vec3 m_halfplane; + vec4 m_ambientColor; + vec4 m_diffuseColor; + vec4 m_specularColor; + private: + // GL index + int32_t m_GL_direction; + int32_t m_GL_halfplane; + int32_t m_GL_ambientColor; + int32_t m_GL_diffuseColor; + int32_t m_GL_specularColor; + public: + Light(void); + ~Light(void); + void link(ewol::Program* _prog, const std::string& _baseName); + void draw(ewol::Program* _prog); + void setDirection(const vec3& val) { + m_direction = val; + } + void setHalfPlane(const vec3& val) { + m_halfplane = val; + } + void setAmbientColor(const vec4& val) { + m_ambientColor = val; + } + void setDiffuseColor(const vec4& val) { + m_diffuseColor = val; + } + void setSpecularColor(const vec4& val) { + m_specularColor = val; + } + + friend etk::CCout& operator <<(etk::CCout& _os, const ewol::Light& _obj); + }; + etk::CCout& operator <<(etk::CCout& _os, const ewol::Light& _obj); +}; + + +#endif + diff --git a/ege/Material.cpp b/ege/Material.cpp new file mode 100644 index 0000000..4943afb --- /dev/null +++ b/ege/Material.cpp @@ -0,0 +1,76 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#include +#include +#include + +ewol::MaterialGlId::MaterialGlId(void) : + m_GL_ambientFactor(0), + m_GL_diffuseFactor(0), + m_GL_specularFactor(0), + m_GL_shininess(0), + m_GL_texture0(0) { + // nothing to do else ... +} + + +void ewol::MaterialGlId::link(ewol::Program* _prog, const std::string& _baseName) { + if (NULL == _prog) { + return; + } + m_GL_ambientFactor = _prog->getUniform(_baseName+".ambientFactor"); + m_GL_diffuseFactor = _prog->getUniform(_baseName+".diffuseFactor"); + m_GL_specularFactor = _prog->getUniform(_baseName+".specularFactor"); + m_GL_shininess = _prog->getUniform(_baseName+".shininess"); + m_GL_texture0 = _prog->getUniform("EW_texID"); +} + +ewol::Material::Material(void) : + m_ambientFactor(1,1,1,1), + m_diffuseFactor(0,0,0,1), + m_specularFactor(0,0,0,1), + m_shininess(1), + m_texture0(NULL) { + // nothing to do else ... +} +ewol::Material::~Material(void) { + if(NULL!=m_texture0) { + ewol::TextureFile::release(m_texture0); + } +} + +void ewol::Material::draw(ewol::Program* _prog, const MaterialGlId& _glID) { + _prog->uniform4(_glID.m_GL_ambientFactor, m_ambientFactor); + _prog->uniform4(_glID.m_GL_diffuseFactor, m_diffuseFactor); + _prog->uniform4(_glID.m_GL_specularFactor, m_specularFactor); + _prog->uniform1f(_glID.m_GL_shininess, m_shininess); + if (NULL != m_texture0) { + _prog->setTexture0(_glID.m_GL_texture0, m_texture0->getId()); + } +} + +void ewol::Material::setTexture0(const std::string& _filename) { + ivec2 tmpSize(256, 256); + // prevent overloard error : + ewol::TextureFile* tmpCopy = m_texture0; + m_texture0 = ewol::TextureFile::keep(_filename, tmpSize); + if (NULL == m_texture0 ) { + EWOL_ERROR("Can not load specific texture : " << _filename); + // retreave previous texture: + m_texture0 = tmpCopy; + return; + } + if (NULL != tmpCopy) { + // really release previous texture. In case of same texture loading, then we did not have reload it .. just increase and decrease index... + ewol::TextureFile::release(tmpCopy); + } +} + + + diff --git a/ege/Material.h b/ege/Material.h new file mode 100644 index 0000000..754cd94 --- /dev/null +++ b/ege/Material.h @@ -0,0 +1,69 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __EWOL_MATERIAL_H__ +#define __EWOL_MATERIAL_H__ + +#include +#include +#include +#include +#include + +namespace ewol { + class MaterialGlId { + public: + // GL index + int32_t m_GL_ambientFactor; + int32_t m_GL_diffuseFactor; + int32_t m_GL_specularFactor; + int32_t m_GL_shininess; + int32_t m_GL_texture0; + MaterialGlId(void); + void link(ewol::Program* _prog, const std::string& _baseName); + }; + class Material { + private: + // values + vec4 m_ambientFactor; + vec4 m_diffuseFactor; + vec4 m_specularFactor; + float m_shininess; + ewol::TextureFile* m_texture0; + public: + std::vector m_listIndexFaces; + public: + Material(void); + ~Material(void); + void draw(ewol::Program* _prog, const MaterialGlId& _glID); + void setAmbientFactor(const vec4& _val) { + m_ambientFactor = _val; + } + void setDiffuseFactor(const vec4& _val) { + m_diffuseFactor = _val; + } + void setSpecularFactor(const vec4& _val) { + m_specularFactor = _val; + } + void setShininess(float _val) { + m_shininess = _val; + } + void setTexture0(const std::string& _filename); + + void setImageSize(const ivec2& _newSize) { if (m_texture0 == NULL){return;} m_texture0->setImageSize(_newSize); }; + // get the reference on this image to draw nomething on it ... + egami::Image* get(void) { if (m_texture0 == NULL){return NULL;} return &m_texture0->get(); }; + // flush the data to send it at the openGl system + void flush(void) { if (m_texture0 == NULL){return;} m_texture0->flush(); }; + }; + +}; + + +#endif + diff --git a/ege/physicsShape/PhysicsBox.cpp b/ege/physicsShape/PhysicsBox.cpp new file mode 100644 index 0000000..8fa6641 --- /dev/null +++ b/ege/physicsShape/PhysicsBox.cpp @@ -0,0 +1,23 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ +#include +#include + + + +bool ewol::PhysicsBox::parse(const char* _line) { + if (true == ewol::PhysicsShape::parse(_line)) { + return true; + } + if(0 == strncmp(_line, "half-extents : ", 15) ) { + sscanf(&_line[15], "%f %f %f", &m_size.m_floats[0], &m_size.m_floats[1], &m_size.m_floats[2] ); + EWOL_VERBOSE(" halfSize=" << m_size); + return true; + } + return false; +} diff --git a/ege/physicsShape/PhysicsBox.h b/ege/physicsShape/PhysicsBox.h new file mode 100644 index 0000000..172f6c7 --- /dev/null +++ b/ege/physicsShape/PhysicsBox.h @@ -0,0 +1,44 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __EWOL_PHYSICS_BOX_H__ +#define __EWOL_PHYSICS_BOX_H__ + + +#include +#include + +namespace ewol { + class PhysicsBox : public ewol::PhysicsShape { + public: + PhysicsBox(void) {}; + virtual ~PhysicsBox(void) {}; + public: + virtual bool parse(const char* _line); + virtual void display(void) {}; + public: + virtual enum type getType(void) { + return ewol::PhysicsShape::box; + }; + private: + vec3 m_size; // Box size property in X, Y and Z + public: + const vec3& getSize(void) const { + return m_size; + }; + public: + virtual const PhysicsBox* toBox(void) const { + return this; + }; + virtual PhysicsBox* toBox(void) { + return this; + }; + }; +}; + +#endif diff --git a/ege/physicsShape/PhysicsCapsule.cpp b/ege/physicsShape/PhysicsCapsule.cpp new file mode 100644 index 0000000..1f6aecb --- /dev/null +++ b/ege/physicsShape/PhysicsCapsule.cpp @@ -0,0 +1,28 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ +#include +#include + + + +bool ewol::PhysicsCapsule::parse(const char* _line) { + if (true == ewol::PhysicsShape::parse(_line)) { + return true; + } + if(0 == strncmp(_line, "radius : ", 9) ) { + sscanf(&_line[9], "%f", &m_radius ); + EWOL_VERBOSE(" radius=" << m_radius); + return true; + } + if(0 == strncmp(_line, "height : ", 9) ) { + sscanf(&_line[9], "%f", &m_height ); + EWOL_VERBOSE(" height=" << m_height); + return true; + } + return false; +} diff --git a/ege/physicsShape/PhysicsCapsule.h b/ege/physicsShape/PhysicsCapsule.h new file mode 100644 index 0000000..6e53974 --- /dev/null +++ b/ege/physicsShape/PhysicsCapsule.h @@ -0,0 +1,52 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __EWOL_PHYSICS_CAPSULE_H__ +#define __EWOL_PHYSICS_CAPSULE_H__ + + +#include +#include + + +namespace ewol { + class PhysicsCapsule : public ewol::PhysicsShape { + public: + PhysicsCapsule(void) {}; + virtual ~PhysicsCapsule(void) {}; + public: + virtual bool parse(const char* _line); + virtual void display(void) {}; + public: + virtual enum type getType(void) { + return ewol::PhysicsShape::capsule; + }; + private: + float m_radius; + public: + float getRadius(void) const { + return m_radius; + }; + private: + float m_height; + public: + float getHeight(void) const { + return m_height; + }; + public: + virtual const PhysicsCapsule* toCapsule(void) const { + return this; + }; + virtual PhysicsCapsule* toCapsule(void) { + return this; + }; + }; +}; + + +#endif diff --git a/ege/physicsShape/PhysicsCone.cpp b/ege/physicsShape/PhysicsCone.cpp new file mode 100644 index 0000000..2b1f5e7 --- /dev/null +++ b/ege/physicsShape/PhysicsCone.cpp @@ -0,0 +1,28 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ +#include +#include + + + +bool ewol::PhysicsCone::parse(const char* _line) { + if (true == ewol::PhysicsShape::parse(_line)) { + return true; + } + if(0 == strncmp(_line, "radius : ", 9) ) { + sscanf(&_line[9], "%f", &m_radius ); + EWOL_VERBOSE(" radius=" << m_radius); + return true; + } + if(0 == strncmp(_line, "height : ", 9) ) { + sscanf(&_line[9], "%f", &m_height ); + EWOL_VERBOSE(" height=" << m_height); + return true; + } + return false; +} diff --git a/ege/physicsShape/PhysicsCone.h b/ege/physicsShape/PhysicsCone.h new file mode 100644 index 0000000..9d5234d --- /dev/null +++ b/ege/physicsShape/PhysicsCone.h @@ -0,0 +1,52 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __EWOL_PHYSICS_CONE_H__ +#define __EWOL_PHYSICS_CONE_H__ + + +#include +#include + + +namespace ewol { + class PhysicsCone : public ewol::PhysicsShape { + public: + PhysicsCone(void) {}; + virtual ~PhysicsCone(void) {}; + public: + virtual bool parse(const char* _line); + virtual void display(void) {}; + public: + virtual enum type getType(void) { + return ewol::PhysicsShape::cone; + }; + private: + float m_radius; + public: + float getRadius(void) const { + return m_radius; + }; + private: + float m_height; + public: + float getHeight(void) const { + return m_height; + }; + public: + virtual const PhysicsCone* toCone(void) const { + return this; + }; + virtual PhysicsCone* toCone(void) { + return this; + }; + }; +}; + + +#endif diff --git a/ege/physicsShape/PhysicsConvexHull.cpp b/ege/physicsShape/PhysicsConvexHull.cpp new file mode 100644 index 0000000..78fb5e4 --- /dev/null +++ b/ege/physicsShape/PhysicsConvexHull.cpp @@ -0,0 +1,44 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ +#include +#include + + + +bool ewol::PhysicsConvexHull::parse(const char* _line) { + if (true == ewol::PhysicsShape::parse(_line)) { + return true; + } + if(0 == strncmp(_line, "points : ", 8) ) { + //EWOL_DEBUG("convex hull point parsing " << _line); + char* base = (char*)(&_line[8]); + char* tmp= strchr(base, '|'); + vec3 pos(0,0,0); + while (tmp != NULL) { + *tmp = '\0'; + sscanf(base, "%f %f %f", &pos.m_floats[0], &pos.m_floats[1], &pos.m_floats[2] ); + m_points.push_back(pos); + base = tmp+1; + tmp= strchr(base, '|'); + } + sscanf(base, "%f %f %f", &pos.m_floats[0], &pos.m_floats[1], &pos.m_floats[2] ); + m_points.push_back(pos); + /* + for (int32_t iii=0; iii +#include +#include +#include + +#undef __class__ +#define __class__ "resource::Mesh" + +ewol::resource::Mesh::Mesh(const std::string& _fileName, const std::string& _shaderName) : + ewol::resource::Resource(_fileName), + m_normalMode(normalModeNone), + m_checkNormal(false), + m_pointerShape(NULL), + m_functionFreeShape(NULL) { + addObjectType("ewol::Mesh"); + EWOL_VERBOSE("Load a new mesh : '" << _fileName << "'"); + // get the shader resource : + m_GLPosition = 0; + + m_light.setDirection(vec3(0,-cos(M_PI/4),0)); + m_light.setHalfPlane(vec3(1,0,0)); + m_light.setAmbientColor(vec4(1,1,1,1)); + m_light.setDiffuseColor(vec4(1.0,1.0,1.0,1)); + m_light.setSpecularColor(vec4(0.0,0.0,0.0,1)); + + //EWOL_DEBUG(m_name << " " << m_light); + m_GLprogram = ewol::Program::keep(_shaderName); + if (NULL != m_GLprogram ) { + m_GLPosition = m_GLprogram->getAttribute("EW_coord3d"); + m_GLtexture = m_GLprogram->getAttribute("EW_texture2d"); + m_GLNormal = m_GLprogram->getAttribute("EW_normal"); + m_GLMatrix = m_GLprogram->getUniform("EW_MatrixTransformation"); + m_GLMatrixPosition = m_GLprogram->getUniform("EW_MatrixPosition"); + // Link material and Lights + m_GLMaterial.link(m_GLprogram, "EW_material"); + m_light.link(m_GLprogram, "EW_directionalLight"); + } + // this is the properties of the buffer requested : "r"/"w" + "-" + buffer type "f"=flaot "i"=integer + m_verticesVBO = ewol::VirtualBufferObject::keep(4); + + // load the curent file : + std::string tmpName = to_lower(_fileName); + // select the corect loader : + if (end_with(tmpName, ".obj") == true) { + if (loadOBJ(_fileName) == false) { + EWOL_ERROR("Error To load OBJ file " << tmpName ); + return; + } + } else if (end_with(tmpName, ".emf") ) { + if (loadEMF(_fileName) == false) { + EWOL_ERROR("Error To load EMF file " << tmpName ); + return; + } + //EWOL_CRITICAL("Load a new mesh : '" << _fileName << "' (end)"); + } else { + // nothing to do == > reqiest an enmpty mesh ==> user manage it ... + } +} + +ewol::resource::Mesh::~Mesh(void) { + // remove dynamics dependencies : + ewol::resource::Program::release(m_GLprogram); + ewol::resource::VirtualBufferObject::release(m_verticesVBO); + if (m_functionFreeShape!=NULL) { + m_functionFreeShape(m_pointerShape); + m_pointerShape = NULL; + } +} + +//#define DISPLAY_NB_VERTEX_DISPLAYED + +void ewol::resource::Mesh::draw(mat4& _positionMatrix, + bool _enableDepthTest, + bool _enableDepthUpdate) { + if (m_GLprogram == NULL) { + EWOL_ERROR("No shader ..."); + return; + } + //EWOL_DEBUG(m_name << " " << m_light); + if (_enableDepthTest == true) { + ewol::openGL::enable(ewol::openGL::FLAG_DEPTH_TEST); + if (false == _enableDepthUpdate) { + glDepthMask(GL_FALSE); + } + } else { + ewol::openGL::disable(ewol::openGL::FLAG_DEPTH_TEST); + } + //EWOL_DEBUG(" display " << m_coord.size() << " elements" ); + m_GLprogram->use(); + // set Matrix : translation/positionMatrix + mat4 projMatrix = ewol::openGL::getMatrix(); + mat4 camMatrix = ewol::openGL::getCameraMatrix(); + mat4 tmpMatrix = projMatrix * camMatrix; + m_GLprogram->uniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat); + m_GLprogram->uniformMatrix4fv(m_GLMatrixPosition, 1, _positionMatrix.m_mat); + // position : + m_GLprogram->sendAttributePointer(m_GLPosition, 3/*x,y,z*/, m_verticesVBO, MESH_VBO_VERTICES); + // Texture : + m_GLprogram->sendAttributePointer(m_GLtexture, 2/*u,v*/, m_verticesVBO, MESH_VBO_TEXTURE); + // position : + m_GLprogram->sendAttributePointer(m_GLNormal, 3/*x,y,z*/, m_verticesVBO, MESH_VBO_VERTICES_NORMAL); + // draw lights : + m_light.draw(m_GLprogram); + #ifdef DISPLAY_NB_VERTEX_DISPLAYED + int32_t nbElementDrawTheoric = 0; + int32_t nbElementDraw = 0; + #endif + for (int32_t kkk=0; kkkdraw(m_GLprogram, m_GLMaterial); + if (m_checkNormal == false) { + ewol::openGL::drawElements(GL_TRIANGLES, m_listFaces.getValue(kkk).m_index); + #ifdef DISPLAY_NB_VERTEX_DISPLAYED + nbElementDraw += m_listFaces.getValue(kkk).m_index.size(); + nbElementDrawTheoric += m_listFaces.getValue(kkk).m_index.size(); + #endif + } else { + mat4 mattttt = (projMatrix * camMatrix) * _positionMatrix; + mattttt.m_mat[3] = 0; + mattttt.m_mat[7] = 0; + mattttt.m_mat[11] = 0; + //vec3 cameraNormal = vec3(-mattttt.m_mat[2], -mattttt.m_mat[6], -mattttt.m_mat[10]); + vec3 cameraNormal = vec3(0,0,-1); + cameraNormal.normalized(); + // remove face that is notin the view ... + std::vector tmpIndexResult; + std::vector& tmppFaces = m_listFaces.getValue(kkk).m_faces; + //std::vector& tmppIndex = m_listFaces.getValue(kkk).m_index; + if (normalModeFace == m_normalMode) { + for(size_t iii=0; iii= 0.0f) { + tmpIndexResult.push_back(iii*3); + tmpIndexResult.push_back(iii*3+1); + tmpIndexResult.push_back(iii*3+2); + } + } + } else { + for(size_t iii=0; iii= -0.2f) + || (btDot(mattttt * m_listVertexNormal[tmppFaces[iii].m_normal[1]], cameraNormal) >= -0.2f) + || (btDot(mattttt * m_listVertexNormal[tmppFaces[iii].m_normal[2]], cameraNormal) >= -0.2f) ) { + tmpIndexResult.push_back(iii*3); + tmpIndexResult.push_back(iii*3+1); + tmpIndexResult.push_back(iii*3+2); + } + } + } + ewol::openGL::drawElements(GL_TRIANGLES, tmpIndexResult); + #ifdef DISPLAY_NB_VERTEX_DISPLAYED + nbElementDraw += tmpIndexResult.size(); + nbElementDrawTheoric += m_listFaces.getValue(kkk).m_index.size(); + #endif + } + } + #ifdef DISPLAY_NB_VERTEX_DISPLAYED + EWOL_DEBUG(((float)nbElementDraw/(float)nbElementDrawTheoric*100.0f) << "% Request draw : " << m_listFaces.size() << ":" << nbElementDraw << "/" << nbElementDrawTheoric << " elements [" << m_name << "]"); + #endif + m_GLprogram->unUse(); + if (_enableDepthTest == true){ + if (false == _enableDepthUpdate) { + glDepthMask(GL_TRUE); + } + ewol::openGL::disable(ewol::openGL::FLAG_DEPTH_TEST); + } + // TODO : UNDERSTAND why ... it is needed + glBindBuffer(GL_ARRAY_BUFFER,0); +} + +// normal calculation of the normal face is really easy : +void ewol::resource::Mesh::calculateNormaleFace(void) { + m_listFacesNormal.clear(); + if (m_normalMode != ewol::Mesh::normalModeFace) { + std::vector& tmpFaceList = m_listFaces.getValue(0).m_faces; + for(size_t iii=0 ; iii& tmpFaceList = m_listFaces.getValue(0).m_faces; + vec3 normal(0,0,0); + // add the vertex from all the element in the list for face when the element in the face ... + for(size_t jjj=0 ; jjjpushOnBuffer(MESH_VBO_VERTICES_NORMAL, normal); + if( tmpFaceList[jjj].m_vertex[0] == (int32_t)iii + || tmpFaceList[jjj].m_vertex[1] == (int32_t)iii + || tmpFaceList[jjj].m_vertex[2] == (int32_t)iii) { + normal += m_listFacesNormal[jjj]; + } + } + if (normal == vec3(0,0,0)) { + m_listVertexNormal.push_back(vec3(1,1,1)); + } else { + m_listVertexNormal.push_back(normal.normalized()); + } + } + m_normalMode = ewol::Mesh::normalModeVertex; + } +} + +// for debugging ... +//#define PRINT_HALF (1) +//#define TRY_MINIMAL_VBO + +void ewol::resource::Mesh::generateVBO(void) { + // calculate the normal of all faces if needed + if (m_normalMode == ewol::Mesh::normalModeNone) { + // when no normal detected == > auto generate Face normal .... + calculateNormaleFace(); + } + // generate element in 2 pass : + // - create new index dependeng a vertex is a unique componenet of position, texture, normal + // - the index list generation (can be dynamic ... (TODO later) + for (int32_t kkk=0; kkksizeOnBufferVec3(MESH_VBO_VERTICES); jjj++) { + if( m_verticesVBO->getOnBufferVec3(MESH_VBO_VERTICES,jjj) == position + && m_verticesVBO->getOnBufferVec3(MESH_VBO_VERTICES_NORMAL,jjj) == normal + && m_verticesVBO->getOnBufferVec2(MESH_VBO_TEXTURE,jjj) == texturepos) { + vertexVBOId[indice] = jjj; + elementFind = true; + //EWOL_DEBUG("search indice : " << jjj); + tmpppppp += jjj; + // stop searching ... + break; + } + } + #endif + if (false == elementFind) { + m_verticesVBO->pushOnBuffer(MESH_VBO_VERTICES, position); + m_verticesVBO->pushOnBuffer(MESH_VBO_VERTICES_NORMAL, normal); + m_verticesVBO->pushOnBuffer(MESH_VBO_TEXTURE, texturepos); + vertexVBOId[indice] = m_verticesVBO->sizeOnBufferVec3(MESH_VBO_VERTICES)-1; + } + } + for(size_t indice=0 ; indice<3; indice++) { + tmpFaceList.m_index.push_back(vertexVBOId[indice]); + } + } + #ifdef TRY_MINIMAL_VBO + EWOL_DEBUG("nb cycle ? : " << tmpppppp); + #endif + } + // update all the VBO elements ... + m_verticesVBO->flush(); +} + + +void ewol::resource::Mesh::createViewBox(const std::string& _materialName,float _size) { + m_normalMode = ewol::Mesh::normalModeNone; + // This is the direct generation basis on the .obj system + /* + 5 6 + o---------------------o + /. /| + / . / | + / . / | + / . / | + / . / | + 4 / . / | + o---------------------o | + | . |7 | + | . | | + | . | | + | . | | + | o..............|......o + | . 1 | / 2 + | . | / + | . | / + | . | / + | . | / + |. |/ + o---------------------o + 0 3 + */ + m_listVertex.push_back(vec3( _size, -_size, -_size)); // 0 + m_listVertex.push_back(vec3( _size, -_size, _size)); // 1 + m_listVertex.push_back(vec3(-_size, -_size, _size)); // 2 + m_listVertex.push_back(vec3(-_size, -_size, -_size)); // 3 + m_listVertex.push_back(vec3( _size, _size, -_size)); // 4 + m_listVertex.push_back(vec3( _size, _size, _size)); // 5 + m_listVertex.push_back(vec3(-_size, _size, _size)); // 6 + m_listVertex.push_back(vec3(-_size, _size, -_size)); // 7 + /* + o----------o----------o----------o + |8 |9 |10 |11 + | | | | + | | | | + | 0 | 1 | 2 | + | | | | + | | | | + | | | | + | | | | + o----------o----------o----------o + |4 |5 |6 |7 + | | | | + | | | | + | 3 | 4 | 5 | + | | | | + | | | | + | | | | + | | | | + o----------o----------o----------o + 0 1 2 3 + */ + m_listUV.push_back(vec2(0.0 , 0.0 )); // 0 + m_listUV.push_back(vec2(1.0/3.0, 0.0 )); // 1 + m_listUV.push_back(vec2(2.0/3.0, 0.0 )); // 2 + m_listUV.push_back(vec2(1.0 , 0.0 )); // 3 + m_listUV.push_back(vec2(0.0 , 0.5 )); // 4 + m_listUV.push_back(vec2(1.0/3.0, 0.5 )); // 5 + m_listUV.push_back(vec2(2.0/3.0, 0.5 )); // 6 + m_listUV.push_back(vec2(1.0 , 0.5 )); // 7 + m_listUV.push_back(vec2(0.0 , 1.0 )); // 8 + m_listUV.push_back(vec2(1.0/3.0, 1.0 )); // 9 + m_listUV.push_back(vec2(2.0/3.0, 1.0 )); // 10 + m_listUV.push_back(vec2(1.0 , 1.0 )); // 11 + + if (m_listFaces.exist(_materialName) == false) { + FaceIndexing empty; + m_listFaces.add(_materialName, empty); + } + { + FaceIndexing& tmpElement = m_listFaces[_materialName]; + tmpElement.m_faces.push_back(Face(0,1, 1,5, 2,6)); // 4 + tmpElement.m_faces.push_back(Face(0,1, 2,6, 3,2)); // 4 + tmpElement.m_faces.push_back(Face(4,4, 0,0, 3,1)); // 3 + tmpElement.m_faces.push_back(Face(4,4, 3,1, 7,5)); // 3 + tmpElement.m_faces.push_back(Face(2,6, 6,10, 7,11)); // 2 + tmpElement.m_faces.push_back(Face(2,6, 7,11, 3,7)); // 2 + tmpElement.m_faces.push_back(Face(4,2, 7,3, 6,7)); // 5 + tmpElement.m_faces.push_back(Face(4,2, 6,7, 5,6)); // 5 + tmpElement.m_faces.push_back(Face(1,5, 5,9, 6,10)); // 1 + tmpElement.m_faces.push_back(Face(1,5, 6,10, 2,6)); // 1 + tmpElement.m_faces.push_back(Face(0,4, 4,8, 5,9)); // 0 + tmpElement.m_faces.push_back(Face(0,4, 5,9, 1,5)); // 0 + } + calculateNormaleFace(); +} + + +bool ewol::resource::Mesh::loadOBJ(const std::string& _fileName) { + m_normalMode = ewol::Mesh::normalModeNone; +#if 0 + etk::FSNode fileName(_fileName); + // get the fileSize ... + int32_t size = fileName.fileSize(); + if (size == 0 ) { + EWOL_ERROR("No data in the file named=\"" << fileName << "\""); + return false; + } + if(false == fileName.fileOpenRead() ) { + EWOL_ERROR("Can not find the file name=\"" << fileName << "\""); + return false; + } + char inputDataLine[2048]; + + int32_t lineID = 0; + while (NULL != fileName.fileGets(inputDataLine, 2048) ) + { + lineID++; + if (inputDataLine[0] == 'v') { + if (inputDataLine[1] == 'n') { + // Vertice normal : vn 0.000000 0.000000 -1.000000 + // we did not use normal == > we recalculated it if needed (some .obj does not export normal, then it is simple like this ... + // TODO : Use the normal provided ... => can be smooth or not ... (cf check "s 1") + } else if (inputDataLine[1] == 't') { + // Texture position : vt 0.748573 0.750412 + vec2 vertex(0,0); + sscanf(&inputDataLine[3], "%f %f", &vertex.m_floats[0], &vertex.m_floats[1]); + m_listUV.push_back(vertex); + } else { + // Vertice position : v 1.000000 -1.000000 -1.000000 + vec3 vertex(0,0,0); + sscanf(&inputDataLine[2], "%f %f %f", &vertex.m_floats[0], &vertex.m_floats[1], &vertex.m_floats[2] ); + m_listVertex.push_back(vertex); + } + } else if (inputDataLine[0] == 'f') { + // face : f 5/1/1 1/2/1 4/3/1* + uint32_t vertexIndex[4], uvIndex[4], normalIndex[4]; + bool quadMode = true; + int32_t matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d\n", + &vertexIndex[0], &uvIndex[0], &normalIndex[0], + &vertexIndex[1], &uvIndex[1], &normalIndex[1], + &vertexIndex[2], &uvIndex[2], &normalIndex[2], + &vertexIndex[3], &uvIndex[3], &normalIndex[3] ); + if (12 != matches){ + // no normal mode : + matches = sscanf(&inputDataLine[2], "%d/%d %d/%d %d/%d %d/%d\n", + &vertexIndex[0], &uvIndex[0], + &vertexIndex[1], &uvIndex[1], + &vertexIndex[2], &uvIndex[2], + &vertexIndex[3], &uvIndex[3] ); + if (8 != matches){ + quadMode = false; + matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d\n", + &vertexIndex[0], &uvIndex[0], &normalIndex[0], + &vertexIndex[1], &uvIndex[1], &normalIndex[1], + &vertexIndex[2], &uvIndex[2], &normalIndex[2] ); + if (9 != matches){ + // no normal mode : + matches = sscanf(&inputDataLine[2], "%d/%d %d/%d %d/%d\n", + &vertexIndex[0], &uvIndex[0], + &vertexIndex[1], &uvIndex[1], + &vertexIndex[2], &uvIndex[2] ); + if (6 != matches){ + EWOL_ERROR("Parsing error in the .obj files : " << fileName << " (l=" << lineID << ") in 'f' section : \"" << &inputDataLine[2] << "\" expected : %d/%d(/%d) %d/%d(/%d) %d/%d(/%d) (%d/%d(/%d)) () for option"); + continue; + } + } + } + } + if (true == quadMode) { + m_listFaces.push_back(Face(vertexIndex[0]-1, uvIndex[0]-1, + vertexIndex[1]-1, uvIndex[1]-1, + vertexIndex[2]-1, uvIndex[2]-1, + vertexIndex[3]-1, uvIndex[3]-1)); + } else { + m_listFaces.push_back(Face(vertexIndex[0]-1, uvIndex[0]-1, + vertexIndex[1]-1, uvIndex[1]-1, + vertexIndex[2]-1, uvIndex[2]-1)); + } + /* + EWOL_DEBUG(" plop : " << tmpFace.m_nbElement << " ? " << m_listFaces[m_listFaces.size()-1].m_nbElement); + EWOL_DEBUG(" : " << tmpFace.m_vertex[0] << " ? " << m_listFaces[m_listFaces.size()-1].m_vertex[0]); + EWOL_DEBUG(" : " << tmpFace.m_uv[0] << " ? " << m_listFaces[m_listFaces.size()-1].m_uv[0]); + */ + } else if (inputDataLine[0] == 's') { + // ??? : s off + } else if (inputDataLine[0] == '#') { + // comment + // nothing to do ... just go to the new line ... + } else if( inputDataLine[0] == 'u' + && inputDataLine[1] == 's' + && inputDataLine[2] == 'e' + && inputDataLine[3] == 'm' + && inputDataLine[4] == 't' + && inputDataLine[5] == 'l' ) { + // Use Material : usemtl imageName.xxx + while( inputDataLine[strlen(inputDataLine)-1] == '\n' + || inputDataLine[strlen(inputDataLine)-1] == '\r' + || inputDataLine[strlen(inputDataLine)-1] == ' ') { + if (1 == strlen(inputDataLine) ){ + break; + } + inputDataLine[strlen(inputDataLine)-1] = '\0'; + } + std::string tmpVal(&inputDataLine[7]); + setTexture(fileName.getRelativeFolder() + tmpVal); + } else if( inputDataLine[0] == 'm' + && inputDataLine[1] == 't' + && inputDataLine[2] == 'l' + && inputDataLine[3] == 'l' + && inputDataLine[4] == 'i' + && inputDataLine[5] == 'b' ) { + // ???? : mtllib cube.mtl + } + } + fileName.fileClose(); + generateVBO(); +#endif + return true; +} + +void jumpEndLine(etk::FSNode& _file) { + char current=_file.fileGet(); + while( current != '\0' + && current != '\n') { + //printf("%c", current); + current=_file.fileGet(); + } +} + +int32_t countIndent(etk::FSNode& _file) { + int32_t nbIndent=0; + int32_t nbSpacesTab=0; + int32_t nbChar=0; + //EWOL_DEBUG(" start count Indent"); + for(char current=_file.fileGet(); current != '\0'; current=_file.fileGet()) { + nbChar++; + //EWOL_DEBUG("parse : " << current); + if (current == '\t') { + nbSpacesTab = 0; + nbIndent++; + } else if (current == ' ') { + nbSpacesTab++; + if (nbSpacesTab == 4) { + nbSpacesTab = 0; + nbIndent++; + } + } else if (current == '#') { + // Auto remove comment ... + jumpEndLine(_file); + return countIndent(_file); + } else { + + break; + } + } + //EWOL_DEBUG("indent : " << nbIndent); + _file.fileSeek(-nbChar, etk::FSN_SEEK_CURRENT); + return nbIndent; +} + +char* loadNextData(char* _elementLine, + int64_t _maxData, + etk::FSNode& _file, + bool _removeTabs=false, + bool _stopColomn=false, + bool _stopPipe=true) { + memset(_elementLine, 0, _maxData); + char * element = _elementLine; + int64_t outSize = 0; + /* + if (m_zipReadingOffset >= m_zipContent->size()) { + element[0] = '\0'; + return NULL; + } + */ + char current = _file.fileGet(); + while (current != '\0') { + if( _removeTabs == false + || element != _elementLine) { + *element = current; + element++; + } + if( current == '\n' + || current == '\r' + || ( current == '|' + && _stopPipe == true) + || ( current == ':' + && _stopColomn == true) ) + { + *element = '\0'; + //EWOL_DEBUG(" plop : '" << _elementLine << "'" ); + return _elementLine; + } else if( element == _elementLine + && current != '\t') { + *element = current; + element++; + } + // check maxData size ... + if (outSize >= _maxData-1) { + *element = '\0'; + return _elementLine; + } + current = _file.fileGet(); + } + if (outSize == 0) { + return NULL; + } else { + // send last line + return _elementLine; + } + return NULL; +} + +void removeEndLine(char* _val) { + int32_t len = strlen(_val); + if( len>0 + && ( _val[len-1] == '\n' + || _val[len-1] == '\r' ) ) { + _val[len-1] = '\0'; + } + len--; + if( len>0 + && ( _val[len-1] == '\n' + || _val[len-1] == '\r') ) { + _val[len-1] = '\0'; + } +} + +enum emfModuleMode { + EMFModuleNone, + EMFModuleMesh, + EMFModuleMeshNamed, + EMFModuleMeshVertex, + EMFModuleMeshUVMapping, + EMFModuleMeshNormalVertex, + EMFModuleMeshNormalFace, + EMFModuleMeshFace, + EMFModuleMeshFaceMaterial, + EMFModuleMeshPhysics, + EMFModuleMeshPhysicsNamed, + EMFModuleMesh_END, + EMFModuleMaterial, + EMFModuleMaterialNamed, + EMFModuleMaterial_END, +}; + +bool ewol::resource::Mesh::loadEMF(const std::string& _fileName) { + m_checkNormal = true; + m_normalMode = ewol::Mesh::normalModeNone; + etk::FSNode fileName(_fileName); + // get the fileSize ... + int32_t size = fileName.fileSize(); + if (size == 0 ) { + EWOL_ERROR("No data in the file named=\"" << fileName << "\""); + return false; + } + if(false == fileName.fileOpenRead() ) { + EWOL_ERROR("Can not find the file name=\"" << fileName << "\""); + return false; + } + char inputDataLine[2048]; + // load the first line : + fileName.fileGets(inputDataLine, 2048); + if(0 == strncmp(inputDataLine, "EMF(STRING)", 11)) { + // parse in string mode ... + } else if (0 == strncmp(inputDataLine, "EMF(BINARY)", 11)) { + EWOL_ERROR(" file binary mode is not supported now : 'EMF(BINARY)'"); + return false; + } else { + EWOL_ERROR(" file mode is not supported now : 'EMF(? ? ?)' = '" << inputDataLine << "'"); + return false; + } + enum emfModuleMode currentMode = EMFModuleNone; + EWOL_VERBOSE("Start parsing Mesh file : " << fileName); + // mesh global param : + std::string currentMeshName = ""; + int32_t meshFaceMaterialID = -1; + // material global param : + std::string materialName = ""; + ewol::Material* material = NULL; + // physical shape: + ewol::PhysicsShape* physics = NULL; + while(1) { + int32_t level = countIndent(fileName); + if (level == 0) { + // new section ... + if (NULL == loadNextData(inputDataLine, 2048, fileName)) { + // reach end of file ... + break; + } + if(0 == strncmp(inputDataLine, "Mesh :", 6) ) { + currentMode = EMFModuleMesh; + EWOL_VERBOSE("Parse Mesh :"); + } else if(0 == strncmp(inputDataLine, "Materials : ", 11) ) { + currentMode = EMFModuleMaterial; + EWOL_VERBOSE("Parse Material :"); + } else { + currentMode = EMFModuleNone; + } + } else { + if (currentMode >= EMFModuleMesh && currentMode <= EMFModuleMesh_END) { + if (level == 1) { + //Find mesh name ... + if (NULL == loadNextData(inputDataLine, 2048, fileName, true)) { + // reach end of file ... + break; + } + removeEndLine(inputDataLine); + currentMeshName = inputDataLine; + currentMode = EMFModuleMeshNamed; + EWOL_VERBOSE(" "<< currentMeshName); + continue; + } + if (level == 2) { + // In the mesh level 2 the line size must not exced 2048 + if (NULL == loadNextData(inputDataLine, 2048, fileName, true)) { + // reach end of file ... + break; + } + removeEndLine(inputDataLine); + if(0 == strncmp(inputDataLine, "Vertex", 6) ) { + currentMode = EMFModuleMeshVertex; + EWOL_VERBOSE(" Vertex ..."); + } else if(0 == strncmp(inputDataLine, "UV-mapping", 10) ) { + currentMode = EMFModuleMeshUVMapping; + EWOL_VERBOSE(" UV-mapping ..."); + } else if(0 == strncmp(inputDataLine, "Normal(vertex)", 14) ) { + currentMode = EMFModuleMeshNormalVertex; + EWOL_VERBOSE(" Normal(vertex) ..."); + } else if(0 == strncmp(inputDataLine, "Normal(face)", 12) ) { + currentMode = EMFModuleMeshNormalFace; + EWOL_VERBOSE(" Normal(face) ..."); + } else if(0 == strncmp(inputDataLine, "Face", 4) ) { + currentMode = EMFModuleMeshFace; + EWOL_VERBOSE(" Face ..."); + } else if(0 == strncmp(inputDataLine, "Physics", 7) ) { + currentMode = EMFModuleMeshPhysics; + EWOL_VERBOSE(" Physics ..."); + } else { + EWOL_ERROR(" Unknow mesh property '"< 2 + switch (currentMode) { + default: + EWOL_ERROR("Unknow ... "<< level); + jumpEndLine(fileName); + break; + case EMFModuleMeshVertex: { + vec3 vertex(0,0,0); + while (NULL != loadNextData(inputDataLine, 2048, fileName, true, true) ) { + if (inputDataLine[0] == '\0') { + break; + } + sscanf(inputDataLine, "%f %f %f", &vertex.m_floats[0], &vertex.m_floats[1], &vertex.m_floats[2] ); + m_listVertex.push_back(vertex); + int32_t len = strlen(inputDataLine)-1; + if( inputDataLine[len] == '\n' + || inputDataLine[len] == '\r') { + break; + } + } + EWOL_VERBOSE(" " << m_listVertex.size() << " vertex"); + break; + } + case EMFModuleMeshUVMapping: { + vec2 uvMap(0,0); + while (NULL != loadNextData(inputDataLine, 2048, fileName, true, true) ) { + if (inputDataLine[0] == '\0') { + break; + } + sscanf(inputDataLine, "%f %f", &uvMap.m_floats[0], &uvMap.m_floats[1]); + m_listUV.push_back(uvMap); + int32_t len = strlen(inputDataLine)-1; + if( inputDataLine[len] == '\n' + || inputDataLine[len] == '\r') { + break; + } + } + EWOL_VERBOSE(" " << m_listUV.size() << " coord"); + break; + } + case EMFModuleMeshNormalVertex: { + m_normalMode = ewol::Mesh::normalModeVertex; + vec3 normal(0,0,0); + // find the vertex Normal list. + while (NULL != loadNextData(inputDataLine, 2048, fileName, true, true) ) { + if (inputDataLine[0] == '\0') { + break; + } + sscanf(inputDataLine, "%f %f %f", &normal.m_floats[0], &normal.m_floats[1], &normal.m_floats[2] ); + m_listVertexNormal.push_back(normal); + int32_t len = strlen(inputDataLine)-1; + if( inputDataLine[len] == '\n' + || inputDataLine[len] == '\r') { + break; + } + } + EWOL_VERBOSE(" " << m_listVertexNormal.size() << " Normals"); + break; + } + case EMFModuleMeshNormalFace: { + m_normalMode = ewol::Mesh::normalModeFace; + vec3 normal(0,0,0); + // find the face Normal list. + while (NULL != loadNextData(inputDataLine, 2048, fileName, true, true) ) { + if (inputDataLine[0] == '\0') { + break; + } + sscanf(inputDataLine, "%f %f %f", &normal.m_floats[0], &normal.m_floats[1], &normal.m_floats[2] ); + m_listFacesNormal.push_back(normal); + int32_t len = strlen(inputDataLine)-1; + if( inputDataLine[len] == '\n' + || inputDataLine[len] == '\r') { + break; + } + } + EWOL_VERBOSE(" " << m_listFacesNormal.size() << " Normals"); + break; + } + case EMFModuleMeshFace: + case EMFModuleMeshFaceMaterial: + if (level == 3) { + //Find mesh name ... + if (NULL == loadNextData(inputDataLine, 2048, fileName, true)) { + // reach end of file ... + break; + } + removeEndLine(inputDataLine); + // new maretial selection + currentMode = EMFModuleMeshFaceMaterial; + FaceIndexing empty; + m_listFaces.add(inputDataLine, empty); + meshFaceMaterialID = m_listFaces.getId(inputDataLine); + EWOL_VERBOSE(" " << inputDataLine); + } else if (currentMode == EMFModuleMeshFaceMaterial) { + while (NULL != loadNextData(inputDataLine, 2048, fileName, true, true) ) { + if (inputDataLine[0] == '\0') { + // end of line + break; + } + if (meshFaceMaterialID < 0) { + continue; + } + uint32_t vertexIndex[3], uvIndex[3], normalIndex[3]; + vertexIndex[0] = 0; + vertexIndex[1] = 0; + vertexIndex[2] = 0; + uvIndex[0] = 0; + uvIndex[1] = 0; + uvIndex[2] = 0; + normalIndex[0] = 0; + normalIndex[1] = 0; + normalIndex[2] = 0; + scanf(inputDataLine, "%d/%d/%d %d/%d/%d %d/%d/%d", + &vertexIndex[0], &uvIndex[0], &normalIndex[0], + &vertexIndex[1], &uvIndex[1], &normalIndex[1], + &vertexIndex[2], &uvIndex[2], &normalIndex[2] ); + m_listFaces.getValue(meshFaceMaterialID).m_faces.push_back(Face(vertexIndex[0], uvIndex[0], normalIndex[0], + vertexIndex[1], uvIndex[1], normalIndex[1], + vertexIndex[2], uvIndex[2], normalIndex[2])); + /* + EWOL_DEBUG("face :" << vertexIndex[0] << "/" << uvIndex[0] << "/" << normalIndex[0] << + " " << vertexIndex[1] << "/" << uvIndex[1] << "/" << normalIndex[1] << + " " << vertexIndex[2] << "/" << uvIndex[2] << "/" << normalIndex[2]); + */ + int32_t len = strlen(inputDataLine)-1; + if( inputDataLine[len] == '\n' + || inputDataLine[len] == '\r') { + break; + } + } + EWOL_VERBOSE(" " << m_listFaces.getValue(meshFaceMaterialID).m_faces.size() << " faces"); + } else { + // insert element without material ... + EWOL_ERROR(" try to add face without material selection ..."); + jumpEndLine(fileName); + } + break; + case EMFModuleMeshPhysics: + case EMFModuleMeshPhysicsNamed: + if (NULL == loadNextData(inputDataLine, 2048, fileName, true, false, false)) { + // reach end of file ... + break; + } + removeEndLine(inputDataLine); + if (level == 3) { + physics = ewol::PhysicsShape::create(inputDataLine); + if (physics == NULL) { + EWOL_ERROR("Allocation error when creating physical shape ..."); + continue; + } + m_physics.push_back(physics); + EWOL_VERBOSE(" " << m_physics.size() << " " << inputDataLine); + currentMode = EMFModuleMeshPhysicsNamed; + } else if (currentMode == EMFModuleMeshPhysicsNamed) { + if (physics == NULL) { + EWOL_ERROR("Can not parse :'" << inputDataLine << "' in physical shape ..."); + continue; + } + if (false == physics->parse(inputDataLine)) { + EWOL_ERROR("ERROR when parsing :'" << inputDataLine << "' in physical shape ..."); + } + } + break; + } + continue; + } else if (currentMode >= EMFModuleMaterial && currentMode <= EMFModuleMaterial_END) { + // all material element is stored on 1 line (size < 2048) + if (NULL == loadNextData(inputDataLine, 2048, fileName, true)) { + // reach end of file ... + break; + } + removeEndLine(inputDataLine); + if (level == 1) { + // add previous material : + if( materialName != "" + && material!=NULL) { + m_materials.add(materialName, material); + materialName = ""; + material = NULL; + } + material = new ewol::Material(); + materialName = inputDataLine; + currentMode = EMFModuleMaterialNamed; + EWOL_VERBOSE(" "<< materialName); + continue; + } + // level >1 + if (currentMode != EMFModuleMaterialNamed) { + EWOL_WARNING(" Unknow element ..."<< level); + jumpEndLine(fileName); + continue; + } + if (NULL == material) { + EWOL_ERROR("material allocation error"); + jumpEndLine(fileName); + continue; + } + if(0 == strncmp(inputDataLine,"Ns ",3)) { + float tmpVal=0; + sscanf(&inputDataLine[3], "%f", &tmpVal); + material->setShininess(tmpVal); + EWOL_VERBOSE(" Shininess " << tmpVal); + } else if(0 == strncmp(inputDataLine,"Ka ",3)) { + float tmpVal1=0; + float tmpVal2=0; + float tmpVal3=0; + sscanf(&inputDataLine[3], "%f %f %f", &tmpVal1, &tmpVal2, &tmpVal3); + vec4 tmp(tmpVal1, tmpVal2, tmpVal3, 1); + material->setAmbientFactor(tmp); + EWOL_VERBOSE(" AmbientFactor " << tmp); + } else if(0 == strncmp(inputDataLine,"Kd ",3)) { + float tmpVal1=0; + float tmpVal2=0; + float tmpVal3=0; + sscanf(&inputDataLine[3], "%f %f %f", &tmpVal1, &tmpVal2, &tmpVal3); + vec4 tmp(tmpVal1, tmpVal2, tmpVal3, 1); + material->setDiffuseFactor(tmp); + EWOL_VERBOSE(" DiffuseFactor " << tmp); + } else if(0 == strncmp(inputDataLine,"Ks ",3)) { + float tmpVal1=0; + float tmpVal2=0; + float tmpVal3=0; + sscanf(&inputDataLine[3], "%f %f %f", &tmpVal1, &tmpVal2, &tmpVal3); + vec4 tmp(tmpVal1, tmpVal2, tmpVal3, 1); + material->setSpecularFactor(tmp); + EWOL_VERBOSE(" SpecularFactor " << tmp); + } else if(0 == strncmp(inputDataLine,"Ni ",3)) { + float tmpVal=0; + sscanf(&inputDataLine[3], "%f", &tmpVal); + // TODO : ... + EWOL_VERBOSE(" Ni " << tmpVal); + } else if(0 == strncmp(inputDataLine,"d ",2)) { + float tmpVal=0; + sscanf(&inputDataLine[2], "%f", &tmpVal); + // TODO : ... + EWOL_VERBOSE(" d " << tmpVal); + } else if(0 == strncmp(inputDataLine,"illum ",6)) { + int tmpVal=0; + sscanf(&inputDataLine[6], "%d", &tmpVal); + // TODO : ... + EWOL_VERBOSE(" illum " << tmpVal); + } else if(0 == strncmp(inputDataLine,"map_Kd ",7)) { + material->setTexture0(fileName.getRelativeFolder() + &inputDataLine[7]); + EWOL_VERBOSE(" Texture " << &inputDataLine[7]); + } else { + EWOL_ERROR("unknow material property ... : '" << inputDataLine << "'"); + } + } else { + // unknow ... + EWOL_WARNING("Unknow type of line == > jump end of line ... "); + jumpEndLine(fileName); + } + } + } + // add last material ... + if( materialName != "" + && material!=NULL) { + m_materials.add(materialName, material); + materialName = ""; + material = NULL; + } + EWOL_VERBOSE("Stop parsing Mesh file"); + + fileName.fileClose(); + generateVBO(); + return true; +} + +void ewol::resource::Mesh::addMaterial(const std::string& _name, ewol::Material* _data) { + if (NULL == _data) { + EWOL_ERROR(" can not add material with null pointer"); + return; + } + if (_name == "") { + EWOL_ERROR(" can not add material with no name"); + return; + } + // really add the material : + m_materials.add(_name, _data); +} + +void ewol::resource::Mesh::setShape(void* _shape) { + if (m_functionFreeShape!=NULL) { + m_functionFreeShape(m_pointerShape); + m_pointerShape = NULL; + } + m_pointerShape=_shape; +} + +ewol::resource::Mesh* ewol::resource::Mesh::keep(const std::string& _meshName) { + ewol::resource::Mesh* object = static_cast(getManager().localKeep(_meshName)); + if (NULL != object) { + return object; + } + EWOL_DEBUG("CREATE: Mesh: '" << _meshName << "'"); + object = new ewol::resource::Mesh(_meshName); + if (NULL == object) { + EWOL_ERROR("allocation error of a resource : ??Mesh??" << _meshName); + return NULL; + } + getManager().localAdd(object); + return object; +} + +void ewol::resource::Mesh::release(ewol::Mesh*& _object) { + if (NULL == _object) { + return; + } + ewol::resource::Resource* object2 = static_cast(_object); + getManager().release(object2); + _object = NULL; +} diff --git a/ege/resources/Mesh.h b/ege/resources/Mesh.h new file mode 100644 index 0000000..0268556 --- /dev/null +++ b/ege/resources/Mesh.h @@ -0,0 +1,169 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __MESH_H__ +#define __MESH_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// 3 "float" elements +#define MESH_VBO_VERTICES (0) +// 2 "float" elements +#define MESH_VBO_TEXTURE (1) +// 3 "float" elements +#define MESH_VBO_VERTICES_NORMAL (2) +// Face normal position : +#define MESH_VBO_FACE_NORMAL (3) +// 4 "float" elements +#define MESH_VBO_COLOR (4) + +namespace ewol { + namespace resource { + class Face { + public: + int32_t m_vertex[3]; + int32_t m_uv[3]; + int32_t m_normal[3]; + public: + Face(void) {}; + Face(int32_t v1, int32_t t1, + int32_t v2, int32_t t2, + int32_t v3, int32_t t3) { + m_vertex[0] = v1; + m_vertex[1] = v2; + m_vertex[2] = v3; + m_uv[0] = t1; + m_uv[1] = t2; + m_uv[2] = t3; + m_normal[0] = -1; + m_normal[1] = -1; + m_normal[2] = -1; + }; + Face(int32_t v1, int32_t t1, int32_t n1, + int32_t v2, int32_t t2, int32_t n2, + int32_t v3, int32_t t3, int32_t n3) { + m_vertex[0] = v1; + m_vertex[1] = v2; + m_vertex[2] = v3; + m_uv[0] = t1; + m_uv[1] = t2; + m_uv[2] = t3; + m_normal[0] = n1; + m_normal[1] = n2; + m_normal[2] = n3; + }; + }; + class FaceIndexing { + public: + std::vector m_faces; + std::vector m_index; + }; + class Mesh : public ewol::resource::Resource { + public: + enum normalMode { + normalModeNone, + normalModeFace, + normalModeVertex, + }; + protected: + enum normalMode m_normalMode; // select the normal mode of display + bool m_checkNormal; //!< when enable, this check the normal of the mesh before sending it at the 3d card + protected: + ewol::Program* m_GLprogram; + int32_t m_GLPosition; + int32_t m_GLMatrix; + int32_t m_GLMatrixPosition; + int32_t m_GLNormal; + int32_t m_GLtexture; + int32_t m_bufferOfset; + int32_t m_numberOfElments; + MaterialGlId m_GLMaterial; + ewol::Light m_light; + protected: + std::vector m_listVertex; //!< List of all vertex in the element + std::vector m_listUV; //!< List of all UV point in the mesh (for the specify texture) + std::vector m_listFacesNormal; //!< List of all Face normal, when calculated + std::vector m_listVertexNormal; //!< List of all Face normal, when calculated + etk::Hash m_listFaces; //!< List of all Face for the mesh + etk::Hash m_materials; + std::vector m_physics; //!< collision shape module ... (independent of bullet lib) + protected: + ewol::VirtualBufferObject* m_verticesVBO; + protected: + Mesh(const std::string& _fileName, const std::string& _shaderName="DATA:textured3D2.prog"); + virtual ~Mesh(void); + public: + virtual const char* getType(void) { return "ewol::Mesh"; }; + virtual void draw(mat4& _positionMatrix, bool _enableDepthTest=true, bool _enableDepthUpdate=true); + void generateVBO(void); + private: + void calculateNormaleFace(void); + void calculateNormaleEdge(void); + public : + void createViewBox(const std::string& _materialName,float _size=1.0); + private: + bool loadOBJ(const std::string& _fileName); + bool loadEMF(const std::string& _fileName); + public: + void addMaterial(const std::string& _name, ewol::Material* _data); + public: + /** + * @brief set the check of normal position befor sending it to the openGl card + * @param[in] _status New state. + */ + void setCheckNormal(bool _status) { m_checkNormal=_status; }; + /** + * @brief get the check value of normal position befor sending it to the openGl card + * @return get the chcking stus of normal or not + */ + bool getCheckNormal(void) { return m_checkNormal; }; + const std::vector& getPhysicalProperties(void) const { return m_physics; }; + private: + void* m_pointerShape; //!< all mesh have a basic shape (bullet or other) the void pointer mermit to not depent on the bullet lib + public: + /** + * @brief set the shape pointer (no type == > user might know it ...) + * @param[in] _shape The new shape (this remove the previous one) + */ + void setShape(void* _shape); + /** + * @brief get the pointer on the shame (no type) + * @return Pointer on shape. + */ + void* getShape(void) { return m_pointerShape; }; + private: + void (*m_functionFreeShape)(void* _pointer); + public: + void setFreeShapeFunction(void (*_functionFreeShape)(void* _pointer)) { m_functionFreeShape = _functionFreeShape; }; + public: + /** + * @brief keep the resource pointer. + * @note Never free this pointer by your own... + * @param[in] _filename Name of the ewol mesh file. + * @return pointer on the resource or NULL if an error occured. + */ + static ewol::Mesh* keep(const std::string& _meshname); + /** + * @brief release the keeped resources + * @param[in,out] reference on the object pointer + */ + static void release(ewol::Mesh*& _object); + }; + }; +}; + + +#endif diff --git a/ege/widget/Mesh.cpp b/ege/widget/Mesh.cpp new file mode 100644 index 0000000..7ecd896 --- /dev/null +++ b/ege/widget/Mesh.cpp @@ -0,0 +1,133 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#include +#include +#include + + +extern const char * const ewolEventMeshPressed = "ewol-mesh-Pressed"; + +#undef __class__ +#define __class__ "Mesh" + + + +ewol::widget::Mesh::Mesh(const std::string& _filename) : + m_meshName(_filename), + m_object(NULL), + m_position(0,0,0), + m_angle(0,0,0), + m_angleSpeed(0,0,0), + m_cameraDistance(10.0) { + addObjectType("ewol::widget::Mesh"); + addEventId(ewolEventMeshPressed); + // Limit event at 1: + setMouseLimit(1); + if (_filename!="") { + m_object = ewol::Mesh::keep(m_meshName); + if (NULL == m_object) { + EWOL_ERROR("Can not load the resource : \"" << m_meshName << "\""); + } + } +} + +ewol::widget::Mesh::~Mesh(void) { + ewol::Mesh::release(m_object); +} + +void ewol::widget::Mesh::onDraw(void) { + mat4 transformationMatrix = etk::matTranslate(vec3(0,0,-m_cameraDistance)) + * etk::matTranslate(m_position) + * etk::matRotate(vec3(1,0,0),m_angle.x()) + * etk::matRotate(vec3(0,1,0),m_angle.y()) + * etk::matRotate(vec3(0,0,1),m_angle.z()); + if (NULL != m_object) { + m_object->draw(transformationMatrix); + } +} + +void ewol::widget::Mesh::systemDraw(const ewol::DrawProperty& _displayProp) { + ewol::openGL::push(); + // here we invert the reference of the standard openGl view because the reference in the common display is Top left and not buttom left + glViewport( m_origin.x(), + m_origin.y(), + m_size.x(), + m_size.y()); + float ratio = m_size.x() / m_size.y(); + //EWOL_INFO("ratio : " << ratio); + mat4 tmpProjection = etk::matPerspective(M_PI/3.0, ratio, 0.5, 100); + //mat4 tmpMat = tmpProjection * m_camera.getMatrix(); + // set internal matrix system : + //ewol::openGL::setMatrix(tmpMat); + ewol::openGL::setMatrix(tmpProjection); + + onDraw(); + ewol::openGL::pop(); +} + +void ewol::widget::Mesh::onRegenerateDisplay(void) { + if (true == needRedraw()) { + + } +} + +void ewol::widget::Mesh::periodicCall(const ewol::EventTime& _event) { + m_angle += m_angleSpeed*_event.getDeltaCall(); + markToRedraw(); +} + +bool ewol::widget::Mesh::onEventInput(const ewol::EventInput& _event) { + //EWOL_DEBUG("Event on BT ..."); + if (1 == _event.getId()) { + if(ewol::keyEvent::statusSingle == _event.getStatus()) { + generateEventId(ewolEventMeshPressed); + return true; + } + } + return false; +} + +void ewol::widget::Mesh::setFile(const std::string& _filename) { + if( _filename!="" + && m_meshName != _filename ) { + ewol::Mesh::release(m_object); + m_meshName = _filename; + m_object = ewol::Mesh::keep(m_meshName); + if (NULL == m_object) { + EWOL_ERROR("Can not load the resource : \"" << m_meshName << "\""); + } + } + markToRedraw(); +} + +void ewol::widget::Mesh::setPosition(const vec3& _pos) { + m_position = _pos; + markToRedraw(); +} + +void ewol::widget::Mesh::setAngle(const vec3& _angle) { + m_angle = _angle; + markToRedraw(); +} + +void ewol::widget::Mesh::setAngleSpeed(const vec3& _speed) { + if (_speed!=vec3(0,0,0)) { + periodicCallEnable(); + } else { + periodicCallDisable(); + } + m_angleSpeed = _speed; + markToRedraw(); +} + +void ewol::widget::Mesh::setDistance(float _distance) +{ + m_cameraDistance = _distance; + markToRedraw(); +} diff --git a/ege/widget/Mesh.h b/ege/widget/Mesh.h new file mode 100644 index 0000000..99d584b --- /dev/null +++ b/ege/widget/Mesh.h @@ -0,0 +1,74 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __EWOL_WIDGET_MESH_H__ +#define __EWOL_WIDGET_MESH_H__ + +#include +#include +#include + +extern const char * const ewolEventMeshPressed; + + +namespace ewol { + namespace widget { + /** + * @ingroup ewolWidgetGroup + */ + class Mesh :public ewol::Widget { + private: + // mesh name : + std::string m_meshName; + ewol::Mesh* m_object; + // mesh display properties: + vec3 m_position; + vec3 m_angle; + vec3 m_angleSpeed; + float m_cameraDistance; + public: + Mesh(const std::string& filename); // automatic considering in the appl Data older + virtual ~Mesh(void); + public: // Derived function + virtual void onRegenerateDisplay(void); + virtual void systemDraw(const ewol::DrawProperty& displayProp); + virtual void onDraw(void); + virtual bool onEventInput(const ewol::EventInput& _event); + virtual void periodicCall(const ewol::EventTime& _event); + public: + /** + * @brief set a mesh name file + * @param[in] filename Name of the new mesh + */ + void setFile(const std::string& filename); + /** + * @brief set the mesh position + * @param[in] pos The new position of the mesh + */ + void setPosition(const vec3& pos); + /** + * @brief set the mesh angle of view + * @param[in] angle view angle of the mesh + */ + void setAngle(const vec3& angle); + /** + * @brief set the mesh angle speed + * @param[in] spped radian speed of the mesh + */ + void setAngleSpeed(const vec3& speed); + /** + * @brief set the camera distance of the mesh + * @param[in] dist Diatance of the mesh + */ + void setDistance(float distance); + }; + }; +}; + + +#endif