2 #include "ShapeRegistry.hpp"
5 #include "../io/TokenStreamReader.hpp"
18 , fill({ false, false, false, false, false, false }) {
22 void Shape::Read(TokenStreamReader &in) {
26 fill = { false, false, false, false, false, false };
29 in.Skip(Token::ANGLE_BRACKET_OPEN);
30 while (in.HasMore() && in.Peek().type != Token::ANGLE_BRACKET_CLOSE) {
31 in.ReadIdentifier(name);
32 in.Skip(Token::EQUALS);
33 if (name == "bounds") {
35 in.ReadIdentifier(bounds_class);
36 in.Skip(Token::PARENTHESIS_OPEN);
37 if (bounds_class == "Cuboid") {
41 in.Skip(Token::COMMA);
43 bounds.reset(new CuboidBounds(AABB{min, max}));
44 } else if (bounds_class == "Stair") {
49 in.Skip(Token::COMMA);
51 in.Skip(Token::COMMA);
53 bounds.reset(new StairBounds(AABB{min, max}, split));
55 while (in.Peek().type != Token::PARENTHESIS_CLOSE) {
59 in.Skip(Token::PARENTHESIS_CLOSE);
61 } else if (name == "vertices") {
62 in.Skip(Token::ANGLE_BRACKET_OPEN);
63 while (in.HasMore() && in.Peek().type != Token::ANGLE_BRACKET_CLOSE) {
64 in.Skip(Token::ANGLE_BRACKET_OPEN);
66 in.ReadVec(vtx.position);
67 in.Skip(Token::COMMA);
68 in.ReadVec(vtx.normal);
69 in.Skip(Token::COMMA);
70 in.ReadVec(vtx.tex_st);
71 in.Skip(Token::COMMA);
72 in.ReadNumber(vtx.tex_id);
73 if (in.Peek().type == Token::COMMA) {
74 in.Skip(Token::COMMA);
76 in.Skip(Token::ANGLE_BRACKET_CLOSE);
77 if (in.Peek().type == Token::COMMA) {
78 in.Skip(Token::COMMA);
80 vertices.push_back(vtx);
82 in.Skip(Token::ANGLE_BRACKET_CLOSE);
84 } else if (name == "indices") {
85 in.Skip(Token::ANGLE_BRACKET_OPEN);
86 while (in.HasMore() && in.Peek().type != Token::ANGLE_BRACKET_CLOSE) {
87 indices.push_back(in.GetULong());
88 if (in.Peek().type == Token::COMMA) {
89 in.Skip(Token::COMMA);
92 in.Skip(Token::ANGLE_BRACKET_CLOSE);
94 } else if (name == "fill") {
95 in.Skip(Token::BRACKET_OPEN);
96 fill.face[Block::FACE_UP] = in.GetBool();
97 in.Skip(Token::COMMA);
98 fill.face[Block::FACE_DOWN] = in.GetBool();
99 in.Skip(Token::COMMA);
100 fill.face[Block::FACE_RIGHT] = in.GetBool();
101 in.Skip(Token::COMMA);
102 fill.face[Block::FACE_LEFT] = in.GetBool();
103 in.Skip(Token::COMMA);
104 fill.face[Block::FACE_FRONT] = in.GetBool();
105 in.Skip(Token::COMMA);
106 fill.face[Block::FACE_BACK] = in.GetBool();
107 in.Skip(Token::BRACKET_CLOSE);
110 // try to skip, might fail though
111 while (in.HasMore() && in.Peek().type != Token::SEMICOLON) {
115 in.Skip(Token::SEMICOLON);
117 in.Skip(Token::ANGLE_BRACKET_CLOSE);
120 float Shape::TexR(const vector<float> &tex_map, size_t off) noexcept {
121 if (off < tex_map.size()) {
123 } else if (!tex_map.empty()) {
124 return tex_map.back();
131 EntityMesh::Buffer &buf,
132 const vector<float> &tex_map
134 for (const auto &vtx : vertices) {
135 buf.vertices.emplace_back(vtx.position);
136 buf.normals.emplace_back(vtx.normal);
137 buf.tex_coords.emplace_back(vtx.tex_st.s, vtx.tex_st.t, TexR(tex_map, vtx.tex_id));
139 for (auto idx : indices) {
140 buf.indices.emplace_back(idx);
145 EntityMesh::Buffer &buf,
146 const glm::mat4 &transform,
147 const vector<float> &tex_map
149 for (const auto &vtx : vertices) {
150 buf.vertices.emplace_back(transform * glm::vec4(vtx.position, 1.0f));
151 buf.normals.emplace_back(transform * glm::vec4(vtx.normal, 0.0f));
152 buf.tex_coords.emplace_back(vtx.tex_st.s, vtx.tex_st.t, TexR(tex_map, vtx.tex_id));
154 for (auto idx : indices) {
155 buf.indices.emplace_back(idx);
160 BlockMesh::Buffer &buf,
161 const glm::mat4 &transform,
162 const vector<float> &tex_map,
165 for (const auto &vtx : vertices) {
166 buf.vertices.emplace_back(transform * glm::vec4(vtx.position, 1.0f));
167 buf.tex_coords.emplace_back(vtx.tex_st.s, vtx.tex_st.t, TexR(tex_map, vtx.tex_id));
169 for (auto idx : indices) {
170 buf.indices.emplace_back(idx_offset + idx);
174 size_t Shape::OutlineCount() const noexcept {
176 return bounds->OutlineCount();
182 size_t Shape::OutlineIndexCount() const noexcept {
184 return bounds->OutlineIndexCount();
190 void Shape::Outline(PrimitiveMesh::Buffer &out) const {
192 bounds->Outline(out);
196 bool Shape::Intersects(
203 return bounds->Intersects(ray, M, dist, normal);
209 bool Shape::Intersects(
212 const glm::mat4 &box_M,
217 return bounds->Intersects(M, box, box_M, depth, normal);
224 ShapeRegistry::ShapeRegistry()
229 Shape &ShapeRegistry::Add(const string &name) {
230 auto result = shapes.emplace(name, Shape());
232 return result.first->second;
234 throw runtime_error("duplicate shape " + name);
238 Shape &ShapeRegistry::Get(const string &name) {
239 auto entry = shapes.find(name);
240 if (entry != shapes.end()) {
241 return entry->second;
243 throw runtime_error("unknown shape " + name);
247 const Shape &ShapeRegistry::Get(const string &name) const {
248 auto entry = shapes.find(name);
249 if (entry != shapes.end()) {
250 return entry->second;
252 throw runtime_error("unknown shape " + name);