diff --git a/ege/resource/Mesh.cpp b/ege/resource/Mesh.cpp index 12af74b..24c87f6 100644 --- a/ege/resource/Mesh.cpp +++ b/ege/resource/Mesh.cpp @@ -376,625 +376,6 @@ void ege::resource::Mesh::createIcoSphere(const std::string& _materialName,float calculateNormaleFace(_materialName); } -bool ege::resource::Mesh::loadOBJ(const std::string& _fileName) { - m_normalMode = normalModeNone; -#if 0 - etk::FSNode fileName(_fileName); - // get the fileSize ... - int32_t size = fileName.fileSize(); - if (size == 0 ) { - EGE_ERROR("No data in the file named=\"" << fileName << "\""); - return false; - } - if(false == fileName.fileOpenRead() ) { - EGE_ERROR("Can not find the file name=\"" << fileName << "\""); - return false; - } - char inputDataLine[2048]; - - int32_t lineID = 0; - while (nullptr != 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){ - EGE_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)); - } - /* - EGE_DEBUG(" plop : " << tmpFace.m_nbElement << " ? " << m_listFaces[m_listFaces.size()-1].m_nbElement); - EGE_DEBUG(" : " << tmpFace.m_vertex[0] << " ? " << m_listFaces[m_listFaces.size()-1].m_vertex[0]); - EGE_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; - //EGE_DEBUG(" start count Indent"); - for(char current=_file.fileGet(); current != '\0'; current=_file.fileGet()) { - nbChar++; - //EGE_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; - } - } - //EGE_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 nullptr; - } - */ - 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'; - //EGE_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 nullptr; - } else { - // send last line - return _elementLine; - } - return nullptr; -} - -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, -}; -// TODO : rework with string line extractor -bool ege::resource::Mesh::loadEMF(const std::string& _fileName) { - m_checkNormal = true; - m_normalMode = normalModeNone; - etk::FSNode fileName(_fileName); - // get the fileSize ... - int32_t size = fileName.fileSize(); - if (size == 0 ) { - EGE_ERROR("No data in the file named=\"" << fileName << "\""); - return false; - } - if(false == fileName.fileOpenRead() ) { - EGE_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)) { - EGE_ERROR(" file binary mode is not supported now : 'EMF(BINARY)'"); - return false; - } else { - EGE_ERROR(" file mode is not supported now : 'EMF(? ? ?)' = '" << inputDataLine << "'"); - return false; - } - enum emfModuleMode currentMode = EMFModuleNone; - EGE_VERBOSE("Start parsing Mesh file : " << fileName); - // mesh global param : - std::string currentMeshName = ""; - int32_t meshFaceMaterialID = -1; - // material global param : - std::string materialName = ""; - std::shared_ptr material; - // physical shape: - std::shared_ptr physics; - while(1) { - int32_t level = countIndent(fileName); - if (level == 0) { - // new section ... - if (nullptr == loadNextData(inputDataLine, 2048, fileName)) { - // reach end of file ... - break; - } - if(0 == strncmp(inputDataLine, "Mesh :", 6) ) { - currentMode = EMFModuleMesh; - EGE_VERBOSE("Parse Mesh :"); - } else if(0 == strncmp(inputDataLine, "Materials : ", 11) ) { - currentMode = EMFModuleMaterial; - EGE_VERBOSE("Parse Material :"); - } else { - currentMode = EMFModuleNone; - } - } else { - if (currentMode >= EMFModuleMesh && currentMode <= EMFModuleMesh_END) { - if (level == 1) { - //Find mesh name ... - if (nullptr == loadNextData(inputDataLine, 2048, fileName, true)) { - // reach end of file ... - break; - } - removeEndLine(inputDataLine); - currentMeshName = inputDataLine; - currentMode = EMFModuleMeshNamed; - EGE_VERBOSE(" "<< currentMeshName); - continue; - } - if (level == 2) { - // In the mesh level 2 the line size must not exced 2048 - if (nullptr == loadNextData(inputDataLine, 2048, fileName, true)) { - // reach end of file ... - break; - } - removeEndLine(inputDataLine); - if(0 == strncmp(inputDataLine, "Vertex", 6) ) { - currentMode = EMFModuleMeshVertex; - EGE_VERBOSE(" Vertex ..."); - } else if(0 == strncmp(inputDataLine, "UV-mapping", 10) ) { - currentMode = EMFModuleMeshUVMapping; - EGE_VERBOSE(" UV-mapping ..."); - } else if(0 == strncmp(inputDataLine, "Normal(vertex)", 14) ) { - currentMode = EMFModuleMeshNormalVertex; - EGE_VERBOSE(" Normal(vertex) ..."); - } else if(0 == strncmp(inputDataLine, "Normal(face)", 12) ) { - currentMode = EMFModuleMeshNormalFace; - EGE_VERBOSE(" Normal(face) ..."); - } else if(0 == strncmp(inputDataLine, "Face", 4) ) { - currentMode = EMFModuleMeshFace; - EGE_VERBOSE(" Face ..."); - } else if(0 == strncmp(inputDataLine, "Physics", 7) ) { - currentMode = EMFModuleMeshPhysics; - EGE_VERBOSE(" Physics ..."); - } else { - EGE_ERROR(" Unknow mesh property '"< 2 - switch (currentMode) { - default: - EGE_ERROR("Unknow ... "<< level); - jumpEndLine(fileName); - break; - case EMFModuleMeshVertex: { - vec3 vertex(0,0,0); - while (nullptr != 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; - } - } - EGE_VERBOSE(" " << m_listVertex.size() << " vertex"); - break; - } - case EMFModuleMeshUVMapping: { - vec2 uvMap(0,0); - while (nullptr != 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; - } - } - EGE_VERBOSE(" " << m_listUV.size() << " coord"); - break; - } - case EMFModuleMeshNormalVertex: { - m_normalMode = normalModeVertex; - vec3 normal(0,0,0); - // find the vertex Normal list. - while (nullptr != 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; - } - } - EGE_VERBOSE(" " << m_listVertexNormal.size() << " Normals"); - break; - } - case EMFModuleMeshNormalFace: { - m_normalMode = normalModeFace; - vec3 normal(0,0,0); - // find the face Normal list. - while (nullptr != 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; - } - } - EGE_VERBOSE(" " << m_listFacesNormal.size() << " Normals"); - break; - } - case EMFModuleMeshFace: - case EMFModuleMeshFaceMaterial: - if (level == 3) { - //Find mesh name ... - if (nullptr == 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); - EGE_VERBOSE(" " << inputDataLine); - } else if (currentMode == EMFModuleMeshFaceMaterial) { - while (nullptr != 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; - sscanf(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])); - /* - EGE_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; - } - } - EGE_VERBOSE(" " << m_listFaces.getValue(meshFaceMaterialID).m_faces.size() << " faces"); - } else { - // insert element without material ... - EGE_ERROR(" try to add face without material selection ..."); - jumpEndLine(fileName); - } - break; - case EMFModuleMeshPhysics: - case EMFModuleMeshPhysicsNamed: - if (nullptr == loadNextData(inputDataLine, 2048, fileName, true, false, false)) { - // reach end of file ... - break; - } - removeEndLine(inputDataLine); - if (level == 3) { - physics = ege::PhysicsShape::create(inputDataLine); - if (physics == nullptr) { - EGE_ERROR("Allocation error when creating physical shape ..."); - continue; - } - m_physics.push_back(physics); - EGE_VERBOSE(" " << m_physics.size() << " " << inputDataLine); - currentMode = EMFModuleMeshPhysicsNamed; - } else if (currentMode == EMFModuleMeshPhysicsNamed) { - if (physics == nullptr) { - EGE_ERROR("Can not parse :'" << inputDataLine << "' in physical shape ..."); - continue; - } - if (false == physics->parse(inputDataLine)) { - EGE_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 (nullptr == loadNextData(inputDataLine, 2048, fileName, true)) { - // reach end of file ... - break; - } - removeEndLine(inputDataLine); - if (level == 1) { - // add previous material : - if( materialName != "" - && material!=nullptr) { - m_materials.add(materialName, material); - materialName = ""; - material = nullptr; - } - material = std::make_shared(); - materialName = inputDataLine; - currentMode = EMFModuleMaterialNamed; - EGE_VERBOSE(" "<< materialName); - continue; - } - // level >1 - if (currentMode != EMFModuleMaterialNamed) { - EGE_WARNING(" Unknow element ..."<< level); - jumpEndLine(fileName); - continue; - } - if (nullptr == material) { - EGE_ERROR("material allocation error"); - jumpEndLine(fileName); - continue; - } - if(0 == strncmp(inputDataLine,"Ns ",3)) { - float tmpVal=0; - sscanf(&inputDataLine[3], "%f", &tmpVal); - material->setShininess(tmpVal); - EGE_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); - EGE_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); - EGE_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); - EGE_VERBOSE(" SpecularFactor " << tmp); - } else if(0 == strncmp(inputDataLine,"Ni ",3)) { - float tmpVal=0; - sscanf(&inputDataLine[3], "%f", &tmpVal); - // TODO : ... - EGE_VERBOSE(" Ni " << tmpVal); - } else if(0 == strncmp(inputDataLine,"d ",2)) { - float tmpVal=0; - sscanf(&inputDataLine[2], "%f", &tmpVal); - // TODO : ... - EGE_VERBOSE(" d " << tmpVal); - } else if(0 == strncmp(inputDataLine,"illum ",6)) { - int tmpVal=0; - sscanf(&inputDataLine[6], "%d", &tmpVal); - // TODO : ... - EGE_VERBOSE(" illum " << tmpVal); - } else if(0 == strncmp(inputDataLine,"map_Kd ",7)) { - material->setTexture0(fileName.getRelativeFolder() + &inputDataLine[7]); - EGE_VERBOSE(" Texture " << &inputDataLine[7]); - } else if(0 == strncmp(inputDataLine,"renderMode ",11)) { - ewol::openGL::renderMode mode; - etk::from_string(mode, &inputDataLine[11]); - material->setRenderMode(mode); - EGE_VERBOSE(" Texture " << mode); - } else { - EGE_ERROR("unknow material property ... : '" << inputDataLine << "'"); - } - } else { - // unknow ... - EGE_WARNING("Unknow type of line == > jump end of line ... "); - jumpEndLine(fileName); - } - } - } - // add last material ... - if( materialName != "" - && material!=nullptr) { - m_materials.add(materialName, material); - materialName = ""; - material.reset(); - } - EGE_VERBOSE("Stop parsing Mesh file"); - - fileName.fileClose(); - generateVBO(); - return true; -} void ege::resource::Mesh::addMaterial(const std::string& _name, std::shared_ptr _data) { if (nullptr == _data) { @@ -1074,7 +455,7 @@ void ege::resource::Mesh::addPoint(const std::string& _layerName, const vec3& _p m_listFaces[_layerName].m_faces.push_back(tmpFace); } -void ege::resource::Mesh::addLine(const std::string& _layerName, const vec3& _pos1, const vec3& _pos2, const etk::Color& _color) { +void ege::resource::Mesh::addLine(const std::string& _layerName, const vec3& _pos1, const vec3& _pos2, const etk::Color& _color1, const etk::Color& _color2) { if ( m_listFaces.exist(_layerName) == false || m_materials.exist(_layerName) == false) { EGE_ERROR("Mesh layer : " << _layerName << " does not exist in list faces=" << m_listFaces.exist(_layerName) << " materials=" << m_listFaces.exist(_layerName) << " ..."); @@ -1091,13 +472,31 @@ void ege::resource::Mesh::addLine(const std::string& _layerName, const vec3& _po int32_t pos1 = findPositionInList(_pos1); int32_t pos2 = findPositionInList(_pos2); // try to find UV mapping: - int32_t color = findColorInList(_color); + int32_t color1 = findColorInList(_color1); + int32_t color2 = findColorInList(_color2); Face tmpFace; tmpFace.setVertex(pos1, pos2); - tmpFace.setColor(color, color, color); + tmpFace.setColor(color1, color2, color2); m_listFaces[_layerName].m_faces.push_back(tmpFace); } +void ege::resource::Mesh::addLines(const std::string& _layerName, const std::vector& _list, const etk::Color& _color) { + for (size_t iii=1; iii<_list.size(); ++iii) { + addLine(_layerName, _list[iii-1], _list[iii], _color); + } +} + +void ege::resource::Mesh::addLines(const std::string& _layerName, const std::vector& _list, const std::vector>& _color) { + if (_color.size() != _list.size()) { + EGE_ERROR("Can not add line with changing color without same number of color"); + return; + } + for (size_t iii=1; iii<_list.size(); ++iii) { + addLine(_layerName, _list[iii-1], _list[iii], _color[iii-1], _color[iii]); + } +} + + void ege::resource::Mesh::addTriangle(const std::string& _layerName, const vec3& _pos1, const vec3& _pos2, const vec3& _pos3, const vec2& _uv1, const vec2& _uv2, const vec2& _uv3, diff --git a/ege/resource/Mesh.h b/ege/resource/Mesh.h index d096bc2..c4b61fb 100644 --- a/ege/resource/Mesh.h +++ b/ege/resource/Mesh.h @@ -22,20 +22,18 @@ #include #include -// 3 "float" elements +// VBO table property: #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 ege { namespace resource { class Mesh : public ewol::Resource { + public: + static std::shared_ptr createGrid(int32_t _lineCount, const vec3& _position=vec3(0,0,0), float _size=1.0f, const std::string& _materialName="basics"); public: /** * @not-in-doc @@ -146,7 +144,12 @@ namespace ege { void addPoint(const std::string& _layerName, const vec3& _pos, const etk::Color& _color); - void addLine(const std::string& _layerName, const vec3& _pos1, const vec3& _pos2, const etk::Color& _color); + void addLine(const std::string& _layerName, const vec3& _pos1, const vec3& _pos2, const etk::Color& _color) { + addLine( _layerName, _pos1, _pos2, _color, _color); + } + void addLine(const std::string& _layerName, const vec3& _pos1, const vec3& _pos2, const etk::Color& _color1, const etk::Color& _color2); + void addLines(const std::string& _layerName, const std::vector& _list, const etk::Color& _color); + void addLines(const std::string& _layerName, const std::vector& _list, const std::vector>& _color); /** * @not-in-doc diff --git a/ege/resource/MeshEmf.cpp b/ege/resource/MeshEmf.cpp new file mode 100644 index 0000000..012958b --- /dev/null +++ b/ege/resource/MeshEmf.cpp @@ -0,0 +1,512 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#include +#include +#include + + + +static void jumpEndLine(etk::FSNode& _file) { + char current=_file.fileGet(); + while( current != '\0' + && current != '\n') { + //printf("%c", current); + current=_file.fileGet(); + } +} + +static int32_t countIndent(etk::FSNode& _file) { + int32_t nbIndent=0; + int32_t nbSpacesTab=0; + int32_t nbChar=0; + //EGE_DEBUG(" start count Indent"); + for(char current=_file.fileGet(); current != '\0'; current=_file.fileGet()) { + nbChar++; + //EGE_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; + } + } + //EGE_DEBUG("indent : " << nbIndent); + _file.fileSeek(-nbChar, etk::FSN_SEEK_CURRENT); + return nbIndent; +} + +static 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 nullptr; + } + */ + 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'; + //EGE_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 nullptr; + } else { + // send last line + return _elementLine; + } + return nullptr; +} + +static 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, +}; + +// TODO : rework with string line extractor +bool ege::resource::Mesh::loadEMF(const std::string& _fileName) { + m_checkNormal = true; + m_normalMode = normalModeNone; + etk::FSNode fileName(_fileName); + // get the fileSize ... + int32_t size = fileName.fileSize(); + if (size == 0 ) { + EGE_ERROR("No data in the file named=\"" << fileName << "\""); + return false; + } + if(false == fileName.fileOpenRead() ) { + EGE_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)) { + EGE_ERROR(" file binary mode is not supported now : 'EMF(BINARY)'"); + return false; + } else { + EGE_ERROR(" file mode is not supported now : 'EMF(? ? ?)' = '" << inputDataLine << "'"); + return false; + } + enum emfModuleMode currentMode = EMFModuleNone; + EGE_VERBOSE("Start parsing Mesh file : " << fileName); + // mesh global param : + std::string currentMeshName = ""; + int32_t meshFaceMaterialID = -1; + // material global param : + std::string materialName = ""; + std::shared_ptr material; + // physical shape: + std::shared_ptr physics; + while(1) { + int32_t level = countIndent(fileName); + if (level == 0) { + // new section ... + if (nullptr == loadNextData(inputDataLine, 2048, fileName)) { + // reach end of file ... + break; + } + if(0 == strncmp(inputDataLine, "Mesh :", 6) ) { + currentMode = EMFModuleMesh; + EGE_VERBOSE("Parse Mesh :"); + } else if(0 == strncmp(inputDataLine, "Materials : ", 11) ) { + currentMode = EMFModuleMaterial; + EGE_VERBOSE("Parse Material :"); + } else { + currentMode = EMFModuleNone; + } + } else { + if (currentMode >= EMFModuleMesh && currentMode <= EMFModuleMesh_END) { + if (level == 1) { + //Find mesh name ... + if (nullptr == loadNextData(inputDataLine, 2048, fileName, true)) { + // reach end of file ... + break; + } + removeEndLine(inputDataLine); + currentMeshName = inputDataLine; + currentMode = EMFModuleMeshNamed; + EGE_VERBOSE(" "<< currentMeshName); + continue; + } + if (level == 2) { + // In the mesh level 2 the line size must not exced 2048 + if (nullptr == loadNextData(inputDataLine, 2048, fileName, true)) { + // reach end of file ... + break; + } + removeEndLine(inputDataLine); + if(0 == strncmp(inputDataLine, "Vertex", 6) ) { + currentMode = EMFModuleMeshVertex; + EGE_VERBOSE(" Vertex ..."); + } else if(0 == strncmp(inputDataLine, "UV-mapping", 10) ) { + currentMode = EMFModuleMeshUVMapping; + EGE_VERBOSE(" UV-mapping ..."); + } else if(0 == strncmp(inputDataLine, "Normal(vertex)", 14) ) { + currentMode = EMFModuleMeshNormalVertex; + EGE_VERBOSE(" Normal(vertex) ..."); + } else if(0 == strncmp(inputDataLine, "Normal(face)", 12) ) { + currentMode = EMFModuleMeshNormalFace; + EGE_VERBOSE(" Normal(face) ..."); + } else if(0 == strncmp(inputDataLine, "Face", 4) ) { + currentMode = EMFModuleMeshFace; + EGE_VERBOSE(" Face ..."); + } else if(0 == strncmp(inputDataLine, "Physics", 7) ) { + currentMode = EMFModuleMeshPhysics; + EGE_VERBOSE(" Physics ..."); + } else { + EGE_ERROR(" Unknow mesh property '"< 2 + switch (currentMode) { + default: + EGE_ERROR("Unknow ... "<< level); + jumpEndLine(fileName); + break; + case EMFModuleMeshVertex: { + vec3 vertex(0,0,0); + while (nullptr != 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; + } + } + EGE_VERBOSE(" " << m_listVertex.size() << " vertex"); + break; + } + case EMFModuleMeshUVMapping: { + vec2 uvMap(0,0); + while (nullptr != 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; + } + } + EGE_VERBOSE(" " << m_listUV.size() << " coord"); + break; + } + case EMFModuleMeshNormalVertex: { + m_normalMode = normalModeVertex; + vec3 normal(0,0,0); + // find the vertex Normal list. + while (nullptr != 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; + } + } + EGE_VERBOSE(" " << m_listVertexNormal.size() << " Normals"); + break; + } + case EMFModuleMeshNormalFace: { + m_normalMode = normalModeFace; + vec3 normal(0,0,0); + // find the face Normal list. + while (nullptr != 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; + } + } + EGE_VERBOSE(" " << m_listFacesNormal.size() << " Normals"); + break; + } + case EMFModuleMeshFace: + case EMFModuleMeshFaceMaterial: + if (level == 3) { + //Find mesh name ... + if (nullptr == 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); + EGE_VERBOSE(" " << inputDataLine); + } else if (currentMode == EMFModuleMeshFaceMaterial) { + while (nullptr != 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; + sscanf(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])); + /* + EGE_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; + } + } + EGE_VERBOSE(" " << m_listFaces.getValue(meshFaceMaterialID).m_faces.size() << " faces"); + } else { + // insert element without material ... + EGE_ERROR(" try to add face without material selection ..."); + jumpEndLine(fileName); + } + break; + case EMFModuleMeshPhysics: + case EMFModuleMeshPhysicsNamed: + if (nullptr == loadNextData(inputDataLine, 2048, fileName, true, false, false)) { + // reach end of file ... + break; + } + removeEndLine(inputDataLine); + if (level == 3) { + physics = ege::PhysicsShape::create(inputDataLine); + if (physics == nullptr) { + EGE_ERROR("Allocation error when creating physical shape ..."); + continue; + } + m_physics.push_back(physics); + EGE_VERBOSE(" " << m_physics.size() << " " << inputDataLine); + currentMode = EMFModuleMeshPhysicsNamed; + } else if (currentMode == EMFModuleMeshPhysicsNamed) { + if (physics == nullptr) { + EGE_ERROR("Can not parse :'" << inputDataLine << "' in physical shape ..."); + continue; + } + if (false == physics->parse(inputDataLine)) { + EGE_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 (nullptr == loadNextData(inputDataLine, 2048, fileName, true)) { + // reach end of file ... + break; + } + removeEndLine(inputDataLine); + if (level == 1) { + // add previous material : + if( materialName != "" + && material!=nullptr) { + m_materials.add(materialName, material); + materialName = ""; + material = nullptr; + } + material = std::make_shared(); + materialName = inputDataLine; + currentMode = EMFModuleMaterialNamed; + EGE_VERBOSE(" "<< materialName); + continue; + } + // level >1 + if (currentMode != EMFModuleMaterialNamed) { + EGE_WARNING(" Unknow element ..."<< level); + jumpEndLine(fileName); + continue; + } + if (nullptr == material) { + EGE_ERROR("material allocation error"); + jumpEndLine(fileName); + continue; + } + if(0 == strncmp(inputDataLine,"Ns ",3)) { + float tmpVal=0; + sscanf(&inputDataLine[3], "%f", &tmpVal); + material->setShininess(tmpVal); + EGE_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); + EGE_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); + EGE_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); + EGE_VERBOSE(" SpecularFactor " << tmp); + } else if(0 == strncmp(inputDataLine,"Ni ",3)) { + float tmpVal=0; + sscanf(&inputDataLine[3], "%f", &tmpVal); + // TODO : ... + EGE_VERBOSE(" Ni " << tmpVal); + } else if(0 == strncmp(inputDataLine,"d ",2)) { + float tmpVal=0; + sscanf(&inputDataLine[2], "%f", &tmpVal); + // TODO : ... + EGE_VERBOSE(" d " << tmpVal); + } else if(0 == strncmp(inputDataLine,"illum ",6)) { + int tmpVal=0; + sscanf(&inputDataLine[6], "%d", &tmpVal); + // TODO : ... + EGE_VERBOSE(" illum " << tmpVal); + } else if(0 == strncmp(inputDataLine,"map_Kd ",7)) { + material->setTexture0(fileName.getRelativeFolder() + &inputDataLine[7]); + EGE_VERBOSE(" Texture " << &inputDataLine[7]); + } else if(0 == strncmp(inputDataLine,"renderMode ",11)) { + ewol::openGL::renderMode mode; + etk::from_string(mode, &inputDataLine[11]); + material->setRenderMode(mode); + EGE_VERBOSE(" Texture " << mode); + } else { + EGE_ERROR("unknow material property ... : '" << inputDataLine << "'"); + } + } else { + // unknow ... + EGE_WARNING("Unknow type of line == > jump end of line ... "); + jumpEndLine(fileName); + } + } + } + // add last material ... + if( materialName != "" + && material!=nullptr) { + m_materials.add(materialName, material); + materialName = ""; + material.reset(); + } + EGE_VERBOSE("Stop parsing Mesh file"); + + fileName.fileClose(); + generateVBO(); + return true; +} \ No newline at end of file diff --git a/ege/resource/MeshGird.cpp b/ege/resource/MeshGird.cpp new file mode 100644 index 0000000..52c811c --- /dev/null +++ b/ege/resource/MeshGird.cpp @@ -0,0 +1,80 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#include +#include + +std::shared_ptr ege::resource::Mesh::createGrid(int32_t _lineCount, const vec3& _position, float _size, const std::string& _materialName) { + std::shared_ptr out = ege::resource::Mesh::create("---", "DATA:color3.prog"); + float lineSize = 0.1f; + if (out != nullptr) { + std::shared_ptr material = std::make_shared(); + // set the element material properties : + material->setAmbientFactor(vec4(1,1,1,1)); + material->setDiffuseFactor(vec4(0,0,0,1)); + material->setSpecularFactor(vec4(0,0,0,1)); + material->setShininess(1); + material->setRenderMode(ewol::openGL::renderLine); + //material->setRenderMode(ewol::openGL::renderPoint); + out->addMaterial(_materialName, material); + + out->addFaceIndexing(_materialName); + // create X lines + for (int32_t iii=-_lineCount; iii<=_lineCount; ++iii) { + if (iii==0) { + out->addLine(_materialName, _position+vec3(-_lineCount,0,0)*_size, _position+vec3(_lineCount+1,0,0)*_size, etk::color::red); + out->addLine(_materialName, _position+vec3(_lineCount+1.0f,0,0)*_size, _position+vec3(_lineCount+0.5f,0.5f,0)*_size, etk::color::red); + out->addLine(_materialName, _position+vec3(_lineCount+1.0f,0,0)*_size, _position+vec3(_lineCount+0.5f,-0.5f,0)*_size, etk::color::red); + out->addLine(_materialName, _position+vec3(_lineCount+1.0f,0,0)*_size, _position+vec3(_lineCount+0.5f,0,0.5f)*_size, etk::color::red); + out->addLine(_materialName, _position+vec3(_lineCount+1.0f,0,0)*_size, _position+vec3(_lineCount+0.5f,0,-0.5f)*_size, etk::color::red); + } else { + out->addLine(_materialName, _position+vec3(-_lineCount,iii,0)*_size, _position+vec3(_lineCount,iii,0)*_size, etk::color::gray); + } + //out->addPoint(_materialName, vec3(-_lineCount,iii,0), etk::color::white); + //out->addPoint(_materialName, vec3(_lineCount,iii,0), etk::color::white); + } + // create Y lines + for (int32_t iii=-_lineCount; iii<=_lineCount; ++iii) { + if (iii==0) { + out->addLine(_materialName, _position+vec3(0,-_lineCount,0)*_size, _position+vec3(0,_lineCount+1,0)*_size, etk::color::green); + out->addLine(_materialName, _position+vec3(0,_lineCount+1.0f,0)*_size, _position+vec3(0.5f,_lineCount+0.5f,0)*_size, etk::color::green); + out->addLine(_materialName, _position+vec3(0,_lineCount+1.0f,0)*_size, _position+vec3(-0.5f,_lineCount+0.5f,0)*_size, etk::color::green); + out->addLine(_materialName, _position+vec3(0,_lineCount+1.0f,0)*_size, _position+vec3(0,_lineCount+0.5f,0.5f)*_size, etk::color::green); + out->addLine(_materialName, _position+vec3(0,_lineCount+1.0f,0)*_size, _position+vec3(0,_lineCount+0.5f,-0.5f)*_size, etk::color::green); + } else { + out->addLine(_materialName, _position+vec3(iii,-_lineCount,0)*_size, _position+vec3(iii,_lineCount,0)*_size, etk::color::gray); + } + //out->addPoint(_materialName, vec3(iii,-_lineCount,0), etk::color::white); + //out->addPoint(_materialName, vec3(iii,_lineCount,0), etk::color::white); + } + // create Z lines + for (int32_t iii=-_lineCount; iii<=_lineCount; ++iii) { + if (iii==0) { + out->addLine(_materialName, _position+vec3(0,0,-_lineCount)*_size, _position+vec3(0,0,_lineCount+1)*_size, etk::color::blue); + out->addLine(_materialName, _position+vec3(0,0,_lineCount+1)*_size, _position+vec3(0.5f,0,_lineCount+0.5f)*_size, etk::color::blue); + out->addLine(_materialName, _position+vec3(0,0,_lineCount+1)*_size, _position+vec3(-0.5f,0,_lineCount+0.5f)*_size, etk::color::blue); + out->addLine(_materialName, _position+vec3(0,0,_lineCount+1)*_size, _position+vec3(0,0.5f,_lineCount+0.5f)*_size, etk::color::blue); + out->addLine(_materialName, _position+vec3(0,0,_lineCount+1)*_size, _position+vec3(0,-0.5f,_lineCount+0.5f)*_size, etk::color::blue); + } else { + std::vector list; + list.push_back(_position+vec3(-1,-1,iii)*_size); + list.push_back(_position+vec3(1,-1,iii)*_size); + list.push_back(_position+vec3(1,1,iii)*_size); + list.push_back(_position+vec3(-1,1,iii)*_size); + list.push_back(_position+vec3(-1,-1,iii)*_size); + out->addLines(_materialName, list, etk::color::gray); + } + //out->addPoint(_materialName, vec3(iii,-_lineCount,0), etk::color::white); + //out->addPoint(_materialName, vec3(iii,_lineCount,0), etk::color::white); + } + + // generate the VBO + out->generateVBO(); + } + return out; +} \ No newline at end of file diff --git a/ege/resource/MeshObj.cpp b/ege/resource/MeshObj.cpp new file mode 100644 index 0000000..1c6a40d --- /dev/null +++ b/ege/resource/MeshObj.cpp @@ -0,0 +1,134 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#include +#include + + +bool ege::resource::Mesh::loadOBJ(const std::string& _fileName) { + m_normalMode = normalModeNone; +#if 0 + etk::FSNode fileName(_fileName); + // get the fileSize ... + int32_t size = fileName.fileSize(); + if (size == 0 ) { + EGE_ERROR("No data in the file named=\"" << fileName << "\""); + return false; + } + if(false == fileName.fileOpenRead() ) { + EGE_ERROR("Can not find the file name=\"" << fileName << "\""); + return false; + } + char inputDataLine[2048]; + + int32_t lineID = 0; + while (nullptr != 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){ + EGE_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)); + } + /* + EGE_DEBUG(" plop : " << tmpFace.m_nbElement << " ? " << m_listFaces[m_listFaces.size()-1].m_nbElement); + EGE_DEBUG(" : " << tmpFace.m_vertex[0] << " ? " << m_listFaces[m_listFaces.size()-1].m_vertex[0]); + EGE_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; +} diff --git a/lutin_ege.py b/lutin_ege.py index 0ecf818..6a44fa6 100644 --- a/lutin_ege.py +++ b/lutin_ege.py @@ -30,6 +30,9 @@ def create(target): 'ege/widget/Scene.cpp', 'ege/Environement.cpp', 'ege/resource/Mesh.cpp', + 'ege/resource/MeshEmf.cpp', + 'ege/resource/MeshGird.cpp', + 'ege/resource/MeshObj.cpp', 'ege/resource/ParticuleMesh.cpp', 'ege/resource/tools/icoSphere.cpp', 'ege/resource/tools/isoSphere.cpp', diff --git a/sample/CameraPosition/README.md b/sample/CameraPosition/README.md index e69de29..8db39b2 100644 --- a/sample/CameraPosition/README.md +++ b/sample/CameraPosition/README.md @@ -0,0 +1 @@ +Camera position sample example \ No newline at end of file diff --git a/sample/CameraPosition/appl/Windows.cpp b/sample/CameraPosition/appl/Windows.cpp new file mode 100644 index 0000000..f28eabb --- /dev/null +++ b/sample/CameraPosition/appl/Windows.cpp @@ -0,0 +1,99 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2010, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef __class__ +#define __class__ "Windows" + +appl::Windows::Windows() { + addObjectType("appl::Windows"); +} + + + + + +void appl::Windows::init() { + ewol::widget::Windows::init(); + setTitle("example ege : CameraPosirion"); + + getObjectManager().periodicCall.bind(shared_from_this(), &appl::Windows::onCallbackPeriodicUpdateCamera); + + m_env = ege::Environement::create(); + // Create basic Camera + m_camera = std::make_shared(vec3(30,30,-100), vec3(0,0,0)); + m_env->addCamera("basic", m_camera); + + std::shared_ptr tmpWidget = ege::widget::Scene::create(m_env); + if (tmpWidget == nullptr) { + APPL_ERROR("Can not allocate widget ==> display might be in error"); + } else { + tmpWidget->setExpand(bvec2(true,true)); + tmpWidget->setFill(bvec2(true,true)); + tmpWidget->setCamera("basic"); + setSubWidget(tmpWidget); + } + // Create an external box : + std::shared_ptr myMesh = ege::resource::Mesh::create("---", "DATA:texturedNoMaterial.prog"); + if (myMesh != nullptr) { + std::shared_ptr material = std::make_shared(); + // set the element material properties : + material->setAmbientFactor(vec4(1,1,1,1)); + material->setDiffuseFactor(vec4(0,0,0,1)); + material->setSpecularFactor(vec4(0,0,0,1)); + material->setShininess(1); + material->setTexture0(""); //" + myMesh->addMaterial("basics", material); + // 1024 == > 1<<9 + // 2048 == > 1<<10 + // 4096 == > 1<<11 + int32_t size = 1<<11; + material->setImageSize(ivec2(size,size)); + egami::Image* myImage = material->get(); + if (nullptr == myImage) { + return; + } + myImage->clear(etk::color::black); + ivec2 tmpPos; + for (int32_t iii=0; iii<6000; iii++) { + tmpPos.setValue(etk::tool::frand(0,size), etk::tool::frand(0,size)) ; + myImage->set(tmpPos, etk::color::white); + } + material->flush(); + // basis on cube : + myMesh->createViewBox("basics", 1000/* distance */); + // generate the VBO + myMesh->generateVBO(); + m_env->addStaticMeshToDraw(myMesh); + } + myMesh = ege::resource::Mesh::createGrid(10, vec3(0,0,0), 5); + if (myMesh != nullptr) { + m_env->addStaticMeshToDraw(myMesh); + } +} + + +void appl::Windows::onCallbackPeriodicUpdateCamera(const ewol::event::Time& _event) { + static float offset = 0; + offset += 0.01; + static float offset2 = 0; + offset2 += 0.003; + m_camera->setEye(vec3(100*std::sin(offset),100*std::cos(offset),40*std::cos(offset2))); +} + + diff --git a/sample/CameraPosition/appl/Windows.h b/sample/CameraPosition/appl/Windows.h new file mode 100644 index 0000000..2e1c631 --- /dev/null +++ b/sample/CameraPosition/appl/Windows.h @@ -0,0 +1,33 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2010, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + +#ifndef __APPL_WINDOWS_H__ +#define __APPL_WINDOWS_H__ + +#include +#include +#include + +namespace appl { + class Windows : public ewol::widget::Windows { + private: + std::shared_ptr m_env; + std::shared_ptr m_camera; + protected: + Windows(); + void init(); + public: + DECLARE_FACTORY(Windows); + virtual ~Windows() { }; + private: + void onCallbackPeriodicUpdateCamera(const ewol::event::Time& _event); + }; +}; + + +#endif \ No newline at end of file diff --git a/sample/CameraPosition/appl/debug.cpp b/sample/CameraPosition/appl/debug.cpp new file mode 100644 index 0000000..07299b6 --- /dev/null +++ b/sample/CameraPosition/appl/debug.cpp @@ -0,0 +1,15 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2010, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + + +#include + +int32_t appl::getLogId() { + static int32_t g_val = etk::log::registerInstance("GP-spaceShip"); + return g_val; +} diff --git a/sample/CameraPosition/appl/debug.h b/sample/CameraPosition/appl/debug.h new file mode 100644 index 0000000..8036fb5 --- /dev/null +++ b/sample/CameraPosition/appl/debug.h @@ -0,0 +1,52 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2010, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + + +#ifndef __APPL_DEBUG_H__ +#define __APPL_DEBUG_H__ + +#include + +namespace appl { + int32_t getLogId(); +}; +// TODO : Review this problem of multiple intanciation of "std::stringbuf sb" +#define APPL_BASE(info,data) \ + do { \ + if (info <= etk::log::getLevel(appl::getLogId())) { \ + std::stringbuf sb; \ + std::ostream tmpStream(&sb); \ + tmpStream << data; \ + etk::log::logStream(appl::getLogId(), info, __LINE__, __class__, __func__, tmpStream); \ + } \ + } while(0) + +#define APPL_CRITICAL(data) APPL_BASE(1, data) +#define APPL_ERROR(data) APPL_BASE(2, data) +#define APPL_WARNING(data) APPL_BASE(3, data) +#ifdef DEBUG + #define APPL_INFO(data) APPL_BASE(4, data) + #define APPL_DEBUG(data) APPL_BASE(5, data) + #define APPL_VERBOSE(data) APPL_BASE(6, data) + #define APPL_TODO(data) APPL_BASE(4, "TODO : " << data) +#else + #define APPL_INFO(data) do { } while(false) + #define APPL_DEBUG(data) do { } while(false) + #define APPL_VERBOSE(data) do { } while(false) + #define APPL_TODO(data) do { } while(false) +#endif + +#define APPL_ASSERT(cond,data) \ + do { \ + if (!(cond)) { \ + APPL_CRITICAL(data); \ + assert(!#cond); \ + } \ + } while (0) + +#endif diff --git a/sample/CameraPosition/appl/main.cpp b/sample/CameraPosition/appl/main.cpp new file mode 100644 index 0000000..ba5e841 --- /dev/null +++ b/sample/CameraPosition/appl/main.cpp @@ -0,0 +1,57 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2010, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + + +#include +#include +#include + +#include +#include +#include +#include +#include + + +class MainApplication : public ewol::context::Application { + public: + bool init(ewol::Context& _context, size_t _initId) { + APPL_INFO("==> Init APPL (START) [" << ewol::getBoardType() << "] (" << ewol::getCompilationMode() << ")"); + + // TODO : Remove this : Move if in the windows properties + _context.setSize(vec2(800, 600)); + + // select internal data for font ... + _context.getFontDefault().setUseExternal(true); + _context.getFontDefault().set("FreeSerif;DejaVuSansMono", 19); + + std::shared_ptr basicWindows = appl::Windows::create(); + // create the specific windows + _context.setWindows(basicWindows); + APPL_INFO("==> Init APPL (END)"); + return true; + } + + void unInit(ewol::Context& _context) { + APPL_INFO("==> Un-Init APPL (START)"); + // nothing to do ... + APPL_INFO("==> Un-Init APPL (END)"); + } +}; + +/** + * @brief Main of the program (This can be set in every case, but it is not used in Andoid...). + * @param std IO + * @return std IO + */ +int main(int _argc, const char *_argv[]) { + // second possibility + return ewol::run(new MainApplication(), _argc, _argv); +} + + diff --git a/sample/CameraPosition/appl/main.h b/sample/CameraPosition/appl/main.h new file mode 100644 index 0000000..caa7110 --- /dev/null +++ b/sample/CameraPosition/appl/main.h @@ -0,0 +1,14 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2010, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + +#ifndef __APPL_MAIN_H__ +#define __APPL_MAIN_H__ + + +#endif + diff --git a/sample/CameraPosition/data/texture_mars.png b/sample/CameraPosition/data/texture_mars.png new file mode 100644 index 0000000..8584cf8 Binary files /dev/null and b/sample/CameraPosition/data/texture_mars.png differ diff --git a/sample/CameraPosition/lutin_egeCameraPosition.py b/sample/CameraPosition/lutin_egeCameraPosition.py new file mode 100644 index 0000000..4073722 --- /dev/null +++ b/sample/CameraPosition/lutin_egeCameraPosition.py @@ -0,0 +1,40 @@ +#!/usr/bin/python +import lutinModule as module +import lutinTools as tools +import lutinDebug as debug +import datetime + + +def get_desc(): + return "ege sample : CameraPisition" + +def create(target): + # module name is 'edn' and type binary. + myModule = module.Module(__file__, 'egeCameraPosition', 'PACKAGE') + + myModule.add_src_file([ + 'appl/debug.cpp', + 'appl/main.cpp', + 'appl/Windows.cpp' + ]) + + myModule.add_module_depend('ege') + + myModule.add_path(tools.get_current_path(__file__)) + + myModule.copy_folder("data/*") + + # set the package properties : + myModule.pkg_set("VERSION", "0.0.0") + myModule.pkg_set("VERSION_CODE", "0") + myModule.pkg_set("COMPAGNY_TYPE", "org") + myModule.pkg_set("COMPAGNY_NAME", "ege") + myModule.pkg_set("MAINTAINER", ["noOne "]) + myModule.pkg_set("SECTION", ["Game"]) + myModule.pkg_set("PRIORITY", "optional") + myModule.pkg_set("DESCRIPTION", "ege sample : MeshCreator") + myModule.pkg_set("NAME", "egeMeshCreator") + + # add the currrent module at the + return myModule + diff --git a/sample/MeshCreator/appl/Windows.cpp b/sample/MeshCreator/appl/Windows.cpp index c018bb8..646b9d1 100644 --- a/sample/MeshCreator/appl/Windows.cpp +++ b/sample/MeshCreator/appl/Windows.cpp @@ -25,39 +25,7 @@ appl::Windows::Windows() { } -static std::shared_ptr createGrid(int32_t _lineCount) { - std::shared_ptr out = ege::resource::Mesh::create("---", "DATA:color3.prog"); - float lineSize = 0.1f; - if (out != nullptr) { - std::shared_ptr material = std::make_shared(); - // set the element material properties : - material->setAmbientFactor(vec4(1,1,1,1)); - material->setDiffuseFactor(vec4(0,0,0,1)); - material->setSpecularFactor(vec4(0,0,0,1)); - material->setShininess(1); - material->setRenderMode(ewol::openGL::renderLine); - //material->setRenderMode(ewol::openGL::renderPoint); - out->addMaterial("basics", material); - - out->addFaceIndexing("basics"); - // create horizontal lines - for (int32_t iii=-_lineCount; iii<=_lineCount; ++iii) { - out->addLine("basics", vec3(-_lineCount,iii,0), vec3(_lineCount,iii,0), etk::color::white); - //out->addPoint("basics", vec3(-_lineCount,iii,0), etk::color::white); - //out->addPoint("basics", vec3(_lineCount,iii,0), etk::color::white); - } - // create vertical lines - for (int32_t iii=-_lineCount; iii<=_lineCount; ++iii) { - out->addLine("basics", vec3(iii,-_lineCount,0), vec3(iii,_lineCount,0), etk::color::white); - //out->addPoint("basics", vec3(iii,-_lineCount,0), etk::color::white); - //out->addPoint("basics", vec3(iii,_lineCount,0), etk::color::white); - } - - // generate the VBO - out->generateVBO(); - } - return out; -} + void appl::Windows::init() { @@ -113,7 +81,7 @@ void appl::Windows::init() { myMesh->generateVBO(); m_env->addStaticMeshToDraw(myMesh); } - myMesh = createGrid(10); + myMesh = ege::resource::Mesh::createGrid(10, vec3(0,0,0), 5); if (myMesh != nullptr) { m_env->addStaticMeshToDraw(myMesh); } @@ -141,11 +109,13 @@ void appl::Windows::init() { void appl::Windows::onCallbackPeriodicUpdateCamera(const ewol::event::Time& _event) { + /* static float offset = 0; offset += 0.01; static float offset2 = 0; offset2 += 0.003; m_camera->setEye(vec3(100*std::sin(offset),100*std::cos(offset),40*std::cos(offset2))+vec3(50,0,0)); + */ }