Я работаю над клоном minecraft, и у меня есть 2 проблемы с загрузкой куска.Куски загрузки и сортировки
Первый: определить куски для загрузки.
я нашел один способ это некрасиво, но работает быстро для меня
- Определение 3d массива (массив) (размер: MAX_CHUNKS_X, MAX_CHUNKS_Y, MAX_CHUNKS_Z)
- Заливка 3d массив с фальшивыми
- При переходе от список блоков, проверяющих, есть ли внутри диапазона видения
- если внутри массива набора [chunk_x] [chunk_y] [chunk_z] = true;
- После прохождения списка начинают bassing массив
- Для всех массивов [chunk_x] [chunk_y] [chunk_z] == ложь добавить в LoadingList кусок в chunk_x chunk_y chunk_z
Еще способы менее некрасиво и по-прежнему быстро?
Код:
ChunksRenderList.clear();
CChunk* Chunk = NULL;
s32 RootChunk_X_Location = (floor(RenderCenter.x)/CHUNK_SIZE);
s32 RootChunk_Y_Location = (floor(RenderCenter.y)/CHUNK_SIZE);
s32 RootChunk_Z_Location = (floor(RenderCenter.z)/CHUNK_SIZE);
if(RenderCenter.x < 0)
RootChunk_X_Location--;
if(RenderCenter.y < 0)
RootChunk_Y_Location--;
if(RenderCenter.z < 0)
RootChunk_Z_Location--;
core::vector3s RootChunkLocation(RootChunk_X_Location,RootChunk_Y_Location,RootChunk_Z_Location);
u32 XZ_ArraySide = (RenderDistance_XZ*2)+1;
u32 Y_ArraySide = (RenderDistance_Y*2)+1;
char array[XZ_ArraySide][Y_ArraySide][XZ_ArraySide];
memset(array,0,(XZ_ArraySide*XZ_ArraySide*Y_ArraySide));
for(auto it = Chunks.begin(); it != Chunks.end(); it++)
{
Chunk = (it->second);
if(Chunk->Locked)
continue;
if(Chunk->KeepAliveCounter <= 0)
{
ChunksUnloadList.push_back(Chunk);
continue;
}
else
{
Chunk->KeepAliveCounter -= WORLD_UPDATE_PERIOD;
Chunk->DistanceToCamera = RenderCenter.distance_to(Chunk->ChunkAbsolutePosition);
}
if(Chunk->ChunkPosition.x >= (RootChunk_X_Location - (s32)RenderDistance_XZ) && Chunk->ChunkPosition.x <= (RootChunk_X_Location + (s32)RenderDistance_XZ))
if(Chunk->ChunkPosition.y >= (RootChunk_Y_Location - (s32)RenderDistance_Y) && Chunk->ChunkPosition.y <= (RootChunk_Y_Location + (s32)RenderDistance_Y))
if(Chunk->ChunkPosition.z >= (RootChunk_Z_Location - (s32)RenderDistance_XZ) && Chunk->ChunkPosition.z <= (RootChunk_Z_Location + (s32)RenderDistance_XZ))
{
s32 PositionInMatrix_X = Chunk->ChunkPosition.x - (RootChunk_X_Location - (s32)RenderDistance_XZ);
s32 PositionInMatrix_Y = Chunk->ChunkPosition.y - (RootChunk_Y_Location - (s32)RenderDistance_Y);
s32 PositionInMatrix_Z = Chunk->ChunkPosition.z - (RootChunk_Z_Location - (s32)RenderDistance_XZ);
array[PositionInMatrix_X][PositionInMatrix_Y][PositionInMatrix_Z] = true;
Chunk->KeepAliveCounter = CHUNK_LIVE_TIME;
}
if(not Chunk->NeightboarsUpdated)
{
ChunksNeightboarUpdateList.push_back(Chunk);
}
if(not Chunk->ChunkUpdated)
{
ChunksRebuildList.push_back(Chunk);
}
if(not Chunk->Locked and Chunk->VisibleBlocks > 0)
{
ChunksRenderList.push_back(Chunk);
}
}
for(u32 y = 0; y < Y_ArraySide; y++)
for(u32 x = 0; x < XZ_ArraySide; x++)
for(u32 z = 0; z < XZ_ArraySide; z++)
{
s32 ChunkPosition_X = (s32)x + (RootChunk_X_Location - (s32)RenderDistance_XZ);
s32 ChunkPosition_Y = (s32)y + (RootChunk_Y_Location - (s32)RenderDistance_Y);
s32 ChunkPosition_Z = (s32)z + (RootChunk_Z_Location - (s32)RenderDistance_XZ);
if(array[x][y][z] == 0)
{
SPendingToLoad ToLoad;
ToLoad.Position.set(ChunkPosition_X,ChunkPosition_Y,ChunkPosition_Z);
ToLoad.DistanceToCamera = ToLoad.Position.distance_to_sqr(RootChunkLocation);
ChunksLoadList.push_back(ToLoad);
}
}
Второе: как сортировать ChunksLoadList вступили в силу, как оставить на этой картинке https://www.dropbox.com/s/owjfaaekcj2m23w/58f2e4c8.png?dl=0 Красный = ближайший к ChunksLoadList.begin() Синий = Farest к ChunksLoadList.begin()
им пытаются использовать
ChunksLoadList.sort([&RootChunkLocation](SPendingToLoad& i,SPendingToLoad& j)
{
return i.DistanceToCamera < j.DistanceToCamera;
}
);
Но это способ замедлить большие диапазоны видимости ... Как я должен переписать код для быстрого эффекта волновой нагрузки?
Извините меня ужасный английский, я надеюсь, что вы меня понимаете ...
Насколько важно точное расстояние до камеры? и точный порядок? и все значения плавают? – Surt
Surt, расстояние до камеры необходимо только для сортировки кусков от ближайшего к далекому. Функция, которая используется для вычисления расстояния, не использует только sqrt() (x^2 + y^2 + z^2) – AnrgyHumster
S32 является int32_t, а переменная, которая является typecast для S32, является float? – Surt