Translated using Weblate (Chinese (Simplified))
[oweals/minetest.git] / src / client / content_mapblock.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #pragma once
21
22 #include "nodedef.h"
23 #include <IMeshManipulator.h>
24
25 struct MeshMakeData;
26 struct MeshCollector;
27
28 struct LightPair {
29         u8 lightDay;
30         u8 lightNight;
31
32         LightPair() = default;
33         explicit LightPair(u16 value) : lightDay(value & 0xff), lightNight(value >> 8) {}
34         LightPair(u8 valueA, u8 valueB) : lightDay(valueA), lightNight(valueB) {}
35         LightPair(float valueA, float valueB) :
36                 lightDay(core::clamp(core::round32(valueA), 0, 255)),
37                 lightNight(core::clamp(core::round32(valueB), 0, 255)) {}
38         operator u16() const { return lightDay | lightNight << 8; }
39 };
40
41 struct LightInfo {
42         float light_day;
43         float light_night;
44         float light_boosted;
45
46         LightPair getPair(float sunlight_boost = 0.0) const
47         {
48                 return LightPair(
49                         (1 - sunlight_boost) * light_day
50                         + sunlight_boost * light_boosted,
51                         light_night);
52         }
53 };
54
55 struct LightFrame {
56         f32 lightsDay[8];
57         f32 lightsNight[8];
58         bool sunlight[8];
59 };
60
61 class MapblockMeshGenerator
62 {
63 public:
64         MeshMakeData *data;
65         MeshCollector *collector;
66
67         const NodeDefManager *nodedef;
68         scene::IMeshManipulator *meshmanip;
69
70 // options
71         bool enable_mesh_cache;
72
73 // current node
74         v3s16 blockpos_nodes;
75         v3s16 p;
76         v3f origin;
77         MapNode n;
78         const ContentFeatures *f;
79         LightPair light;
80         LightFrame frame;
81         video::SColor color;
82         TileSpec tile;
83         float scale;
84
85 // lighting
86         void getSmoothLightFrame();
87         LightInfo blendLight(const v3f &vertex_pos);
88         video::SColor blendLightColor(const v3f &vertex_pos);
89         video::SColor blendLightColor(const v3f &vertex_pos, const v3f &vertex_normal);
90
91         void useTile(int index = 0, u8 set_flags = MATERIAL_FLAG_CRACK_OVERLAY,
92                 u8 reset_flags = 0, bool special = false);
93         void getTile(int index, TileSpec *tile);
94         void getTile(v3s16 direction, TileSpec *tile);
95         void getSpecialTile(int index, TileSpec *tile, bool apply_crack = false);
96
97 // face drawing
98         void drawQuad(v3f *vertices, const v3s16 &normal = v3s16(0, 0, 0),
99                 float vertical_tiling = 1.0);
100
101 // cuboid drawing!
102         void drawCuboid(const aabb3f &box, TileSpec *tiles, int tilecount,
103                 const LightInfo *lights , const f32 *txc);
104         void generateCuboidTextureCoords(aabb3f const &box, f32 *coords);
105         void drawAutoLightedCuboid(aabb3f box, const f32 *txc = NULL,
106                 TileSpec *tiles = NULL, int tile_count = 0);
107
108 // liquid-specific
109         bool top_is_same_liquid;
110         bool draw_liquid_bottom;
111         TileSpec tile_liquid;
112         TileSpec tile_liquid_top;
113         content_t c_flowing;
114         content_t c_source;
115         video::SColor color_liquid_top;
116         struct NeighborData {
117                 f32 level;
118                 content_t content;
119                 bool is_same_liquid;
120                 bool top_is_same_liquid;
121         };
122         NeighborData liquid_neighbors[3][3];
123         f32 corner_levels[2][2];
124
125         void prepareLiquidNodeDrawing();
126         void getLiquidNeighborhood();
127         void calculateCornerLevels();
128         f32 getCornerLevel(int i, int k);
129         void drawLiquidSides();
130         void drawLiquidTop();
131         void drawLiquidBottom();
132
133 // raillike-specific
134         // name of the group that enables connecting to raillike nodes of different kind
135         static const std::string raillike_groupname;
136         int raillike_group;
137         bool isSameRail(v3s16 dir);
138
139 // plantlike-specific
140         PlantlikeStyle draw_style;
141         v3f offset;
142         int rotate_degree;
143         bool random_offset_Y;
144         int face_num;
145         float plant_height;
146
147         void drawPlantlikeQuad(float rotation, float quad_offset = 0,
148                 bool offset_top_only = false);
149         void drawPlantlike();
150
151 // firelike-specific
152         void drawFirelikeQuad(float rotation, float opening_angle,
153                 float offset_h, float offset_v = 0.0);
154
155 // drawtypes
156         void drawLiquidNode();
157         void drawGlasslikeNode();
158         void drawGlasslikeFramedNode();
159         void drawAllfacesNode();
160         void drawTorchlikeNode();
161         void drawSignlikeNode();
162         void drawPlantlikeNode();
163         void drawPlantlikeRootedNode();
164         void drawFirelikeNode();
165         void drawFencelikeNode();
166         void drawRaillikeNode();
167         void drawNodeboxNode();
168         void drawMeshNode();
169
170 // common
171         void errorUnknownDrawtype();
172         void drawNode();
173
174 public:
175         MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output);
176         void generate();
177         void renderSingle(content_t node);
178 };