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 "irrlichttypes_extrabloated.h" 23 #include "client/tile.h" 24 #include "voxel.h" 25 #include <array> 26 #include <map> 27 28 class Client; 29 class IShaderSource; 30 31 /* 32 Mesh making stuff 33 */ 34 35 36 class MapBlock; 37 struct MinimapMapblock; 38 39 struct MeshMakeData 40 { 41 VoxelManipulator m_vmanip; 42 v3s16 m_blockpos = v3s16(-1337,-1337,-1337); 43 v3s16 m_crack_pos_relative = v3s16(-1337,-1337,-1337); 44 bool m_smooth_lighting = false; 45 46 Client *m_client; 47 bool m_use_shaders; 48 49 MeshMakeData(Client *client, bool use_shaders); 50 51 /* 52 Copy block data manually (to allow optimizations by the caller) 53 */ 54 void fillBlockDataBegin(const v3s16 &blockpos); 55 void fillBlockData(const v3s16 &block_offset, MapNode *data); 56 57 /* 58 Copy central data directly from block, and other data from 59 parent of block. 60 */ 61 void fill(MapBlock *block); 62 63 /* 64 Set the (node) position of a crack 65 */ 66 void setCrack(int crack_level, v3s16 crack_pos); 67 68 /* 69 Enable or disable smooth lighting 70 */ 71 void setSmoothLighting(bool smooth_lighting); 72 }; 73 74 /* 75 Holds a mesh for a mapblock. 76 77 Besides the SMesh*, this contains information used for animating 78 the vertex positions, colors and texture coordinates of the mesh. 79 For example: 80 - cracks [implemented] 81 - day/night transitions [implemented] 82 - animated flowing liquids [not implemented] 83 - animating vertex positions for e.g. axles [not implemented] 84 */ 85 class MapBlockMesh 86 { 87 public: 88 // Builds the mesh given 89 MapBlockMesh(MeshMakeData *data, v3s16 camera_offset); 90 ~MapBlockMesh(); 91 92 // Main animation function, parameters: 93 // faraway: whether the block is far away from the camera (~50 nodes) 94 // time: the global animation time, 0 .. 60 (repeats every minute) 95 // daynight_ratio: 0 .. 1000 96 // crack: -1 .. CRACK_ANIMATION_LENGTH-1 (-1 for off) 97 // Returns true if anything has been changed. 98 bool animate(bool faraway, float time, int crack, u32 daynight_ratio); 99 getMesh()100 scene::IMesh *getMesh() 101 { 102 return m_mesh[0]; 103 } 104 getMesh(u8 layer)105 scene::IMesh *getMesh(u8 layer) 106 { 107 return m_mesh[layer]; 108 } 109 moveMinimapMapblock()110 MinimapMapblock *moveMinimapMapblock() 111 { 112 MinimapMapblock *p = m_minimap_mapblock; 113 m_minimap_mapblock = NULL; 114 return p; 115 } 116 isAnimationForced()117 bool isAnimationForced() const 118 { 119 return m_animation_force_timer == 0; 120 } 121 decreaseAnimationForceTimer()122 void decreaseAnimationForceTimer() 123 { 124 if(m_animation_force_timer > 0) 125 m_animation_force_timer--; 126 } 127 128 private: 129 scene::IMesh *m_mesh[MAX_TILE_LAYERS]; 130 MinimapMapblock *m_minimap_mapblock; 131 ITextureSource *m_tsrc; 132 IShaderSource *m_shdrsrc; 133 134 bool m_enable_shaders; 135 bool m_enable_vbo; 136 137 // Must animate() be called before rendering? 138 bool m_has_animation; 139 int m_animation_force_timer; 140 141 // Animation info: cracks 142 // Last crack value passed to animate() 143 int m_last_crack; 144 // Maps mesh and mesh buffer (i.e. material) indices to base texture names 145 std::map<std::pair<u8, u32>, std::string> m_crack_materials; 146 147 // Animation info: texture animationi 148 // Maps mesh and mesh buffer indices to TileSpecs 149 // Keys are pairs of (mesh index, buffer index in the mesh) 150 std::map<std::pair<u8, u32>, TileLayer> m_animation_tiles; 151 std::map<std::pair<u8, u32>, int> m_animation_frames; // last animation frame 152 std::map<std::pair<u8, u32>, int> m_animation_frame_offsets; 153 154 // Animation info: day/night transitions 155 // Last daynight_ratio value passed to animate() 156 u32 m_last_daynight_ratio; 157 // For each mesh and mesh buffer, stores pre-baked colors 158 // of sunlit vertices 159 // Keys are pairs of (mesh index, buffer index in the mesh) 160 std::map<std::pair<u8, u32>, std::map<u32, video::SColor > > m_daynight_diffs; 161 }; 162 163 /*! 164 * Encodes light of a node. 165 * The result is not the final color, but a 166 * half-baked vertex color. 167 * You have to multiply the resulting color 168 * with the node's color. 169 * 170 * \param light the first 8 bits are day light, 171 * the last 8 bits are night light 172 * \param emissive_light amount of light the surface emits, 173 * from 0 to LIGHT_SUN. 174 */ 175 video::SColor encode_light(u16 light, u8 emissive_light); 176 177 // Compute light at node 178 u16 getInteriorLight(MapNode n, s32 increment, const NodeDefManager *ndef); 179 u16 getFaceLight(MapNode n, MapNode n2, const v3s16 &face_dir, 180 const NodeDefManager *ndef); 181 u16 getSmoothLightSolid(const v3s16 &p, const v3s16 &face_dir, const v3s16 &corner, MeshMakeData *data); 182 u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData *data); 183 184 /*! 185 * Returns the sunlight's color from the current 186 * day-night ratio. 187 */ 188 void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio); 189 190 /*! 191 * Gives the final SColor shown on screen. 192 * 193 * \param result output color 194 * \param light first 8 bits are day light, second 8 bits are 195 * night light 196 */ 197 void final_color_blend(video::SColor *result, 198 u16 light, u32 daynight_ratio); 199 200 /*! 201 * Gives the final SColor shown on screen. 202 * 203 * \param result output color 204 * \param data the half-baked vertex color 205 * \param dayLight color of the sunlight 206 */ 207 void final_color_blend(video::SColor *result, 208 const video::SColor &data, const video::SColorf &dayLight); 209 210 // Retrieves the TileSpec of a face of a node 211 // Adds MATERIAL_FLAG_CRACK if the node is cracked 212 // TileSpec should be passed as reference due to the underlying TileFrame and its vector 213 // TileFrame vector copy cost very much to client 214 void getNodeTileN(MapNode mn, const v3s16 &p, u8 tileindex, MeshMakeData *data, TileSpec &tile); 215 void getNodeTile(MapNode mn, const v3s16 &p, const v3s16 &dir, MeshMakeData *data, TileSpec &tile); 216