Ticket #2039: FasterNormalCalc.patch

File FasterNormalCalc.patch, 3.2 KB (added by wraitii, 11 years ago)
  • source/graphics/Terrain.cpp

     
    146146    CVector3D left, right, up, down;
    147147
    148148    // Calculate normals of the four half-tile triangles surrounding this vertex:
    149 
     149   
    150150    // get position of vertex where normal is being evaluated
    151     CVector3D basepos;
    152     CalcPosition(i, j, basepos);
     151    ssize_t hi = clamp(i, (ssize_t)0, m_MapSize-1);
     152    ssize_t hj = clamp(j, (ssize_t)0, m_MapSize-1);
     153    float baseHeight = float(m_Heightmap[hj*m_MapSize + hi]);
    153154
    154     if (i > 0) {
    155         CalcPosition(i-1, j, left);
    156         left -= basepos;
     155    // I have no idea if it's faster to check for != or >
     156    if (i != 0) {
     157        left.X = -4.0f;
     158        left.Y = (float(m_Heightmap[hj*m_MapSize + (hi-1)])-baseHeight)*HEIGHT_SCALE;
     159        left.Z = 0.0f;
    157160        left.Normalize();
    158161    }
    159162
    160     if (i < m_MapSize-1) {
    161         CalcPosition(i+1, j, right);
    162         right -= basepos;
     163    if (i != m_MapSize-1) {
     164        right.X = 4.0f;
     165        right.Y = (float(m_Heightmap[hj*m_MapSize + (hi+1)])-baseHeight)*HEIGHT_SCALE;
     166        right.Z = 0.0f;
    163167        right.Normalize();
    164168    }
    165169
    166     if (j > 0) {
    167         CalcPosition(i, j-1, up);
    168         up -= basepos;
     170    if (j != 0) {
     171        up.X = 0.0f;
     172        up.Y = (float(m_Heightmap[(hj-1)*m_MapSize + hi])-baseHeight)*HEIGHT_SCALE;
     173        up.Z = -4.0f;
    169174        up.Normalize();
    170175    }
    171176
    172     if (j < m_MapSize-1) {
    173         CalcPosition(i, j+1, down);
    174         down -= basepos;
     177    if (j != m_MapSize-1) {
     178        down.X = 0.0f;
     179        down.Y = (float(m_Heightmap[(hj+1)*m_MapSize + hi])-baseHeight)*HEIGHT_SCALE;
     180        down.Z = 4.0f;
    175181        down.Normalize();
    176182    }
    177183
     
    195201    // Calculate normals of the four half-tile triangles surrounding this vertex:
    196202
    197203    // get position of vertex where normal is being evaluated
    198     CFixedVector3D basepos;
    199     CalcPositionFixed(i, j, basepos);
    200 
    201     if (i > 0) {
    202         CalcPositionFixed(i-1, j, left);
    203         left -= basepos;
     204    ssize_t hi = clamp(i, (ssize_t)0, m_MapSize-1);
     205    ssize_t hj = clamp(j, (ssize_t)0, m_MapSize-1);
     206    // fixed max value is 32767, but height is a u16, so divide by two to avoid overflow
     207    int baseHeight = (m_Heightmap[hj*m_MapSize + hi]/ 2 );
     208   
     209    if (i != 0) {
     210        left.X = fixed::FromInt(-4);
     211        left.Y = fixed::FromInt((m_Heightmap[hj*m_MapSize + hi-1]/2 - baseHeight) / ((int)HEIGHT_UNITS_PER_METRE / 2));
     212        left.Z = fixed::Zero();
    204213        left.Normalize();
    205214    }
    206215
    207     if (i < m_MapSize-1) {
    208         CalcPositionFixed(i+1, j, right);
    209         right -= basepos;
     216    if (i != m_MapSize-1) {
     217        right.X = fixed::FromInt(4);
     218        right.Y = fixed::FromInt((m_Heightmap[hj*m_MapSize + hi+1]/2 - baseHeight) / ((int)HEIGHT_UNITS_PER_METRE / 2));
     219        right.Z = fixed::Zero();
    210220        right.Normalize();
    211221    }
    212222
    213     if (j > 0) {
    214         CalcPositionFixed(i, j-1, up);
    215         up -= basepos;
     223    if (j != 0) {
     224        right.X = fixed::Zero();
     225        right.Y = fixed::FromInt((m_Heightmap[(hj-1)*m_MapSize + hi]/2 - baseHeight) / ((int)HEIGHT_UNITS_PER_METRE / 2));
     226        right.Z = fixed::FromInt(-4);
    216227        up.Normalize();
    217228    }
    218229
    219     if (j < m_MapSize-1) {
    220         CalcPositionFixed(i, j+1, down);
    221         down -= basepos;
     230    if (j != m_MapSize-1) {
     231        right.X = fixed::Zero();
     232        right.Y = fixed::FromInt((m_Heightmap[(hj+1)*m_MapSize + hi]/2 - baseHeight) / ((int)HEIGHT_UNITS_PER_METRE / 2));
     233        right.Z = fixed::FromInt(4);
    222234        down.Normalize();
    223235    }
    224236