Ignore:
Timestamp:
Feb 8, 2013, 12:28:51 AM (7 years ago)
Author:
touky
Message:

Added VertexDictionnary object to manage vertices with same coord && connected vertices.
Added UVs system with and UVs generation test (not very conclusive)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/easymesh/easymesh.cpp

    r2370 r2379  
    4646{
    4747
     48//-----------------------------------------------------------------------------
    4849EasyMesh::EasyMesh()
    4950  : m_color(0), m_color2(0), m_ignore_winding_on_scale(0)
     
    5253}
    5354
     55//-----------------------------------------------------------------------------
    5456bool EasyMesh::Compile(char const *command)
    5557{
     
    5860}
    5961
     62//-----------------------------------------------------------------------------
    6063void EasyMesh::OpenBrace()
    6164{
     
    6366}
    6467
     68//-----------------------------------------------------------------------------
    6569void EasyMesh::CloseBrace()
    6670{
     
    6872}
    6973
     74//-----------------------------------------------------------------------------
    7075void EasyMesh::MeshConvert(Shader* provided_shader)
    7176{
     
    8994
    9095        m_gpu.modelview << m_gpu.shader.Last()->GetUniformLocation("in_ModelView");
     96        m_gpu.invmodelview << m_gpu.shader.Last()->GetUniformLocation("in_Inv_ModelView");
    9197        m_gpu.view << m_gpu.shader.Last()->GetUniformLocation("in_View");
    9298        m_gpu.invview << m_gpu.shader.Last()->GetUniformLocation("in_Inv_View");
     
    96102        m_gpu.lights << m_gpu.shader.Last()->GetUniformLocation("u_Lights");
    97103        m_gpu.coord << m_gpu.shader.Last()->GetAttribLocation("in_Vertex",
    98                                               VertexUsage::Position, 0);
     104                                             VertexUsage::Position, 0);
    99105        m_gpu.norm << m_gpu.shader.Last()->GetAttribLocation("in_Normal",
    100106                                             VertexUsage::Normal, 0);
    101107        m_gpu.color << m_gpu.shader.Last()->GetAttribLocation("in_Color",
    102                                               VertexUsage::Color, 0);
    103     }
    104 
     108                                             VertexUsage::Color, 0);
     109#if VERTEX_USEAGE == VU_BONES
     110        //TODO : -- BONE SUPPORT --
     111#elif VERTEX_USEAGE == VU_TEX_UV
     112        //UV SUPPORT --
     113        m_gpu.tex_coord << m_gpu.shader.Last()->GetAttribLocation("in_TexCoord",
     114                                              VertexUsage::TexCoord, 0);
     115#endif
     116    }
     117
     118#if VERTEX_USEAGE == VU_BONES
     119        //TODO : -- BONE SUPPORT --
     120#elif VERTEX_USEAGE == VU_TEX_UV
     121    //UV SUPPORT --
     122    m_gpu.vdecl = new VertexDeclaration(
     123        VertexStream<vec3,vec3,u8vec4,vec2>(VertexUsage::Position,
     124                                            VertexUsage::Normal,
     125                                            VertexUsage::Color,
     126                                            VertexUsage::TexCoord));
     127
     128    Array<vec3,vec3,u8vec4,vec2> vertexlist;
     129    for (int i = 0; i < m_vert.Count(); i++)
     130        vertexlist.Push(m_vert[i].m1,
     131                        m_vert[i].m2,
     132                        (u8vec4)(m_vert[i].m3 * 255.f),
     133                        m_vert[i].m4);
     134#else
     135    //-- VANILLA --
    105136    m_gpu.vdecl = new VertexDeclaration(
    106137        VertexStream<vec3,vec3,u8vec4>(VertexUsage::Position,
    107                                        VertexUsage::Normal,
    108                                        VertexUsage::Color));
     138                                        VertexUsage::Normal,
     139                                        VertexUsage::Color));
    109140
    110141    Array<vec3,vec3,u8vec4> vertexlist;
     
    113144                        m_vert[i].m2,
    114145                        (u8vec4)(m_vert[i].m3 * 255.f));
     146#endif
    115147
    116148    Array<uint16_t> indexlist;
     
    136168}
    137169
     170//-----------------------------------------------------------------------------
    138171void EasyMesh::Render(mat4 const &model, float damage)
    139172{
     
    156189
    157190    m_gpu.shader[d]->SetUniform(m_gpu.modelview[d], modelview);
     191    m_gpu.shader[d]->SetUniform(m_gpu.invmodelview[d], inverse(modelview));
    158192    m_gpu.shader[d]->SetUniform(m_gpu.view[d], Scene::GetDefault()->GetViewMatrix());
    159193    m_gpu.shader[d]->SetUniform(m_gpu.invview[d], inverse(Scene::GetDefault()->GetViewMatrix()));
     
    162196    m_gpu.shader[d]->SetUniform(m_gpu.damage[d], damage);
    163197    m_gpu.vdecl->Bind();
     198#if VERTEX_USEAGE == VU_BONES
     199    //TODO : -- BONE SUPPORT --
     200#elif VERTEX_USEAGE == VU_TEX_UV
     201    //UV SUPPORT --
     202    m_gpu.vdecl->SetStream(m_gpu.vbo, m_gpu.coord[d], m_gpu.norm[d], m_gpu.color[d], m_gpu.tex_coord[d]);
     203#else
     204    //-- VANILLA --
    164205    m_gpu.vdecl->SetStream(m_gpu.vbo, m_gpu.coord[d], m_gpu.norm[d], m_gpu.color[d]);
     206#endif
    165207    m_gpu.ibo->Bind();
    166208    m_gpu.vdecl->DrawIndexedElements(MeshPrimitive::Triangles,
     
    171213}
    172214
    173 
    174215//-------------------
    175216// "Collisions" functions
     
    178219#define VX_MASTER -1
    179220
     221//-----------------------------------------------------------------------------
    180222//helpers func to retrieve a vertex.
    181 int FindVertexInDict(int search_idx, Array< int, int > const &vertex_dict)
     223int VertexDictionnary::FindVertexMaster(const int search_idx)
    182224{
    183225    //Resolve current vertex idx in the dictionnary (if exist)
    184     for (int j = 0; j < vertex_dict.Count(); j++)
    185         if (vertex_dict[j].m1 == search_idx)
    186             return j;
    187     return -1;
    188 }
    189 
    190 //helpers func to retrieve a triangle.
    191 int FindTriangleInDict(int search_idx, Array< int, Array< vec3, vec3, vec3 > > const &triangle_isec)
    192 {
    193     //Resolve current vertex idx in the dictionnary (if exist)
    194     for (int j = 0; j < triangle_isec.Count(); j++)
    195         if (triangle_isec[j].m1 == search_idx)
    196             return j;
    197     return -1;
    198 }
    199 
     226    for (int j = 0; j < vertex_list.Count(); j++)
     227        if (vertex_list[j].m1 == search_idx)
     228            return vertex_list[j].m3;
     229    return VDictType::DoesNotExist;
     230}
     231
     232//-----------------------------------------------------------------------------
     233//retrieve a list of matching vertices, doesn't include search_idx.
     234bool VertexDictionnary::FindMatchingVertices(const int search_idx, Array<int> &matching_ids)
     235{
     236    int cur_mast = FindVertexMaster(search_idx);
     237
     238    if (cur_mast == VDictType::DoesNotExist || cur_mast == VDictType::Alone)
     239        return false;
     240
     241    if (cur_mast == VDictType::Master)
     242        cur_mast = search_idx;
     243    else
     244        matching_ids << vertex_list[cur_mast].m1;
     245
     246    for (int j = 0; j < vertex_list.Count(); j++)
     247        if (vertex_list[j].m3 == cur_mast && vertex_list[j].m1 != search_idx)
     248            matching_ids << vertex_list[cur_mast].m1;
     249
     250    return (matching_ids.Count() > 0);
     251}
     252
     253//-----------------------------------------------------------------------------
     254//Will return connected vertices (through triangles), if returned vertex has matching ones, it only returns the master.
     255bool VertexDictionnary::FindConnectedVertices(const int search_idx, const Array<int> &tri_list, Array<int> &connected_vert, Array<int> const *ignored_tri)
     256{
     257    Array<int> connected_tri;
     258    FindConnectedTriangles(search_idx, tri_list, connected_tri, ignored_tri);
     259
     260    for (int i = 0; i < connected_tri.Count(); i++)
     261    {
     262        for (int j = 0; j < 3; j++)
     263        {
     264            int v_indice = tri_list[connected_tri[j] + j];
     265            if (v_indice != search_idx)
     266            {
     267                int found_master = FindVertexMaster(tri_list[connected_tri[j] + j]);
     268                if (found_master == VDictType::Alone || found_master == VDictType::Master)
     269                    connected_vert << v_indice;
     270                else
     271                    connected_vert << found_master;
     272            }
     273        }
     274    }
     275    return (connected_vert.Count() > 0);
     276}
     277//-----------------------------------------------------------------------------
     278bool VertexDictionnary::FindConnectedTriangles(const int search_idx, const Array<int> &tri_list, Array<int> &connected_tri, Array<int> const *ignored_tri)
     279{
     280    return FindConnectedTriangles(ivec3(search_idx, search_idx, search_idx), tri_list, connected_tri, ignored_tri);
     281}
     282//-----------------------------------------------------------------------------
     283bool VertexDictionnary::FindConnectedTriangles(const ivec2 &search_idx, const Array<int> &tri_list, Array<int> &connected_tri, Array<int> const *ignored_tri)
     284{
     285    return FindConnectedTriangles(ivec3(search_idx, search_idx.x), tri_list, connected_tri, ignored_tri);
     286}
     287//-----------------------------------------------------------------------------
     288bool VertexDictionnary::FindConnectedTriangles(const ivec3 &search_idx, const Array<int> &tri_list, Array<int> &connected_tri, Array<int> const *ignored_tri)
     289{
     290    int needed_validation = 0;
     291    Array<int> vert_list[3];
     292    for (int i = 0; i < 3; i++)
     293    {
     294        //Small optim since above func will use this one
     295        if ((i == 1 && search_idx[0] == search_idx[1]) ||
     296            (i == 2 && (search_idx[0] == search_idx[2] || search_idx[1] == search_idx[2])))
     297            continue;
     298        else
     299        {
     300            //increment the validation info, hence empty list aren't taken into account.
     301            needed_validation++;
     302            vert_list[i] << search_idx[i];
     303            FindMatchingVertices(search_idx[i], vert_list[i]);
     304        }
     305    }
     306
     307    for (int i = 0; i < tri_list.Count(); i += 3)
     308    {
     309        if (ignored_tri)
     310        {
     311            bool should_pass = false;
     312            for (int j = 0; !should_pass && j < ignored_tri->Count(); j++)
     313                if ((*ignored_tri)[j] == i)
     314                    should_pass = true;
     315            if (should_pass)
     316                continue;
     317        }
     318        int found_validation = 0;
     319        for (int j = 0; j < 3; j++)
     320        {
     321            bool validated = false;
     322            for (int k = 0; !validated && k < vert_list[j].Count(); k++)
     323                for (int l = 0; !validated && l < 3; l++)
     324                    if (vert_list[j][k] == tri_list[i + l])
     325                        validated = true;
     326            found_validation += (validated)?(1):(0);
     327        }
     328        //triangle is validated store it
     329        if (found_validation == needed_validation)
     330            connected_tri << i;
     331    }
     332
     333    return (connected_tri.Count() > 0);
     334}
     335
     336//-----------------------------------------------------------------------------
    200337//Will update the given list with all the vertices on the same spot.
    201 void EasyMesh::UpdateVertexDict(Array< int, int > &vertex_dict)
    202 {
     338void VertexDictionnary::AddVertex(const int vert_id, const vec3 vert_coord)
     339{
     340    for (int j = 0; j < vertex_list.Count(); j++)
     341        if (vertex_list[j].m1 == vert_id)
     342            return;
     343
    203344    //First, build the vertex Dictionnary
    204     for (int i = 0; i < m_vert.Count(); i++)
    205     {
    206         int CurIdx = FindVertexInDict(i, vertex_dict);
    207 
    208         //go through all vertices and do the match-up.
    209         if (CurIdx == -1)
    210         {
    211             for (int j = i + 1; j < m_vert.Count(); j++)
    212             {
    213                 if (sqlength(m_vert[i].m1 - m_vert[j].m1) < CSG_EPSILON)
    214                 {
    215                     if (CurIdx == -1)
    216                     {
    217                         CurIdx = vertex_dict.Count();
    218                         vertex_dict.Push(i, VX_MASTER);
    219                     }
    220                     vertex_dict.Push(j, CurIdx);
    221                 }
    222             }
    223         }
    224     }
    225 }
    226 
     345    int i = 0;
     346    for (; i < master_list.Count(); i++)
     347    {
     348        int cur_mast  = master_list[i];
     349        int cur_id    = vertex_list[cur_mast].m1;
     350        vec3 cur_loc  = vertex_list[cur_mast].m2;
     351        int &cur_type = vertex_list[cur_mast].m3;
     352
     353        if (cur_id == vert_id)
     354            return;
     355
     356        if (sqlength(cur_loc - vert_coord) < CSG_EPSILON)
     357        {
     358            if (cur_type == VDictType::Alone)
     359                cur_type = VDictType::Master;
     360            vertex_list.Push(vert_id, vert_coord, cur_mast);
     361            return;
     362        }
     363    }
     364
     365    //We're here because we couldn't find any matching vertex
     366    master_list.Push(vertex_list.Count());
     367    vertex_list.Push(vert_id, vert_coord, VDictType::Alone);
     368}
     369
     370//-----------------------------------------------------------------------------
    227371void EasyMesh::MeshCsg(CSGUsage csg_operation)
    228372{
     
    400544    m_cursors.Last().m2 = m_indices.Count();
    401545
    402 #if 0
    403     UpdateVertexDict(vertex_dict);
    404 
    405     for (int t0 = 0; t0 < m_indices.Count(); t0 += 3)
    406     {
    407         for (int t1 = t0 + 3; t1 < m_indices.Count(); t1 += 3)
    408         {
    409             int CommonVertices = 0;
    410             //Search for common vertices, if > 1 the two triangle share a side, so no split is required.
    411             for (int k = 0; k < 3; k++)
    412             {
    413                 int ref_master = FindVertexInDict(m_indices[t0 + k], vertex_dict);
    414                 if (ref_master != -1)
    415                 {
    416                     if (vertex_dict[ref_master].m2 != VX_MASTER)
    417                         ref_master = vertex_dict[ref_master].m2;
    418                     for (int l = 0; l < 3; l++)
    419                     {
    420                         int test_master = FindVertexInDict(m_indices[t1 + l], vertex_dict);
    421                         if (test_master != -1)
    422                         {
    423                             if (vertex_dict[test_master].m2 != VX_MASTER)
    424                                 test_master = vertex_dict[test_master].m2;
    425                             if (test_master == ref_master)
    426                             {
    427                                 CommonVertices++;
    428                                 break;
    429                             }
    430                         }
    431                     }
    432                 }
    433             }
    434 
    435             if (CommonVertices < 2)
    436             {
    437                 vec3 iP0, iP1;
    438                 //Build the triangle intersection list
    439                 if (TriangleIsectTriangle(m_vert[m_indices[t0]].m1, m_vert[m_indices[t0 + 1]].m1, m_vert[m_indices[t0 + 2]].m1,
    440                                           m_vert[m_indices[t1]].m1, m_vert[m_indices[t1 + 1]].m1, m_vert[m_indices[t1 + 2]].m1,
    441                                           iP0, iP1))
    442                 {
    443                     int CurIdx = FindTriangleInDict(t0, triangle_isec);
    444                     if (CurIdx == -1)
    445                     {
    446                         CurIdx = triangle_isec.Count();
    447                         triangle_isec.Push(t0, Array<vec3, vec3, vec3>());
    448                     }
    449                     triangle_isec[CurIdx].m2.Push(iP0, iP1, vec3(.0f));
    450                     CurIdx = FindTriangleInDict(t1, triangle_isec);
    451                     if (CurIdx == -1)
    452                     {
    453                         CurIdx = triangle_isec.Count();
    454                         triangle_isec.Push(t1, Array<vec3, vec3, vec3>());
    455                     }
    456                     triangle_isec[CurIdx].m2.Push(iP0, iP1, vec3(.0f));
    457                 }
    458             }
    459         }
    460     }
    461 
    462     /* seems to be counter-productive in some rare cases. */
    463     /*
    464     //Every intersection has been found, let's remove those that exist twice.
    465     for(int i = 0; i < triangle_isec.Count(); i++)
    466     {
    467         for(int j = 0; j < triangle_isec[i].m2.Count(); j++)
    468         {
    469             for(int k = j + 1; k < triangle_isec[i].m2.Count(); k++)
    470             {
    471                 //if the two Dir-vector are parallel & the fist Dir-vector is parallel to the (P0, P1)-vector, this is the same intersection, so kill it.
    472                 if (abs(dot(normalize(triangle_isec[i].m2[j].m2 - triangle_isec[i].m2[j].m1),
    473                             normalize(triangle_isec[i].m2[k].m2 - triangle_isec[i].m2[k].m1)))
    474                         >= 1.0 &&
    475                     abs(dot(normalize(triangle_isec[i].m2[j].m2 - triangle_isec[i].m2[j].m1),
    476                             normalize(triangle_isec[i].m2[k].m1 - triangle_isec[i].m2[j].m1)))
    477                         >= 1.0 )
    478                     triangle_isec[i].m2.Remove(k--);
    479             }
    480         }
    481     }
    482     */
    483 
    484     //Now, the triangle intersection tab should be nice and cosy, so we can start actually cutting some triangles.
    485     vec3 isecV[2] = { vec3(.0f), vec3(.0f) };
    486     int isecI[2] = { -1, -1 };
    487     int v_idx0 = 0; int v_idx1 = 0;
    488     int new_v_idx[2] = { 0, 0 };
    489     vec3 n0(.0f); vec3 n1(.0f);
    490     vec4 c0(.0f); vec4 c1(.0f);
    491     for(int i = 0; i < triangle_isec.Count(); i++)
    492     {
    493         int tri_idx = triangle_isec[i].m1;
    494         for(int j = 0; j < triangle_isec[i].m2.Count(); j++)
    495         {
    496             //Get intersection on actual triangle sides.
    497             if (RayIsectTriangleSide(m_vert[m_indices[tri_idx]].m1, m_vert[m_indices[tri_idx + 1]].m1, m_vert[m_indices[tri_idx + 2]].m1,
    498                                      triangle_isec[i].m2[j].m1, triangle_isec[i].m2[j].m2,
    499                                      isecV[0], isecI[0], isecV[1], isecI[1]))
    500             {
    501                 //Check if the found intersections point are in the triangle. If not, ignore.
    502                 //Cases are :
    503                 //  1) at least one dot is negative (one point in the triangle).
    504                 //  2) the two dot are positive but the intersection point are on all parts of the triangle, and therefore negative.
    505                 //If one of the point is on one side, some calculations tweak are needed.
    506                 //If the two points are on the triangle sides, just go with it.
    507                 bool should_proceed_with_cutting = true;
    508                 //find out if points are on one of the side
    509                 int p0_tri_idx = ((sqlength(triangle_isec[i].m2[j].m1 - isecV[0]) < CSG_EPSILON)?(0):(
    510                                     (sqlength(triangle_isec[i].m2[j].m1 - isecV[1]) < CSG_EPSILON)?(1):(-1)));
    511                 int p1_tri_idx = ((sqlength(triangle_isec[i].m2[j].m2 - isecV[0]) < CSG_EPSILON)?(0):(
    512                                     (sqlength(triangle_isec[i].m2[j].m2 - isecV[1]) < CSG_EPSILON)?(1):(-1)));
    513                 if (p0_tri_idx < 0 || p1_tri_idx < 0)
    514                 {
    515                     float dot0 = (p0_tri_idx >= 0)?(1.0f):(dot(triangle_isec[i].m2[j].m1 - isecV[0],
    516                                                                triangle_isec[i].m2[j].m1 - isecV[1]));
    517                     float dot1 = (p1_tri_idx >= 0)?(1.0f):(dot(triangle_isec[i].m2[j].m2 - isecV[0],
    518                                                                triangle_isec[i].m2[j].m2 - isecV[1]));
    519                     float dot2 = dot(triangle_isec[i].m2[j].m1 - isecV[(p0_tri_idx == -1)?(0):(1 - p0_tri_idx)],
    520                                      triangle_isec[i].m2[j].m2 - isecV[(p1_tri_idx == -1)?(0):(1 - p1_tri_idx)]);
    521                     should_proceed_with_cutting = (((dot0 < .0f) || dot1 < .0f) || (dot0 > .0f && dot1 > .0f && dot2 < .0f));
    522                 }
    523                 if (should_proceed_with_cutting)
    524                 {
    525                     //Add the new vertices
    526                     int b_idx = 0;
    527                     for(int k = 0; k < 2; k++)
    528                     {
    529                         if (b_idx == isecI[k])
    530                             b_idx++;
    531 
    532                         new_v_idx[k] = m_vert.Count();
    533                         AddVertex(isecV[k]);
    534                         //bad calculations of normal there.
    535                         n0 = m_vert[m_indices[tri_idx + isecI[k]]].m2;
    536                         n1 = m_vert[m_indices[tri_idx + (isecI[k] + 1) % 3]].m2;
    537                         SetCurVertNormal(normalize((n0 + n1) * .5f));
    538                         //color
    539 #if 0
    540                         c0 = m_vert[m_indices[tri_idx + isecI[k]]].m3;
    541                         c1 = m_vert[m_indices[tri_idx + (isecI[k] + 1) % 3]].m3;
    542                         SetCurVertColor((c0 + c1) * .5f);
     546    //DONE for the splitting !
     547}
     548
     549
     550//-----------------------------------------------------------------------------
     551void EasyMesh::ToggleScaleWinding()
     552{
     553    m_ignore_winding_on_scale = !m_ignore_winding_on_scale;
     554}
     555
     556//-----------------------------------------------------------------------------
     557void EasyMesh::SetCurColor(vec4 const &color)
     558{
     559    m_color = color;
     560}
     561
     562//-----------------------------------------------------------------------------
     563void EasyMesh::SetCurColor2(vec4 const &color)
     564{
     565    m_color2 = color;
     566}
     567
     568//-----------------------------------------------------------------------------
     569void EasyMesh::AddVertex(vec3 const &coord)
     570{
     571#if VERTEX_USEAGE == VU_BONES
     572    //TODO : -- BONE SUPPORT --
     573    m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color, ivec2(0), vec2(0));
     574#elif VERTEX_USEAGE == VU_TEX_UV
     575    //-- UV SUPPORT --
     576    m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color, vec2(-1));
    543577#else
    544                         SetCurVertColor(vec4(1.0f, 0.0f, 0.0f, 1.0f));
     578    //-- VANILLA --
     579    m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color);
    545580#endif
    546                     }
    547 
    548                     //small trick, b_idx is the side index that has no intersection.
    549                     v_idx0 = (b_idx == 1)?(1):(0);
    550                     v_idx1 = (b_idx == 1)?(0):(1);
    551 
    552                     //Add the new triangles
    553                     AppendTriangle(m_indices[tri_idx + b_idx],              new_v_idx[v_idx0], new_v_idx[v_idx1], 0);
    554                     AppendTriangle(m_indices[tri_idx + ((b_idx + 2) % 3)],  new_v_idx[v_idx1], new_v_idx[v_idx0], 0);
    555                     //Replace the current triangle by on of the new one, instead of erasing it.
    556                     m_indices[tri_idx + ((b_idx + 2) % 3)] = new_v_idx[v_idx0];
    557 
    558                     if (j + 1 < triangle_isec[i].m2.Count())
    559                     {
    560                         triangle_isec[i].m2.Remove(j--);
    561                         //add the two new triangle to the checklist.
    562                         triangle_isec.Push(m_indices.Count() - 6, triangle_isec[i].m2);
    563                         triangle_isec.Push(m_indices.Count() - 3, triangle_isec[i].m2);
    564                     }
    565                 }
    566             }
    567         }
    568     }
    569 #endif
    570     //DONE for the splitting !
    571 }
    572 
    573 
    574 //-------------------
    575 
    576 void EasyMesh::ToggleScaleWinding()
    577 {
    578     m_ignore_winding_on_scale = !m_ignore_winding_on_scale;
    579 }
    580 
    581 void EasyMesh::SetCurColor(vec4 const &color)
    582 {
    583     m_color = color;
    584 }
    585 
    586 void EasyMesh::SetCurColor2(vec4 const &color)
    587 {
    588     m_color2 = color;
    589 }
    590 
    591 void EasyMesh::AddVertex(vec3 const &coord)
    592 {
    593     //TODO : m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color, ivec2(0), vec2(0));
    594     m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color);
    595 }
    596 
     581}
     582
     583//-----------------------------------------------------------------------------
    597584void EasyMesh::AddDuplicateVertex(int i)
    598585{
     
    600587}
    601588
     589//-----------------------------------------------------------------------------
    602590void EasyMesh::AppendQuad(int i1, int i2, int i3, int i4, int base)
    603591{
     
    611599}
    612600
     601//-----------------------------------------------------------------------------
    613602void EasyMesh::AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base)
    614603{
     
    622611}
    623612
     613//-----------------------------------------------------------------------------
    624614void EasyMesh::AppendTriangle(int i1, int i2, int i3, int base)
    625615{
     
    629619}
    630620
     621//-----------------------------------------------------------------------------
    631622void EasyMesh::AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base)
    632623{
     
    636627}
    637628
     629//-----------------------------------------------------------------------------
    638630void EasyMesh::ComputeNormals(int start, int vcount)
    639631{
     
    651643}
    652644
     645//-----------------------------------------------------------------------------
     646void EasyMesh::ComputeTexCoord(float uv_scale, int uv_offset)
     647{
     648#if VERTEX_USEAGE == VU_TEX_UV
     649    VertexDictionnary vert_dict;
     650    Array<int> tri_list;
     651   
     652    tri_list.Reserve(m_indices.Count() - m_cursors.Last().m2);
     653    for (int i = m_cursors.Last().m2; i < m_indices.Count(); i++)
     654    {
     655        vert_dict.AddVertex(m_indices[i], m_vert[m_indices[i]].m1);
     656        tri_list << m_indices[i];
     657    }
     658
     659    //full triangle count
     660    Array<int> tri_done;
     661    Array<int> tri_check;
     662    int tri_count = (m_indices.Count() - m_cursors.Last().m2) / 3;
     663
     664    tri_check << tri_list[0];
     665
     666    while (tri_check.Count())
     667    {
     668        int cur_tri = tri_check[0];
     669        int v[3]   = { tri_list[cur_tri + uv_offset % 3], tri_list[cur_tri + (1 + uv_offset) % 3], tri_list[cur_tri + (2 + uv_offset) % 3] };
     670        vec2 uv[3] = { m_vert[tri_list[cur_tri]].m4, m_vert[tri_list[cur_tri + 1]].m4, m_vert[tri_list[cur_tri + 2]].m4 };
     671        for (int j = 0; j < 3; j++)
     672        {
     673            if (uv[j] != vec2(-1.0f) && uv[j] == uv[(j + 1) % 3])
     674            {
     675                uv[0] = vec2(-1.0f);
     676                uv[1] = vec2(-1.0f);
     677                uv[2] = vec2(-1.0f);
     678                break;
     679            }
     680        }
     681        int uv_set = 0;
     682        for (int j = 0; j < 3; j++)
     683            uv_set += (uv[j].x < 0.f)?(0):(1);
     684
     685        //this case shouldn't happen.
     686        if (uv_set == 1)
     687        {
     688            /*
     689            for (int j = 0; j < 3; j++)
     690            {
     691                if (uv[j] != vec2(-1.0f))
     692                {
     693                    uv[(j + 1) % 2] = uv[j] + vec2(.0f, uv_scale * length(m_vert[v[j]].m1 - m_vert[v[(j + 1) % 3]].m1));
     694                    uv_set = 2;
     695                    break;
     696                }
     697            }
     698            */
     699        }
     700        //No UV is set, let's do the arbitrary set and use the basic method.
     701        if (uv_set == 0)
     702        {
     703            float new_dot = FLT_MAX;
     704            int base_i = 0;
     705            for (int j = 0; j < 3; j++)
     706            {
     707                float tmp_dot = abs(dot(normalize(m_vert[v[(j + 1) % 3]].m1 - m_vert[v[j]].m1),
     708                                        normalize(m_vert[v[(j + 2) % 3]].m1 - m_vert[v[j]].m1)));
     709                if (tmp_dot < new_dot)
     710                {
     711                    base_i = j;
     712                    new_dot = tmp_dot;
     713                }
     714            }
     715            uv[base_i] = vec2(.0f);
     716            uv[(base_i + 1) % 3] = vec2(.0f, uv_scale * length(m_vert[v[base_i]].m1 - m_vert[v[(base_i + 1) % 3]].m1));
     717            uv_set = 2;
     718        }
     719        //2 points have been set, let's figure the third
     720        if (uv_set == 2)
     721        {
     722            {
     723                //invert values so the two set uv are in [0, 1] slots.
     724                int new_v[3];
     725                vec2 new_uv[3];
     726                bool ignore_set = false;
     727                if (uv[0].x >= 0.f && uv[1].x < 0.f)
     728                {
     729                    new_v[0] = v[2]; new_v[1] = v[0]; new_v[2] = v[1];
     730                    new_uv[0] = uv[2]; new_uv[1] = uv[0]; new_uv[2] = uv[1];
     731                }
     732                else if (uv[0].x < 0.f && uv[1].x >= 0.f)
     733                {
     734                    new_v[0] = v[1]; new_v[1] = v[2]; new_v[2] = v[0];
     735                    new_uv[0] = uv[1]; new_uv[1] = uv[2]; new_uv[2] = uv[0];
     736                }
     737                else
     738                    ignore_set = true;
     739                if (!ignore_set)
     740                {
     741                    v[0]  = new_v[0];  v[1]  = new_v[1];  v[2]  = new_v[2];
     742                    uv[0] = new_uv[0]; uv[1] = new_uv[1]; uv[2] = new_uv[2];
     743                }
     744            }
     745
     746            //Do this to be sure the normal is OK.
     747            ComputeNormals(cur_tri, 3);
     748            vec3 v01 = normalize(m_vert[v[1]].m1 - m_vert[v[0]].m1);
     749            vec3 v02 = m_vert[v[2]].m1 - m_vert[v[0]].m1;
     750            vec3 v_dir = normalize(cross(m_vert[m_indices[cur_tri]].m2, v01));
     751            vec2 texu_dir = uv[1] - uv[0];
     752            vec2 texv_dir = vec2(texu_dir.y, -texu_dir.x);
     753            //Final calculations
     754            uv[2] = texu_dir * dot(v01, v02) + texv_dir * dot(v_dir, v02);
     755
     756            //Set UV on ALL matching vertices!
     757            Array<int> matching_vert;
     758            for (int i = 0; i < 3; i++)
     759            {
     760#if 1
     761                //This marks all same position UV to the same values
     762                //Deactivation is a test.
     763                matching_vert << v[i];
     764                vert_dict.FindMatchingVertices(v[i], matching_vert);
     765                for (int j = 0; j < matching_vert.Count(); j++)
     766                    if (m_vert[matching_vert[j]].m4 == vec2(-1.0f))
     767                        m_vert[matching_vert[j]].m4 = abs(uv[i]);
     768#else
     769                m_vert[v[i]].m4 = abs(uv[i]);
     770#endif
     771            }
     772
     773            tri_done << cur_tri;
     774            tri_check.Remove(0);
     775
     776            //Get connected triangles and go from there.
     777            for (int j = 0; j < 3; j++)
     778            {
     779#if 0
     780                //This finds triangle that are connected to this triangle
     781                vert_dict.FindConnectedTriangles(ivec2(v[j], v[(j + 1) % 3]), tri_list, tri_check, &tri_done);
     782#else
     783                //This finds triangle that are connected to the vertices of this triangle
     784                vert_dict.FindConnectedTriangles(v[j], tri_list, tri_check, &tri_done);
     785#endif
     786            }
     787        }
     788        else if (uv_set == 3)
     789        {
     790            bool tri_present = false;
     791            for (int j = 0; j < tri_done.Count(); j++)
     792                if (cur_tri == tri_done[j])
     793                    tri_present = true;
     794            if (!tri_present)
     795                tri_done << cur_tri;
     796            tri_check.Remove(0);
     797        }
     798
     799        if (tri_check.Count() == 0 && tri_done.Count() != tri_count)
     800        {
     801            //look for unset triangle
     802            for (int i = 0; !tri_check.Count() && i < tri_list.Count(); i += 3)
     803            {
     804                bool tri_present = false;
     805                for (int j = 0; j < tri_done.Count(); j++)
     806                    if (i == tri_done[j])
     807                        tri_present = true;
     808                if (!tri_present)
     809                    tri_check << i;
     810            }
     811        }
     812    }
     813#endif
     814}
     815
     816//-----------------------------------------------------------------------------
    653817void EasyMesh::SetVertColor(vec4 const &color)
    654818{
     
    657821}
    658822
     823//-----------------------------------------------------------------------------
    659824void EasyMesh::SetCurVertNormal(vec3 const &normal)
    660825{
     
    662827}
    663828
     829//-----------------------------------------------------------------------------
    664830void EasyMesh::SetCurVertColor(vec4 const &color)
    665831{
     
    667833}
    668834
     835//-----------------------------------------------------------------------------
    669836void EasyMesh::Translate(vec3 const &v)
    670837{
     
    673840}
    674841
     842//-----------------------------------------------------------------------------
    675843void EasyMesh::RotateX(float t) { Rotate(t, vec3(1, 0, 0)); }
    676844void EasyMesh::RotateY(float t) { Rotate(t, vec3(0, 1, 0)); }
    677845void EasyMesh::RotateZ(float t) { Rotate(t, vec3(0, 0, 1)); }
    678846
     847//-----------------------------------------------------------------------------
    679848void EasyMesh::Rotate(float t, vec3 const &axis)
    680849{
     
    687856}
    688857
     858//-----------------------------------------------------------------------------
    689859void EasyMesh::RadialJitter(float r)
    690860{
     
    731901}
    732902
     903//-----------------------------------------------------------------------------
    733904void EasyMesh::TaperX(float y, float z, float xoff)
    734905{
     
    741912}
    742913
     914//-----------------------------------------------------------------------------
    743915void EasyMesh::TaperY(float x, float z, float yoff)
    744916{
     
    750922}
    751923
     924//-----------------------------------------------------------------------------
    752925void EasyMesh::TaperZ(float x, float y, float zoff)
    753926{
     
    759932}
    760933
     934//-----------------------------------------------------------------------------
    761935void EasyMesh::Scale(vec3 const &s)
    762936{
     
    781955}
    782956
     957//-----------------------------------------------------------------------------
    783958void EasyMesh::MirrorX() { DupAndScale(vec3(-1, 1, 1)); }
    784959void EasyMesh::MirrorY() { DupAndScale(vec3(1, -1, 1)); }
    785960void EasyMesh::MirrorZ() { DupAndScale(vec3(1, 1, -1)); }
    786961
     962//-----------------------------------------------------------------------------
    787963void EasyMesh::DupAndScale(vec3 const &s)
    788964{
     
    802978}
    803979
     980//-----------------------------------------------------------------------------
    804981void EasyMesh::AppendCylinder(int nsides, float h, float r1, float r2,
    805982                    int dualside, int smooth)
     
    8541031}
    8551032
     1033//-----------------------------------------------------------------------------
    8561034void EasyMesh::AppendCapsule(int ndivisions, float h, float r)
    8571035{
     
    9501128}
    9511129
     1130//-----------------------------------------------------------------------------
    9521131void EasyMesh::AppendSphere(int ndivisions, vec3 const &size)
    9531132{
     
    9581137}
    9591138
     1139//-----------------------------------------------------------------------------
    9601140void EasyMesh::AppendTorus(int ndivisions, float r1, float r2)
    9611141{
     
    9911171}
    9921172
     1173//-----------------------------------------------------------------------------
    9931174void EasyMesh::AppendBox(vec3 const &size, float chamf)
    9941175{
     
    9961177}
    9971178
     1179//-----------------------------------------------------------------------------
    9981180void EasyMesh::AppendSmoothChamfBox(vec3 const &size, float chamf)
    9991181{
     
    10011183}
    10021184
     1185//-----------------------------------------------------------------------------
    10031186void EasyMesh::AppendFlatChamfBox(vec3 const &size, float chamf)
    10041187{
     
    10061189}
    10071190
     1191//-----------------------------------------------------------------------------
    10081192void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth)
    10091193{
     
    11011285}
    11021286
     1287//-----------------------------------------------------------------------------
    11031288void EasyMesh::AppendStar(int nbranches, float r1, float r2,
    11041289                          int fade, int fade2)
     
    11321317}
    11331318
     1319//-----------------------------------------------------------------------------
    11341320void EasyMesh::AppendExpandedStar(int nbranches, float r1,
    11351321                                  float r2, float extrar)
     
    11661352}
    11671353
     1354//-----------------------------------------------------------------------------
    11681355void EasyMesh::AppendDisc(int nsides, float r, int fade)
    11691356{
     
    11851372}
    11861373
     1374//-----------------------------------------------------------------------------
    11871375void EasyMesh::AppendSimpleTriangle(float size, int fade)
    11881376{
     
    12031391}
    12041392
     1393//-----------------------------------------------------------------------------
    12051394void EasyMesh::AppendSimpleQuad(float size, int fade)
    12061395{
     
    12081397}
    12091398
     1399//-----------------------------------------------------------------------------
    12101400void EasyMesh::AppendSimpleQuad(vec2 p1, vec2 p2, float z, int fade)
    12111401{
     
    12231413}
    12241414
     1415//-----------------------------------------------------------------------------
    12251416void EasyMesh::AppendCog(int nbsides, float h, float r10, float r20,
    12261417                         float r1, float r2, float r12, float r22,
     
    12981489}
    12991490
     1491//-----------------------------------------------------------------------------
    13001492void EasyMesh::Chamfer(float f)
    13011493{
     
    13211513
    13221514    for (int i = 0; i < ilen / 3; i++)
     1515
    13231516    {
    13241517    #if 0
Note: See TracChangeset for help on using the changeset viewer.