]> git.localhorst.tv Git - blank.git/blob - src/model/shape.cpp
actually load shapes
[blank.git] / src / model / shape.cpp
1 #include "Shape.hpp"
2 #include "ShapeRegistry.hpp"
3
4 #include "bounds.hpp"
5 #include "../io/TokenStreamReader.hpp"
6
7 #include <string>
8
9 using namespace std;
10
11
12 namespace blank {
13
14 Shape::Shape()
15 : bounds()
16 , vertices()
17 , indices() {
18
19 }
20
21 void Shape::Read(TokenStreamReader &in) {
22         bounds.reset();
23         vertices.clear();
24         indices.clear();
25
26         string name;
27         in.Skip(Token::ANGLE_BRACKET_OPEN);
28         while (in.HasMore() && in.Peek().type != Token::ANGLE_BRACKET_CLOSE) {
29                 in.ReadIdentifier(name);
30                 in.Skip(Token::EQUALS);
31                 if (name == "bounds") {
32                         string bounds_class;
33                         in.ReadIdentifier(bounds_class);
34                         in.Skip(Token::PARENTHESIS_OPEN);
35                         if (bounds_class == "Cuboid") {
36                                 glm::vec3 min;
37                                 glm::vec3 max;
38                                 in.ReadVec(min);
39                                 in.Skip(Token::COMMA);
40                                 in.ReadVec(max);
41                                 bounds.reset(new CuboidBounds(AABB{min, max}));
42                         } else if (bounds_class == "Stair") {
43                                 glm::vec3 min;
44                                 glm::vec3 max;
45                                 glm::vec2 split;
46                                 in.ReadVec(min);
47                                 in.Skip(Token::COMMA);
48                                 in.ReadVec(max);
49                                 in.Skip(Token::COMMA);
50                                 in.ReadVec(split);
51                                 bounds.reset(new StairBounds(AABB{min, max}, split));
52                         } else {
53                                 while (in.Peek().type != Token::PARENTHESIS_CLOSE) {
54                                         in.Next();
55                                 }
56                         }
57                         in.Skip(Token::PARENTHESIS_CLOSE);
58
59                 } else if (name == "vertices") {
60                         in.Skip(Token::ANGLE_BRACKET_OPEN);
61                         while (in.HasMore() && in.Peek().type != Token::ANGLE_BRACKET_CLOSE) {
62                                 in.Skip(Token::ANGLE_BRACKET_OPEN);
63                                 Vertex vtx;
64                                 in.ReadVec(vtx.position);
65                                 in.Skip(Token::COMMA);
66                                 in.ReadVec(vtx.normal);
67                                 in.Skip(Token::COMMA);
68                                 in.ReadVec(vtx.tex_st);
69                                 in.Skip(Token::COMMA);
70                                 in.ReadNumber(vtx.tex_id);
71                                 if (in.Peek().type == Token::COMMA) {
72                                         in.Skip(Token::COMMA);
73                                 }
74                                 in.Skip(Token::ANGLE_BRACKET_CLOSE);
75                                 if (in.Peek().type == Token::COMMA) {
76                                         in.Skip(Token::COMMA);
77                                 }
78                         }
79                         in.Skip(Token::ANGLE_BRACKET_CLOSE);
80
81                 } else if (name == "indices") {
82                         in.Skip(Token::ANGLE_BRACKET_OPEN);
83                         while (in.HasMore() && in.Peek().type != Token::ANGLE_BRACKET_CLOSE) {
84                                 indices.push_back(in.GetULong());
85                                 if (in.Peek().type == Token::COMMA) {
86                                         in.Skip(Token::COMMA);
87                                 }
88                         }
89                         in.Skip(Token::ANGLE_BRACKET_CLOSE);
90
91                 } else {
92                         // try to skip, might fail though
93                         while (in.Peek().type != Token::SEMICOLON) {
94                                 in.Next();
95                         }
96                 }
97                 in.Skip(Token::SEMICOLON);
98         }
99         in.Skip(Token::ANGLE_BRACKET_CLOSE);
100 }
101
102 float Shape::TexR(const vector<float> &tex_map, size_t off) noexcept {
103         if (off < tex_map.size()) {
104                 return tex_map[off];
105         } else if (!tex_map.empty()) {
106                 return tex_map.back();
107         } else {
108                 return 0.0f;
109         }
110 }
111
112 void Shape::Fill(
113         EntityMesh::Buffer &buf,
114         const vector<float> &tex_map
115 ) const {
116         for (const auto &vtx : vertices) {
117                 buf.vertices.emplace_back(vtx.position);
118                 buf.normals.emplace_back(vtx.normal);
119                 buf.tex_coords.emplace_back(vtx.tex_st.s, vtx.tex_st.t, TexR(tex_map, vtx.tex_id));
120         }
121         for (auto idx : indices) {
122                 buf.indices.emplace_back(idx);
123         }
124 }
125
126 void Shape::Fill(
127         EntityMesh::Buffer &buf,
128         const glm::mat4 &transform,
129         const vector<float> &tex_map
130 ) const {
131         for (const auto &vtx : vertices) {
132                 buf.vertices.emplace_back(transform * glm::vec4(vtx.position, 1.0f));
133                 buf.normals.emplace_back(transform * glm::vec4(vtx.normal, 0.0f));
134                 buf.tex_coords.emplace_back(vtx.tex_st.s, vtx.tex_st.t, TexR(tex_map, vtx.tex_id));
135         }
136         for (auto idx : indices) {
137                 buf.indices.emplace_back(idx);
138         }
139 }
140
141 void Shape::Fill(
142         BlockMesh::Buffer &buf,
143         const glm::mat4 &transform,
144         const vector<float> &tex_map,
145         size_t idx_offset
146 ) const {
147         for (const auto &vtx : vertices) {
148                 buf.vertices.emplace_back(transform * glm::vec4(vtx.position, 1.0f));
149                 buf.tex_coords.emplace_back(vtx.tex_st.s, vtx.tex_st.t, TexR(tex_map, vtx.tex_id));
150         }
151         for (auto idx : indices) {
152                 buf.indices.emplace_back(idx_offset + idx);
153         }
154 }
155
156
157 ShapeRegistry::ShapeRegistry()
158 : shapes() {
159
160 }
161
162 Shape &ShapeRegistry::Add(const string &name) {
163         auto result = shapes.emplace(name, Shape());
164         if (result.second) {
165                 return result.first->second;
166         } else {
167                 throw runtime_error("duplicate shape " + name);
168         }
169 }
170
171 Shape &ShapeRegistry::Get(const string &name) {
172         auto entry = shapes.find(name);
173         if (entry != shapes.end()) {
174                 return entry->second;
175         } else {
176                 throw runtime_error("unknown shape " + name);
177         }
178 }
179
180 const Shape &ShapeRegistry::Get(const string &name) const {
181         auto entry = shapes.find(name);
182         if (entry != shapes.end()) {
183                 return entry->second;
184         } else {
185                 throw runtime_error("unknown shape " + name);
186         }
187 }
188
189 }