mapblock_mesh.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518
  1. /*
  2. Minetest
  3. Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "mapblock_mesh.h"
  17. #include "client.h"
  18. #include "mapblock.h"
  19. #include "map.h"
  20. #include "profiler.h"
  21. #include "shader.h"
  22. #include "mesh.h"
  23. #include "minimap.h"
  24. #include "content_mapblock.h"
  25. #include "util/directiontables.h"
  26. #include "client/renderingengine.h"
  27. /*
  28. MeshMakeData
  29. */
  30. MeshMakeData::MeshMakeData(Client *client, bool use_shaders,
  31. bool use_tangent_vertices):
  32. m_client(client),
  33. m_use_shaders(use_shaders),
  34. m_use_tangent_vertices(use_tangent_vertices)
  35. {}
  36. void MeshMakeData::fillBlockDataBegin(const v3s16 &blockpos)
  37. {
  38. m_blockpos = blockpos;
  39. v3s16 blockpos_nodes = m_blockpos*MAP_BLOCKSIZE;
  40. m_vmanip.clear();
  41. VoxelArea voxel_area(blockpos_nodes - v3s16(1,1,1) * MAP_BLOCKSIZE,
  42. blockpos_nodes + v3s16(1,1,1) * MAP_BLOCKSIZE*2-v3s16(1,1,1));
  43. m_vmanip.addArea(voxel_area);
  44. }
  45. void MeshMakeData::fillBlockData(const v3s16 &block_offset, MapNode *data)
  46. {
  47. v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
  48. VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
  49. v3s16 bp = m_blockpos + block_offset;
  50. v3s16 blockpos_nodes = bp * MAP_BLOCKSIZE;
  51. m_vmanip.copyFrom(data, data_area, v3s16(0,0,0), blockpos_nodes, data_size);
  52. }
  53. void MeshMakeData::fill(MapBlock *block)
  54. {
  55. fillBlockDataBegin(block->getPos());
  56. fillBlockData(v3s16(0,0,0), block->getData());
  57. // Get map for reading neigbhor blocks
  58. Map *map = block->getParent();
  59. for (const v3s16 &dir : g_26dirs) {
  60. v3s16 bp = m_blockpos + dir;
  61. MapBlock *b = map->getBlockNoCreateNoEx(bp);
  62. if(b)
  63. fillBlockData(dir, b->getData());
  64. }
  65. }
  66. void MeshMakeData::fillSingleNode(MapNode *node)
  67. {
  68. m_blockpos = v3s16(0,0,0);
  69. v3s16 blockpos_nodes = v3s16(0,0,0);
  70. VoxelArea area(blockpos_nodes-v3s16(1,1,1)*MAP_BLOCKSIZE,
  71. blockpos_nodes+v3s16(1,1,1)*MAP_BLOCKSIZE*2-v3s16(1,1,1));
  72. s32 volume = area.getVolume();
  73. s32 our_node_index = area.index(1,1,1);
  74. // Allocate this block + neighbors
  75. m_vmanip.clear();
  76. m_vmanip.addArea(area);
  77. // Fill in data
  78. MapNode *data = new MapNode[volume];
  79. for(s32 i = 0; i < volume; i++)
  80. {
  81. if (i == our_node_index)
  82. data[i] = *node;
  83. else
  84. data[i] = MapNode(CONTENT_AIR, LIGHT_MAX, 0);
  85. }
  86. m_vmanip.copyFrom(data, area, area.MinEdge, area.MinEdge, area.getExtent());
  87. delete[] data;
  88. }
  89. void MeshMakeData::setCrack(int crack_level, v3s16 crack_pos)
  90. {
  91. if (crack_level >= 0)
  92. m_crack_pos_relative = crack_pos - m_blockpos*MAP_BLOCKSIZE;
  93. }
  94. void MeshMakeData::setSmoothLighting(bool smooth_lighting)
  95. {
  96. m_smooth_lighting = smooth_lighting;
  97. }
  98. /*
  99. Light and vertex color functions
  100. */
  101. /*
  102. Calculate non-smooth lighting at interior of node.
  103. Single light bank.
  104. */
  105. static u8 getInteriorLight(enum LightBank bank, MapNode n, s32 increment,
  106. INodeDefManager *ndef)
  107. {
  108. u8 light = n.getLight(bank, ndef);
  109. while(increment > 0)
  110. {
  111. light = undiminish_light(light);
  112. --increment;
  113. }
  114. while(increment < 0)
  115. {
  116. light = diminish_light(light);
  117. ++increment;
  118. }
  119. return decode_light(light);
  120. }
  121. /*
  122. Calculate non-smooth lighting at interior of node.
  123. Both light banks.
  124. */
  125. u16 getInteriorLight(MapNode n, s32 increment, INodeDefManager *ndef)
  126. {
  127. u16 day = getInteriorLight(LIGHTBANK_DAY, n, increment, ndef);
  128. u16 night = getInteriorLight(LIGHTBANK_NIGHT, n, increment, ndef);
  129. return day | (night << 8);
  130. }
  131. /*
  132. Calculate non-smooth lighting at face of node.
  133. Single light bank.
  134. */
  135. static u8 getFaceLight(enum LightBank bank, MapNode n, MapNode n2,
  136. v3s16 face_dir, INodeDefManager *ndef)
  137. {
  138. u8 light;
  139. u8 l1 = n.getLight(bank, ndef);
  140. u8 l2 = n2.getLight(bank, ndef);
  141. if(l1 > l2)
  142. light = l1;
  143. else
  144. light = l2;
  145. // Boost light level for light sources
  146. u8 light_source = MYMAX(ndef->get(n).light_source,
  147. ndef->get(n2).light_source);
  148. if(light_source > light)
  149. light = light_source;
  150. return decode_light(light);
  151. }
  152. /*
  153. Calculate non-smooth lighting at face of node.
  154. Both light banks.
  155. */
  156. u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, INodeDefManager *ndef)
  157. {
  158. u16 day = getFaceLight(LIGHTBANK_DAY, n, n2, face_dir, ndef);
  159. u16 night = getFaceLight(LIGHTBANK_NIGHT, n, n2, face_dir, ndef);
  160. return day | (night << 8);
  161. }
  162. /*
  163. Calculate smooth lighting at the XYZ- corner of p.
  164. Both light banks
  165. */
  166. static u16 getSmoothLightCombined(const v3s16 &p, MeshMakeData *data)
  167. {
  168. static const v3s16 dirs8[8] = {
  169. v3s16(0,0,0),
  170. v3s16(0,0,1),
  171. v3s16(0,1,0),
  172. v3s16(0,1,1),
  173. v3s16(1,0,0),
  174. v3s16(1,1,0),
  175. v3s16(1,0,1),
  176. v3s16(1,1,1),
  177. };
  178. INodeDefManager *ndef = data->m_client->ndef();
  179. u16 ambient_occlusion = 0;
  180. u16 light_count = 0;
  181. u8 light_source_max = 0;
  182. u16 light_day = 0;
  183. u16 light_night = 0;
  184. for (const v3s16 &dir : dirs8) {
  185. MapNode n = data->m_vmanip.getNodeNoExNoEmerge(p - dir);
  186. // if it's CONTENT_IGNORE we can't do any light calculations
  187. if (n.getContent() == CONTENT_IGNORE)
  188. continue;
  189. const ContentFeatures &f = ndef->get(n);
  190. if (f.light_source > light_source_max)
  191. light_source_max = f.light_source;
  192. // Check f.solidness because fast-style leaves look better this way
  193. if (f.param_type == CPT_LIGHT && f.solidness != 2) {
  194. light_day += decode_light(n.getLightNoChecks(LIGHTBANK_DAY, &f));
  195. light_night += decode_light(
  196. n.getLightNoChecks(LIGHTBANK_NIGHT, &f));
  197. light_count++;
  198. } else {
  199. ambient_occlusion++;
  200. }
  201. }
  202. if(light_count == 0)
  203. return 0xffff;
  204. light_day /= light_count;
  205. light_night /= light_count;
  206. // Boost brightness around light sources
  207. bool skip_ambient_occlusion_day = false;
  208. if (decode_light(light_source_max) >= light_day) {
  209. light_day = decode_light(light_source_max);
  210. skip_ambient_occlusion_day = true;
  211. }
  212. bool skip_ambient_occlusion_night = false;
  213. if(decode_light(light_source_max) >= light_night) {
  214. light_night = decode_light(light_source_max);
  215. skip_ambient_occlusion_night = true;
  216. }
  217. if (ambient_occlusion > 4) {
  218. static thread_local const float ao_gamma = rangelim(
  219. g_settings->getFloat("ambient_occlusion_gamma"), 0.25, 4.0);
  220. // Table of gamma space multiply factors.
  221. static const float light_amount[3] = {
  222. powf(0.75, 1.0 / ao_gamma),
  223. powf(0.5, 1.0 / ao_gamma),
  224. powf(0.25, 1.0 / ao_gamma)
  225. };
  226. //calculate table index for gamma space multiplier
  227. ambient_occlusion -= 5;
  228. if (!skip_ambient_occlusion_day)
  229. light_day = rangelim(core::round32(
  230. light_day * light_amount[ambient_occlusion]), 0, 255);
  231. if (!skip_ambient_occlusion_night)
  232. light_night = rangelim(core::round32(
  233. light_night * light_amount[ambient_occlusion]), 0, 255);
  234. }
  235. return light_day | (light_night << 8);
  236. }
  237. /*
  238. Calculate smooth lighting at the given corner of p.
  239. Both light banks.
  240. */
  241. u16 getSmoothLight(v3s16 p, v3s16 corner, MeshMakeData *data)
  242. {
  243. if (corner.X == 1)
  244. ++p.X;
  245. // else corner.X == -1
  246. if (corner.Y == 1)
  247. ++p.Y;
  248. // else corner.Y == -1
  249. if (corner.Z == 1)
  250. ++p.Z;
  251. // else corner.Z == -1
  252. return getSmoothLightCombined(p, data);
  253. }
  254. void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio){
  255. f32 rg = daynight_ratio / 1000.0f - 0.04f;
  256. f32 b = (0.98f * daynight_ratio) / 1000.0f + 0.078f;
  257. sunlight->r = rg;
  258. sunlight->g = rg;
  259. sunlight->b = b;
  260. }
  261. void final_color_blend(video::SColor *result,
  262. u16 light, u32 daynight_ratio)
  263. {
  264. video::SColorf dayLight;
  265. get_sunlight_color(&dayLight, daynight_ratio);
  266. final_color_blend(result,
  267. encode_light(light, 0), dayLight);
  268. }
  269. void final_color_blend(video::SColor *result,
  270. const video::SColor &data, const video::SColorf &dayLight)
  271. {
  272. static const video::SColorf artificialColor(1.04f, 1.04f, 1.04f);
  273. video::SColorf c(data);
  274. f32 n = 1 - c.a;
  275. f32 r = c.r * (c.a * dayLight.r + n * artificialColor.r) * 2.0f;
  276. f32 g = c.g * (c.a * dayLight.g + n * artificialColor.g) * 2.0f;
  277. f32 b = c.b * (c.a * dayLight.b + n * artificialColor.b) * 2.0f;
  278. // Emphase blue a bit in darker places
  279. // Each entry of this array represents a range of 8 blue levels
  280. static const u8 emphase_blue_when_dark[32] = {
  281. 1, 4, 6, 6, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0,
  282. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  283. };
  284. b += emphase_blue_when_dark[irr::core::clamp((s32) ((r + g + b) / 3 * 255),
  285. 0, 255) / 8] / 255.0f;
  286. result->setRed(core::clamp((s32) (r * 255.0f), 0, 255));
  287. result->setGreen(core::clamp((s32) (g * 255.0f), 0, 255));
  288. result->setBlue(core::clamp((s32) (b * 255.0f), 0, 255));
  289. }
  290. /*
  291. Mesh generation helpers
  292. */
  293. /*
  294. vertex_dirs: v3s16[4]
  295. */
  296. static void getNodeVertexDirs(v3s16 dir, v3s16 *vertex_dirs)
  297. {
  298. /*
  299. If looked from outside the node towards the face, the corners are:
  300. 0: bottom-right
  301. 1: bottom-left
  302. 2: top-left
  303. 3: top-right
  304. */
  305. if (dir == v3s16(0, 0, 1)) {
  306. // If looking towards z+, this is the face that is behind
  307. // the center point, facing towards z+.
  308. vertex_dirs[0] = v3s16(-1,-1, 1);
  309. vertex_dirs[1] = v3s16( 1,-1, 1);
  310. vertex_dirs[2] = v3s16( 1, 1, 1);
  311. vertex_dirs[3] = v3s16(-1, 1, 1);
  312. } else if (dir == v3s16(0, 0, -1)) {
  313. // faces towards Z-
  314. vertex_dirs[0] = v3s16( 1,-1,-1);
  315. vertex_dirs[1] = v3s16(-1,-1,-1);
  316. vertex_dirs[2] = v3s16(-1, 1,-1);
  317. vertex_dirs[3] = v3s16( 1, 1,-1);
  318. } else if (dir == v3s16(1, 0, 0)) {
  319. // faces towards X+
  320. vertex_dirs[0] = v3s16( 1,-1, 1);
  321. vertex_dirs[1] = v3s16( 1,-1,-1);
  322. vertex_dirs[2] = v3s16( 1, 1,-1);
  323. vertex_dirs[3] = v3s16( 1, 1, 1);
  324. } else if (dir == v3s16(-1, 0, 0)) {
  325. // faces towards X-
  326. vertex_dirs[0] = v3s16(-1,-1,-1);
  327. vertex_dirs[1] = v3s16(-1,-1, 1);
  328. vertex_dirs[2] = v3s16(-1, 1, 1);
  329. vertex_dirs[3] = v3s16(-1, 1,-1);
  330. } else if (dir == v3s16(0, 1, 0)) {
  331. // faces towards Y+ (assume Z- as "down" in texture)
  332. vertex_dirs[0] = v3s16( 1, 1,-1);
  333. vertex_dirs[1] = v3s16(-1, 1,-1);
  334. vertex_dirs[2] = v3s16(-1, 1, 1);
  335. vertex_dirs[3] = v3s16( 1, 1, 1);
  336. } else if (dir == v3s16(0, -1, 0)) {
  337. // faces towards Y- (assume Z+ as "down" in texture)
  338. vertex_dirs[0] = v3s16( 1,-1, 1);
  339. vertex_dirs[1] = v3s16(-1,-1, 1);
  340. vertex_dirs[2] = v3s16(-1,-1,-1);
  341. vertex_dirs[3] = v3s16( 1,-1,-1);
  342. }
  343. }
  344. struct FastFace
  345. {
  346. TileLayer layer;
  347. video::S3DVertex vertices[4]; // Precalculated vertices
  348. /*!
  349. * The face is divided into two triangles. If this is true,
  350. * vertices 0 and 2 are connected, othervise vertices 1 and 3
  351. * are connected.
  352. */
  353. bool vertex_0_2_connected;
  354. u8 layernum;
  355. };
  356. static void makeFastFace(const TileSpec &tile, u16 li0, u16 li1, u16 li2, u16 li3,
  357. const v3f &p, v3s16 dir, v3f scale, std::vector<FastFace> &dest)
  358. {
  359. // Position is at the center of the cube.
  360. v3f pos = p * BS;
  361. float x0 = 0.0f;
  362. float y0 = 0.0f;
  363. float w = 1.0f;
  364. float h = 1.0f;
  365. v3f vertex_pos[4];
  366. v3s16 vertex_dirs[4];
  367. getNodeVertexDirs(dir, vertex_dirs);
  368. v3s16 t;
  369. u16 t1;
  370. switch (tile.rotation) {
  371. case 0:
  372. break;
  373. case 1: //R90
  374. t = vertex_dirs[0];
  375. vertex_dirs[0] = vertex_dirs[3];
  376. vertex_dirs[3] = vertex_dirs[2];
  377. vertex_dirs[2] = vertex_dirs[1];
  378. vertex_dirs[1] = t;
  379. t1 = li0;
  380. li0 = li3;
  381. li3 = li2;
  382. li2 = li1;
  383. li1 = t1;
  384. break;
  385. case 2: //R180
  386. t = vertex_dirs[0];
  387. vertex_dirs[0] = vertex_dirs[2];
  388. vertex_dirs[2] = t;
  389. t = vertex_dirs[1];
  390. vertex_dirs[1] = vertex_dirs[3];
  391. vertex_dirs[3] = t;
  392. t1 = li0;
  393. li0 = li2;
  394. li2 = t1;
  395. t1 = li1;
  396. li1 = li3;
  397. li3 = t1;
  398. break;
  399. case 3: //R270
  400. t = vertex_dirs[0];
  401. vertex_dirs[0] = vertex_dirs[1];
  402. vertex_dirs[1] = vertex_dirs[2];
  403. vertex_dirs[2] = vertex_dirs[3];
  404. vertex_dirs[3] = t;
  405. t1 = li0;
  406. li0 = li1;
  407. li1 = li2;
  408. li2 = li3;
  409. li3 = t1;
  410. break;
  411. case 4: //FXR90
  412. t = vertex_dirs[0];
  413. vertex_dirs[0] = vertex_dirs[3];
  414. vertex_dirs[3] = vertex_dirs[2];
  415. vertex_dirs[2] = vertex_dirs[1];
  416. vertex_dirs[1] = t;
  417. t1 = li0;
  418. li0 = li3;
  419. li3 = li2;
  420. li2 = li1;
  421. li1 = t1;
  422. y0 += h;
  423. h *= -1;
  424. break;
  425. case 5: //FXR270
  426. t = vertex_dirs[0];
  427. vertex_dirs[0] = vertex_dirs[1];
  428. vertex_dirs[1] = vertex_dirs[2];
  429. vertex_dirs[2] = vertex_dirs[3];
  430. vertex_dirs[3] = t;
  431. t1 = li0;
  432. li0 = li1;
  433. li1 = li2;
  434. li2 = li3;
  435. li3 = t1;
  436. y0 += h;
  437. h *= -1;
  438. break;
  439. case 6: //FYR90
  440. t = vertex_dirs[0];
  441. vertex_dirs[0] = vertex_dirs[3];
  442. vertex_dirs[3] = vertex_dirs[2];
  443. vertex_dirs[2] = vertex_dirs[1];
  444. vertex_dirs[1] = t;
  445. t1 = li0;
  446. li0 = li3;
  447. li3 = li2;
  448. li2 = li1;
  449. li1 = t1;
  450. x0 += w;
  451. w *= -1;
  452. break;
  453. case 7: //FYR270
  454. t = vertex_dirs[0];
  455. vertex_dirs[0] = vertex_dirs[1];
  456. vertex_dirs[1] = vertex_dirs[2];
  457. vertex_dirs[2] = vertex_dirs[3];
  458. vertex_dirs[3] = t;
  459. t1 = li0;
  460. li0 = li1;
  461. li1 = li2;
  462. li2 = li3;
  463. li3 = t1;
  464. x0 += w;
  465. w *= -1;
  466. break;
  467. case 8: //FX
  468. y0 += h;
  469. h *= -1;
  470. break;
  471. case 9: //FY
  472. x0 += w;
  473. w *= -1;
  474. break;
  475. default:
  476. break;
  477. }
  478. for (u16 i = 0; i < 4; i++) {
  479. vertex_pos[i] = v3f(
  480. BS / 2 * vertex_dirs[i].X,
  481. BS / 2 * vertex_dirs[i].Y,
  482. BS / 2 * vertex_dirs[i].Z
  483. );
  484. }
  485. for (v3f &vpos : vertex_pos) {
  486. vpos.X *= scale.X;
  487. vpos.Y *= scale.Y;
  488. vpos.Z *= scale.Z;
  489. vpos += pos;
  490. }
  491. f32 abs_scale = 1.0f;
  492. if (scale.X < 0.999f || scale.X > 1.001f) abs_scale = scale.X;
  493. else if (scale.Y < 0.999f || scale.Y > 1.001f) abs_scale = scale.Y;
  494. else if (scale.Z < 0.999f || scale.Z > 1.001f) abs_scale = scale.Z;
  495. v3f normal(dir.X, dir.Y, dir.Z);
  496. u16 li[4] = { li0, li1, li2, li3 };
  497. u16 day[4];
  498. u16 night[4];
  499. for (u8 i = 0; i < 4; i++) {
  500. day[i] = li[i] >> 8;
  501. night[i] = li[i] & 0xFF;
  502. }
  503. bool vertex_0_2_connected = abs(day[0] - day[2]) + abs(night[0] - night[2])
  504. < abs(day[1] - day[3]) + abs(night[1] - night[3]);
  505. v2f32 f[4] = {
  506. core::vector2d<f32>(x0 + w * abs_scale, y0 + h),
  507. core::vector2d<f32>(x0, y0 + h),
  508. core::vector2d<f32>(x0, y0),
  509. core::vector2d<f32>(x0 + w * abs_scale, y0) };
  510. for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) {
  511. const TileLayer *layer = &tile.layers[layernum];
  512. if (layer->texture_id == 0)
  513. continue;
  514. // equivalent to dest.push_back(FastFace()) but faster
  515. dest.emplace_back();
  516. FastFace& face = *dest.rbegin();
  517. for (u8 i = 0; i < 4; i++) {
  518. video::SColor c = encode_light(li[i], tile.emissive_light);
  519. if (!tile.emissive_light)
  520. applyFacesShading(c, normal);
  521. face.vertices[i] = video::S3DVertex(vertex_pos[i], normal, c, f[i]);
  522. }
  523. /*
  524. Revert triangles for nicer looking gradient if the
  525. brightness of vertices 1 and 3 differ less than
  526. the brightness of vertices 0 and 2.
  527. */
  528. face.vertex_0_2_connected = vertex_0_2_connected;
  529. face.layer = *layer;
  530. face.layernum = layernum;
  531. }
  532. }
  533. /*
  534. Nodes make a face if contents differ and solidness differs.
  535. Return value:
  536. 0: No face
  537. 1: Face uses m1's content
  538. 2: Face uses m2's content
  539. equivalent: Whether the blocks share the same face (eg. water and glass)
  540. TODO: Add 3: Both faces drawn with backface culling, remove equivalent
  541. */
  542. static u8 face_contents(content_t m1, content_t m2, bool *equivalent,
  543. INodeDefManager *ndef)
  544. {
  545. *equivalent = false;
  546. if (m1 == m2 || m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
  547. return 0;
  548. const ContentFeatures &f1 = ndef->get(m1);
  549. const ContentFeatures &f2 = ndef->get(m2);
  550. // Contents don't differ for different forms of same liquid
  551. if (f1.sameLiquid(f2))
  552. return 0;
  553. u8 c1 = f1.solidness;
  554. u8 c2 = f2.solidness;
  555. if (c1 == c2)
  556. return 0;
  557. if (c1 == 0)
  558. c1 = f1.visual_solidness;
  559. else if (c2 == 0)
  560. c2 = f2.visual_solidness;
  561. if (c1 == c2) {
  562. *equivalent = true;
  563. // If same solidness, liquid takes precense
  564. if (f1.isLiquid())
  565. return 1;
  566. if (f2.isLiquid())
  567. return 2;
  568. }
  569. if (c1 > c2)
  570. return 1;
  571. return 2;
  572. }
  573. /*
  574. Gets nth node tile (0 <= n <= 5).
  575. */
  576. void getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data, TileSpec &tile)
  577. {
  578. INodeDefManager *ndef = data->m_client->ndef();
  579. const ContentFeatures &f = ndef->get(mn);
  580. tile = f.tiles[tileindex];
  581. bool has_crack = p == data->m_crack_pos_relative;
  582. for (TileLayer &layer : tile.layers) {
  583. if (layer.texture_id == 0)
  584. continue;
  585. if (!layer.has_color)
  586. mn.getColor(f, &(layer.color));
  587. // Apply temporary crack
  588. if (has_crack)
  589. layer.material_flags |= MATERIAL_FLAG_CRACK;
  590. }
  591. }
  592. /*
  593. Gets node tile given a face direction.
  594. */
  595. void getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data, TileSpec &tile)
  596. {
  597. INodeDefManager *ndef = data->m_client->ndef();
  598. // Direction must be (1,0,0), (-1,0,0), (0,1,0), (0,-1,0),
  599. // (0,0,1), (0,0,-1) or (0,0,0)
  600. assert(dir.X * dir.X + dir.Y * dir.Y + dir.Z * dir.Z <= 1);
  601. // Convert direction to single integer for table lookup
  602. // 0 = (0,0,0)
  603. // 1 = (1,0,0)
  604. // 2 = (0,1,0)
  605. // 3 = (0,0,1)
  606. // 4 = invalid, treat as (0,0,0)
  607. // 5 = (0,0,-1)
  608. // 6 = (0,-1,0)
  609. // 7 = (-1,0,0)
  610. u8 dir_i = ((dir.X + 2 * dir.Y + 3 * dir.Z) & 7) * 2;
  611. // Get rotation for things like chests
  612. u8 facedir = mn.getFaceDir(ndef);
  613. static const u16 dir_to_tile[24 * 16] =
  614. {
  615. // 0 +X +Y +Z -Z -Y -X -> value=tile,rotation
  616. 0,0, 2,0 , 0,0 , 4,0 , 0,0, 5,0 , 1,0 , 3,0 , // rotate around y+ 0 - 3
  617. 0,0, 4,0 , 0,3 , 3,0 , 0,0, 2,0 , 1,1 , 5,0 ,
  618. 0,0, 3,0 , 0,2 , 5,0 , 0,0, 4,0 , 1,2 , 2,0 ,
  619. 0,0, 5,0 , 0,1 , 2,0 , 0,0, 3,0 , 1,3 , 4,0 ,
  620. 0,0, 2,3 , 5,0 , 0,2 , 0,0, 1,0 , 4,2 , 3,1 , // rotate around z+ 4 - 7
  621. 0,0, 4,3 , 2,0 , 0,1 , 0,0, 1,1 , 3,2 , 5,1 ,
  622. 0,0, 3,3 , 4,0 , 0,0 , 0,0, 1,2 , 5,2 , 2,1 ,
  623. 0,0, 5,3 , 3,0 , 0,3 , 0,0, 1,3 , 2,2 , 4,1 ,
  624. 0,0, 2,1 , 4,2 , 1,2 , 0,0, 0,0 , 5,0 , 3,3 , // rotate around z- 8 - 11
  625. 0,0, 4,1 , 3,2 , 1,3 , 0,0, 0,3 , 2,0 , 5,3 ,
  626. 0,0, 3,1 , 5,2 , 1,0 , 0,0, 0,2 , 4,0 , 2,3 ,
  627. 0,0, 5,1 , 2,2 , 1,1 , 0,0, 0,1 , 3,0 , 4,3 ,
  628. 0,0, 0,3 , 3,3 , 4,1 , 0,0, 5,3 , 2,3 , 1,3 , // rotate around x+ 12 - 15
  629. 0,0, 0,2 , 5,3 , 3,1 , 0,0, 2,3 , 4,3 , 1,0 ,
  630. 0,0, 0,1 , 2,3 , 5,1 , 0,0, 4,3 , 3,3 , 1,1 ,
  631. 0,0, 0,0 , 4,3 , 2,1 , 0,0, 3,3 , 5,3 , 1,2 ,
  632. 0,0, 1,1 , 2,1 , 4,3 , 0,0, 5,1 , 3,1 , 0,1 , // rotate around x- 16 - 19
  633. 0,0, 1,2 , 4,1 , 3,3 , 0,0, 2,1 , 5,1 , 0,0 ,
  634. 0,0, 1,3 , 3,1 , 5,3 , 0,0, 4,1 , 2,1 , 0,3 ,
  635. 0,0, 1,0 , 5,1 , 2,3 , 0,0, 3,1 , 4,1 , 0,2 ,
  636. 0,0, 3,2 , 1,2 , 4,2 , 0,0, 5,2 , 0,2 , 2,2 , // rotate around y- 20 - 23
  637. 0,0, 5,2 , 1,3 , 3,2 , 0,0, 2,2 , 0,1 , 4,2 ,
  638. 0,0, 2,2 , 1,0 , 5,2 , 0,0, 4,2 , 0,0 , 3,2 ,
  639. 0,0, 4,2 , 1,1 , 2,2 , 0,0, 3,2 , 0,3 , 5,2
  640. };
  641. u16 tile_index = facedir * 16 + dir_i;
  642. getNodeTileN(mn, p, dir_to_tile[tile_index], data, tile);
  643. tile.rotation = dir_to_tile[tile_index + 1];
  644. }
  645. static void getTileInfo(
  646. // Input:
  647. MeshMakeData *data,
  648. const v3s16 &p,
  649. const v3s16 &face_dir,
  650. // Output:
  651. bool &makes_face,
  652. v3s16 &p_corrected,
  653. v3s16 &face_dir_corrected,
  654. u16 *lights,
  655. TileSpec &tile
  656. )
  657. {
  658. VoxelManipulator &vmanip = data->m_vmanip;
  659. INodeDefManager *ndef = data->m_client->ndef();
  660. v3s16 blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE;
  661. const MapNode &n0 = vmanip.getNodeRefUnsafe(blockpos_nodes + p);
  662. // Don't even try to get n1 if n0 is already CONTENT_IGNORE
  663. if (n0.getContent() == CONTENT_IGNORE) {
  664. makes_face = false;
  665. return;
  666. }
  667. const MapNode &n1 = vmanip.getNodeRefUnsafeCheckFlags(blockpos_nodes + p + face_dir);
  668. if (n1.getContent() == CONTENT_IGNORE) {
  669. makes_face = false;
  670. return;
  671. }
  672. // This is hackish
  673. bool equivalent = false;
  674. u8 mf = face_contents(n0.getContent(), n1.getContent(),
  675. &equivalent, ndef);
  676. if (mf == 0) {
  677. makes_face = false;
  678. return;
  679. }
  680. makes_face = true;
  681. MapNode n = n0;
  682. if (mf == 1) {
  683. p_corrected = p;
  684. face_dir_corrected = face_dir;
  685. } else {
  686. n = n1;
  687. p_corrected = p + face_dir;
  688. face_dir_corrected = -face_dir;
  689. }
  690. getNodeTile(n, p_corrected, face_dir_corrected, data, tile);
  691. const ContentFeatures &f = ndef->get(n);
  692. tile.emissive_light = f.light_source;
  693. // eg. water and glass
  694. if (equivalent) {
  695. for (TileLayer &layer : tile.layers)
  696. layer.material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
  697. }
  698. if (!data->m_smooth_lighting) {
  699. lights[0] = lights[1] = lights[2] = lights[3] =
  700. getFaceLight(n0, n1, face_dir, ndef);
  701. } else {
  702. v3s16 vertex_dirs[4];
  703. getNodeVertexDirs(face_dir_corrected, vertex_dirs);
  704. v3s16 light_p = blockpos_nodes + p_corrected;
  705. for (u16 i = 0; i < 4; i++)
  706. lights[i] = getSmoothLight(light_p, vertex_dirs[i], data);
  707. }
  708. }
  709. /*
  710. startpos:
  711. translate_dir: unit vector with only one of x, y or z
  712. face_dir: unit vector with only one of x, y or z
  713. */
  714. static void updateFastFaceRow(
  715. MeshMakeData *data,
  716. const v3s16 &&startpos,
  717. v3s16 translate_dir,
  718. const v3f &&translate_dir_f,
  719. const v3s16 &&face_dir,
  720. std::vector<FastFace> &dest)
  721. {
  722. v3s16 p = startpos;
  723. u16 continuous_tiles_count = 1;
  724. bool makes_face = false;
  725. v3s16 p_corrected;
  726. v3s16 face_dir_corrected;
  727. u16 lights[4] = {0, 0, 0, 0};
  728. TileSpec tile;
  729. getTileInfo(data, p, face_dir,
  730. makes_face, p_corrected, face_dir_corrected,
  731. lights, tile);
  732. // Unroll this variable which has a significant build cost
  733. TileSpec next_tile;
  734. for (u16 j = 0; j < MAP_BLOCKSIZE; j++) {
  735. // If tiling can be done, this is set to false in the next step
  736. bool next_is_different = true;
  737. v3s16 p_next;
  738. bool next_makes_face = false;
  739. v3s16 next_p_corrected;
  740. v3s16 next_face_dir_corrected;
  741. u16 next_lights[4] = {0, 0, 0, 0};
  742. // If at last position, there is nothing to compare to and
  743. // the face must be drawn anyway
  744. if (j != MAP_BLOCKSIZE - 1) {
  745. p_next = p + translate_dir;
  746. getTileInfo(data, p_next, face_dir,
  747. next_makes_face, next_p_corrected,
  748. next_face_dir_corrected, next_lights,
  749. next_tile);
  750. if (next_makes_face == makes_face
  751. && next_p_corrected == p_corrected + translate_dir
  752. && next_face_dir_corrected == face_dir_corrected
  753. && memcmp(next_lights, lights, ARRLEN(lights) * sizeof(u16)) == 0
  754. && next_tile.isTileable(tile)) {
  755. next_is_different = false;
  756. continuous_tiles_count++;
  757. }
  758. }
  759. if (next_is_different) {
  760. /*
  761. Create a face if there should be one
  762. */
  763. if (makes_face) {
  764. // Floating point conversion of the position vector
  765. v3f pf(p_corrected.X, p_corrected.Y, p_corrected.Z);
  766. // Center point of face (kind of)
  767. v3f sp = pf - ((f32)continuous_tiles_count * 0.5f - 0.5f)
  768. * translate_dir_f;
  769. v3f scale(1, 1, 1);
  770. if (translate_dir.X != 0)
  771. scale.X = continuous_tiles_count;
  772. if (translate_dir.Y != 0)
  773. scale.Y = continuous_tiles_count;
  774. if (translate_dir.Z != 0)
  775. scale.Z = continuous_tiles_count;
  776. makeFastFace(tile, lights[0], lights[1], lights[2], lights[3],
  777. sp, face_dir_corrected, scale, dest);
  778. g_profiler->avg("Meshgen: faces drawn by tiling", 0);
  779. for (int i = 1; i < continuous_tiles_count; i++)
  780. g_profiler->avg("Meshgen: faces drawn by tiling", 1);
  781. }
  782. continuous_tiles_count = 1;
  783. }
  784. makes_face = next_makes_face;
  785. p_corrected = next_p_corrected;
  786. face_dir_corrected = next_face_dir_corrected;
  787. std::memcpy(lights, next_lights, ARRLEN(lights) * sizeof(u16));
  788. if (next_is_different)
  789. tile = next_tile;
  790. p = p_next;
  791. }
  792. }
  793. static void updateAllFastFaceRows(MeshMakeData *data,
  794. std::vector<FastFace> &dest)
  795. {
  796. /*
  797. Go through every y,z and get top(y+) faces in rows of x+
  798. */
  799. for (s16 y = 0; y < MAP_BLOCKSIZE; y++)
  800. for (s16 z = 0; z < MAP_BLOCKSIZE; z++)
  801. updateFastFaceRow(data,
  802. v3s16(0, y, z),
  803. v3s16(1, 0, 0), //dir
  804. v3f (1, 0, 0),
  805. v3s16(0, 1, 0), //face dir
  806. dest);
  807. /*
  808. Go through every x,y and get right(x+) faces in rows of z+
  809. */
  810. for (s16 x = 0; x < MAP_BLOCKSIZE; x++)
  811. for (s16 y = 0; y < MAP_BLOCKSIZE; y++)
  812. updateFastFaceRow(data,
  813. v3s16(x, y, 0),
  814. v3s16(0, 0, 1), //dir
  815. v3f (0, 0, 1),
  816. v3s16(1, 0, 0), //face dir
  817. dest);
  818. /*
  819. Go through every y,z and get back(z+) faces in rows of x+
  820. */
  821. for (s16 z = 0; z < MAP_BLOCKSIZE; z++)
  822. for (s16 y = 0; y < MAP_BLOCKSIZE; y++)
  823. updateFastFaceRow(data,
  824. v3s16(0, y, z),
  825. v3s16(1, 0, 0), //dir
  826. v3f (1, 0, 0),
  827. v3s16(0, 0, 1), //face dir
  828. dest);
  829. }
  830. /*
  831. MapBlockMesh
  832. */
  833. MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
  834. m_minimap_mapblock(NULL),
  835. m_tsrc(data->m_client->getTextureSource()),
  836. m_shdrsrc(data->m_client->getShaderSource()),
  837. m_animation_force_timer(0), // force initial animation
  838. m_last_crack(-1),
  839. m_last_daynight_ratio((u32) -1)
  840. {
  841. for (auto &m : m_mesh)
  842. m = new scene::SMesh();
  843. m_enable_shaders = data->m_use_shaders;
  844. m_use_tangent_vertices = data->m_use_tangent_vertices;
  845. m_enable_vbo = g_settings->getBool("enable_vbo");
  846. if (g_settings->getBool("enable_minimap")) {
  847. m_minimap_mapblock = new MinimapMapblock;
  848. m_minimap_mapblock->getMinimapNodes(
  849. &data->m_vmanip, data->m_blockpos * MAP_BLOCKSIZE);
  850. }
  851. // 4-21ms for MAP_BLOCKSIZE=16 (NOTE: probably outdated)
  852. // 24-155ms for MAP_BLOCKSIZE=32 (NOTE: probably outdated)
  853. //TimeTaker timer1("MapBlockMesh()");
  854. std::vector<FastFace> fastfaces_new;
  855. fastfaces_new.reserve(512);
  856. /*
  857. We are including the faces of the trailing edges of the block.
  858. This means that when something changes, the caller must
  859. also update the meshes of the blocks at the leading edges.
  860. NOTE: This is the slowest part of this method.
  861. */
  862. {
  863. // 4-23ms for MAP_BLOCKSIZE=16 (NOTE: probably outdated)
  864. //TimeTaker timer2("updateAllFastFaceRows()");
  865. updateAllFastFaceRows(data, fastfaces_new);
  866. }
  867. // End of slow part
  868. /*
  869. Convert FastFaces to MeshCollector
  870. */
  871. MeshCollector collector(m_use_tangent_vertices);
  872. {
  873. // avg 0ms (100ms spikes when loading textures the first time)
  874. // (NOTE: probably outdated)
  875. //TimeTaker timer2("MeshCollector building");
  876. for (const FastFace &f : fastfaces_new) {
  877. static const u16 indices[] = {0, 1, 2, 2, 3, 0};
  878. static const u16 indices_alternate[] = {0, 1, 3, 2, 3, 1};
  879. if (!f.layer.texture)
  880. continue;
  881. const u16 *indices_p =
  882. f.vertex_0_2_connected ? indices : indices_alternate;
  883. collector.append(f.layer, f.vertices, 4, indices_p, 6,
  884. f.layernum);
  885. }
  886. }
  887. /*
  888. Add special graphics:
  889. - torches
  890. - flowing water
  891. - fences
  892. - whatever
  893. */
  894. {
  895. MapblockMeshGenerator generator(data, &collector);
  896. generator.generate();
  897. }
  898. collector.applyTileColors();
  899. /*
  900. Convert MeshCollector to SMesh
  901. */
  902. for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
  903. for(u32 i = 0; i < collector.prebuffers[layer].size(); i++)
  904. {
  905. PreMeshBuffer &p = collector.prebuffers[layer][i];
  906. // Generate animation data
  907. // - Cracks
  908. if (p.layer.material_flags & MATERIAL_FLAG_CRACK) {
  909. // Find the texture name plus ^[crack:N:
  910. std::ostringstream os(std::ios::binary);
  911. os << m_tsrc->getTextureName(p.layer.texture_id) << "^[crack";
  912. if (p.layer.material_flags & MATERIAL_FLAG_CRACK_OVERLAY)
  913. os << "o"; // use ^[cracko
  914. os << ":" << (u32)p.layer.animation_frame_count << ":";
  915. m_crack_materials.insert(std::make_pair(
  916. std::pair<u8, u32>(layer, i), os.str()));
  917. // Replace tile texture with the cracked one
  918. p.layer.texture = m_tsrc->getTextureForMesh(
  919. os.str() + "0",
  920. &p.layer.texture_id);
  921. }
  922. // - Texture animation
  923. if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) {
  924. // Add to MapBlockMesh in order to animate these tiles
  925. m_animation_tiles[std::pair<u8, u32>(layer, i)] = p.layer;
  926. m_animation_frames[std::pair<u8, u32>(layer, i)] = 0;
  927. if (g_settings->getBool(
  928. "desynchronize_mapblock_texture_animation")) {
  929. // Get starting position from noise
  930. m_animation_frame_offsets[std::pair<u8, u32>(layer, i)] =
  931. 100000 * (2.0 + noise3d(
  932. data->m_blockpos.X, data->m_blockpos.Y,
  933. data->m_blockpos.Z, 0));
  934. } else {
  935. // Play all synchronized
  936. m_animation_frame_offsets[std::pair<u8, u32>(layer, i)] = 0;
  937. }
  938. // Replace tile texture with the first animation frame
  939. p.layer.texture = (*p.layer.frames)[0].texture;
  940. }
  941. if (!m_enable_shaders) {
  942. // Extract colors for day-night animation
  943. // Dummy sunlight to handle non-sunlit areas
  944. video::SColorf sunlight;
  945. get_sunlight_color(&sunlight, 0);
  946. u32 vertex_count = m_use_tangent_vertices ?
  947. p.tangent_vertices.size() : p.vertices.size();
  948. for (u32 j = 0; j < vertex_count; j++) {
  949. video::SColor *vc;
  950. if (m_use_tangent_vertices) {
  951. vc = &p.tangent_vertices[j].Color;
  952. } else {
  953. vc = &p.vertices[j].Color;
  954. }
  955. video::SColor copy(*vc);
  956. if (vc->getAlpha() == 0) // No sunlight - no need to animate
  957. final_color_blend(vc, copy, sunlight); // Finalize color
  958. else // Record color to animate
  959. m_daynight_diffs[std::pair<u8, u32>(layer, i)][j] = copy;
  960. // The sunlight ratio has been stored,
  961. // delete alpha (for the final rendering).
  962. vc->setAlpha(255);
  963. }
  964. }
  965. // Create material
  966. video::SMaterial material;
  967. material.setFlag(video::EMF_LIGHTING, false);
  968. material.setFlag(video::EMF_BACK_FACE_CULLING, true);
  969. material.setFlag(video::EMF_BILINEAR_FILTER, false);
  970. material.setFlag(video::EMF_FOG_ENABLE, true);
  971. material.setTexture(0, p.layer.texture);
  972. if (m_enable_shaders) {
  973. material.MaterialType = m_shdrsrc->getShaderInfo(
  974. p.layer.shader_id).material;
  975. p.layer.applyMaterialOptionsWithShaders(material);
  976. if (p.layer.normal_texture)
  977. material.setTexture(1, p.layer.normal_texture);
  978. material.setTexture(2, p.layer.flags_texture);
  979. } else {
  980. p.layer.applyMaterialOptions(material);
  981. }
  982. scene::SMesh *mesh = (scene::SMesh *)m_mesh[layer];
  983. // Create meshbuffer, add to mesh
  984. if (m_use_tangent_vertices) {
  985. scene::SMeshBufferTangents *buf =
  986. new scene::SMeshBufferTangents();
  987. // Set material
  988. buf->Material = material;
  989. // Add to mesh
  990. mesh->addMeshBuffer(buf);
  991. // Mesh grabbed it
  992. buf->drop();
  993. buf->append(&p.tangent_vertices[0], p.tangent_vertices.size(),
  994. &p.indices[0], p.indices.size());
  995. } else {
  996. scene::SMeshBuffer *buf = new scene::SMeshBuffer();
  997. // Set material
  998. buf->Material = material;
  999. // Add to mesh
  1000. mesh->addMeshBuffer(buf);
  1001. // Mesh grabbed it
  1002. buf->drop();
  1003. buf->append(&p.vertices[0], p.vertices.size(),
  1004. &p.indices[0], p.indices.size());
  1005. }
  1006. }
  1007. /*
  1008. Do some stuff to the mesh
  1009. */
  1010. m_camera_offset = camera_offset;
  1011. translateMesh(m_mesh[layer],
  1012. intToFloat(data->m_blockpos * MAP_BLOCKSIZE - camera_offset, BS));
  1013. if (m_use_tangent_vertices) {
  1014. scene::IMeshManipulator* meshmanip =
  1015. RenderingEngine::get_scene_manager()->getMeshManipulator();
  1016. meshmanip->recalculateTangents(m_mesh[layer], true, false, false);
  1017. }
  1018. if (m_mesh[layer]) {
  1019. #if 0
  1020. // Usually 1-700 faces and 1-7 materials
  1021. std::cout << "Updated MapBlock has " << fastfaces_new.size()
  1022. << " faces and uses " << m_mesh[layer]->getMeshBufferCount()
  1023. << " materials (meshbuffers)" << std::endl;
  1024. #endif
  1025. // Use VBO for mesh (this just would set this for ever buffer)
  1026. if (m_enable_vbo)
  1027. m_mesh[layer]->setHardwareMappingHint(scene::EHM_STATIC);
  1028. }
  1029. }
  1030. //std::cout<<"added "<<fastfaces.getSize()<<" faces."<<std::endl;
  1031. // Check if animation is required for this mesh
  1032. m_has_animation =
  1033. !m_crack_materials.empty() ||
  1034. !m_daynight_diffs.empty() ||
  1035. !m_animation_tiles.empty();
  1036. }
  1037. MapBlockMesh::~MapBlockMesh()
  1038. {
  1039. for (scene::IMesh *m : m_mesh) {
  1040. if (m_enable_vbo && m)
  1041. for (u32 i = 0; i < m->getMeshBufferCount(); i++) {
  1042. scene::IMeshBuffer *buf = m->getMeshBuffer(i);
  1043. RenderingEngine::get_video_driver()->removeHardwareBuffer(buf);
  1044. }
  1045. m->drop();
  1046. m = NULL;
  1047. }
  1048. delete m_minimap_mapblock;
  1049. }
  1050. bool MapBlockMesh::animate(bool faraway, float time, int crack,
  1051. u32 daynight_ratio)
  1052. {
  1053. if (!m_has_animation) {
  1054. m_animation_force_timer = 100000;
  1055. return false;
  1056. }
  1057. m_animation_force_timer = myrand_range(5, 100);
  1058. // Cracks
  1059. if (crack != m_last_crack) {
  1060. for (auto &crack_material : m_crack_materials) {
  1061. scene::IMeshBuffer *buf = m_mesh[crack_material.first.first]->
  1062. getMeshBuffer(crack_material.first.second);
  1063. std::string basename = crack_material.second;
  1064. // Create new texture name from original
  1065. std::ostringstream os;
  1066. os << basename << crack;
  1067. u32 new_texture_id = 0;
  1068. video::ITexture *new_texture =
  1069. m_tsrc->getTextureForMesh(os.str(), &new_texture_id);
  1070. buf->getMaterial().setTexture(0, new_texture);
  1071. // If the current material is also animated,
  1072. // update animation info
  1073. auto anim_iter = m_animation_tiles.find(crack_material.first);
  1074. if (anim_iter != m_animation_tiles.end()) {
  1075. TileLayer &tile = anim_iter->second;
  1076. tile.texture = new_texture;
  1077. tile.texture_id = new_texture_id;
  1078. // force animation update
  1079. m_animation_frames[crack_material.first] = -1;
  1080. }
  1081. }
  1082. m_last_crack = crack;
  1083. }
  1084. // Texture animation
  1085. for (auto &animation_tile : m_animation_tiles) {
  1086. const TileLayer &tile = animation_tile.second;
  1087. // Figure out current frame
  1088. int frameoffset = m_animation_frame_offsets[animation_tile.first];
  1089. int frame = (int)(time * 1000 / tile.animation_frame_length_ms
  1090. + frameoffset) % tile.animation_frame_count;
  1091. // If frame doesn't change, skip
  1092. if (frame == m_animation_frames[animation_tile.first])
  1093. continue;
  1094. m_animation_frames[animation_tile.first] = frame;
  1095. scene::IMeshBuffer *buf = m_mesh[animation_tile.first.first]->
  1096. getMeshBuffer(animation_tile.first.second);
  1097. const FrameSpec &animation_frame = (*tile.frames)[frame];
  1098. buf->getMaterial().setTexture(0, animation_frame.texture);
  1099. if (m_enable_shaders) {
  1100. if (animation_frame.normal_texture)
  1101. buf->getMaterial().setTexture(1,
  1102. animation_frame.normal_texture);
  1103. buf->getMaterial().setTexture(2, animation_frame.flags_texture);
  1104. }
  1105. }
  1106. // Day-night transition
  1107. if (!m_enable_shaders && (daynight_ratio != m_last_daynight_ratio)) {
  1108. // Force reload mesh to VBO
  1109. if (m_enable_vbo)
  1110. for (scene::IMesh *m : m_mesh)
  1111. m->setDirty();
  1112. video::SColorf day_color;
  1113. get_sunlight_color(&day_color, daynight_ratio);
  1114. for (auto &daynight_diff : m_daynight_diffs) {
  1115. scene::IMeshBuffer *buf = m_mesh[daynight_diff.first.first]->
  1116. getMeshBuffer(daynight_diff.first.second);
  1117. video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices();
  1118. for (const auto &j : daynight_diff.second)
  1119. final_color_blend(&(vertices[j.first].Color), j.second,
  1120. day_color);
  1121. }
  1122. m_last_daynight_ratio = daynight_ratio;
  1123. }
  1124. return true;
  1125. }
  1126. void MapBlockMesh::updateCameraOffset(v3s16 camera_offset)
  1127. {
  1128. if (camera_offset != m_camera_offset) {
  1129. for (scene::IMesh *layer : m_mesh) {
  1130. translateMesh(layer,
  1131. intToFloat(m_camera_offset - camera_offset, BS));
  1132. if (m_enable_vbo)
  1133. layer->setDirty();
  1134. }
  1135. m_camera_offset = camera_offset;
  1136. }
  1137. }
  1138. /*
  1139. MeshCollector
  1140. */
  1141. void MeshCollector::append(const TileSpec &tile,
  1142. const video::S3DVertex *vertices, u32 numVertices,
  1143. const u16 *indices, u32 numIndices)
  1144. {
  1145. for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) {
  1146. const TileLayer *layer = &tile.layers[layernum];
  1147. if (layer->texture_id == 0)
  1148. continue;
  1149. append(*layer, vertices, numVertices, indices, numIndices, layernum);
  1150. }
  1151. }
  1152. void MeshCollector::append(const TileLayer &layer,
  1153. const video::S3DVertex *vertices, u32 numVertices,
  1154. const u16 *indices, u32 numIndices, u8 layernum)
  1155. {
  1156. if (numIndices > 65535) {
  1157. dstream << "FIXME: MeshCollector::append() called with numIndices="
  1158. << numIndices << " (limit 65535)" << std::endl;
  1159. return;
  1160. }
  1161. std::vector<PreMeshBuffer> *buffers = &prebuffers[layernum];
  1162. PreMeshBuffer *p = NULL;
  1163. for (PreMeshBuffer &pp : *buffers) {
  1164. if (pp.layer == layer && pp.indices.size() + numIndices <= 65535) {
  1165. p = &pp;
  1166. break;
  1167. }
  1168. }
  1169. if (p == NULL) {
  1170. PreMeshBuffer pp;
  1171. pp.layer = layer;
  1172. buffers->push_back(pp);
  1173. p = &(*buffers)[buffers->size() - 1];
  1174. }
  1175. u32 vertex_count;
  1176. if (m_use_tangent_vertices) {
  1177. vertex_count = p->tangent_vertices.size();
  1178. for (u32 i = 0; i < numVertices; i++) {
  1179. video::S3DVertexTangents vert(vertices[i].Pos, vertices[i].Normal,
  1180. vertices[i].Color, vertices[i].TCoords);
  1181. p->tangent_vertices.push_back(vert);
  1182. }
  1183. } else {
  1184. vertex_count = p->vertices.size();
  1185. for (u32 i = 0; i < numVertices; i++) {
  1186. video::S3DVertex vert(vertices[i].Pos, vertices[i].Normal,
  1187. vertices[i].Color, vertices[i].TCoords);
  1188. p->vertices.push_back(vert);
  1189. }
  1190. }
  1191. for (u32 i = 0; i < numIndices; i++) {
  1192. u32 j = indices[i] + vertex_count;
  1193. p->indices.push_back(j);
  1194. }
  1195. }
  1196. /*
  1197. MeshCollector - for meshnodes and converted drawtypes.
  1198. */
  1199. void MeshCollector::append(const TileSpec &tile,
  1200. const video::S3DVertex *vertices, u32 numVertices,
  1201. const u16 *indices, u32 numIndices,
  1202. v3f pos, video::SColor c, u8 light_source)
  1203. {
  1204. for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) {
  1205. const TileLayer *layer = &tile.layers[layernum];
  1206. if (layer->texture_id == 0)
  1207. continue;
  1208. append(*layer, vertices, numVertices, indices, numIndices, pos,
  1209. c, light_source, layernum);
  1210. }
  1211. }
  1212. void MeshCollector::append(const TileLayer &layer,
  1213. const video::S3DVertex *vertices, u32 numVertices,
  1214. const u16 *indices, u32 numIndices,
  1215. v3f pos, video::SColor c, u8 light_source, u8 layernum)
  1216. {
  1217. if (numIndices > 65535) {
  1218. dstream << "FIXME: MeshCollector::append() called with numIndices="
  1219. << numIndices << " (limit 65535)" << std::endl;
  1220. return;
  1221. }
  1222. std::vector<PreMeshBuffer> *buffers = &prebuffers[layernum];
  1223. PreMeshBuffer *p = NULL;
  1224. for (PreMeshBuffer &pp : *buffers) {
  1225. if (pp.layer == layer && pp.indices.size() + numIndices <= 65535) {
  1226. p = &pp;
  1227. break;
  1228. }
  1229. }
  1230. if (p == NULL) {
  1231. PreMeshBuffer pp;
  1232. pp.layer = layer;
  1233. buffers->push_back(pp);
  1234. p = &(*buffers)[buffers->size() - 1];
  1235. }
  1236. video::SColor original_c = c;
  1237. u32 vertex_count;
  1238. if (m_use_tangent_vertices) {
  1239. vertex_count = p->tangent_vertices.size();
  1240. for (u32 i = 0; i < numVertices; i++) {
  1241. if (!light_source) {
  1242. c = original_c;
  1243. applyFacesShading(c, vertices[i].Normal);
  1244. }
  1245. video::S3DVertexTangents vert(vertices[i].Pos + pos,
  1246. vertices[i].Normal, c, vertices[i].TCoords);
  1247. p->tangent_vertices.push_back(vert);
  1248. }
  1249. } else {
  1250. vertex_count = p->vertices.size();
  1251. for (u32 i = 0; i < numVertices; i++) {
  1252. if (!light_source) {
  1253. c = original_c;
  1254. applyFacesShading(c, vertices[i].Normal);
  1255. }
  1256. video::S3DVertex vert(vertices[i].Pos + pos, vertices[i].Normal, c,
  1257. vertices[i].TCoords);
  1258. p->vertices.push_back(vert);
  1259. }
  1260. }
  1261. for (u32 i = 0; i < numIndices; i++) {
  1262. u32 j = indices[i] + vertex_count;
  1263. p->indices.push_back(j);
  1264. }
  1265. }
  1266. void MeshCollector::applyTileColors()
  1267. {
  1268. if (m_use_tangent_vertices)
  1269. for (auto &prebuffer : prebuffers) {
  1270. for (PreMeshBuffer &pmb : prebuffer) {
  1271. video::SColor tc = pmb.layer.color;
  1272. if (tc == video::SColor(0xFFFFFFFF))
  1273. continue;
  1274. for (video::S3DVertexTangents &tangent_vertex : pmb.tangent_vertices) {
  1275. video::SColor *c = &tangent_vertex.Color;
  1276. c->set(c->getAlpha(), c->getRed() * tc.getRed() / 255,
  1277. c->getGreen() * tc.getGreen() / 255,
  1278. c->getBlue() * tc.getBlue() / 255);
  1279. }
  1280. }
  1281. }
  1282. else
  1283. for (auto &prebuffer : prebuffers) {
  1284. for (PreMeshBuffer &pmb : prebuffer) {
  1285. video::SColor tc = pmb.layer.color;
  1286. if (tc == video::SColor(0xFFFFFFFF))
  1287. continue;
  1288. for (video::S3DVertex &vertex : pmb.vertices) {
  1289. video::SColor *c = &vertex.Color;
  1290. c->set(c->getAlpha(), c->getRed() * tc.getRed() / 255,
  1291. c->getGreen() * tc.getGreen() / 255,
  1292. c->getBlue() * tc.getBlue() / 255);
  1293. }
  1294. }
  1295. }
  1296. }
  1297. video::SColor encode_light(u16 light, u8 emissive_light)
  1298. {
  1299. // Get components
  1300. u32 day = (light & 0xff);
  1301. u32 night = (light >> 8);
  1302. // Add emissive light
  1303. night += emissive_light * 2.5f;
  1304. if (night > 255)
  1305. night = 255;
  1306. // Since we don't know if the day light is sunlight or
  1307. // artificial light, assume it is artificial when the night
  1308. // light bank is also lit.
  1309. if (day < night)
  1310. day = 0;
  1311. else
  1312. day = day - night;
  1313. u32 sum = day + night;
  1314. // Ratio of sunlight:
  1315. u32 r;
  1316. if (sum > 0)
  1317. r = day * 255 / sum;
  1318. else
  1319. r = 0;
  1320. // Average light:
  1321. float b = (day + night) / 2;
  1322. return video::SColor(r, b, b, b);
  1323. }