2 #include "BlockType.hpp"
3 #include "BlockTypeRegistry.hpp"
5 #include "../io/TokenStreamReader.hpp"
6 #include "../model/ShapeRegistry.hpp"
7 #include "../shared/ResourceIndex.hpp"
10 #include <glm/gtx/euler_angles.hpp>
11 #include <glm/gtx/transform.hpp>
16 std::ostream &operator <<(std::ostream &out, const Block &block) {
17 return out << "Block(" << block.type << ", " << block.GetFace() << ", " << block.GetTurn() << ')';
20 std::ostream &operator <<(std::ostream &out, const Block::Face &face) {
25 case Block::FACE_DOWN:
28 case Block::FACE_RIGHT:
31 case Block::FACE_LEFT:
34 case Block::FACE_FRONT:
37 case Block::FACE_BACK:
41 case Block::FACE_COUNT:
42 out << "invalid Block::Face";
48 std::ostream &operator <<(std::ostream &out, const Block::Turn &turn) {
50 case Block::TURN_NONE:
53 case Block::TURN_LEFT:
56 case Block::TURN_AROUND:
59 case Block::TURN_RIGHT:
63 case Block::TURN_COUNT:
64 out << "invalid Block::Turn";
71 BlockType::BlockType() noexcept
74 , hsl_mod(0.0f, 1.0f, 1.0f)
75 , rgb_mod(1.0f, 1.0f, 1.0f)
76 , outline_color(-1, -1, -1)
93 , min_temperature(-1.0f)
94 , mid_temperature(0.0f)
95 , max_temperature(1.0f)
103 void BlockType::Read(
104 TokenStreamReader &in,
105 ResourceIndex &snd_index,
106 ResourceIndex &tex_index,
107 const ShapeRegistry &shapes
110 in.Skip(Token::ANGLE_BRACKET_OPEN);
111 while (in.Peek().type != Token::ANGLE_BRACKET_CLOSE) {
112 in.ReadIdentifier(name);
113 in.Skip(Token::EQUALS);
114 if (name == "visible") {
115 visible = in.GetBool();
116 } else if (name == "texture") {
118 textures.push_back(tex_index.GetID(name));
119 } else if (name == "textures") {
120 in.Skip(Token::BRACKET_OPEN);
121 while (in.Peek().type != Token::BRACKET_CLOSE) {
123 textures.push_back(tex_index.GetID(name));
124 if (in.Peek().type == Token::COMMA) {
125 in.Skip(Token::COMMA);
128 in.Skip(Token::BRACKET_CLOSE);
129 } else if (name == "rgb_mod") {
131 } else if (name == "hsl_mod") {
133 } else if (name == "outline") {
134 in.ReadVec(outline_color);
135 } else if (name == "label") {
136 in.ReadString(label);
137 } else if (name == "place_sound") {
139 place_sound = snd_index.GetID(name);
140 } else if (name == "remove_sound") {
142 remove_sound = snd_index.GetID(name);
143 } else if (name == "luminosity") {
144 luminosity = in.GetInt();
145 } else if (name == "block_light") {
146 block_light = in.GetBool();
147 } else if (name == "collision") {
148 collision = in.GetBool();
149 } else if (name == "collide_block") {
150 collide_block = in.GetBool();
151 } else if (name == "generate") {
152 generate = in.GetBool();
153 } else if (name == "min_solidity") {
154 min_solidity = in.GetFloat();
155 } else if (name == "mid_solidity") {
156 mid_solidity = in.GetFloat();
157 } else if (name == "max_solidity") {
158 max_solidity = in.GetFloat();
159 } else if (name == "min_humidity") {
160 min_humidity = in.GetFloat();
161 } else if (name == "mid_humidity") {
162 mid_humidity = in.GetFloat();
163 } else if (name == "max_humidity") {
164 max_humidity = in.GetFloat();
165 } else if (name == "min_temperature") {
166 min_temperature = in.GetFloat();
167 } else if (name == "mid_temperature") {
168 mid_temperature = in.GetFloat();
169 } else if (name == "max_temperature") {
170 max_temperature = in.GetFloat();
171 } else if (name == "min_richness") {
172 min_richness = in.GetFloat();
173 } else if (name == "mid_richness") {
174 mid_richness = in.GetFloat();
175 } else if (name == "max_richness") {
176 max_richness = in.GetFloat();
177 } else if (name == "commonness") {
178 commonness = in.GetFloat();
179 } else if (name == "shape") {
180 in.ReadIdentifier(name);
181 shape = &shapes.Get(name);
183 std::cerr << "warning: unknown block type property " << name << std::endl;
184 while (in.Peek().type != Token::SEMICOLON) {
188 in.Skip(Token::SEMICOLON);
190 in.Skip(Token::ANGLE_BRACKET_CLOSE);
193 void BlockType::FillEntityMesh(
194 EntityMesh::Buffer &buf,
195 const glm::mat4 &transform
198 shape->Fill(buf, transform, textures);
199 buf.hsl_mods.insert(buf.hsl_mods.end(), shape->VertexCount(), hsl_mod);
200 buf.rgb_mods.insert(buf.rgb_mods.end(), shape->VertexCount(), rgb_mod);
203 void BlockType::FillBlockMesh(
204 BlockMesh::Buffer &buf,
205 const glm::mat4 &transform,
206 BlockMesh::Index idx_offset
209 shape->Fill(buf, transform, textures, idx_offset);
210 buf.hsl_mods.insert(buf.hsl_mods.end(), shape->VertexCount(), hsl_mod);
211 buf.rgb_mods.insert(buf.rgb_mods.end(), shape->VertexCount(), rgb_mod);
214 void BlockType::OutlinePrimitiveMesh(PrimitiveMesh::Buffer &buf) const noexcept {
217 buf.colors.insert(buf.colors.end(), shape->OutlineCount(), glm::vec4(outline_color, 1.0f));
221 BlockTypeRegistry::BlockTypeRegistry() {
224 air.block_light = false;
225 air.collision = false;
226 air.collide_block = false;
230 Block::Type BlockTypeRegistry::Add(const BlockType &t) {
231 int id = types.size();
233 types.back().id = id;
238 const glm::mat4 Block::orient2transform[ORIENT_COUNT] = {
239 { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: up, turn: none
240 { 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: up, turn: left
241 { -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: up, turn: around
242 { 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: up, turn: right
243 { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: down, turn: none
244 { 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: down, turn: left
245 { -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: down, turn: around
246 { 0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: down, turn: right
247 { 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: right, turn: none
248 { 0, -1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: right, turn: left
249 { 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: right, turn: around
250 { 0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: right, turn: right
251 { 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: left, turn: none
252 { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: left, turn: left
253 { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: left, turn: around
254 { 0, 1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: left, turn: right
255 { 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: none
256 { 0, 0, -1, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: left
257 { -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: around
258 { 0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: right
259 { 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: none
260 { 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: left
261 { -1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: around
262 { 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: right
265 const glm::ivec3 Block::face2normal[FACE_COUNT] = {
274 const Block::Face Block::orient2face[ORIENT_COUNT][FACE_COUNT] = {
275 { FACE_UP, FACE_DOWN, FACE_RIGHT, FACE_LEFT, FACE_FRONT, FACE_BACK, }, // face: up, turn: none
276 { FACE_UP, FACE_DOWN, FACE_FRONT, FACE_BACK, FACE_LEFT, FACE_RIGHT, }, // face: up, turn: left
277 { FACE_UP, FACE_DOWN, FACE_LEFT, FACE_RIGHT, FACE_BACK, FACE_FRONT, }, // face: up, turn: around
278 { FACE_UP, FACE_DOWN, FACE_BACK, FACE_FRONT, FACE_RIGHT, FACE_LEFT, }, // face: up, turn: right
279 { FACE_DOWN, FACE_UP, FACE_RIGHT, FACE_LEFT, FACE_BACK, FACE_FRONT, }, // face: down, turn: none
280 { FACE_DOWN, FACE_UP, FACE_BACK, FACE_FRONT, FACE_LEFT, FACE_RIGHT, }, // face: down, turn: left
281 { FACE_DOWN, FACE_UP, FACE_LEFT, FACE_RIGHT, FACE_FRONT, FACE_BACK, }, // face: down, turn: around
282 { FACE_DOWN, FACE_UP, FACE_FRONT, FACE_BACK, FACE_RIGHT, FACE_LEFT, }, // face: down, turn: right
283 { FACE_LEFT, FACE_RIGHT, FACE_UP, FACE_DOWN, FACE_FRONT, FACE_BACK, }, // face: right, turn: none
284 { FACE_LEFT, FACE_RIGHT, FACE_FRONT, FACE_BACK, FACE_DOWN, FACE_UP, }, // face: right, turn: left
285 { FACE_LEFT, FACE_RIGHT, FACE_DOWN, FACE_UP, FACE_BACK, FACE_FRONT, }, // face: right, turn: around
286 { FACE_LEFT, FACE_RIGHT, FACE_BACK, FACE_FRONT, FACE_UP, FACE_DOWN, }, // face: right, turn: right
287 { FACE_RIGHT, FACE_LEFT, FACE_DOWN, FACE_UP, FACE_FRONT, FACE_BACK, }, // face: left, turn: none
288 { FACE_RIGHT, FACE_LEFT, FACE_FRONT, FACE_BACK, FACE_UP, FACE_DOWN, }, // face: left, turn: left
289 { FACE_RIGHT, FACE_LEFT, FACE_UP, FACE_DOWN, FACE_BACK, FACE_FRONT, }, // face: left, turn: around
290 { FACE_RIGHT, FACE_LEFT, FACE_BACK, FACE_FRONT, FACE_DOWN, FACE_UP, }, // face: left, turn: right
291 { FACE_BACK, FACE_FRONT, FACE_RIGHT, FACE_LEFT, FACE_UP, FACE_DOWN, }, // face: front, turn: none
292 { FACE_BACK, FACE_FRONT, FACE_UP, FACE_DOWN, FACE_LEFT, FACE_RIGHT, }, // face: front, turn: left
293 { FACE_BACK, FACE_FRONT, FACE_LEFT, FACE_RIGHT, FACE_DOWN, FACE_UP, }, // face: front, turn: around
294 { FACE_BACK, FACE_FRONT, FACE_DOWN, FACE_UP, FACE_RIGHT, FACE_LEFT, }, // face: front, turn: right
295 { FACE_FRONT, FACE_BACK, FACE_RIGHT, FACE_LEFT, FACE_DOWN, FACE_UP, }, // face: back, turn: none
296 { FACE_FRONT, FACE_BACK, FACE_DOWN, FACE_UP, FACE_LEFT, FACE_RIGHT, }, // face: back, turn: left
297 { FACE_FRONT, FACE_BACK, FACE_LEFT, FACE_RIGHT, FACE_UP, FACE_DOWN, }, // face: back, turn: around
298 { FACE_FRONT, FACE_BACK, FACE_UP, FACE_DOWN, FACE_RIGHT, FACE_LEFT, }, // face: back, turn: right