X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fmodel%2Fmodel.cpp;h=632a5b64289533c343c18fd1a18ef35b28cf0ba2;hb=bc2806164f55b7ac48dbb6d224b7d4b55683decf;hp=987d86c3be4fbcc655324f2da8d8bd6edc989741;hpb=eba29c8ad489194cd1e3cd64b5f23424ad4384ef;p=blank.git diff --git a/src/model/model.cpp b/src/model/model.cpp index 987d86c..632a5b6 100644 --- a/src/model/model.cpp +++ b/src/model/model.cpp @@ -2,7 +2,9 @@ #include "Instance.hpp" #include "Skeletons.hpp" -#include "shapes.hpp" +#include "Shape.hpp" +#include "ShapeRegistry.hpp" +#include "../app/TextureIndex.hpp" #include "../graphics/DirectionalLighting.hpp" #include "../graphics/EntityMesh.hpp" @@ -11,96 +13,102 @@ namespace blank { -Model::Model() -: parent(nullptr) -, node_mesh(nullptr) -, id(0) -, bounds{{ 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }} -, position(0.0f) -, orientation(1.0f, 0.0f, 0.0f, 0.0f) -, parts() { +Instance::Instance() +: model(nullptr) +, state() { } - -Model &Model::AddPart() { - parts.emplace_back(); - parts.back().parent = this; - return parts.back(); +void Instance::Render(const glm::mat4 &M, DirectionalLighting &prog) const { + model->RootPart().Render(M, state, prog); } -glm::mat4 Model::LocalTransform() const noexcept { - glm::mat4 transform(toMat4(orientation)); - transform[3].x = position.x; - transform[3].y = position.y; - transform[3].z = position.z; - return transform; -} +Model::Model() +: id(0) +, root() +, part() { -glm::mat4 Model::GlobalTransform() const noexcept { - if (HasParent()) { - return Parent().GlobalTransform() * LocalTransform(); - } else { - return LocalTransform(); - } } +void Model::Enumerate() { + part.clear(); + part.resize(root.Enumerate(0), nullptr); + root.Index(part); +} void Model::Instantiate(Instance &inst) const { - inst.part_model = this; - inst.position = position; - inst.orientation = orientation; - inst.parts.clear(); - inst.parts.reserve(parts.size()); - for (const Model &part : parts) { - part.Instantiate(inst.AddPart()); - } + inst.model = this; + inst.state.clear(); + inst.state.resize(part.size()); } -Instance::Instance() -: part_model(nullptr) +Part::Part() +: id(0) +, bounds{ glm::vec3(0.0f), glm::vec3(0.0f) } +, initial() +, mesh(nullptr) , parent(nullptr) -, position(0.0f) -, orientation(1.0f, 0.0f, 0.0f, 0.0f) -, parts() { +, children() { } +Part::~Part() { + +} + +Part &Part::AddChild() { + children.emplace_back(); + children.back().parent = this; + return children.back(); +} -Instance &Instance::AddPart() { - parts.emplace_back(); - parts.back().parent = this; - return parts.back(); +std::uint16_t Part::Enumerate(std::uint16_t counter) noexcept { + id = counter++; + for (Part &part : children) { + counter = part.Enumerate(counter); + } + return counter; } +void Part::Index(std::vector &index) noexcept { + index[id] = this; + for (Part &part : children) { + part.Index(index); + } +} -glm::mat4 Instance::LocalTransform() const noexcept { - glm::mat4 transform(toMat4(orientation)); - transform[3].x = position.x; - transform[3].y = position.y; - transform[3].z = position.z; +glm::mat4 Part::LocalTransform( + const std::vector &state +) const noexcept { + glm::mat4 transform(toMat4(initial.orientation * state[id].orientation)); + transform[3] = glm::vec4(initial.position + state[id].position, 1.0f); return transform; } -glm::mat4 Instance::GlobalTransform() const noexcept { - if (HasParent()) { - return Parent().GlobalTransform() * LocalTransform(); +glm::mat4 Part::GlobalTransform( + const std::vector &state +) const noexcept { + if (parent) { + return parent->GlobalTransform(state) * LocalTransform(state); } else { - return LocalTransform(); + return LocalTransform(state); } } - -void Instance::Render(const glm::mat4 &M, DirectionalLighting &prog) const { - glm::mat4 transform(M * LocalTransform()); - if (part_model->HasNodeMesh()) { +void Part::Render( + const glm::mat4 &M, + const std::vector &state, + DirectionalLighting &prog +) const { + glm::mat4 transform = M * LocalTransform(state); + if (mesh) { prog.SetM(transform); - part_model->NodeMesh().Draw(); + mesh->Draw(); } - for (const Instance &part : parts) { - part.Render(transform, prog); + for (const Part &part : children) { + part.Render(transform, state, prog); } } @@ -118,70 +126,72 @@ Skeletons::~Skeletons() { void Skeletons::LoadHeadless() { skeletons.clear(); skeletons.reserve(4); + AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}; { - AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}; skeletons.emplace_back(new Model); skeletons[0]->ID(1); - skeletons[0]->Bounds(bounds); + skeletons[0]->RootPart().bounds = bounds; + skeletons[0]->Enumerate(); } { - AABB bounds{{ -0.5f, -0.25f, -0.5f }, { 0.5f, 0.25f, 0.5f }}; skeletons.emplace_back(new Model); skeletons[1]->ID(2); - skeletons[1]->Bounds(bounds); + skeletons[1]->RootPart().bounds = bounds; + skeletons[1]->Enumerate(); } { - AABB bounds{{ -0.25f, -0.5f, -0.25f }, { 0.25f, 0.5f, 0.25f }}; skeletons.emplace_back(new Model); skeletons[2]->ID(3); - skeletons[2]->Bounds(bounds); + skeletons[2]->RootPart().bounds = bounds; + skeletons[2]->Enumerate(); } { - AABB bounds{{ -0.25f, -0.5f, -0.35f }, { 0.25f, 0.5f, 0.35f }}; skeletons.emplace_back(new Model); skeletons[3]->ID(4); - skeletons[3]->Bounds(bounds); + skeletons[3]->RootPart().bounds = bounds; + skeletons[3]->Enumerate(); } } -void Skeletons::Load() { +void Skeletons::Load(const ShapeRegistry &shapes, TextureIndex &tex_index) { LoadHeadless(); meshes.resize(4); + const Shape &shape = shapes.Get("player_head_block"); EntityMesh::Buffer buf; + std::vector tex_map; + tex_map.push_back(tex_index.GetID("rock-1")); + tex_map.push_back(tex_index.GetID("rock-face")); + buf.Reserve(shape.VertexCount(), shape.IndexCount()); { - CuboidShape shape(skeletons[0]->Bounds()); - shape.Vertices(buf, 3.0f); + shape.Fill(buf, tex_map); buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 1.0f, 0.0f }); meshes[0].Update(buf); - skeletons[0]->SetNodeMesh(&meshes[0]); + skeletons[0]->RootPart().mesh = &meshes[0]; } { - CuboidShape shape(skeletons[1]->Bounds()); buf.Clear(); - shape.Vertices(buf, 0.0f); + shape.Fill(buf, tex_map); buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); buf.rgb_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); meshes[1].Update(buf); - skeletons[1]->SetNodeMesh(&meshes[1]); + skeletons[1]->RootPart().mesh = &meshes[1]; } { - StairShape shape(skeletons[2]->Bounds(), { 0.4f, 0.4f }); buf.Clear(); - shape.Vertices(buf, 1.0f); + shape.Fill(buf, tex_map); buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 0.0f, 1.0f }); meshes[2].Update(buf); - skeletons[2]->SetNodeMesh(&meshes[2]); + skeletons[2]->RootPart().mesh = &meshes[2]; } { - CuboidShape shape(skeletons[3]->Bounds()); buf.Clear(); - shape.Vertices(buf, 2.0f); + shape.Fill(buf, tex_map); buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 0.25f, 0.5f }); meshes[3].Update(buf); - skeletons[3]->SetNodeMesh(&meshes[3]); + skeletons[3]->RootPart().mesh = &meshes[3]; } }