A 3D game engine from scratch.
1// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net>
2
3#pragma once
4
5#include "types.hpp"
6#include "stackarray.hpp"
7#include "mats.hpp"
8#include "entities.hpp"
9#include "spatial.hpp"
10#include "anim.hpp"
11#include "behavior.hpp"
12#include "physics.hpp"
13#include "queue.hpp"
14#include "tasks.hpp"
15#include "pack.hpp"
16#include "lights.hpp"
17#include "geom.hpp"
18#include "drawable.hpp"
19
20class models {
21public:
22 // NOTE: Should be at least peony_parser::MAX_N_ARRAY_VALUES
23 static constexpr u32 const MAX_N_COMMON_ARRAY_VALUES = 8;
24
25 enum class ModelLoaderState {
26 empty,
27 initialized,
28 mesh_data_being_loaded,
29 mesh_data_loaded,
30 vertex_buffers_set_up,
31 complete
32 };
33
34 struct ModelLoader {
35 // These from from the file
36 char model_path[MAX_PATH];
37 char material_names[MAX_COMMON_NAME_LENGTH][MAX_N_COMMON_ARRAY_VALUES];
38 u32 n_material_names;
39
40 // These are created later
41 geom::Mesh meshes[MAX_N_MESHES];
42 u32 n_meshes;
43 anim::Component animation_component;
44 ModelLoaderState state;
45 };
46
47 enum class EntityLoaderState {
48 empty,
49 initialized,
50 complete
51 };
52
53 struct EntityLoader {
54 char name[MAX_DEBUG_NAME_LENGTH];
55 char model_path[MAX_PATH];
56 entities::Handle entity_handle;
57 drawable::Pass render_pass;
58 EntityLoaderState state;
59 spatial::Component spatial_component;
60 lights::Component light_component;
61 behavior::Component behavior_component;
62 physics::Component physics_component;
63 };
64
65#include "models_data.hpp"
66
67 static bool prepare_model_loader_and_check_if_done(ModelLoader *model_loader);
68 static bool prepare_entity_loader_and_check_if_done(
69 EntityLoader *entity_loader,
70 ModelLoader *model_loader
71 );
72 static bool is_model_loader_valid(ModelLoader *model_loader);
73 static bool is_entity_loader_valid(EntityLoader *entity_loader);
74 static void add_material_to_model_loader(
75 ModelLoader *model_loader,
76 char const *material_name
77 );
78 static ModelLoader * init_model_loader(
79 ModelLoader *model_loader,
80 char const *model_path
81 );
82 static EntityLoader * init_entity_loader(
83 EntityLoader *entity_loader,
84 const char *name,
85 const char *model_path,
86 drawable::Pass render_pass,
87 entities::Handle entity_handle
88 );
89
90private:
91 static bool is_bone_only_node(aiNode *node);
92 static aiNode * find_root_bone(const aiScene *scene);
93 static void add_bone_tree_to_animation_component(
94 anim::Component *animation_component,
95 aiNode *node,
96 u32 idx_parent
97 );
98 static void load_bones(
99 anim::Component *animation_component,
100 const aiScene *scene
101 );
102 static void load_animations(
103 anim::Component *animation_component,
104 const aiScene *scene
105 );
106 static void load_mesh(
107 geom::Mesh *mesh,
108 aiMesh *ai_mesh,
109 const aiScene *scene,
110 ModelLoader *model_loader,
111 m4 transform,
112 pack::Pack indices_pack
113 );
114 static void load_node(
115 ModelLoader *model_loader,
116 aiNode *node, const aiScene *scene,
117 m4 accumulated_transform, pack::Pack indices_pack
118 );
119 static void load_model_from_file(ModelLoader *model_loader);
120 static void load_model_from_data(ModelLoader *model_loader);
121};