From: Daniel Karbach Date: Mon, 12 Oct 2015 15:46:02 +0000 (+0200) Subject: (data) shape prototype X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=bc48fbd6be3283a2e1aaa9249909fab32c617692;p=blank.git (data) shape prototype --- diff --git a/src/model/Shape.cpp b/src/model/Shape.cpp new file mode 100644 index 0000000..7be434d --- /dev/null +++ b/src/model/Shape.cpp @@ -0,0 +1,152 @@ +#include "Shape.hpp" + +#include "bounds.hpp" +#include "../io/TokenStreamReader.hpp" + +#include + +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 &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 &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 &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 &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 index 0000000..2160270 --- /dev/null +++ b/src/model/Shape.hpp @@ -0,0 +1,58 @@ +#ifndef BLANK_MODEL_SHAPE_HPP_ +#define BLANK_MODEL_SHAPE_HPP_ + +#include "../graphics/BlockMesh.hpp" +#include "../graphics/EntityMesh.hpp" + +#include +#include +#include + + +namespace blank { + +struct CollisionBounds; +class TokenStreamReader; + +class Shape { + +public: + Shape(); + + void Read(TokenStreamReader &); + + void Fill( + EntityMesh::Buffer &, + const std::vector &tex_map + ) const; + void Fill( + EntityMesh::Buffer &, + const glm::mat4 &transform, + const std::vector &tex_map + ) const; + void Fill( + BlockMesh::Buffer &, + const glm::mat4 &transform, + const std::vector &tex_map, + std::size_t idx_offset = 0 + ) const; + +private: + static float TexR(const std::vector &, std::size_t) noexcept; + +private: + std::unique_ptr bounds; + struct Vertex { + glm::vec3 position; + glm::vec3 normal; + glm::vec3 tex_st; + std::size_t tex_id; + }; + std::vector vertices; + std::vector indices; + +}; + +} + +#endif