Ticket #169: terrain_triangulation_test2.patch

File terrain_triangulation_test2.patch, 9.7 KB (added by Xin, 14 years ago)

Fixed accessing out of bounds locations.

  • 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;
     285           
     286            size_t indexBase=m_VBBase->m_Index;
    280287
    281288            for (size_t k=0;k<splats.size();k++) {
    282289                if (splats[k].m_Texture==tex) {
     290                    /*
    283291                    m_BlendIndices.push_back(splats[k].m_Indices[0]+base);
    284292                    m_BlendIndices.push_back(splats[k].m_Indices[1]+base);
    285293                    m_BlendIndices.push_back(splats[k].m_Indices[2]+base);
    286294                    m_BlendIndices.push_back(splats[k].m_Indices[3]+base);
    287295                    splat.m_IndexCount+=4;
     296                    */
     297
     298                    //save these for convenience
     299                    CVector3D v1 = m_BlendVertices[splats[k].m_Indices[0]].m_Position;
     300                    CVector3D v2 = m_BlendVertices[splats[k].m_Indices[1]].m_Position;
     301                    CVector3D v3 = m_BlendVertices[splats[k].m_Indices[2]].m_Position;
     302                    CVector3D v4 = m_BlendVertices[splats[k].m_Indices[3]].m_Position;
     303
     304                    /*
     305                    debug_printf(L"Trying to add vertex1 (%f,%f,%f)\n", v1.X, v1.Y, v1.Z);
     306                    debug_printf(L"Trying to add vertex2 (%f,%f,%f)\n", v2.X, v2.Y, v2.Z);
     307                    debug_printf(L"Trying to add vertex3 (%f,%f,%f)\n", v3.X, v3.Y, v3.Z);
     308                    debug_printf(L"Trying to add vertex4 (%f,%f,%f)\n", v4.X, v4.Y, v4.Z);
     309                    */
     310
     311                    //this is terrible, but: find the set of indices in m_Indices that correspond to the vertices
     312                    //being used by the current blend texture so that we can match up the triangulation used
     313                    std::list<unsigned short> IndexList;    //store the order indices should be added to m_BlendIndices
     314                    for (int p = 0; p < m_Indices.size()-5; p++)
     315                    {
     316                        if (
     317                            m_Vertices[m_Indices[p]-indexBase].m_Position == v1 ||
     318                            m_Vertices[m_Indices[p]-indexBase].m_Position == v2 ||
     319                            m_Vertices[m_Indices[p]-indexBase].m_Position == v3 ||
     320                            m_Vertices[m_Indices[p]-indexBase].m_Position == v4
     321                            )
     322                        {
     323                            //debug_printf(L"Matched\n");
     324                            //we've found a match to one of the vertices, but that does not necessarily mean we're at the right set of
     325                            //indices so we check the block of 6 vertices to see if they contain all the vertices we're using
     326                            for (int q = p; q < p+6; q++)
     327                            {
     328                                CVector3D f = m_Vertices[m_Indices[q]-indexBase].m_Position;
     329                                //debug_printf(L"Looking at (%f,%f,%f)\n", f.X, f.Y,f.Z);
     330                                if (m_Vertices[m_Indices[q]-indexBase].m_Position == v1)
     331                                {
     332                                    IndexList.push_back(0);
     333                                }
     334                                else if (m_Vertices[m_Indices[q]-indexBase].m_Position == v2)
     335                                {
     336                                    IndexList.push_back(1);
     337                                }
     338                                else if (m_Vertices[m_Indices[q]-indexBase].m_Position == v3)
     339                                {
     340                                    IndexList.push_back(2);
     341                                }
     342                                else if (m_Vertices[m_Indices[q]-indexBase].m_Position == v4)
     343                                {
     344                                    IndexList.push_back(3);
     345                                }
     346                                else
     347                                {
     348                                    //this means we've encountered a vertex that's not one of the ones we're looking for so exit out
     349                                    CVector3D z = m_Vertices[m_Indices[q]-indexBase].m_Position;
     350                                    CVector3D z2 = m_BlendVertices[splats[k].m_Indices[3]].m_Position;
     351                                    //debug_printf(L"Failed to match (%f,%f,%f)\n", z.X,z.Y,z.Z);
     352                                    IndexList.clear();
     353                                    break;
     354                                }
     355                            }
     356                        }
     357                        if (IndexList.size() == 6)
     358                        {
     359                            //found our triangulation so early out for the search
     360                            break;
     361                        }
     362                    }
     363                   
     364                    if (IndexList.size() != 6)
     365                    {
     366                        //tried to use debug_assert(IndexList.size() == 6), but that started throwing memory access violations for some reason
     367                        debug_printf(L"WARNING: Blend Indices building failed. IndexList does not contain 6 elements.\n");
     368                        debug_break();
     369                    }
     370                    std::list<unsigned short>::iterator it;
     371                    //debug_printf(L"About to start adding indices\n");
     372                    for (it = IndexList.begin(); it != IndexList.end(); it++)
     373                    {
     374                        //add the indices in the order we found them in
     375                        //debug_printf(L"%i",*it);
     376                        //debug_printf(L"\n");
     377                        m_BlendIndices.push_back(splats[k].m_Indices[*it]+base);
     378                    }
    288379                }
    289380            }
    290381            splatCount++;
     
    302393
    303394    // release existing indices and bins
    304395    m_Indices.clear();
    305     m_ShadowMapIndices.clear();
    306396    m_Splats.clear();
    307397
    308398    // build grid of textures on this patch and boundaries of adjacent patches
     
    332422        for (ssize_t j=0;j<PATCH_SIZE;j++) {
    333423            for (ssize_t i=0;i<PATCH_SIZE;i++) {
    334424                if (texgrid[j][i]==h){
     425
     426                    //save these values for convenience
     427                    u16 index1 = u16(((j+0)*vsize+(i+0))+base);
     428                    u16 index2 = u16(((j+0)*vsize+(i+1))+base);
     429                    u16 index3 = u16(((j+1)*vsize+(i+1))+base);
     430                    u16 index4 = u16(((j+1)*vsize+(i+0))+base);
     431
     432                    //calculate triangulation
     433                    //reminder: incrementing i shifts x coordinates, j shifts z
     434                    //first, get all the positions of the vertices in world space
     435                    CVector3D v1 = m_Vertices[(j+0)*vsize+(i+0)].m_Position;
     436                    CVector3D v2 = m_Vertices[(j+0)*vsize+(i+1)].m_Position;
     437                    CVector3D v3 = m_Vertices[(j+1)*vsize+(i+1)].m_Position;
     438                    CVector3D v4 = m_Vertices[(j+1)*vsize+(i+0)].m_Position;
     439                   
     440                    /*
     441                    debug_printf(L"Vertex 1 is at position: %f, %f, %f\n", v1.X, v1.Y, v1.Z);
     442                    debug_printf(L"Vertex 2 is at position: %f, %f, %f\n", v2.X, v2.Y, v2.Z);
     443                    debug_printf(L"Vertex 3 is at position: %f, %f, %f\n", v3.X, v3.Y, v3.Z);
     444                    debug_printf(L"Vertex 4 is at position: %f, %f, %f\n", v4.X, v4.Y, v4.Z);
     445                    */
     446
     447                   
     448                    //we have two possible triangulations to check: (123, 143) and (234, 214)
     449                    //our goal is to pick the one that minimizes the angle between the planes formed by the triangles
     450                    //the normals are constructed in such a way as to avoid having to normalize the vectors for the dot product
     451                    CVector3D normal1 = (v1-v2).Cross(v3-v2);
     452                    CVector3D normal2 = (v1-v4).Cross(v3-v4);
     453                    CVector3D normal3 = (v4-v3).Cross(v2-v3);
     454                    CVector3D normal4 = (v4-v1).Cross(v2-v1);
     455                    float angle1 = normal1.Dot(normal2);    //since we don't need the exact angle, we can just use the value of the dot product
     456                    float angle2 = normal3.Dot(normal4);
     457
     458                    //cos gets smaller as the angle increases so we take the triangulation with the larger value
     459                    if (angle1 < angle2)
     460                    {
     461                       
     462                       
     463                        m_Indices.push_back(index3);
     464                        m_Indices.push_back(index4);
     465                        m_Indices.push_back(index2);
     466                        m_Indices.push_back(index2);
     467                        m_Indices.push_back(index4);
     468                        m_Indices.push_back(index1);
     469                       
     470                        /*
     471                        //for triangle strip
     472                        m_Indices.push_back(index3);
     473                        m_Indices.push_back(index4);
     474                        m_Indices.push_back(index2);
     475                        m_Indices.push_back(index1);
     476                        */
     477                    }
     478                    else
     479                    {
     480                       
     481                        m_Indices.push_back(index2);
     482                        m_Indices.push_back(index3);
     483                        m_Indices.push_back(index1);
     484                        m_Indices.push_back(index1);
     485                        m_Indices.push_back(index3);
     486                        m_Indices.push_back(index4);
     487                       
     488                        /*
     489                        //for triangle strip
     490                        m_Indices.push_back(index2);
     491                        m_Indices.push_back(index3);
     492                        m_Indices.push_back(index1);
     493                        m_Indices.push_back(index4);
     494                        */
     495                    }
     496                   
     497                    /*
    335498                    m_Indices.push_back(u16(((j+0)*vsize+(i+0))+base));
    336499                    m_Indices.push_back(u16(((j+0)*vsize+(i+1))+base));
    337500                    m_Indices.push_back(u16(((j+1)*vsize+(i+1))+base));
    338501                    m_Indices.push_back(u16(((j+1)*vsize+(i+0))+base));
     502                    */
     503
    339504                }
    340505            }
    341506        }
    342507        splat.m_IndexCount=m_Indices.size()-splat.m_IndexStart;
    343508    }
    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     }
    354509}
    355510
    356511
     
    519674        ogl_tex_bind(splat.m_Texture);
    520675
    521676        if (!g_Renderer.m_SkipSubmit) {
    522             glDrawElements(GL_QUADS, (GLsizei)splat.m_IndexCount,
     677            glDrawElements(GL_TRIANGLES, (GLsizei)splat.m_IndexCount,
    523678                GL_UNSIGNED_SHORT, &m_Indices[splat.m_IndexStart]);
    524679        }
    525 
     680       
    526681        // bump stats
    527682        g_Renderer.m_Stats.m_DrawCalls++;
    528683        g_Renderer.m_Stats.m_TerrainTris+=splat.m_IndexCount/2;
     
    552707
    553708    // render all base splats at once
    554709    if (!g_Renderer.m_SkipSubmit) {
    555         glDrawElements(GL_QUADS,(GLsizei)m_Indices.size(),GL_UNSIGNED_SHORT,&m_Indices[0]);
     710        glDrawElements(GL_TRIANGLES,(GLsizei)m_Indices.size(),GL_UNSIGNED_SHORT,&m_Indices[0]);
    556711    }
    557712
    558713    // bump stats
     
    591746        ogl_tex_bind(splat.m_Texture);
    592747
    593748        if (!g_Renderer.m_SkipSubmit) {
    594             glDrawElements(GL_QUADS, (GLsizei)splat.m_IndexCount,
     749            glDrawElements(GL_TRIANGLES, (GLsizei)splat.m_IndexCount,
    595750                GL_UNSIGNED_SHORT, &m_BlendIndices[splat.m_IndexStart]);
    596751        }
    597752
  • 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