X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fmodel%2FShape.cpp;fp=src%2Fmodel%2FShape.cpp;h=7be434d258828f20311d11cc8532dc5d3ca6941a;hb=bc48fbd6be3283a2e1aaa9249909fab32c617692;hp=0000000000000000000000000000000000000000;hpb=b61d462707dd3d40a32a6104d88eb24f6a52df63;p=blank.git 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); + } +} + +}