2010-09-11 2 views
0

Я делаю игру, полностью сделанную из кубов. Я замечаю, что когда я иду вперед, он быстро горит, но если я поверную игрока в противоположном направлении, он будет падать медленно. Итак, то, что я сделал, упорядочивается на основе угла, но у меня все еще есть некоторые углы, которые немного медленны. Вот как я это сделал:Z геометрия упорядочения

Я в основном обратный итерации под определенными углами, но как я могу сделать это согласованным, чтобы каждый угол быстро осветлялся, некоторые из прямых углов, например 88-92 или 178-182, действительно медленный (overdraw).

Благодаря

SetPlayerPosition(); 


PlayerPosition.x -= 70; 

PlayerPosition.y -= 20; 

PlayerPosition.z -= 70; 


collids.clear(); 
CBox* tmp; 
float offset = -10; 
if(Wrap(Camera.roty + offset) > 180 && Wrap(Camera.roty + offset) < 270) 
{ 
    for(int i = 140; i > 0; --i) 
    { 
     for(int j = 0; j < 40; ++j) 
     { 
      for(int k = 0; k < 140; ++k) 
      { 

       tmp = GetCube(PlayerPosition.x + i, PlayerPosition.y + j, PlayerPosition.z + k); 



       if(tmp != 0) 
       { 
        if(frustum.sphereInFrustum(tmp->center,25) != NULL) 
        { 
         collids.push_back(tmp); 
        } 
       } 

      } 
     } 
    } 
} 
else if(Wrap(Camera.roty + offset) > 0 && Wrap(Camera.roty + offset) < 90) 
{ 
    for(int i = 0; i < 140; ++i) 
    { 
     for(int j = 0; j < 40; ++j) 
     { 
      for(int k = 140; k > 0; --k) 
      { 

       tmp = GetCube(PlayerPosition.x + i, PlayerPosition.y + j, PlayerPosition.z + k); 



       if(tmp != 0) 
       { 
        if(frustum.sphereInFrustum(tmp->center,25) != NULL) 
        { 
         collids.push_back(tmp); 
        } 
       } 

      } 
     } 
    } 
} 

else if(Wrap(Camera.roty + offset) > 90 && Wrap(Camera.roty + offset) < 180) 
{ 
    for(int i = 0; i < 140; ++i) 
    { 
     for(int j = 0; j < 40; ++j) 
     { 
      for(int k = 0; k < 140; ++k) 
      { 

       tmp = GetCube(PlayerPosition.x + i, PlayerPosition.y + j, PlayerPosition.z + k); 



       if(tmp != 0) 
       { 
        if(frustum.sphereInFrustum(tmp->center,25) != NULL) 
        { 
         collids.push_back(tmp); 
        } 
       } 

      } 
     } 
    } 
} 
else if (Wrap(Camera.roty + offset) > 270 && Wrap(Camera.roty + offset) < 360) 
{ 
    for(int i = 140; i > 0; --i) 
    { 
     for(int j = 0; j < 40; ++j) 
     { 
      for(int k = 140; k > 0; --k) 
      { 

       tmp = GetCube(PlayerPosition.x + i, PlayerPosition.y + j, PlayerPosition.z + k); 



       if(tmp != 0) 
       { 
        if(frustum.sphereInFrustum(tmp->center,25) != NULL) 
        { 
         collids.push_back(tmp); 
        } 
       } 

      } 
     } 
    } 
} 


} 

ответ

3

Yikes.

Не зная, что делает GetCube, я не могу догадаться, как это влияет на вашу производительность, но совершенно ясно, почему ситуация настолько значительно замедляется. Вы делаете много ненужной работы.

Вы можете устранить большую часть ваших циклов, просто используя другой подход: Игнорируйте угол и выполните более упрощенные тесты. Для любого значения i, j и k ничего не делать, если он отмечает куб за «игроком». Это само по себе позволит выровнять частоту кадров и упростить ваши петли. (Вам не нужны четыре различных наборов вложенных циклов!)

Еще лучше, если использовать пространственный график - что-то вроде октодерева или кД дерева - для хранения экземпляров ваших кубиков (или других объектов), а также выполните ваши тесты пересечения на узлах дерева. Таким образом, вы можете устранить огромные полосы объектов, которые никогда не будут находиться внутри усеченного конуса, и значительно улучшить производительность.