97 lines
2.7 KiB
C
97 lines
2.7 KiB
C
/**
|
|
* Copyright (c) 2025 Dominic Masters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#include "worldpos.h"
|
|
#include "assert/assert.h"
|
|
|
|
bool_t worldPosIsEqual(const worldpos_t a, const worldpos_t b) {
|
|
return a.x == b.x && a.y == b.y && a.z == b.z;
|
|
}
|
|
|
|
void chunkPosToWorldPos(const chunkpos_t* chunkPos, worldpos_t* out) {
|
|
assertNotNull(chunkPos, "Chunk position pointer cannot be NULL");
|
|
assertNotNull(out, "Output world position pointer cannot be NULL");
|
|
|
|
out->x = (worldunit_t)(chunkPos->x * CHUNK_WIDTH);
|
|
out->y = (worldunit_t)(chunkPos->y * CHUNK_HEIGHT);
|
|
out->z = (worldunit_t)(chunkPos->z * CHUNK_DEPTH);
|
|
}
|
|
|
|
void worldPosToChunkPos(const worldpos_t* worldPos, chunkpos_t* out) {
|
|
assertNotNull(worldPos, "World position pointer cannot be NULL");
|
|
assertNotNull(out, "Output chunk position pointer cannot be NULL");
|
|
|
|
if(worldPos->x < 0) {
|
|
out->x = (chunkunit_t)((worldPos->x - (CHUNK_WIDTH - 1)) / CHUNK_WIDTH);
|
|
} else {
|
|
out->x = (chunkunit_t)(worldPos->x / CHUNK_WIDTH);
|
|
}
|
|
|
|
if(worldPos->y < 0) {
|
|
out->y = (chunkunit_t)((worldPos->y - (CHUNK_HEIGHT - 1)) / CHUNK_HEIGHT);
|
|
} else {
|
|
out->y = (chunkunit_t)(worldPos->y / CHUNK_HEIGHT);
|
|
}
|
|
|
|
if(worldPos->z < 0) {
|
|
out->z = (chunkunit_t)((worldPos->z - (CHUNK_DEPTH - 1)) / CHUNK_DEPTH);
|
|
} else {
|
|
out->z = (chunkunit_t)(worldPos->z / CHUNK_DEPTH);
|
|
}
|
|
}
|
|
|
|
chunktileindex_t worldPosToChunkTileIndex(const worldpos_t* worldPos) {
|
|
assertNotNull(worldPos, "World position pointer cannot be NULL");
|
|
|
|
uint8_t localX, localY, localZ;
|
|
if(worldPos->x < 0) {
|
|
localX = (uint8_t)(
|
|
(CHUNK_WIDTH - 1) - ((-worldPos->x - 1) % CHUNK_WIDTH)
|
|
);
|
|
} else {
|
|
localX = (uint8_t)(worldPos->x % CHUNK_WIDTH);
|
|
}
|
|
|
|
if(worldPos->y < 0) {
|
|
localY = (uint8_t)(
|
|
(CHUNK_HEIGHT - 1) - ((-worldPos->y - 1) % CHUNK_HEIGHT)
|
|
);
|
|
} else {
|
|
localY = (uint8_t)(worldPos->y % CHUNK_HEIGHT);
|
|
}
|
|
|
|
if(worldPos->z < 0) {
|
|
localZ = (uint8_t)(
|
|
(CHUNK_DEPTH - 1) - ((-worldPos->z - 1) % CHUNK_DEPTH)
|
|
);
|
|
} else {
|
|
localZ = (uint8_t)(worldPos->z % CHUNK_DEPTH);
|
|
}
|
|
|
|
chunktileindex_t chunkTileIndex = (chunktileindex_t)(
|
|
(localZ * CHUNK_WIDTH * CHUNK_HEIGHT) +
|
|
(localY * CHUNK_WIDTH) +
|
|
localX
|
|
);
|
|
assertTrue(
|
|
chunkTileIndex < CHUNK_TILE_COUNT,
|
|
"Calculated chunk tile index is out of bounds"
|
|
);
|
|
return chunkTileIndex;
|
|
}
|
|
|
|
chunkindex_t chunkPosToIndex(const chunkpos_t* pos) {
|
|
assertNotNull(pos, "Chunk position pointer cannot be NULL");
|
|
|
|
chunkindex_t chunkIndex = (chunkindex_t)(
|
|
(pos->z * MAP_CHUNK_WIDTH * MAP_CHUNK_HEIGHT) +
|
|
(pos->y * MAP_CHUNK_WIDTH) +
|
|
pos->x
|
|
);
|
|
|
|
return chunkIndex;
|
|
} |