feat: implemented city generator

This commit is contained in:
Sara 2024-10-04 11:12:13 +02:00
parent 0ca2972218
commit 315ae2d3b4
12 changed files with 67 additions and 15 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
resources/building_a.glb Normal file

Binary file not shown.

BIN
resources/building_b.glb Normal file

Binary file not shown.

BIN
resources/building_c.glb Normal file

Binary file not shown.

BIN
resources/building_d.glb Normal file

Binary file not shown.

View file

@ -2,7 +2,44 @@
#include "core/mesh_render_entity.h" #include "core/mesh_render_entity.h"
#include "core/transform_node.h" #include "core/transform_node.h"
SceneNode *GenerateCity() { static struct {
SceneNode *node = CreateTransformNode(); size_t x, y;
return node; } 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;
} }

View file

@ -132,9 +132,9 @@ bool GetModelResource(char const *path, ModelResource *out) {
ResourceContainer *container = hash_map_get_as(ResourceContainer, &g_resource_map, &path); ResourceContainer *container = hash_map_get_as(ResourceContainer, &g_resource_map, &path);
*out = ResourceEmpty(Model); *out = ResourceEmpty(Model);
// assert some assumptions about the found resource // assert some assumptions about the found resource
ASSERT_RETURN(container != NULL, false, "GetTextureResource: Resource %s not in index.", path); ASSERT_RETURN(container != NULL, false, "GetModelResource: Resource %s not in index.", path);
ASSERT_RETURN(container->type == RESOURCE_MODEL, false, "GetTextureResource: Resource %s is not a Texture.", path); ASSERT_RETURN(container->type == RESOURCE_MODEL, false, "GetModelResource: Resource %s is not a Texture.", path);
++container->use_counter; ASSERT_RETURN(strcmp(container->name, path) == 0, false, "GetModelResource: Resource %s was loaded for path %s", container->name, path);
*out = (ModelResource) { *out = (ModelResource) {
.handle = container, .handle = container,
.resource = &container->model .resource = &container->model
@ -174,16 +174,20 @@ bool IsResourceLoaded(ResourceHandle handle) {
void LoadResource(ResourceHandle handle) { void LoadResource(ResourceHandle handle) {
ASSERT_RETURN(handle != NULL,, "LoadResource: Resource handle invalid"); ASSERT_RETURN(handle != NULL,, "LoadResource: Resource handle invalid");
g_load_functions[handle->type](handle); if(!handle->is_loaded) {
handle->is_loaded = true; g_load_functions[handle->type](handle);
handle->is_loaded = true;
}
++handle->use_counter; ++handle->use_counter;
} }
void ReleaseResource(ResourceHandle handle) { void ReleaseResource(ResourceHandle handle) {
ASSERT_RETURN(handle != NULL,, "ReleaseResource: Resource handle invalid"); ASSERT_RETURN(handle != NULL,, "ReleaseResource: Resource handle invalid");
ASSERT_RETURN_WARN(handle->is_loaded,, "ReleaseResource: Resource %s is not loaded.", handle->path); ASSERT_RETURN_WARN(handle->is_loaded,, "ReleaseResource: Resource %s is not loaded.", handle->path);
g_unload_functions[handle->type](handle); if(handle->use_counter == 1) {
handle->is_loaded = false; g_unload_functions[handle->type](handle);
handle->is_loaded = false;
}
--handle->use_counter; --handle->use_counter;
} }

View file

@ -1,6 +1,7 @@
#include "raylib.h" #include "raylib.h"
#include "player_controller.h" #include "player_controller.h"
#include "camera_controller.h" #include "camera_controller.h"
#include "city_generator.h"
#include "core/input.h" #include "core/input.h"
#include "core/camera_node.h" #include "core/camera_node.h"
#include "core/engine_global.h" #include "core/engine_global.h"
@ -48,6 +49,7 @@ Scene *CreateInitialScene() {
SceneNodeAddChild(root, model); SceneNodeAddChild(root, model);
SceneNodeAddChild(root, camera_scene); SceneNodeAddChild(root, camera_scene);
SceneNodeAddChild(camera_scene, CreateCameraController(TC_CAST(model->entity, Transformable))); SceneNodeAddChild(camera_scene, CreateCameraController(TC_CAST(model->entity, Transformable)));
SceneNodeAddChild(root, GenerateCity());
return CreateScene(root); return CreateScene(root);
} }

View file

@ -20,6 +20,15 @@ impl_SceneNodeEntity_for(PlayerController,
PlayerControllerTick 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() { SceneNode *CreatePlayerController() {
PlayerController *self = new(PlayerController); PlayerController *self = new(PlayerController);
*self = (PlayerController) { *self = (PlayerController) {
@ -73,8 +82,8 @@ void PlayerControllerTickAngularAcceleration(PlayerController *self, double delt
//! linear acceleration limited to the local Z axis //! linear acceleration limited to the local Z axis
static static
void PlayerControllerTickLinearAcceleration(PlayerController *self, double delta) { 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 target = self->brake ? PLAYER_BRAKE_SPEED : (self->boost ? PLAYER_BOOST_SPEED : PLAYER_BASE_SPEED);
float const acceleration = self->brake ? 40.f : (self->boost ? 60.f : 10.f); 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); self->speed = MoveTowards(self->speed, target, delta * acceleration);
} }
@ -83,11 +92,11 @@ static
void PlayerControllerTickTransform(PlayerController *self, double delta) { void PlayerControllerTickTransform(PlayerController *self, double delta) {
Transform global_transform = self->transform.tc->get_global_transform(self->transform.data); Transform global_transform = self->transform.tc->get_global_transform(self->transform.data);
Matrix global_matrix = TransformGetMatrix(global_transform); 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.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_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_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); self->transform.tc->set_global_transform(self->transform.data, global_transform);
} }

@ -1 +1 @@
Subproject commit 96323d7abc5a1568573bef8a4293989a311dbd23 Subproject commit bb201d5085cfb2e54ebad9a0bf22347a5251f7a2