]> git.localhorst.tv Git - blank.git/blob - src/model/composite.cpp
send entity visual from server to client
[blank.git] / src / model / composite.cpp
1 #include "CompositeModel.hpp"
2 #include "CompositeInstance.hpp"
3 #include "Skeletons.hpp"
4
5 #include "EntityModel.hpp"
6 #include "shapes.hpp"
7 #include "../graphics/DirectionalLighting.hpp"
8
9 #include <glm/gtx/quaternion.hpp>
10
11
12 namespace blank {
13
14 CompositeModel::CompositeModel()
15 : parent(nullptr)
16 , node_model(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->HasNodeModel()) {
99                 prog.SetM(transform);
100                 part_model->NodeModel().Draw();
101         }
102         for (const CompositeInstance &part : parts) {
103                 part.Render(transform, prog);
104         }
105 }
106
107
108 Skeletons::Skeletons()
109 : skeletons()
110 , models() {
111
112 }
113
114 Skeletons::~Skeletons() {
115
116 }
117
118 void Skeletons::LoadHeadless() {
119         skeletons.clear();
120         skeletons.reserve(3);
121         {
122                 AABB bounds{{ -0.25f, -0.5f, -0.25f }, { 0.25f, 0.5f, 0.25f }};
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.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }};
135                 skeletons.emplace_back(new CompositeModel);
136                 skeletons[2]->ID(3);
137                 skeletons[2]->Bounds(bounds);
138         }
139 }
140
141 void Skeletons::Load() {
142         LoadHeadless();
143         models.resize(3);
144         EntityModel::Buffer buf;
145         {
146                 CuboidShape shape(skeletons[0]->Bounds());
147                 shape.Vertices(buf, 1.0f);
148                 buf.colors.resize(shape.VertexCount(), { 1.0f, 1.0f, 0.0f });
149                 models[0].Update(buf);
150                 skeletons[0]->SetNodeModel(&models[0]);
151         }
152         {
153                 CuboidShape shape(skeletons[1]->Bounds());
154                 buf.Clear();
155                 shape.Vertices(buf, 2.0f);
156                 buf.colors.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
157                 models[1].Update(buf);
158                 skeletons[1]->SetNodeModel(&models[1]);
159         }
160         {
161                 StairShape shape(skeletons[2]->Bounds(), { 0.4f, 0.4f });
162                 buf.Clear();
163                 shape.Vertices(buf, 3.0f);
164                 buf.colors.resize(shape.VertexCount(), { 1.0f, 0.0f, 1.0f });
165                 models[2].Update(buf);
166                 skeletons[2]->SetNodeModel(&models[2]);
167         }
168 }
169
170 CompositeModel *Skeletons::ByID(std::uint16_t id) noexcept {
171         if (id == 0 || id > skeletons.size()) {
172                 return nullptr;
173         } else {
174                 return skeletons[id - 1].get();
175         }
176 }
177
178 const CompositeModel *Skeletons::ByID(std::uint16_t id) const noexcept {
179         if (id == 0 || id > skeletons.size()) {
180                 return nullptr;
181         } else {
182                 return skeletons[id - 1].get();
183         }
184 }
185
186 }