]> git.localhorst.tv Git - blank.git/commitdiff
(data) shape prototype
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 12 Oct 2015 15:46:02 +0000 (17:46 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 12 Oct 2015 15:46:02 +0000 (17:46 +0200)
src/model/Shape.cpp [new file with mode: 0644]
src/model/Shape.hpp [new file with mode: 0644]

diff --git a/src/model/Shape.cpp b/src/model/Shape.cpp
new file mode 100644 (file)
index 0000000..7be434d
--- /dev/null
@@ -0,0 +1,152 @@
+#include "Shape.hpp"
+
+#include "bounds.hpp"
+#include "../io/TokenStreamReader.hpp"
+
+#include <string>
+
+using namespace std;
+
+
+namespace blank {
+
+Shape::Shape()
+: bounds()
+, vertices()
+, indices() {
+
+}
+
+
+void Shape::Read(TokenStreamReader &in) {
+       bounds.reset();
+       vertices.clear();
+       indices.clear();
+
+       string name;
+       while (in.HasMore()) {
+               in.ReadIdentifier(name);
+               in.Skip(Token::EQUALS);
+               if (name == "bounds") {
+                       string bounds_class;
+                       in.ReadIdentifier(bounds_class);
+                       in.Skip(Token::BRACKET_OPEN);
+                       if (bounds_class == "Cuboid") {
+                               glm::vec3 min;
+                               glm::vec3 max;
+                               in.ReadVec(min);
+                               in.Skip(Token::COMMA);
+                               in.ReadVec(max);
+                               bounds.reset(new CuboidBounds(AABB{min, max}));
+                       } else if (bounds_class == "Stair") {
+                               glm::vec3 min;
+                               glm::vec3 max;
+                               glm::vec2 split;
+                               in.ReadVec(min);
+                               in.Skip(Token::COMMA);
+                               in.ReadVec(max);
+                               in.Skip(Token::COMMA);
+                               in.ReadVec(split);
+                               bounds.reset(new StairBounds(AABB{min, max}, split));
+                       } else {
+                               while (in.Peek().type != Token::BRACKET_CLOSE) {
+                                       in.Next();
+                               }
+                       }
+                       in.Skip(Token::BRACKET_CLOSE);
+
+               } else if (name == "vertices") {
+                       in.Skip(Token::ANGLE_BRACKET_OPEN);
+                       while (in.HasMore() && in.Peek().type != Token::ANGLE_BRACKET_CLOSE) {
+                               in.Skip(Token::ANGLE_BRACKET_OPEN);
+                               Vertex vtx;
+                               in.ReadVec(vtx.position);
+                               in.Skip(Token::COMMA);
+                               in.ReadVec(vtx.normal);
+                               in.Skip(Token::COMMA);
+                               in.ReadVec(vtx.tex_st);
+                               in.Skip(Token::COMMA);
+                               in.ReadNumber(vtx.tex_id);
+                               if (in.Peek().type == Token::COMMA) {
+                                       in.Skip(Token::COMMA);
+                               }
+                               in.Skip(Token::ANGLE_BRACKET_CLOSE);
+                               if (in.Peek().type == Token::COMMA) {
+                                       in.Skip(Token::COMMA);
+                               }
+                       }
+
+               } else if (name == "indices") {
+                       in.Skip(Token::ANGLE_BRACKET_OPEN);
+                       while (in.HasMore() && in.Peek().type != Token::ANGLE_BRACKET_CLOSE) {
+                               indices.push_back(in.GetULong());
+                               if (in.Peek().type == Token::COMMA) {
+                                       in.Skip(Token::COMMA);
+                               }
+                       }
+
+               } else {
+                       // try to skip, might fail though
+                       while (in.Peek().type != Token::SEMICOLON) {
+                               in.Next();
+                       }
+               }
+               in.Skip(Token::SEMICOLON);
+       }
+}
+
+float Shape::TexR(const vector<float> &tex_map, size_t off) noexcept {
+       if (off < tex_map.size()) {
+               return tex_map[off];
+       } else if (!tex_map.empty()) {
+               return tex_map.back();
+       } else {
+               return 0.0f;
+       }
+}
+
+void Shape::Fill(
+       EntityMesh::Buffer &buf,
+       const vector<float> &tex_map
+) const {
+       for (const auto &vtx : vertices) {
+               buf.vertices.emplace_back(vtx.position);
+               buf.normals.emplace_back(vtx.normal);
+               buf.tex_coords.emplace_back(vtx.tex_st.s, vtx.tex_st.t, TexR(tex_map, vtx.tex_id));
+       }
+       for (auto idx : indices) {
+               buf.indices.emplace_back(idx);
+       }
+}
+
+void Shape::Fill(
+       EntityMesh::Buffer &buf,
+       const glm::mat4 &transform,
+       const vector<float> &tex_map
+) const {
+       for (const auto &vtx : vertices) {
+               buf.vertices.emplace_back(transform * glm::vec4(vtx.position, 1.0f));
+               buf.normals.emplace_back(transform * glm::vec4(vtx.normal, 0.0f));
+               buf.tex_coords.emplace_back(vtx.tex_st.s, vtx.tex_st.t, TexR(tex_map, vtx.tex_id));
+       }
+       for (auto idx : indices) {
+               buf.indices.emplace_back(idx);
+       }
+}
+
+void Shape::Fill(
+       BlockMesh::Buffer &buf,
+       const glm::mat4 &transform,
+       const vector<float> &tex_map,
+       size_t idx_offset
+) const {
+       for (const auto &vtx : vertices) {
+               buf.vertices.emplace_back(transform * glm::vec4(vtx.position, 1.0f));
+               buf.tex_coords.emplace_back(vtx.tex_st.s, vtx.tex_st.t, TexR(tex_map, vtx.tex_id));
+       }
+       for (auto idx : indices) {
+               buf.indices.emplace_back(idx_offset + idx);
+       }
+}
+
+}
diff --git a/src/model/Shape.hpp b/src/model/Shape.hpp
new file mode 100644 (file)
index 0000000..2160270
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef BLANK_MODEL_SHAPE_HPP_
+#define BLANK_MODEL_SHAPE_HPP_
+
+#include "../graphics/BlockMesh.hpp"
+#include "../graphics/EntityMesh.hpp"
+
+#include <memory>
+#include <vector>
+#include <glm/glm.hpp>
+
+
+namespace blank {
+
+struct CollisionBounds;
+class TokenStreamReader;
+
+class Shape {
+
+public:
+       Shape();
+
+       void Read(TokenStreamReader &);
+
+       void Fill(
+               EntityMesh::Buffer &,
+               const std::vector<float> &tex_map
+       ) const;
+       void Fill(
+               EntityMesh::Buffer &,
+               const glm::mat4 &transform,
+               const std::vector<float> &tex_map
+       ) const;
+       void Fill(
+               BlockMesh::Buffer &,
+               const glm::mat4 &transform,
+               const std::vector<float> &tex_map,
+               std::size_t idx_offset = 0
+       ) const;
+
+private:
+       static float TexR(const std::vector<float> &, std::size_t) noexcept;
+
+private:
+       std::unique_ptr<CollisionBounds> bounds;
+       struct Vertex {
+               glm::vec3 position;
+               glm::vec3 normal;
+               glm::vec3 tex_st;
+               std::size_t tex_id;
+       };
+       std::vector<Vertex> vertices;
+       std::vector<std::size_t> indices;
+
+};
+
+}
+
+#endif