133 lines
3.0 KiB
C
133 lines
3.0 KiB
C
/**
|
|
* Copyright (c) 2021 Dominic Masters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#include "chunklist.h"
|
|
|
|
chunklist_t * chunkListCreate(int32_t width, int32_t height, int32_t depth) {
|
|
chunklist_t *list;
|
|
int32_t i, x, y, z;
|
|
|
|
list = malloc(sizeof(chunklist_t));
|
|
if(!list) return NULL;
|
|
|
|
list->width = width, list->height = height, list->depth = depth;
|
|
list->x = 0, list->y = 0, list->z = 0;
|
|
list->count = width * height * depth;
|
|
|
|
//Create chunks
|
|
list->chunks = malloc(list->count * sizeof(chunk_t));
|
|
if(list->chunks == NULL) {
|
|
free(list);
|
|
return NULL;
|
|
}
|
|
|
|
list->chunkList = malloc(list->count * sizeof(chunk_t *));
|
|
if(list->chunkList == NULL) {
|
|
free(list->chunks);
|
|
free(list);
|
|
return NULL;
|
|
}
|
|
|
|
// Load initial chunks, ZYX order is necessary.
|
|
i = 0;
|
|
for(z = 0; z < width; z++) {
|
|
for(y = 0; y < height; y++) {
|
|
for(x = 0; x < depth; x++) {
|
|
chunk_t *chunk = list->chunks + i;
|
|
list->chunkList[i] = chunk;
|
|
|
|
// Load initial coordinates
|
|
chunk->x = x;
|
|
chunk->y = y;
|
|
chunk->z = z;
|
|
|
|
chunkLoad(chunk, x, y, z);
|
|
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
void chunkListDispose(chunklist_t *list) {
|
|
free(list->chunks);
|
|
free(list);
|
|
}
|
|
|
|
void chunkListShift(chunklist_t *list, int32_t x, int32_t y, int32_t z) {
|
|
int32_t i,
|
|
/** New List Coordinates */
|
|
lx, ly, lz,
|
|
/** New Local Chunk Coordinates */
|
|
nx, ny, nz,
|
|
/** New Absolute Chunk Coordinates */
|
|
ax, ay, az,
|
|
/** New Chunk Index */
|
|
ni,
|
|
/** Precalculated width * height */
|
|
wh
|
|
;
|
|
chunk_t *chunk;
|
|
chunk_t **chunkList;
|
|
|
|
// Calculate the new chunklist coordinates
|
|
lx = list->x + x;
|
|
ly = list->y + y;
|
|
lz = list->z + z;
|
|
|
|
// Precalc width * height.
|
|
wh = list->width * list->height;
|
|
|
|
chunkList = malloc(list->count * sizeof(chunk_t *));
|
|
for(i = 0; i < list->count; i++) {
|
|
chunk = list->chunkList[i];
|
|
|
|
// Calculate the new local positions for the chunk.
|
|
nx = mod(chunk->x - list->x - x, list->width);
|
|
ny = mod(chunk->y - list->y - y, list->height);
|
|
nz = mod(chunk->z - list->z - z, list->depth);
|
|
|
|
// Load the chunk if we need to. We also use this to calculate new absolutes
|
|
if(
|
|
(ax = lx + nx) != chunk->x ||
|
|
(ly + ny) != chunk->y ||
|
|
(lz + nz) != chunk->z
|
|
) {
|
|
// Calculate those things that may have not been done within the if
|
|
ay = ly + ny;
|
|
az = lz + nz;
|
|
|
|
// Load new chunk.
|
|
chunkUnload(chunk);
|
|
chunkLoad(chunk, ax, ay, az);
|
|
|
|
// Update the absolute coordinates.
|
|
chunk->x = ax;
|
|
chunk->y = ay;
|
|
chunk->z = az;
|
|
}
|
|
|
|
// Now, based off those new local positions, calculate the new index.
|
|
ni = (
|
|
nx +
|
|
(ny * list->width) +
|
|
(nz * wh)
|
|
);
|
|
chunkList[ni] = chunk;
|
|
}
|
|
|
|
// Update Absolutes.
|
|
list->x = lx;
|
|
list->y = ly;
|
|
list->z = lz;
|
|
|
|
// Now copy that array over.
|
|
memcpy(list->chunkList, chunkList, sizeof(chunk_t *) * list->count);
|
|
free(chunkList);
|
|
} |