Ticket #169: terrain_triangulation_test3.patch

File terrain_triangulation_test3.patch, 9.2 KB (added by Xin, 14 years ago)

Blends semi-work now.

  • PatchRData.cpp

     
    8888
    8989struct STmpSplat {
    9090    Handle m_Texture;
    91     u16 m_Indices[4];
     91    u16 m_Indices[6];   //a splat is now composed of two triangles instead of a single quad
    9292};
    9393
    9494void CPatchRData::BuildBlends()
     
    237237                        m_BlendVertices.push_back(dst);
    238238                        m_BlendVertexIndices.push_back(((j+1)*vsize)+i);
    239239
    240                         // build a splat for this quad
     240                        // build a splat for this quad (really two tris)
    241241                        STmpSplat splat;
    242242                        splat.m_Texture=neighbourTextures[k].m_Handle;
    243                         splat.m_Indices[0]=(u16)(vindex);
     243                        /*splat.m_Indices[0]=(u16)(vindex);
    244244                        splat.m_Indices[1]=(u16)(vindex+1);
    245245                        splat.m_Indices[2]=(u16)(vindex+2);
    246246                        splat.m_Indices[3]=(u16)(vindex+3);
     247                        */
     248                        //save these for convenience
     249                        CVector3D vertex1 = vtx0.m_Position;
     250                        CVector3D vertex2 = vtx1.m_Position;
     251                        CVector3D vertex3 = vtx2.m_Position;
     252                        CVector3D vertex4 = vtx3.m_Position;
     253
     254                        //find the set of indices in m_Indices that correspond to the vertices
     255                        //being used by the current blend texture so that we can match up the triangulation used
     256                        std::list<u16> IndexList;   //store the order indices should be added to m_BlendIndices
     257                        size_t indexBase=m_VBBase->m_Index;     //used to get correct index position in m_Vertices
     258                        for (int p = 0; p < m_Indices.size()-5; p++)
     259                        {
     260                            if (
     261                                m_Vertices[m_Indices[p]-indexBase].m_Position == vertex1 ||
     262                                m_Vertices[m_Indices[p]-indexBase].m_Position == vertex2 ||
     263                                m_Vertices[m_Indices[p]-indexBase].m_Position == vertex3 ||
     264                                m_Vertices[m_Indices[p]-indexBase].m_Position == vertex4
     265                                )
     266                            {
     267                                //we've found a match to one of the vertices, but that does not necessarily mean we're at the right set of
     268                                //indices so we check the block of 6 vertices to see if they contain all the vertices we're using
     269                                for (int q = p; q < p+6; q++)
     270                                {
     271                                    if (m_Vertices[m_Indices[q]-indexBase].m_Position == vertex1)
     272                                    {
     273                                        IndexList.push_back((u16)(vindex));
     274                                    }
     275                                    else if (m_Vertices[m_Indices[q]-indexBase].m_Position == vertex2)
     276                                    {
     277                                        IndexList.push_back((u16)(vindex+1));
     278                                    }
     279                                    else if (m_Vertices[m_Indices[q]-indexBase].m_Position == vertex3)
     280                                    {
     281                                        IndexList.push_back((u16)(vindex+2));
     282                                    }
     283                                    else if (m_Vertices[m_Indices[q]-indexBase].m_Position == vertex4)
     284                                    {
     285                                        IndexList.push_back((u16)(vindex+3));
     286                                    }
     287                                    else
     288                                    {
     289                                        //this means we've encountered a vertex that's not one of the ones we're looking for so exit out
     290                                        IndexList.clear();
     291                                        p = q;  //so that we don't recheck the vertices we know can't possibly match
     292                                        break;
     293                                    }
     294                                }
     295                            }
     296                            if (IndexList.size() == 6)
     297                            {
     298                                //found our triangulation so early out for the search
     299                                break;
     300                            }
     301                        }
     302                        if (IndexList.size() != 6)
     303                        {
     304                            //tried to use debug_assert(IndexList.size() == 6), but that started throwing memory access violations for some reason
     305                            debug_printf(L"WARNING: Blend Indices building failed. IndexList does not contain 6 elements.\n");
     306                            debug_break();
     307                        }
     308                        std::list<u16>::iterator it;
     309                        int splatIndex = 0;
     310                        for (it = IndexList.begin(); it != IndexList.end(); it++)
     311                        {
     312                            //add the indices in the order we found them in
     313                            splat.m_Indices[splatIndex++] = *it;
     314                        }
    247315                        splats.push_back(splat);
    248316
    249317                        // add this texture to set of unique splat textures
     
    284352                    m_BlendIndices.push_back(splats[k].m_Indices[1]+base);
    285353                    m_BlendIndices.push_back(splats[k].m_Indices[2]+base);
    286354                    m_BlendIndices.push_back(splats[k].m_Indices[3]+base);
    287                     splat.m_IndexCount+=4;
     355                    m_BlendIndices.push_back(splats[k].m_Indices[4]+base);
     356                    m_BlendIndices.push_back(splats[k].m_Indices[5]+base);
     357                    splat.m_IndexCount+=6;
    288358                }
    289359            }
    290360            splatCount++;
     
    302372
    303373    // release existing indices and bins
    304374    m_Indices.clear();
    305     m_ShadowMapIndices.clear();
    306375    m_Splats.clear();
    307376
    308377    // build grid of textures on this patch and boundaries of adjacent patches
     
    332401        for (ssize_t j=0;j<PATCH_SIZE;j++) {
    333402            for (ssize_t i=0;i<PATCH_SIZE;i++) {
    334403                if (texgrid[j][i]==h){
     404
     405                    //save these values for convenience
     406                    u16 index1 = u16(((j+0)*vsize+(i+0))+base);
     407                    u16 index2 = u16(((j+0)*vsize+(i+1))+base);
     408                    u16 index3 = u16(((j+1)*vsize+(i+1))+base);
     409                    u16 index4 = u16(((j+1)*vsize+(i+0))+base);
     410
     411                    //calculate triangulation
     412                    //reminder: incrementing i shifts x coordinates, j shifts z
     413                    //first, get all the positions of the vertices in world space
     414                    CVector3D v1 = m_Vertices[(j+0)*vsize+(i+0)].m_Position;
     415                    CVector3D v2 = m_Vertices[(j+0)*vsize+(i+1)].m_Position;
     416                    CVector3D v3 = m_Vertices[(j+1)*vsize+(i+1)].m_Position;
     417                    CVector3D v4 = m_Vertices[(j+1)*vsize+(i+0)].m_Position;
     418                   
     419                    /*
     420                    debug_printf(L"Vertex 1 is at position: %f, %f, %f\n", v1.X, v1.Y, v1.Z);
     421                    debug_printf(L"Vertex 2 is at position: %f, %f, %f\n", v2.X, v2.Y, v2.Z);
     422                    debug_printf(L"Vertex 3 is at position: %f, %f, %f\n", v3.X, v3.Y, v3.Z);
     423                    debug_printf(L"Vertex 4 is at position: %f, %f, %f\n", v4.X, v4.Y, v4.Z);
     424                    */
     425
     426                   
     427                    //we have two possible triangulations to check: (123, 143) and (234, 214)
     428                    //our goal is to pick the one that minimizes the angle between the planes formed by the triangles
     429                    //the normals are constructed in such a way as to avoid having to normalize the vectors for the dot product
     430                    CVector3D normal1 = (v1-v2).Cross(v3-v2);
     431                    CVector3D normal2 = (v1-v4).Cross(v3-v4);
     432                    CVector3D normal3 = (v4-v3).Cross(v2-v3);
     433                    CVector3D normal4 = (v4-v1).Cross(v2-v1);
     434                    float angle1 = normal1.Dot(normal2);    //since we don't need the exact angle, we can just use the value of the dot product
     435                    float angle2 = normal3.Dot(normal4);
     436
     437                    //cos gets smaller as the angle increases so we take the triangulation with the larger value
     438                    if (angle1 < angle2)
     439                    {
     440                       
     441                       
     442                        m_Indices.push_back(index3);
     443                        m_Indices.push_back(index4);
     444                        m_Indices.push_back(index2);
     445                        m_Indices.push_back(index2);
     446                        m_Indices.push_back(index4);
     447                        m_Indices.push_back(index1);
     448                       
     449                        /*
     450                        //for triangle strip
     451                        m_Indices.push_back(index3);
     452                        m_Indices.push_back(index4);
     453                        m_Indices.push_back(index2);
     454                        m_Indices.push_back(index1);
     455                        */
     456                    }
     457                    else
     458                    {
     459                       
     460                        m_Indices.push_back(index2);
     461                        m_Indices.push_back(index3);
     462                        m_Indices.push_back(index1);
     463                        m_Indices.push_back(index1);
     464                        m_Indices.push_back(index3);
     465                        m_Indices.push_back(index4);
     466                       
     467                        /*
     468                        //for triangle strip
     469                        m_Indices.push_back(index2);
     470                        m_Indices.push_back(index3);
     471                        m_Indices.push_back(index1);
     472                        m_Indices.push_back(index4);
     473                        */
     474                    }
     475                   
     476                    /*
    335477                    m_Indices.push_back(u16(((j+0)*vsize+(i+0))+base));
    336478                    m_Indices.push_back(u16(((j+0)*vsize+(i+1))+base));
    337479                    m_Indices.push_back(u16(((j+1)*vsize+(i+1))+base));
    338480                    m_Indices.push_back(u16(((j+1)*vsize+(i+0))+base));
     481                    */
     482
    339483                }
    340484            }
    341485        }
    342486        splat.m_IndexCount=m_Indices.size()-splat.m_IndexStart;
    343487    }
    344 
    345     // build indices for the shadow map pass
    346     for (ssize_t j=0;j<PATCH_SIZE;j++) {
    347         for (ssize_t i=0;i<PATCH_SIZE;i++) {
    348             m_ShadowMapIndices.push_back(u16(((j+0)*vsize+(i+0))+base));
    349             m_ShadowMapIndices.push_back(u16(((j+0)*vsize+(i+1))+base));
    350             m_ShadowMapIndices.push_back(u16(((j+1)*vsize+(i+1))+base));
    351             m_ShadowMapIndices.push_back(u16(((j+1)*vsize+(i+0))+base));
    352         }
    353     }
    354488}
    355489
    356490
     
    519653        ogl_tex_bind(splat.m_Texture);
    520654
    521655        if (!g_Renderer.m_SkipSubmit) {
    522             glDrawElements(GL_QUADS, (GLsizei)splat.m_IndexCount,
     656            glDrawElements(GL_TRIANGLES, (GLsizei)splat.m_IndexCount,
    523657                GL_UNSIGNED_SHORT, &m_Indices[splat.m_IndexStart]);
    524658        }
    525 
     659       
    526660        // bump stats
    527661        g_Renderer.m_Stats.m_DrawCalls++;
    528662        g_Renderer.m_Stats.m_TerrainTris+=splat.m_IndexCount/2;
     
    552686
    553687    // render all base splats at once
    554688    if (!g_Renderer.m_SkipSubmit) {
    555         glDrawElements(GL_QUADS,(GLsizei)m_Indices.size(),GL_UNSIGNED_SHORT,&m_Indices[0]);
     689        glDrawElements(GL_TRIANGLES,(GLsizei)m_Indices.size(),GL_UNSIGNED_SHORT,&m_Indices[0]);
    556690    }
    557691
    558692    // bump stats
     
    591725        ogl_tex_bind(splat.m_Texture);
    592726
    593727        if (!g_Renderer.m_SkipSubmit) {
    594             glDrawElements(GL_QUADS, (GLsizei)splat.m_IndexCount,
     728            glDrawElements(GL_TRIANGLES, (GLsizei)splat.m_IndexCount,
    595729                GL_UNSIGNED_SHORT, &m_BlendIndices[splat.m_IndexStart]);
    596730        }
    597731
  • PatchRData.h

     
    104104    // indices into base vertices for the base splats
    105105    std::vector<unsigned short> m_Indices;
    106106
    107     // indices into base vertices for the shadow map pass
    108     std::vector<unsigned short> m_ShadowMapIndices;
    109 
    110107    // list of base splats to apply to this patch
    111108    std::vector<SSplat> m_Splats;
    112109