Ticket #169: terrain_triangulation_test.patch

File terrain_triangulation_test.patch, 9.4 KB (added by Xin, 14 years ago)

Initial work into triangulating BuildBlends. Submitted for debugging help. See comment: http://trac.wildfiregames.com/ticket/169#comment:10

  • PatchRData.cpp

     
    238238                        m_BlendVertexIndices.push_back(((j+1)*vsize)+i);
    239239
    240240                        // build a splat for this quad
     241                        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     242                        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     243                        //!!!!!!!THIS MIGHT NEED TO BE CHANGED AND EVERYTHING ABOVE IT!!!!!!!!!
     244                        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     245                        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    241246                        STmpSplat splat;
    242247                        splat.m_Texture=neighbourTextures[k].m_Handle;
    243248                        splat.m_Indices[0]=(u16)(vindex);
     
    277282            SSplat& splat=m_BlendSplats[splatCount];
    278283            splat.m_IndexStart=m_BlendIndices.size();
    279284            splat.m_Texture=tex;
    280 
     285           
    281286            for (size_t k=0;k<splats.size();k++) {
    282287                if (splats[k].m_Texture==tex) {
     288                    /*
    283289                    m_BlendIndices.push_back(splats[k].m_Indices[0]+base);
    284290                    m_BlendIndices.push_back(splats[k].m_Indices[1]+base);
    285291                    m_BlendIndices.push_back(splats[k].m_Indices[2]+base);
    286292                    m_BlendIndices.push_back(splats[k].m_Indices[3]+base);
    287293                    splat.m_IndexCount+=4;
     294                    */
     295
     296                    //save these for convenience
     297                    CVector3D v1 = m_BlendVertices[splats[k].m_Indices[0]].m_Position;
     298                    CVector3D v2 = m_BlendVertices[splats[k].m_Indices[1]].m_Position;
     299                    CVector3D v3 = m_BlendVertices[splats[k].m_Indices[2]].m_Position;
     300                    CVector3D v4 = m_BlendVertices[splats[k].m_Indices[3]].m_Position;
     301
     302                    debug_printf(L"Trying to add vertex1 (%f,%f,%f)\n", v1.X, v1.Y, v1.Z);
     303                    debug_printf(L"Trying to add vertex2 (%f,%f,%f)\n", v2.X, v2.Y, v2.Z);
     304                    debug_printf(L"Trying to add vertex3 (%f,%f,%f)\n", v3.X, v3.Y, v3.Z);
     305                    debug_printf(L"Trying to add vertex4 (%f,%f,%f)\n", v4.X, v4.Y, v4.Z);
     306
     307                    //this is terrible, but: find the set of indices in m_Indices that correspond to the vertices
     308                    //being used by the current blend texture so that we can match up the triangulation used
     309                    std::list<unsigned short> IndexList;    //store the order indices should be added to m_BlendIndices
     310                    for (int p = 0; p < m_Indices.size()-5; p++)
     311                    {
     312                        const SBaseVertex& temp = m_Vertices[m_Indices[p]];
     313                        CVector3D t = m_Vertices[m_Indices[p]].m_Position;
     314                        if (v1.X >= 68.0f)
     315                        {
     316                            debug_printf(L"Looking at (%f,%f,%f)\n", t.X, t.Y, t.Z);
     317                            debug_printf(L"Current p: %i\n", p);
     318                        }
     319                        if (
     320                            m_Vertices[m_Indices[p]].m_Position == v1 ||
     321                            m_Vertices[m_Indices[p]].m_Position == v2 ||
     322                            m_Vertices[m_Indices[p]].m_Position == v3 ||
     323                            m_Vertices[m_Indices[p]].m_Position == v4
     324                            )
     325                        {
     326                            debug_printf(L"Matched\n");
     327                            //we've found a match to one of the vertices, but that does not necessarily mean we're at the right set of
     328                            //indices so we check the block of 6 vertices to see if they contain all the vertices we're using
     329                            for (int q = p; q < p+6; q++)
     330                            {
     331                                CVector3D f = m_Vertices[m_Indices[q]].m_Position;
     332                                debug_printf(L"Looking at (%f,%f,%f)\n", f.X, f.Y,f.Z);
     333                                if (m_Vertices[m_Indices[q]].m_Position == v1)
     334                                {
     335                                    IndexList.push_back(0);
     336                                }
     337                                else if (m_Vertices[m_Indices[q]].m_Position == v2)
     338                                {
     339                                    IndexList.push_back(1);
     340                                }
     341                                else if (m_Vertices[m_Indices[q]].m_Position == v3)
     342                                {
     343                                    IndexList.push_back(2);
     344                                }
     345                                else if (m_Vertices[m_Indices[q]].m_Position == v4)
     346                                {
     347                                    IndexList.push_back(3);
     348                                }
     349                                else
     350                                {
     351                                    //this means we've encountered a vertex that's not one of the ones we're looking for so exit out
     352                                    CVector3D z = m_Vertices[m_Indices[q]].m_Position;
     353                                    CVector3D z2 = m_BlendVertices[splats[k].m_Indices[3]].m_Position;
     354                                    debug_printf(L"Failed to match (%f,%f,%f)\n", z.X,z.Y,z.Z);
     355                                    IndexList.clear();
     356                                    break;
     357                                }
     358                            }
     359                        }
     360                        if (IndexList.size() == 6)
     361                        {
     362                            //found our triangulation so early out for the search
     363                            break;
     364                        }
     365                    }
     366                   
     367                    if (IndexList.size() != 6)
     368                    {
     369                        //tried to use debug_assert(IndexList.size() == 6), but that started throwing memory access violations for some reason
     370                        debug_printf(L"WARNING: Blend Indices building failed. IndexList does not contain 6 elements.\n");
     371                        debug_break();
     372                    }
     373                    std::list<unsigned short>::iterator it;
     374                    debug_printf(L"About to start adding indices\n");
     375                    for (it = IndexList.begin(); it != IndexList.end(); it++)
     376                    {
     377                        //add the indices in the order we found them in
     378                        debug_printf(L"%i",*it);
     379                        debug_printf(L"\n");
     380                        m_BlendIndices.push_back(splats[k].m_Indices[*it]+base);
     381                    }
    288382                }
    289383            }
    290384            splatCount++;
     
    302396
    303397    // release existing indices and bins
    304398    m_Indices.clear();
    305     m_ShadowMapIndices.clear();
    306399    m_Splats.clear();
    307400
    308401    // build grid of textures on this patch and boundaries of adjacent patches
     
    332425        for (ssize_t j=0;j<PATCH_SIZE;j++) {
    333426            for (ssize_t i=0;i<PATCH_SIZE;i++) {
    334427                if (texgrid[j][i]==h){
     428
     429                    //save these values for convenience
     430                    u16 index1 = u16(((j+0)*vsize+(i+0))+base);
     431                    u16 index2 = u16(((j+0)*vsize+(i+1))+base);
     432                    u16 index3 = u16(((j+1)*vsize+(i+1))+base);
     433                    u16 index4 = u16(((j+1)*vsize+(i+0))+base);
     434
     435                    //calculate triangulation
     436                    //reminder: incrementing i shifts x coordinates, j shifts z
     437                    //first, get all the positions of the vertices in world space
     438                    CVector3D v1 = m_Vertices[(j+0)*vsize+(i+0)].m_Position;
     439                    CVector3D v2 = m_Vertices[(j+0)*vsize+(i+1)].m_Position;
     440                    CVector3D v3 = m_Vertices[(j+1)*vsize+(i+1)].m_Position;
     441                    CVector3D v4 = m_Vertices[(j+1)*vsize+(i+0)].m_Position;
     442                   
     443                    /*
     444                    debug_printf(L"Vertex 1 is at position: %f, %f, %f\n", v1.X, v1.Y, v1.Z);
     445                    debug_printf(L"Vertex 2 is at position: %f, %f, %f\n", v2.X, v2.Y, v2.Z);
     446                    debug_printf(L"Vertex 3 is at position: %f, %f, %f\n", v3.X, v3.Y, v3.Z);
     447                    debug_printf(L"Vertex 4 is at position: %f, %f, %f\n", v4.X, v4.Y, v4.Z);
     448                    */
     449
     450                   
     451                    //we have two possible triangulations to check: (123, 143) and (234, 214)
     452                    //our goal is to pick the one that minimizes the angle between the planes formed by the triangles
     453                    //the normals are constructed in such a way as to avoid having to normalize the vectors for the dot product
     454                    CVector3D normal1 = (v1-v2).Cross(v3-v2);
     455                    CVector3D normal2 = (v1-v4).Cross(v3-v4);
     456                    CVector3D normal3 = (v4-v3).Cross(v2-v3);
     457                    CVector3D normal4 = (v4-v1).Cross(v2-v1);
     458                    float angle1 = normal1.Dot(normal2);    //since we don't need the exact angle, we can just use the value of the dot product
     459                    float angle2 = normal3.Dot(normal4);
     460
     461                    //cos gets smaller as the angle increases so we take the triangulation with the larger value
     462                    if (angle1 < angle2)
     463                    {
     464                       
     465                       
     466                        m_Indices.push_back(index3);
     467                        m_Indices.push_back(index4);
     468                        m_Indices.push_back(index2);
     469                        m_Indices.push_back(index2);
     470                        m_Indices.push_back(index4);
     471                        m_Indices.push_back(index1);
     472                       
     473                        /*
     474                        //for triangle strip
     475                        m_Indices.push_back(index3);
     476                        m_Indices.push_back(index4);
     477                        m_Indices.push_back(index2);
     478                        m_Indices.push_back(index1);
     479                        */
     480                    }
     481                    else
     482                    {
     483                       
     484                        m_Indices.push_back(index2);
     485                        m_Indices.push_back(index3);
     486                        m_Indices.push_back(index1);
     487                        m_Indices.push_back(index1);
     488                        m_Indices.push_back(index3);
     489                        m_Indices.push_back(index4);
     490                       
     491                        /*
     492                        //for triangle strip
     493                        m_Indices.push_back(index2);
     494                        m_Indices.push_back(index3);
     495                        m_Indices.push_back(index1);
     496                        m_Indices.push_back(index4);
     497                        */
     498                    }
     499                   
     500                    /*
    335501                    m_Indices.push_back(u16(((j+0)*vsize+(i+0))+base));
    336502                    m_Indices.push_back(u16(((j+0)*vsize+(i+1))+base));
    337503                    m_Indices.push_back(u16(((j+1)*vsize+(i+1))+base));
    338504                    m_Indices.push_back(u16(((j+1)*vsize+(i+0))+base));
     505                    */
     506
    339507                }
    340508            }
    341509        }
    342510        splat.m_IndexCount=m_Indices.size()-splat.m_IndexStart;
    343511    }
    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     }
    354512}
    355513
    356514
     
    519677        ogl_tex_bind(splat.m_Texture);
    520678
    521679        if (!g_Renderer.m_SkipSubmit) {
    522             glDrawElements(GL_QUADS, (GLsizei)splat.m_IndexCount,
     680            glDrawElements(GL_TRIANGLES, (GLsizei)splat.m_IndexCount,
    523681                GL_UNSIGNED_SHORT, &m_Indices[splat.m_IndexStart]);
    524682        }
    525 
     683       
    526684        // bump stats
    527685        g_Renderer.m_Stats.m_DrawCalls++;
    528686        g_Renderer.m_Stats.m_TerrainTris+=splat.m_IndexCount/2;
     
    552710
    553711    // render all base splats at once
    554712    if (!g_Renderer.m_SkipSubmit) {
    555         glDrawElements(GL_QUADS,(GLsizei)m_Indices.size(),GL_UNSIGNED_SHORT,&m_Indices[0]);
     713        glDrawElements(GL_TRIANGLES,(GLsizei)m_Indices.size(),GL_UNSIGNED_SHORT,&m_Indices[0]);
    556714    }
    557715
    558716    // bump stats
     
    591749        ogl_tex_bind(splat.m_Texture);
    592750
    593751        if (!g_Renderer.m_SkipSubmit) {
    594             glDrawElements(GL_QUADS, (GLsizei)splat.m_IndexCount,
     752            glDrawElements(GL_TRIANGLES, (GLsizei)splat.m_IndexCount,
    595753                GL_UNSIGNED_SHORT, &m_BlendIndices[splat.m_IndexStart]);
    596754        }
    597755