From: Daniel Karbach Date: Fri, 28 Aug 2015 07:03:01 +0000 (+0200) Subject: split composite model in template and instance X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=2ea26d9ca5eaeae65daa0edbbaeada8c1f23670e;p=blank.git split composite model in template and instance --- diff --git a/src/ai/Spawner.cpp b/src/ai/Spawner.cpp index 5b54c3e..1120b5b 100644 --- a/src/ai/Spawner.cpp +++ b/src/ai/Spawner.cpp @@ -21,24 +21,33 @@ Spawner::Spawner(World &world) , chunk_range(4) { EntityModel::Buffer buf; { - CuboidShape shape({{ -0.25f, -0.5f, -0.25f }, { 0.25f, 0.5f, 0.25f }}); + AABB bounds{{ -0.25f, -0.5f, -0.25f }, { 0.25f, 0.5f, 0.25f }}; + CuboidShape shape(bounds); shape.Vertices(buf, 1.0f); buf.colors.resize(shape.VertexCount(), { 1.0f, 1.0f, 0.0f }); models[0].Update(buf); + skeletons[0].Bounds(bounds); + skeletons[0].SetNodeModel(&models[0]); } { - CuboidShape shape({{ -0.5f, -0.25f, -0.5f }, { 0.5f, 0.25f, 0.5f }}); + AABB bounds{{ -0.5f, -0.25f, -0.5f }, { 0.5f, 0.25f, 0.5f }}; + CuboidShape shape(bounds); buf.Clear(); shape.Vertices(buf, 2.0f); buf.colors.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); models[1].Update(buf); + skeletons[1].Bounds(bounds); + skeletons[1].SetNodeModel(&models[1]); } { - StairShape shape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}, { 0.4f, 0.4f }); + AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}; + StairShape shape(bounds, { 0.4f, 0.4f }); buf.Clear(); shape.Vertices(buf, 3.0f); buf.colors.resize(shape.VertexCount(), { 1.0f, 0.0f, 1.0f }); models[2].Update(buf); + skeletons[2].Bounds(bounds); + skeletons[2].SetNodeModel(&models[2]); } timer.Start(); @@ -132,7 +141,7 @@ void Spawner::Spawn(const glm::ivec3 &chunk, const glm::vec3 &pos) { e.Position(chunk, pos); e.Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } }); e.WorldCollidable(true); - e.GetModel().SetNodeModel(&models[rand() % 3]); + skeletons[rand() % 3].Instantiate(e.GetModel()); e.AngularVelocity(rot); Controller *ctrl; if (rand() % 2) { diff --git a/src/ai/Spawner.hpp b/src/ai/Spawner.hpp index c55d73c..7b56130 100644 --- a/src/ai/Spawner.hpp +++ b/src/ai/Spawner.hpp @@ -2,6 +2,7 @@ #define BLANK_AI_SPAWNER_HPP_ #include "../app/IntervalTimer.hpp" +#include "../model/CompositeModel.hpp" #include "../model/EntityModel.hpp" #include @@ -31,6 +32,7 @@ private: std::vector controllers; EntityModel models[3]; + CompositeModel skeletons[3]; IntervalTimer timer; float despawn_range; diff --git a/src/model/CompositeInstance.hpp b/src/model/CompositeInstance.hpp new file mode 100644 index 0000000..7d48b76 --- /dev/null +++ b/src/model/CompositeInstance.hpp @@ -0,0 +1,55 @@ +#ifndef BLANK_MODEL_COMPOSITEINSTANCE_HPP_ +#define BLANK_MODEL_COMPOSITEINSTANCE_HPP_ + +#include +#include +#include + + +namespace blank { + +class CompositeModel; +class DirectionalLighting; + +// TODO: this doesn't have to be a tree, actually +// linearizing might be a good opportunity to optimize +class CompositeInstance { + + friend class CompositeModel; + +public: + CompositeInstance(); + + operator bool() const noexcept { return part_model; } + + const glm::vec3 &Position() const noexcept { return position; } + void Position(const glm::vec3 &p) noexcept { position = p; } + + const glm::quat &Orientation() const noexcept { return orientation; } + void Orientation(const glm::quat &o) noexcept { orientation = o; } + + glm::mat4 LocalTransform() const noexcept; + glm::mat4 GlobalTransform() const noexcept; + + void Render(const glm::mat4 &, DirectionalLighting &) const; + +private: + CompositeInstance &AddPart(); + bool HasParent() const noexcept { return parent; } + CompositeInstance &Parent() const noexcept { return *parent; } + bool IsRoot() const noexcept { return !HasParent(); } + +private: + const CompositeModel *part_model; + CompositeInstance *parent; + + glm::vec3 position; + glm::quat orientation; + + std::vector parts; + +}; + +} + +#endif diff --git a/src/model/CompositeModel.cpp b/src/model/CompositeModel.cpp deleted file mode 100644 index d5b25af..0000000 --- a/src/model/CompositeModel.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "CompositeModel.hpp" - -#include "EntityModel.hpp" -#include "../graphics/DirectionalLighting.hpp" - -#include - - -namespace blank { - -CompositeModel::CompositeModel() -: node_model(nullptr) -, position(0.0f) -, orientation(1.0f, 0.0f, 0.0f, 0.0f) -, parts() { - -} - - -CompositeModel &CompositeModel::AddPart() { - parts.emplace_back(); - parts.back().parent = this; - return parts.back(); -} - - -glm::mat4 CompositeModel::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; -} - -glm::mat4 CompositeModel::GlobalTransform() const noexcept { - if (HasParent()) { - return Parent().GlobalTransform() * LocalTransform(); - } else { - return LocalTransform(); - } -} - - -void CompositeModel::Render(const glm::mat4 &M, DirectionalLighting &prog) const { - glm::mat4 transform(M * LocalTransform()); - if (HasNodeModel()) { - prog.SetM(transform); - NodeModel().Draw(); - } - for (const CompositeModel &part : parts) { - part.Render(transform, prog); - } -} - -} diff --git a/src/model/CompositeModel.hpp b/src/model/CompositeModel.hpp index b548a9c..5570849 100644 --- a/src/model/CompositeModel.hpp +++ b/src/model/CompositeModel.hpp @@ -1,6 +1,8 @@ #ifndef BLANK_MODEL_COMPOSITEMODEL_HPP_ #define BLANK_MODEL_COMPOSITEMODEL_HPP_ +#include "geometry.hpp" + #include #include #include @@ -8,7 +10,7 @@ namespace blank { -class DirectionalLighting; +class CompositeInstance; class EntityModel; class CompositeModel { @@ -19,6 +21,9 @@ public: CompositeModel(const CompositeModel &) = delete; CompositeModel &operator =(const CompositeModel &) = delete; + const AABB &Bounds() const noexcept { return bounds; } + void Bounds(const AABB &b) noexcept { bounds = b; } + const glm::vec3 &Position() const noexcept { return position; } void Position(const glm::vec3 &p) noexcept { position = p; } @@ -38,12 +43,14 @@ public: glm::mat4 LocalTransform() const noexcept; glm::mat4 GlobalTransform() const noexcept; - void Render(const glm::mat4 &, DirectionalLighting &) const; + void Instantiate(CompositeInstance &) const; private: CompositeModel *parent; const EntityModel *node_model; + AABB bounds; + glm::vec3 position; glm::quat orientation; diff --git a/src/model/composite.cpp b/src/model/composite.cpp new file mode 100644 index 0000000..4cf2f12 --- /dev/null +++ b/src/model/composite.cpp @@ -0,0 +1,102 @@ +#include "CompositeModel.hpp" +#include "CompositeInstance.hpp" + +#include "EntityModel.hpp" +#include "../graphics/DirectionalLighting.hpp" + +#include + + +namespace blank { + +CompositeModel::CompositeModel() +: node_model(nullptr) +, position(0.0f) +, orientation(1.0f, 0.0f, 0.0f, 0.0f) +, parts() { + +} + + +CompositeModel &CompositeModel::AddPart() { + parts.emplace_back(); + parts.back().parent = this; + return parts.back(); +} + + +glm::mat4 CompositeModel::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; +} + +glm::mat4 CompositeModel::GlobalTransform() const noexcept { + if (HasParent()) { + return Parent().GlobalTransform() * LocalTransform(); + } else { + return LocalTransform(); + } +} + + +void CompositeModel::Instantiate(CompositeInstance &inst) const { + inst.part_model = this; + inst.position = position; + inst.orientation = orientation; + inst.parts.clear(); + inst.parts.reserve(parts.size()); + for (const CompositeModel &part : parts) { + part.Instantiate(inst.AddPart()); + } +} + + +CompositeInstance::CompositeInstance() +: part_model(nullptr) +, parent(nullptr) +, position(0.0f) +, orientation(1.0f, 0.0f, 0.0f, 0.0f) +, parts() { + +} + + +CompositeInstance &CompositeInstance::AddPart() { + parts.emplace_back(); + parts.back().parent = this; + return parts.back(); +} + + +glm::mat4 CompositeInstance::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; +} + +glm::mat4 CompositeInstance::GlobalTransform() const noexcept { + if (HasParent()) { + return Parent().GlobalTransform() * LocalTransform(); + } else { + return LocalTransform(); + } +} + + +void CompositeInstance::Render(const glm::mat4 &M, DirectionalLighting &prog) const { + glm::mat4 transform(M * LocalTransform()); + if (part_model->HasNodeModel()) { + prog.SetM(transform); + part_model->NodeModel().Draw(); + } + for (const CompositeInstance &part : parts) { + part.Render(transform, prog); + } +} + +} diff --git a/src/world/Entity.hpp b/src/world/Entity.hpp index ef5e4e3..a381142 100644 --- a/src/world/Entity.hpp +++ b/src/world/Entity.hpp @@ -2,7 +2,7 @@ #define BLANK_WORLD_ENTITY_HPP_ #include "Chunk.hpp" -#include "../model/CompositeModel.hpp" +#include "../model/CompositeInstance.hpp" #include "../model/geometry.hpp" #include @@ -20,8 +20,8 @@ class Entity { public: Entity() noexcept; - CompositeModel &GetModel() noexcept { return model; } - const CompositeModel &GetModel() const noexcept { return model; } + CompositeInstance &GetModel() noexcept { return model; } + const CompositeInstance &GetModel() const noexcept { return model; } const std::string &Name() const noexcept { return name; } void Name(const std::string &n) { name = n; } @@ -71,11 +71,11 @@ public: void Update(int dt) noexcept; void Render(const glm::mat4 &M, DirectionalLighting &prog) noexcept { - model.Render(M, prog); + if (model) model.Render(M, prog); } private: - CompositeModel model; + CompositeInstance model; std::string name;