2 #include "Instance.hpp"
3 #include "Skeletons.hpp"
6 #include "ShapeRegistry.hpp"
7 #include "../app/TextureIndex.hpp"
8 #include "../graphics/DirectionalLighting.hpp"
9 #include "../graphics/EntityMesh.hpp"
11 #include <glm/gtx/quaternion.hpp>
20 , bounds{{ 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }}
22 , orientation(1.0f, 0.0f, 0.0f, 0.0f)
28 Model &Model::AddPart() {
30 parts.back().parent = this;
35 glm::mat4 Model::LocalTransform() const noexcept {
36 glm::mat4 transform(toMat4(orientation));
37 transform[3].x = position.x;
38 transform[3].y = position.y;
39 transform[3].z = position.z;
43 glm::mat4 Model::GlobalTransform() const noexcept {
45 return Parent().GlobalTransform() * LocalTransform();
47 return LocalTransform();
52 void Model::Instantiate(Instance &inst) const {
53 inst.part_model = this;
54 inst.position = position;
55 inst.orientation = orientation;
57 inst.parts.reserve(parts.size());
58 for (const Model &part : parts) {
59 part.Instantiate(inst.AddPart());
68 , orientation(1.0f, 0.0f, 0.0f, 0.0f)
74 Instance &Instance::AddPart() {
76 parts.back().parent = this;
81 glm::mat4 Instance::LocalTransform() const noexcept {
82 glm::mat4 transform(toMat4(orientation));
83 transform[3].x = position.x;
84 transform[3].y = position.y;
85 transform[3].z = position.z;
89 glm::mat4 Instance::GlobalTransform() const noexcept {
91 return Parent().GlobalTransform() * LocalTransform();
93 return LocalTransform();
98 void Instance::Render(const glm::mat4 &M, DirectionalLighting &prog) const {
99 glm::mat4 transform(M * LocalTransform());
100 if (part_model->HasNodeMesh()) {
101 prog.SetM(transform);
102 part_model->NodeMesh().Draw();
104 for (const Instance &part : parts) {
105 part.Render(transform, prog);
110 Skeletons::Skeletons()
116 Skeletons::~Skeletons() {
120 void Skeletons::LoadHeadless() {
122 skeletons.reserve(4);
123 AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }};
125 skeletons.emplace_back(new Model);
127 skeletons[0]->Bounds(bounds);
130 skeletons.emplace_back(new Model);
132 skeletons[1]->Bounds(bounds);
135 skeletons.emplace_back(new Model);
137 skeletons[2]->Bounds(bounds);
140 skeletons.emplace_back(new Model);
142 skeletons[3]->Bounds(bounds);
146 void Skeletons::Load(const ShapeRegistry &shapes, TextureIndex &tex_index) {
149 const Shape &shape = shapes.Get("player_head_block");
150 EntityMesh::Buffer buf;
151 std::vector<float> tex_map;
152 tex_map.push_back(tex_index.GetID("rock-1"));
153 tex_map.push_back(tex_index.GetID("rock-face"));
154 buf.Reserve(shape.VertexCount(), shape.IndexCount());
156 shape.Fill(buf, tex_map);
157 buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
158 buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 1.0f, 0.0f });
159 meshes[0].Update(buf);
160 skeletons[0]->SetNodeMesh(&meshes[0]);
164 shape.Fill(buf, tex_map);
165 buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
166 buf.rgb_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
167 meshes[1].Update(buf);
168 skeletons[1]->SetNodeMesh(&meshes[1]);
172 shape.Fill(buf, tex_map);
173 buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
174 buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 0.0f, 1.0f });
175 meshes[2].Update(buf);
176 skeletons[2]->SetNodeMesh(&meshes[2]);
180 shape.Fill(buf, tex_map);
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]);
188 Model *Skeletons::ByID(std::uint16_t id) noexcept {
189 if (id == 0 || id > skeletons.size()) {
192 return skeletons[id - 1].get();
196 const Model *Skeletons::ByID(std::uint16_t id) const noexcept {
197 if (id == 0 || id > skeletons.size()) {
200 return skeletons[id - 1].get();