]> git.localhorst.tv Git - blank.git/blob - src/model/composite.cpp
model -> mesh
[blank.git] / src / model / composite.cpp
1 #include "CompositeModel.hpp"
2 #include "CompositeInstance.hpp"
3 #include "Skeletons.hpp"
4
5 #include "shapes.hpp"
6 #include "../graphics/DirectionalLighting.hpp"
7 #include "../graphics/EntityMesh.hpp"
8
9 #include <glm/gtx/quaternion.hpp>
10
11
12 namespace blank {
13
14 CompositeModel::CompositeModel()
15 : parent(nullptr)
16 , node_mesh(nullptr)
17 , id(0)
18 , bounds{{ 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }}
19 , position(0.0f)
20 , orientation(1.0f, 0.0f, 0.0f, 0.0f)
21 , parts() {
22
23 }
24
25
26 CompositeModel &CompositeModel::AddPart() {
27         parts.emplace_back();
28         parts.back().parent = this;
29         return parts.back();
30 }
31
32
33 glm::mat4 CompositeModel::LocalTransform() const noexcept {
34         glm::mat4 transform(toMat4(orientation));
35         transform[3].x = position.x;
36         transform[3].y = position.y;
37         transform[3].z = position.z;
38         return transform;
39 }
40
41 glm::mat4 CompositeModel::GlobalTransform() const noexcept {
42         if (HasParent()) {
43                 return Parent().GlobalTransform() * LocalTransform();
44         } else {
45                 return LocalTransform();
46         }
47 }
48
49
50 void CompositeModel::Instantiate(CompositeInstance &inst) const {
51         inst.part_model = this;
52         inst.position = position;
53         inst.orientation = orientation;
54         inst.parts.clear();
55         inst.parts.reserve(parts.size());
56         for (const CompositeModel &part : parts) {
57                 part.Instantiate(inst.AddPart());
58         }
59 }
60
61
62 CompositeInstance::CompositeInstance()
63 : part_model(nullptr)
64 , parent(nullptr)
65 , position(0.0f)
66 , orientation(1.0f, 0.0f, 0.0f, 0.0f)
67 , parts() {
68
69 }
70
71
72 CompositeInstance &CompositeInstance::AddPart() {
73         parts.emplace_back();
74         parts.back().parent = this;
75         return parts.back();
76 }
77
78
79 glm::mat4 CompositeInstance::LocalTransform() const noexcept {
80         glm::mat4 transform(toMat4(orientation));
81         transform[3].x = position.x;
82         transform[3].y = position.y;
83         transform[3].z = position.z;
84         return transform;
85 }
86
87 glm::mat4 CompositeInstance::GlobalTransform() const noexcept {
88         if (HasParent()) {
89                 return Parent().GlobalTransform() * LocalTransform();
90         } else {
91                 return LocalTransform();
92         }
93 }
94
95
96 void CompositeInstance::Render(const glm::mat4 &M, DirectionalLighting &prog) const {
97         glm::mat4 transform(M * LocalTransform());
98         if (part_model->HasNodeMesh()) {
99                 prog.SetM(transform);
100                 part_model->NodeMesh().Draw();
101         }
102         for (const CompositeInstance &part : parts) {
103                 part.Render(transform, prog);
104         }
105 }
106
107
108 Skeletons::Skeletons()
109 : skeletons()
110 , meshes() {
111
112 }
113
114 Skeletons::~Skeletons() {
115
116 }
117
118 void Skeletons::LoadHeadless() {
119         skeletons.clear();
120         skeletons.reserve(4);
121         {
122                 AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }};
123                 skeletons.emplace_back(new CompositeModel);
124                 skeletons[0]->ID(1);
125                 skeletons[0]->Bounds(bounds);
126         }
127         {
128                 AABB bounds{{ -0.5f, -0.25f, -0.5f }, { 0.5f, 0.25f, 0.5f }};
129                 skeletons.emplace_back(new CompositeModel);
130                 skeletons[1]->ID(2);
131                 skeletons[1]->Bounds(bounds);
132         }
133         {
134                 AABB bounds{{ -0.25f, -0.5f, -0.25f }, { 0.25f, 0.5f, 0.25f }};
135                 skeletons.emplace_back(new CompositeModel);
136                 skeletons[2]->ID(3);
137                 skeletons[2]->Bounds(bounds);
138         }
139         {
140                 AABB bounds{{ -0.25f, -0.5f, -0.35f }, { 0.25f, 0.5f, 0.35f }};
141                 skeletons.emplace_back(new CompositeModel);
142                 skeletons[3]->ID(4);
143                 skeletons[3]->Bounds(bounds);
144         }
145 }
146
147 void Skeletons::Load() {
148         LoadHeadless();
149         meshes.resize(4);
150         EntityMesh::Buffer buf;
151         {
152                 CuboidShape shape(skeletons[0]->Bounds());
153                 shape.Vertices(buf, 3.0f);
154                 buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
155                 buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 1.0f, 0.0f });
156                 meshes[0].Update(buf);
157                 skeletons[0]->SetNodeMesh(&meshes[0]);
158         }
159         {
160                 CuboidShape shape(skeletons[1]->Bounds());
161                 buf.Clear();
162                 shape.Vertices(buf, 0.0f);
163                 buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
164                 buf.rgb_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
165                 meshes[1].Update(buf);
166                 skeletons[1]->SetNodeMesh(&meshes[1]);
167         }
168         {
169                 StairShape shape(skeletons[2]->Bounds(), { 0.4f, 0.4f });
170                 buf.Clear();
171                 shape.Vertices(buf, 1.0f);
172                 buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
173                 buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 0.0f, 1.0f });
174                 meshes[2].Update(buf);
175                 skeletons[2]->SetNodeMesh(&meshes[2]);
176         }
177         {
178                 CuboidShape shape(skeletons[3]->Bounds());
179                 buf.Clear();
180                 shape.Vertices(buf, 2.0f);
181                 buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
182                 buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 0.25f, 0.5f });
183                 meshes[3].Update(buf);
184                 skeletons[3]->SetNodeMesh(&meshes[3]);
185         }
186 }
187
188 CompositeModel *Skeletons::ByID(std::uint16_t id) noexcept {
189         if (id == 0 || id > skeletons.size()) {
190                 return nullptr;
191         } else {
192                 return skeletons[id - 1].get();
193         }
194 }
195
196 const CompositeModel *Skeletons::ByID(std::uint16_t id) const noexcept {
197         if (id == 0 || id > skeletons.size()) {
198                 return nullptr;
199         } else {
200                 return skeletons[id - 1].get();
201         }
202 }
203
204 }