A 3D game engine from scratch.
1// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net>
2
3#include "spatial.hpp"
4#include "logs.hpp"
5#include "engine.hpp"
6
7
8spatial::State *spatial::state = nullptr;
9
10
11void
12spatial::print_spatial_component(spatial::Component *spatial_component)
13{
14 logs::info("spatial::Component:");
15 logs::info(" entity_handle: %d", spatial_component->entity_handle);
16 logs::info(" position:");
17 logs::print_v3(&spatial_component->position);
18 logs::info(" rotation:");
19 logs::info("(don't know how to print rotation, sorry)");
20 /* logs::print_v4(&spatial_component->rotation); */
21 logs::info(" scale:");
22 logs::print_v3(&spatial_component->scale);
23 logs::info(" parent_entity_handle: %d", spatial_component->parent_entity_handle);
24}
25
26
27bool
28spatial::does_spatial_component_have_dimensions(spatial::Component *spatial_component)
29{
30 return (
31 spatial_component->scale.x > 0.0f &&
32 spatial_component->scale.y > 0.0f &&
33 spatial_component->scale.z > 0.0f
34 );
35}
36
37
38bool
39spatial::is_spatial_component_valid(spatial::Component *spatial_component)
40{
41 return does_spatial_component_have_dimensions(spatial_component) ||
42 spatial_component->parent_entity_handle != entities::NO_ENTITY_HANDLE;
43}
44
45
46m4
47spatial::make_model_matrix(
48 spatial::Component *spatial_component,
49 ModelMatrixCache *cache
50) {
51 m4 model_matrix = m4(1.0f);
52
53 if (spatial_component->parent_entity_handle != entities::NO_ENTITY_HANDLE) {
54 spatial::Component *parent = spatial::get_component(
55 spatial_component->parent_entity_handle);
56 model_matrix = make_model_matrix(parent, cache);
57 }
58
59 if (does_spatial_component_have_dimensions(spatial_component)) {
60 // TODO: This is somehow really #slow, the multiplication in particular.
61 // Is there a better way?
62 if (
63 spatial_component == cache->last_model_matrix_spatial_component
64 ) {
65 model_matrix = cache->last_model_matrix;
66 } else {
67 model_matrix = glm::translate(model_matrix, spatial_component->position);
68 model_matrix = glm::scale(model_matrix, spatial_component->scale);
69 model_matrix = model_matrix *
70 glm::toMat4(normalize(spatial_component->rotation));
71 cache->last_model_matrix = model_matrix;
72 cache->last_model_matrix_spatial_component = spatial_component;
73 }
74 }
75
76 return model_matrix;
77}
78
79
80Array<spatial::Component> *
81spatial::get_components()
82{
83 return &spatial::state->components;
84}
85
86
87spatial::Component *
88spatial::get_component(entities::Handle entity_handle)
89{
90 return spatial::state->components[entity_handle];
91}
92
93
94void
95spatial::init(spatial::State *spatial_state, memory::Pool *asset_memory_pool)
96{
97 spatial::state = spatial_state;
98 spatial::state->components = Array<spatial::Component>(
99 asset_memory_pool, MAX_N_ENTITIES, "spatial_components", true, 1);
100}