diff --git a/models/building-1.blend b/models/building-1.blend index 86c0e55..88f86cc 100644 Binary files a/models/building-1.blend and b/models/building-1.blend differ diff --git a/models/building-1.blend1 b/models/building-1.blend1 index 4dc55fa..1952caf 100644 Binary files a/models/building-1.blend1 and b/models/building-1.blend1 differ diff --git a/resources/building-1.glb b/resources/building-1.glb index 1e16ff4..e38919e 100644 Binary files a/resources/building-1.glb and b/resources/building-1.glb differ diff --git a/resources/building_a.glb b/resources/building_a.glb new file mode 100644 index 0000000..c6b7373 Binary files /dev/null and b/resources/building_a.glb differ diff --git a/resources/building_b.glb b/resources/building_b.glb new file mode 100644 index 0000000..a149f69 Binary files /dev/null and b/resources/building_b.glb differ diff --git a/resources/building_c.glb b/resources/building_c.glb new file mode 100644 index 0000000..b7af293 Binary files /dev/null and b/resources/building_c.glb differ diff --git a/resources/building_d.glb b/resources/building_d.glb new file mode 100644 index 0000000..a850650 Binary files /dev/null and b/resources/building_d.glb differ diff --git a/src/city_generator.c b/src/city_generator.c index d419698..e82cb69 100644 --- a/src/city_generator.c +++ b/src/city_generator.c @@ -2,7 +2,44 @@ #include "core/mesh_render_entity.h" #include "core/transform_node.h" -SceneNode *GenerateCity() { - SceneNode *node = CreateTransformNode(); - return node; +static struct { + size_t x, y; +} const CITY_SIZE = {20, 20}; + +#define MODELS_LENGTH 4 +static ModelResource models[MODELS_LENGTH] = { + ResourceEmpty(Model), + ResourceEmpty(Model), + ResourceEmpty(Model), + ResourceEmpty(Model) +}; + +static void Internal_LoadModelsIfRequired() { + for(size_t i = 0; i < MODELS_LENGTH; ++i) + if(models[i].handle == NULL && GetModelResource(TextFormat("building_%c", 'a' + i), &models[i])) + LoadResource(models[i].handle); +} + +static SceneNode *Internal_CreateBuilding(size_t x, size_t y) { + size_t building_index = (3 * (x + y + GetRandomValue(0, 50))) % MODELS_LENGTH; // semi-random number based on the x,y coordinate + SceneNode *mesh_render_node = CreateMeshRenderEntity(TextFormat("building_%c", 'a' + building_index)); + SceneNode *transform_node = CreateTransformNode(); + SceneNodeAddChild(transform_node, mesh_render_node); + Transformable transform = TC_CAST(transform_node->entity, Transformable); + Transform local = transform.tc->get_transform(transform.data); + local.translation.x = (float)(x * 40); + local.translation.z = (float)(y * 40); + transform.tc->set_transform(transform.data, local); + return transform_node; +} + +SceneNode *GenerateCity() { + Internal_LoadModelsIfRequired(); + SceneNode *root = CreateTransformNode(); + for(size_t x = 0; x < CITY_SIZE.x; ++x) { + for(size_t y = 0; y < CITY_SIZE.y; ++y) { + SceneNodeAddChild(root, Internal_CreateBuilding(x, y)); + } + } + return root; } diff --git a/src/core/resources.c b/src/core/resources.c index 57831f6..7ed929e 100644 --- a/src/core/resources.c +++ b/src/core/resources.c @@ -132,9 +132,9 @@ bool GetModelResource(char const *path, ModelResource *out) { ResourceContainer *container = hash_map_get_as(ResourceContainer, &g_resource_map, &path); *out = ResourceEmpty(Model); // assert some assumptions about the found resource - ASSERT_RETURN(container != NULL, false, "GetTextureResource: Resource %s not in index.", path); - ASSERT_RETURN(container->type == RESOURCE_MODEL, false, "GetTextureResource: Resource %s is not a Texture.", path); - ++container->use_counter; + ASSERT_RETURN(container != NULL, false, "GetModelResource: Resource %s not in index.", path); + ASSERT_RETURN(container->type == RESOURCE_MODEL, false, "GetModelResource: Resource %s is not a Texture.", path); + ASSERT_RETURN(strcmp(container->name, path) == 0, false, "GetModelResource: Resource %s was loaded for path %s", container->name, path); *out = (ModelResource) { .handle = container, .resource = &container->model @@ -174,16 +174,20 @@ bool IsResourceLoaded(ResourceHandle handle) { void LoadResource(ResourceHandle handle) { ASSERT_RETURN(handle != NULL,, "LoadResource: Resource handle invalid"); - g_load_functions[handle->type](handle); - handle->is_loaded = true; + if(!handle->is_loaded) { + g_load_functions[handle->type](handle); + handle->is_loaded = true; + } ++handle->use_counter; } void ReleaseResource(ResourceHandle handle) { ASSERT_RETURN(handle != NULL,, "ReleaseResource: Resource handle invalid"); ASSERT_RETURN_WARN(handle->is_loaded,, "ReleaseResource: Resource %s is not loaded.", handle->path); - g_unload_functions[handle->type](handle); - handle->is_loaded = false; + if(handle->use_counter == 1) { + g_unload_functions[handle->type](handle); + handle->is_loaded = false; + } --handle->use_counter; } diff --git a/src/main.c b/src/main.c index 98571b2..23c4de1 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ #include "raylib.h" #include "player_controller.h" #include "camera_controller.h" +#include "city_generator.h" #include "core/input.h" #include "core/camera_node.h" #include "core/engine_global.h" @@ -48,6 +49,7 @@ Scene *CreateInitialScene() { SceneNodeAddChild(root, model); SceneNodeAddChild(root, camera_scene); SceneNodeAddChild(camera_scene, CreateCameraController(TC_CAST(model->entity, Transformable))); + SceneNodeAddChild(root, GenerateCity()); return CreateScene(root); } diff --git a/src/player_controller.c b/src/player_controller.c index 7e7215b..918f62d 100644 --- a/src/player_controller.c +++ b/src/player_controller.c @@ -20,6 +20,15 @@ impl_SceneNodeEntity_for(PlayerController, PlayerControllerTick ) +static float const PLAYER_BASE_SPEED = 10.f; +static float const PLAYER_BASE_ACCELERATION = 10.f; +static float const PLAYER_BOOST_SPEED = 30.f; +static float const PLAYER_BOOST_ACCELERATION = 60.f; +static float const PLAYER_BRAKE_SPEED = 0.5f; +static float const PLAYER_BRAKE_DECELERATION = 10.f; +static float const PLAYER_FALL_SPEED = 10.f; +static float const PLAYER_FALL_ACCELERATION = 10.f; + SceneNode *CreatePlayerController() { PlayerController *self = new(PlayerController); *self = (PlayerController) { @@ -73,8 +82,8 @@ void PlayerControllerTickAngularAcceleration(PlayerController *self, double delt //! linear acceleration limited to the local Z axis static void PlayerControllerTickLinearAcceleration(PlayerController *self, double delta) { - float const target = self->brake ? 5.f : (self->boost ? 50.f : (self->rotation.y == 0.f ? 30.f : 10.f)); - float const acceleration = self->brake ? 40.f : (self->boost ? 60.f : 10.f); + float const target = self->brake ? PLAYER_BRAKE_SPEED : (self->boost ? PLAYER_BOOST_SPEED : PLAYER_BASE_SPEED); + float const acceleration = target < self->speed ? PLAYER_BRAKE_DECELERATION : (self->boost ? PLAYER_BOOST_ACCELERATION : PLAYER_BASE_ACCELERATION); self->speed = MoveTowards(self->speed, target, delta * acceleration); } @@ -83,11 +92,11 @@ static void PlayerControllerTickTransform(PlayerController *self, double delta) { Transform global_transform = self->transform.tc->get_global_transform(self->transform.data); Matrix global_matrix = TransformGetMatrix(global_transform); - float const rotate_speed = 1.f - self->speed / 60.f; + float const rotate_speed = 1.f - 0.9f * self->speed / PLAYER_BOOST_SPEED; global_transform.translation = Vector3Add(global_transform.translation, Vector3Scale(MATRIX_FORWARD(global_matrix), self->speed * delta)); global_transform.rotation = QuaternionMultiply(QuaternionFromAxisAngle(MATRIX_FORWARD(global_matrix), self->rotation.x * 1.25f * delta), global_transform.rotation); global_transform.rotation = QuaternionMultiply(QuaternionFromAxisAngle(MATRIX_RIGHT(global_matrix), self->rotation.y * rotate_speed * 3.75f * delta), global_transform.rotation); - global_transform.rotation = QuaternionMultiply(QuaternionFromAxisAngle(MATRIX_UP(global_matrix), self->rotation.z * .2f * delta), global_transform.rotation); + global_transform.rotation = QuaternionMultiply(QuaternionFromAxisAngle(MATRIX_UP(global_matrix), self->rotation.z * rotate_speed * 1.f * delta), global_transform.rotation); self->transform.tc->set_global_transform(self->transform.data, global_transform); } diff --git a/src/utils b/src/utils index 96323d7..bb201d5 160000 --- a/src/utils +++ b/src/utils @@ -1 +1 @@ -Subproject commit 96323d7abc5a1568573bef8a4293989a311dbd23 +Subproject commit bb201d5085cfb2e54ebad9a0bf22347a5251f7a2