]> git.localhorst.tv Git - blank.git/commitdiff
split composite model in template and instance
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 28 Aug 2015 07:03:01 +0000 (09:03 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 28 Aug 2015 13:44:48 +0000 (15:44 +0200)
src/ai/Spawner.cpp
src/ai/Spawner.hpp
src/model/CompositeInstance.hpp [new file with mode: 0644]
src/model/CompositeModel.cpp [deleted file]
src/model/CompositeModel.hpp
src/model/composite.cpp [new file with mode: 0644]
src/world/Entity.hpp

index 5b54c3eb56cd03dbb827f20bc754db5dbfb55a26..1120b5b320c5987d415243314d3c58cf7c33ce37 100644 (file)
@@ -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) {
index c55d73c0f7f90b835b5791f69e8c9096e17cc81d..7b56130f5f090aba00cfe9426637b1aa7d7d4bab 100644 (file)
@@ -2,6 +2,7 @@
 #define BLANK_AI_SPAWNER_HPP_
 
 #include "../app/IntervalTimer.hpp"
+#include "../model/CompositeModel.hpp"
 #include "../model/EntityModel.hpp"
 
 #include <vector>
@@ -31,6 +32,7 @@ private:
        std::vector<Controller *> 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 (file)
index 0000000..7d48b76
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef BLANK_MODEL_COMPOSITEINSTANCE_HPP_
+#define BLANK_MODEL_COMPOSITEINSTANCE_HPP_
+
+#include <vector>
+#include <glm/glm.hpp>
+#include <glm/gtc/quaternion.hpp>
+
+
+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<CompositeInstance> parts;
+
+};
+
+}
+
+#endif
diff --git a/src/model/CompositeModel.cpp b/src/model/CompositeModel.cpp
deleted file mode 100644 (file)
index d5b25af..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "CompositeModel.hpp"
-
-#include "EntityModel.hpp"
-#include "../graphics/DirectionalLighting.hpp"
-
-#include <glm/gtx/quaternion.hpp>
-
-
-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);
-       }
-}
-
-}
index b548a9c8485dbe20337f7e5af52959fbcee6ae3e..55708494cbbf37a53f61952503ad6f843dc071ef 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef BLANK_MODEL_COMPOSITEMODEL_HPP_
 #define BLANK_MODEL_COMPOSITEMODEL_HPP_
 
+#include "geometry.hpp"
+
 #include <list>
 #include <glm/glm.hpp>
 #include <glm/gtc/quaternion.hpp>
@@ -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 (file)
index 0000000..4cf2f12
--- /dev/null
@@ -0,0 +1,102 @@
+#include "CompositeModel.hpp"
+#include "CompositeInstance.hpp"
+
+#include "EntityModel.hpp"
+#include "../graphics/DirectionalLighting.hpp"
+
+#include <glm/gtx/quaternion.hpp>
+
+
+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);
+       }
+}
+
+}
index ef5e4e32eb92ce4667e233d85f3b485a3aeffcf6..a3811427332628250761bad32210bc64103ea9de 100644 (file)
@@ -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 <string>
@@ -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;