/** * 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); }