transfered from codeberg
This commit is contained in:
45
source_code/chunk_module/chunk/_internal/private_chunk.c
Normal file
45
source_code/chunk_module/chunk/_internal/private_chunk.c
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "private_chunk.h"
|
||||
#include "chunk.h"
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
void _initialize_chunk(struct chunk_struct* chunk, struct chunk_position_struct position_in_world)
|
||||
{
|
||||
memset(chunk, 0, sizeof(struct chunk_struct));
|
||||
|
||||
chunk->position = position_in_world;
|
||||
chunk->model = (Model){0};
|
||||
|
||||
chunk->bounds.min.x = (float)position_in_world.x;
|
||||
chunk->bounds.min.y = (float)position_in_world.y;
|
||||
chunk->bounds.min.z = (float)position_in_world.z;
|
||||
|
||||
chunk->bounds.max = (Vector3)
|
||||
{
|
||||
(float)position_in_world.x + chunk_size,
|
||||
(float)position_in_world.y + chunk_size,
|
||||
(float)position_in_world.z + chunk_size
|
||||
};
|
||||
|
||||
chunk->pending_mesh = NULL;
|
||||
atomic_init(&chunk->build_state, state_new);
|
||||
atomic_init(&chunk->marked_for_unload, false);
|
||||
atomic_store_explicit(&chunk->reference_counter, 1, memory_order_relaxed);
|
||||
}
|
||||
|
||||
void _free_chunk_data(struct chunk_struct* chunk)
|
||||
{
|
||||
if (chunk == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
free(chunk);
|
||||
}
|
||||
|
||||
10
source_code/chunk_module/chunk/_internal/private_chunk.h
Normal file
10
source_code/chunk_module/chunk/_internal/private_chunk.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef private_chunk_h
|
||||
#define private_chunk_h
|
||||
|
||||
struct chunk_position_struct;
|
||||
struct chunk_struct;
|
||||
|
||||
void _initialize_chunk(struct chunk_struct* chunk, struct chunk_position_struct world_position);
|
||||
void _free_chunk_data(struct chunk_struct* chunk);
|
||||
|
||||
#endif
|
||||
41
source_code/chunk_module/chunk/chunk.c
Normal file
41
source_code/chunk_module/chunk/chunk.c
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "chunk.h"
|
||||
#include "_internal/private_chunk.h"
|
||||
|
||||
#include "chunk_mesh_builder.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
chunk_struct* initialize_chunk(struct chunk_position_struct position_in_world) {
|
||||
chunk_struct *chunk = malloc(sizeof(chunk_struct));
|
||||
|
||||
if ( chunk == NULL )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_initialize_chunk(chunk, position_in_world);
|
||||
return chunk;
|
||||
}
|
||||
|
||||
void destroy_chunk(struct chunk_struct* chunk)
|
||||
{
|
||||
destroy_chunk_mesh(chunk);
|
||||
_free_chunk_data(chunk);
|
||||
}
|
||||
|
||||
uint32_t index_chunk(int32_t x, int32_t y, int32_t z) {
|
||||
return (uint32_t)(x + y * chunk_size + z * chunk_size * chunk_size);
|
||||
}
|
||||
|
||||
chunk_position_struct offset_chunk_position(struct chunk_position_struct origin_to_offset,
|
||||
int32_t x_offset,
|
||||
int32_t y_offset,
|
||||
int32_t z_offset)
|
||||
{
|
||||
chunk_position_struct new_chunk_coordinate;
|
||||
new_chunk_coordinate.x = origin_to_offset.x + x_offset;
|
||||
new_chunk_coordinate.y = origin_to_offset.y + y_offset;
|
||||
new_chunk_coordinate.z = origin_to_offset.z + z_offset;
|
||||
|
||||
return new_chunk_coordinate;
|
||||
}
|
||||
66
source_code/chunk_module/chunk/chunk.h
Normal file
66
source_code/chunk_module/chunk/chunk.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef chunk_h
|
||||
#define chunk_h
|
||||
|
||||
#include "raylib.h"
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
#define chunk_size 32
|
||||
|
||||
struct cpu_mesh_data_struct;
|
||||
|
||||
typedef enum chunk_state_enum
|
||||
{
|
||||
state_new = 0,
|
||||
state_needs_data,
|
||||
state_getting_data,
|
||||
|
||||
state_needs_terrain,
|
||||
state_getting_terrain,
|
||||
|
||||
state_needs_lighting,
|
||||
state_getting_lighting,
|
||||
|
||||
state_needs_mesh,
|
||||
state_getting_mesh,
|
||||
|
||||
state_need_upload_to_gpu,
|
||||
state_chunk_pending_upload,
|
||||
state_chunk_uploaded_to_render_queue,
|
||||
state_chunk_is_uploading,
|
||||
state_chunk_finished_uploading
|
||||
} chunk_state_enum;
|
||||
|
||||
|
||||
typedef struct chunk_position_struct
|
||||
{
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t z;
|
||||
} chunk_position_struct;
|
||||
|
||||
typedef struct chunk_struct
|
||||
{
|
||||
_Atomic uint32_t reference_counter;
|
||||
chunk_position_struct position;
|
||||
atomic_int build_state;
|
||||
atomic_bool marked_for_unload;
|
||||
BoundingBox bounds;
|
||||
Model model;
|
||||
struct cpu_mesh_data_struct* pending_mesh;
|
||||
uint16_t block_data[chunk_size * chunk_size * chunk_size];
|
||||
uint8_t light_data[chunk_size * chunk_size * chunk_size];
|
||||
} chunk_struct;
|
||||
|
||||
chunk_struct* initialize_chunk(struct chunk_position_struct position_in_world);
|
||||
|
||||
chunk_position_struct offset_chunk_position(struct chunk_position_struct origin_to_offset,
|
||||
int32_t x_offset,
|
||||
int32_t y_offset,
|
||||
int32_t z_offset);
|
||||
|
||||
void destroy_chunk(struct chunk_struct* chunk);
|
||||
uint32_t index_chunk(int32_t x, int32_t y, int32_t z);
|
||||
|
||||
#endif
|
||||
56
source_code/chunk_module/chunk/tests/test_chunk.c
Normal file
56
source_code/chunk_module/chunk/tests/test_chunk.c
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "test_chunk.h"
|
||||
|
||||
#include "chunk.h"
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Verify spatial indexing is unique and within the 1D array bounds */
|
||||
void test_chunk_index_calculation_is_unique_and_valid(void)
|
||||
{
|
||||
uint16_t maximum_index = chunk_size * chunk_size * chunk_size;
|
||||
|
||||
uint32_t index_origin = index_chunk(0, 0, 0);
|
||||
uint32_t index_far_corner = index_chunk(chunk_size - 1,
|
||||
chunk_size - 1,
|
||||
chunk_size - 1);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT16(0, index_origin);
|
||||
TEST_ASSERT_LESS_THAN_UINT16(maximum_index, index_far_corner);
|
||||
}
|
||||
|
||||
/* Verify that a new chunk is initialized with the correct defaults */
|
||||
void test_chunk_initialization_sets_correct_defaults(void)
|
||||
{
|
||||
chunk_position_struct initial_position = { 16.0f, 0.0f, -32.0f };
|
||||
chunk_struct *test_chunk = initialize_chunk(initial_position);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(test_chunk);
|
||||
TEST_ASSERT_EQUAL_FLOAT(initial_position.x, test_chunk->position.x);
|
||||
TEST_ASSERT_EQUAL_INT(state_needs_data, test_chunk->build_state);
|
||||
|
||||
destroy_chunk(test_chunk);
|
||||
}
|
||||
|
||||
/* Verify that chunk bounds are correctly calculated based on world position */
|
||||
void test_chunk_bounds_calculation_is_accurate(void)
|
||||
{
|
||||
chunk_position_struct initial_position = { 100.0f, 100.0f, 100.0f };
|
||||
chunk_struct *test_chunk = initialize_chunk(initial_position);
|
||||
|
||||
float expected_maximum_x = (float)(initial_position.x + chunk_size);
|
||||
|
||||
TEST_ASSERT_EQUAL_FLOAT(initial_position.x, test_chunk->bounds.min.x);
|
||||
TEST_ASSERT_EQUAL_FLOAT(expected_maximum_x, test_chunk->bounds.max.x);
|
||||
|
||||
destroy_chunk(test_chunk);
|
||||
}
|
||||
|
||||
/* Runner for this specific module */
|
||||
void run_chunk_tests(void)
|
||||
{
|
||||
RUN_TEST(test_chunk_index_calculation_is_unique_and_valid);
|
||||
RUN_TEST(test_chunk_initialization_sets_correct_defaults);
|
||||
RUN_TEST(test_chunk_bounds_calculation_is_accurate);
|
||||
}
|
||||
12
source_code/chunk_module/chunk/tests/test_chunk.h
Normal file
12
source_code/chunk_module/chunk/tests/test_chunk.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef test_chunk_h
|
||||
#define test_chunk_h
|
||||
|
||||
void test_chunk_index_calculation_is_unique_and_valid(void);
|
||||
|
||||
void test_chunk_initialization_sets_correct_defaults(void);
|
||||
|
||||
void test_chunk_bounds_calculation_is_accurate(void);
|
||||
|
||||
void run_chunk_tests(void);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user