Line data Source code
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 : #ifndef MAPBLOCK_MESH_HEADER
21 : #define MAPBLOCK_MESH_HEADER
22 :
23 : #include "irrlichttypes_extrabloated.h"
24 : #include "client/tile.h"
25 : #include "voxel.h"
26 : #include <map>
27 :
28 : class IGameDef;
29 : class IShaderSource;
30 :
31 : /*
32 : Mesh making stuff
33 : */
34 :
35 :
36 : class MapBlock;
37 : struct MinimapMapblock;
38 :
39 3549 : struct MeshMakeData
40 : {
41 : VoxelManipulator m_vmanip;
42 : v3s16 m_blockpos;
43 : v3s16 m_crack_pos_relative;
44 : v3s16 m_highlighted_pos_relative;
45 : bool m_smooth_lighting;
46 : bool m_show_hud;
47 : video::SColor m_highlight_mesh_color;
48 :
49 : IGameDef *m_gamedef;
50 : bool m_use_shaders;
51 :
52 : MeshMakeData(IGameDef *gamedef, bool use_shaders);
53 :
54 : /*
55 : Copy central data directly from block, and other data from
56 : parent of block.
57 : */
58 : void fill(MapBlock *block);
59 :
60 : /*
61 : Set up with only a single node at (1,1,1)
62 : */
63 : void fillSingleNode(MapNode *node);
64 :
65 : /*
66 : Set the (node) position of a crack
67 : */
68 : void setCrack(int crack_level, v3s16 crack_pos);
69 :
70 : /*
71 : Set the highlighted node position
72 : */
73 :
74 : void setHighlighted(v3s16 highlighted_pos, bool show_hud);
75 : /*
76 : Enable or disable smooth lighting
77 : */
78 : void setSmoothLighting(bool smooth_lighting);
79 : };
80 :
81 : /*
82 : Holds a mesh for a mapblock.
83 :
84 : Besides the SMesh*, this contains information used for animating
85 : the vertex positions, colors and texture coordinates of the mesh.
86 : For example:
87 : - cracks [implemented]
88 : - day/night transitions [implemented]
89 : - animated flowing liquids [not implemented]
90 : - animating vertex positions for e.g. axles [not implemented]
91 : */
92 : class MapBlockMesh
93 : {
94 : public:
95 : // Builds the mesh given
96 : MapBlockMesh(MeshMakeData *data, v3s16 camera_offset);
97 : ~MapBlockMesh();
98 :
99 : // Main animation function, parameters:
100 : // faraway: whether the block is far away from the camera (~50 nodes)
101 : // time: the global animation time, 0 .. 60 (repeats every minute)
102 : // daynight_ratio: 0 .. 1000
103 : // crack: -1 .. CRACK_ANIMATION_LENGTH-1 (-1 for off)
104 : // Returns true if anything has been changed.
105 : bool animate(bool faraway, float time, int crack, u32 daynight_ratio);
106 :
107 154803 : scene::SMesh* getMesh()
108 : {
109 154803 : return m_mesh;
110 : }
111 :
112 2124 : MinimapMapblock* getMinimapMapblock()
113 : {
114 2124 : return m_minimap_mapblock;
115 : }
116 :
117 152678 : bool isAnimationForced() const
118 : {
119 152678 : return m_animation_force_timer == 0;
120 : }
121 :
122 4277 : void decreaseAnimationForceTimer()
123 : {
124 4277 : if(m_animation_force_timer > 0)
125 4277 : m_animation_force_timer--;
126 4277 : }
127 :
128 : void updateCameraOffset(v3s16 camera_offset);
129 :
130 : private:
131 : scene::SMesh *m_mesh;
132 : MinimapMapblock *m_minimap_mapblock;
133 : IGameDef *m_gamedef;
134 : ITextureSource *m_tsrc;
135 : IShaderSource *m_shdrsrc;
136 :
137 : bool m_enable_shaders;
138 : bool m_enable_highlighting;
139 :
140 : video::SColor m_highlight_mesh_color;
141 :
142 : // Must animate() be called before rendering?
143 : bool m_has_animation;
144 : int m_animation_force_timer;
145 :
146 : // Animation info: cracks
147 : // Last crack value passed to animate()
148 : int m_last_crack;
149 : // Maps mesh buffer (i.e. material) indices to base texture names
150 : std::map<u32, std::string> m_crack_materials;
151 : std::list<u32> m_highlighted_materials;
152 :
153 : // Animation info: texture animationi
154 : // Maps meshbuffers to TileSpecs
155 : std::map<u32, TileSpec> m_animation_tiles;
156 : std::map<u32, int> m_animation_frames; // last animation frame
157 : std::map<u32, int> m_animation_frame_offsets;
158 :
159 : // Animation info: day/night transitions
160 : // Last daynight_ratio value passed to animate()
161 : u32 m_last_daynight_ratio;
162 : // For each meshbuffer, maps vertex indices to (day,night) pairs
163 : std::map<u32, std::map<u32, std::pair<u8, u8> > > m_daynight_diffs;
164 :
165 : // Camera offset info -> do we have to translate the mesh?
166 : v3s16 m_camera_offset;
167 : };
168 :
169 :
170 :
171 : /*
172 : This is used because CMeshBuffer::append() is very slow
173 : */
174 210530 : struct PreMeshBuffer
175 : {
176 : TileSpec tile;
177 : std::vector<u16> indices;
178 : std::vector<video::S3DVertexTangents> vertices;
179 : };
180 :
181 4280 : struct MeshCollector
182 : {
183 : std::vector<PreMeshBuffer> prebuffers;
184 : void append(const TileSpec &material,
185 : const video::S3DVertex *vertices, u32 numVertices,
186 : const u16 *indices, u32 numIndices);
187 : void append(const TileSpec &material,
188 : const video::S3DVertex *vertices, u32 numVertices,
189 : const u16 *indices, u32 numIndices,
190 : v3f pos, video::SColor c);
191 : };
192 :
193 : // This encodes
194 : // alpha in the A channel of the returned SColor
195 : // day light (0-255) in the R channel of the returned SColor
196 : // night light (0-255) in the G channel of the returned SColor
197 : // light source (0-255) in the B channel of the returned SColor
198 3261820 : inline video::SColor MapBlock_LightColor(u8 alpha, u16 light, u8 light_source=0)
199 : {
200 3261820 : return video::SColor(alpha, (light & 0xff), (light >> 8), light_source);
201 : }
202 :
203 : // Compute light at node
204 : u16 getInteriorLight(MapNode n, s32 increment, INodeDefManager *ndef);
205 : u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, INodeDefManager *ndef);
206 : u16 getSmoothLight(v3s16 p, v3s16 corner, MeshMakeData *data);
207 :
208 : // Converts from day + night color values (0..255)
209 : // and a given daynight_ratio to the final SColor shown on screen.
210 : void finalColorBlend(video::SColor& result,
211 : u8 day, u8 night, u32 daynight_ratio);
212 :
213 : // Retrieves the TileSpec of a face of a node
214 : // Adds MATERIAL_FLAG_CRACK if the node is cracked
215 : TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data);
216 : TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data);
217 :
218 : #endif
219 :
|