]> git.localhorst.tv Git - blank.git/blob - src/world/BlockType.hpp
glm backwards compatibility
[blank.git] / src / world / BlockType.hpp
1 #ifndef BLANK_WORLD_BLOCKTYPE_HPP_
2 #define BLANK_WORLD_BLOCKTYPE_HPP_
3
4 #include "Block.hpp"
5 #include "BlockGravity.hpp"
6 #include "../graphics/BlockMesh.hpp"
7 #include "../graphics/EntityMesh.hpp"
8 #include "../graphics/glm.hpp"
9 #include "../graphics/PrimitiveMesh.hpp"
10 #include "../model/Shape.hpp"
11
12 #include <limits>
13 #include <vector>
14
15
16 namespace blank {
17
18 class ResourceIndex;
19 class ShapeRegistry;
20 class TokenStreamReader;
21
22 /// single 1x1x1 cube
23 /// attributes of a type of block
24 struct BlockType {
25
26         const Shape *shape;
27         std::vector<float> textures;
28         TVEC3<unsigned char, glm::precision(0)> hsl_mod;
29         TVEC3<unsigned char, glm::precision(0)> rgb_mod;
30         TVEC3<unsigned char, glm::precision(0)> outline_color;
31
32         /// gravity configuration or null if not emitting gravity
33         std::unique_ptr<BlockGravity> gravity;
34
35         /// a string identifying in contexts where numbers just won't do
36         /// must be unique within any given set
37         std::string name;
38         /// a string to display to the user
39         std::string label;
40
41         int place_sound;
42         int remove_sound;
43
44         Block::Type id;
45
46         /// light level that blocks of this type emit
47         int luminosity;
48
49         /// whether to draw
50         bool visible;
51         /// if true, stops light from propagating and fixes level to luminosity
52         bool block_light;
53
54         /// whether to check for collisions at all
55         bool collision;
56         /// if the block should be impenetrable
57         bool collide_block;
58
59         // generation properties
60         /// whether to use this block in generation at all
61         bool generate;
62
63         // min/mid/max points for the respective properties
64         // should all be in the (-1,1) range
65         class Distribution {
66
67         public:
68                 Distribution(float min, float mid, float max)
69                 : xmin(min), xmid(mid), xmax(max) { Update(); }
70
71                 bool Valid(float x) const noexcept {
72                         return x >= xmin && x <= xmax;
73                 }
74                 float Map(float x) const noexcept {
75                         // previous algo as was used by Generator
76                         //return 4.0f - ((x - xmid) * (x - xmid));
77
78                         // linear mapping of [min,mid,max] to [-1,0,1]
79                         x -= xmid;
80                         x *= (x < 0) ? inv_neg : inv_pos;
81
82                         // smoothing: x^4 - 2x^2 + 1
83                         x *= x;
84                         return x * x - 2.0f * x + 1.0f;
85                 }
86
87                 void Min(float m) noexcept { xmin = m; Update(); }
88                 float Min() const noexcept { return xmin; }
89                 void Mid(float m) noexcept { xmid = m; Update(); }
90                 float Mid() const noexcept { return xmid; }
91                 void Max(float m) noexcept { xmax = m; Update(); }
92                 float Max() const noexcept { return xmax; }
93
94         private:
95                 void Update() {
96                         float abs_min = std::abs(xmin - xmid);
97                         inv_neg = abs_min < std::numeric_limits<float>::epsilon() ? 0.0f : 1.0f / abs_min;
98                         float abs_max = std::abs(xmax - xmid);
99                         inv_pos = abs_max < std::numeric_limits<float>::epsilon() ? 0.0f : 1.0f / abs_max;
100                 }
101
102                 float xmin;
103                 float xmid;
104                 float xmax;
105                 float inv_neg;
106                 float inv_pos;
107
108         };
109
110         Distribution solidity;
111         Distribution humidity;
112         Distribution temperature;
113         Distribution richness;
114         /// commonness factor, random chance is multiplied by this
115         float commonness;
116
117         BlockType() noexcept;
118
119         /// clone values of given type
120         /// this copies everything except for ID, name, label, and gravity
121         void Copy(const BlockType &) noexcept;
122
123         void Read(
124                 TokenStreamReader &in,
125                 ResourceIndex &snd_index,
126                 ResourceIndex &tex_index,
127                 const ShapeRegistry &shapes);
128
129         bool FaceFilled(const Block &block, Block::Face face) const noexcept {
130                 return shape && shape->FaceFilled(block.OrientedFace(face));
131         }
132
133         void FillEntityMesh(
134                 EntityMesh::Buffer &m,
135                 const glm::mat4 &transform = glm::mat4(1.0f)
136         ) const noexcept;
137         void FillBlockMesh(
138                 BlockMesh::Buffer &m,
139                 const glm::mat4 &transform = glm::mat4(1.0f),
140                 BlockMesh::Index idx_offset = 0
141         ) const noexcept;
142         void OutlinePrimitiveMesh(PrimitiveMesh::Buffer &) const noexcept;
143
144 };
145
146 }
147
148 #endif