feat: implemented city generator
This commit is contained in:
parent
0ca2972218
commit
315ae2d3b4
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
resources/building_a.glb
Normal file
BIN
resources/building_a.glb
Normal file
Binary file not shown.
BIN
resources/building_b.glb
Normal file
BIN
resources/building_b.glb
Normal file
Binary file not shown.
BIN
resources/building_c.glb
Normal file
BIN
resources/building_c.glb
Normal file
Binary file not shown.
BIN
resources/building_d.glb
Normal file
BIN
resources/building_d.glb
Normal file
Binary file not shown.
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
Loading…
Reference in a new issue