diff --git a/sources/ewol/renderer/resources/Mesh.cpp b/sources/ewol/renderer/resources/Mesh.cpp index 2f2cc0a6..33d574d5 100644 --- a/sources/ewol/renderer/resources/Mesh.cpp +++ b/sources/ewol/renderer/resources/Mesh.cpp @@ -10,6 +10,52 @@ #include #include +typedef enum { + VERTEX_OLD, + VERTEX_CENTER_FACE, + VERTEX_CERTER_EDGE +} vertex_te; + +class VertexNode { + private: + vertex_te m_type; + vec3 m_pos; + etk::Vector m_link; + public: + VertexNode(vertex_te type, const vec3& pos) : + m_type(type), + m_pos(pos) + { + + }; + void AddLink(int32_t id) + { + for(int32_t iii=0; iii& GetLink(void) + { + return m_link; + }; + +}; + // 3 "float" elements #define MESH_VBO_VERTICES (0) @@ -250,6 +296,21 @@ int32_t CreateOrGetNewPointId(const vec3& point, etk::Vector& list) return list.Size()-1; } +int32_t CreateOrGetNewPointId2(vertex_te type, const vec3& point, etk::Vector& list) +{ + for (int32_t iii=0; iiiGetPos() == point) { + return iii; + } + } + VertexNode* tmpElement = new VertexNode(type, point); + if (NULL==tmpElement) { + EWOL_CRITICAL ("allocation error"); + } + list.PushBack(tmpElement); + return list.Size()-1; +} + int32_t CreateOrGetNewTexId(const vec2& point, etk::Vector& list) { for (int32_t iii=0; iii& list) void ewol::Mesh::InternalSubdivide(bool smooth) { - //Copy the mesh for modify this one and not his parrent (that one is needed for smoothing) - etk::Vector listVertex(m_listVertex); - etk::Vector listUV(m_listUV); - etk::Vector listFaces; // no face here ... - etk::Vector listElementHalfPoint(16);// preallocate at 16.. - etk::Vector listElementHalfUV(16);// preallocate at 16.. - - for (int32_t iii=0; iii o.. ..o - / \ / ''o'' \ - / \ / | \ - / \ / | \ - / \ / | \ - o-------------------o o---------o---------o - - */ - } else { - // create the center point: - centerPoint = ( m_listVertex[m_listFaces[iii].m_vertex[0]] - + m_listVertex[m_listFaces[iii].m_vertex[1]] - + m_listVertex[m_listFaces[iii].m_vertex[2]] - + m_listVertex[m_listFaces[iii].m_vertex[3]] ) / vec3(4,4,4); - // create the center Texture coord: - centerTex = ( listUV[m_listFaces[iii].m_uv[0]] - + listUV[m_listFaces[iii].m_uv[1]] - + listUV[m_listFaces[iii].m_uv[2]] - + listUV[m_listFaces[iii].m_uv[3]] ) / vec2(4,4); - /* - - o---------------------o o----------o----------o - | | | | | - | | | | | - | | | | | - | | | | | - | | | | | - | | ==> o----------o----------o - | | | | | - | | | | | - | | | | | - | | | | | - | | | | | - o---------------------o o----------o----------o - - */ - } + if (false==smooth) { + //Copy the mesh for modify this one and not his parrent (that one is needed for smoothing) + etk::Vector listVertex(m_listVertex); + etk::Vector listUV(m_listUV); + etk::Vector listFaces; // no face here ... + etk::Vector listElementHalfPoint(16);// preallocate at 16.. + etk::Vector listElementHalfUV(16);// preallocate at 16.. - int32_t newCenterVertexID = CreateOrGetNewPointId(centerPoint, listVertex); - int32_t newCenterTexID = CreateOrGetNewTexId(centerTex, listUV); - - listElementHalfPoint.Clear(); - listElementHalfUV.Clear(); - // generate list f the forder elements - for (int32_t jjj=0; jjj o.. ..o + / \ / ''o'' \ + / \ / | \ + / \ / | \ + / \ / | \ + o-------------------o o---------o---------o + + */ + } else { + // create the center point: + centerPoint = ( m_listVertex[m_listFaces[iii].m_vertex[0]] + + m_listVertex[m_listFaces[iii].m_vertex[1]] + + m_listVertex[m_listFaces[iii].m_vertex[2]] + + m_listVertex[m_listFaces[iii].m_vertex[3]] ) / vec3(4,4,4); + // create the center Texture coord: + centerTex = ( listUV[m_listFaces[iii].m_uv[0]] + + listUV[m_listFaces[iii].m_uv[1]] + + listUV[m_listFaces[iii].m_uv[2]] + + listUV[m_listFaces[iii].m_uv[3]] ) / vec2(4,4); + /* + + o---------------------o o----------o----------o + | | | | | + | | | | | + | | | | | + | | | | | + | | | | | + | | ==> o----------o----------o + | | | | | + | | | | | + | | | | | + | | | | | + | | | | | + o---------------------o o----------o----------o + + */ + } - listElementHalfPoint.PushBack(m_listFaces[iii].m_vertex[jjj]); - listElementHalfUV.PushBack(m_listFaces[iii].m_uv[jjj]); - // calculate and add middle point : - vec3 middlePoint = ( m_listVertex[m_listFaces[iii].m_vertex[jjj]] - + m_listVertex[m_listFaces[iii].m_vertex[cyclicID]] ) / 2.0f; - int32_t newMiddleVertexID = CreateOrGetNewPointId(middlePoint, listVertex); - listElementHalfPoint.PushBack(newMiddleVertexID); - // create the center Texture coord: - vec2 middleTex = ( listUV[m_listFaces[iii].m_uv[jjj]] - + listUV[m_listFaces[iii].m_uv[cyclicID]]) / 2.0f; - int32_t newMiddleTexID = CreateOrGetNewTexId(middleTex, listUV); - listElementHalfUV.PushBack(newMiddleTexID); + int32_t newCenterVertexID = CreateOrGetNewPointId(centerPoint, listVertex); + int32_t newCenterTexID = CreateOrGetNewTexId(centerTex, listUV); + + listElementHalfPoint.Clear(); + listElementHalfUV.Clear(); + // generate list f the forder elements + for (int32_t jjj=0; jjj listVertex; + for(int32_t iii=0; iii listUV(m_listUV); + etk::Vector listFaces; // no face here ... + etk::Vector listElementHalfPoint(16);// preallocate at 16.. + etk::Vector listElementHalfUV(16);// preallocate at 16.. + for (int32_t iii=0; iii o.. ..o + / \ / ''o'' \ + / \ / | \ + / \ / | \ + / \ / | \ + o-------------------o o---------o---------o + + */ + } else { + // create the center point: + centerPoint = ( m_listVertex[m_listFaces[iii].m_vertex[0]] + + m_listVertex[m_listFaces[iii].m_vertex[1]] + + m_listVertex[m_listFaces[iii].m_vertex[2]] + + m_listVertex[m_listFaces[iii].m_vertex[3]] ) / vec3(4,4,4); + // create the center Texture coord: + centerTex = ( listUV[m_listFaces[iii].m_uv[0]] + + listUV[m_listFaces[iii].m_uv[1]] + + listUV[m_listFaces[iii].m_uv[2]] + + listUV[m_listFaces[iii].m_uv[3]] ) / vec2(4,4); + /* + + o---------------------o o----------o----------o + | | | | | + | | | | | + | | | | | + | | | | | + | | | | | + | | ==> o----------o----------o + | | | | | + | | | | | + | | | | | + | | | | | + | | | | | + o---------------------o o----------o----------o + + */ + } + + int32_t newCenterVertexID = CreateOrGetNewPointId2(VERTEX_CENTER_FACE, centerPoint, listVertex); + int32_t newCenterTexID = CreateOrGetNewTexId(centerTex, listUV); + + listElementHalfPoint.Clear(); + listElementHalfUV.Clear(); + // generate list f the forder elements + for (int32_t jjj=0; jjjAddLink(newCenterVertexID); + // add center of edge end face at the old element point : + listVertex[m_listFaces[iii].m_vertex[jjj]]->AddLink(newCenterVertexID); + listVertex[m_listFaces[iii].m_vertex[jjj]]->AddLink(newMiddleVertexID); + listVertex[m_listFaces[iii].m_vertex[cyclicID]]->AddLink(newCenterVertexID); + listVertex[m_listFaces[iii].m_vertex[cyclicID]]->AddLink(newMiddleVertexID); + // list of all middle point to recontitute the faces + listElementHalfPoint.PushBack(newMiddleVertexID); + // create the center Texture coord: + vec2 middleTex = ( listUV[m_listFaces[iii].m_uv[jjj]] + + listUV[m_listFaces[iii].m_uv[cyclicID]]) / 2.0f; + int32_t newMiddleTexID = CreateOrGetNewTexId(middleTex, listUV); + listElementHalfUV.PushBack(newMiddleTexID); + } + // generate faces: + //EWOL_DEBUG(" ==> Generatedd faces"); + for (int32_t jjj=0; jjj Update middle edge points position"); + // reposition the Middle point of the edge + for(int32_t iii=0; iiiGetType()) { + // generate barycenter of all link point if > 1... + etk::Vector& link = listVertex[iii]->GetLink(); + if (1GetPos(); + for(int32_t jjj=0; jjj= listVertex.Size()) { + EWOL_ERROR("Id is out of bounds ... : " << iii << " link=" << link[jjj] << " / " << listVertex.Size()); + continue; + } + if(NULL == listVertex[link[jjj]]) { + continue; + } + if (VERTEX_CENTER_FACE != listVertex[link[jjj]]->GetType()) { + EWOL_ERROR("Center face error type ..." << (int32_t)listVertex[link[jjj]]->GetType()); + continue; + } + nbDivide++; + posBase += listVertex[link[jjj]]->GetPos(); + } + posBase /= nbDivide; + // update the position : + listVertex[iii]->SetPos(posBase); + } + } + } + EWOL_DEBUG(" ==> Update old points position"); + /* + Formule de calcule : + - calculate F the barycenter of k Face center nearest + - Calculate R the barycenter of k Edge point nearest + - Move P with equation : F + 2R + (k-3)P + ----------------- + k + */ + // reposition the old pont of the system + for(int32_t iii=0; iiiGetType()) { + vec3 val_P = listVertex[iii]->GetPos(); + vec3 val_F(0,0,0); + vec3 val_R(0,0,0); + int32_t countFace = 0; + int32_t countEdge = 0; + // generate barycenter of all link point if > 1... + etk::Vector& link = listVertex[iii]->GetLink(); + for(int32_t jjj=0; jjj= listVertex.Size()) { + EWOL_ERROR("Id is out of bounds ... : " << iii << " link=" << link[jjj] << " / " << listVertex.Size()); + continue; + } + if(NULL == listVertex[link[jjj]]) { + continue; + } + if (VERTEX_OLD == listVertex[link[jjj]]->GetType()) { + EWOL_ERROR("Center face error type ... old???"); + continue; + } + if (VERTEX_CENTER_FACE == listVertex[link[jjj]]->GetType()) { + countFace++; + val_F += listVertex[link[jjj]]->GetPos(); + } else { + countEdge++; + val_R += listVertex[link[jjj]]->GetPos(); + } + } + val_F /= countFace; + val_R /= countEdge; + if (countFace != countEdge) { + EWOL_WARNING("Case not coded, result not predictible ..."); + } else { + vec3 newPos = (val_F + 2*val_R + (countFace-3)*val_P)/countFace; + if (newPos != val_P) { + EWOL_DEBUG("update position : " << newPos << " <== " << val_P << " count=" << countFace); + } + // update the position : + listVertex[iii]->SetPos(newPos); + } + } + } + EWOL_DEBUG(" ==> Back to the normal list of element:"); + // copy all the element in the internal structure : + m_listUV = listUV; + m_listFaces = listFaces; + m_listVertex.Clear(); + for(int32_t iii=0; iiiGetPos()); + delete(listVertex[iii]); + listVertex[iii] = NULL; + } + } + listVertex.Clear(); } - // copy all the element in the internal structure : - m_listVertex = listVertex; - m_listUV = listUV; - m_listFaces = listFaces; } diff --git a/sources/ewol/renderer/resources/Mesh.h b/sources/ewol/renderer/resources/Mesh.h index 054a5c6a..2ab95b6d 100644 --- a/sources/ewol/renderer/resources/Mesh.h +++ b/sources/ewol/renderer/resources/Mesh.h @@ -16,9 +16,6 @@ #include #include -// note using modify Half-Edge system to store data (modify is for storing UV mapping too -// help on : http://www.flipcode.com/archives/The_Half-Edge_Data_Structure.shtml - namespace ewol { class Face