aboutsummaryrefslogtreecommitdiff
path: root/build/android/icons/aux_btn.svg
blob: 6bbefff678ba713b2d02156de99d586f6973bf19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="512"
   height="512"
   viewBox="0 0 135.46666 135.46667"
   version="1.1"
   id="svg8"
   inkscape:version="0.92.1 r15371"
   sodipodi:docname="aux_btn.svg"
   inkscape:export-filename="/home/stu/Desktop/icons/png/aux_btn.png"
   inkscape:export-xdpi="24.000002"
   inkscape:export-ydpi="24.000002">
  <defs
     id="defs2">
    <filter
       style="color-interpolation-filters:sRGB;"
       inkscape:label="Colorize"
       id="filter4628">
      <feComposite
         in2="SourceGraphic"
         operator="arithmetic"
         k1="0"
         k2="1"
         result="composite1"
         id="feComposite4614" />
      <feColorMatrix
         in="composite1"
         values="1"
         type="saturate"
         result="colormatrix1"
         id="feColorMatrix4616" />
      <feFlood
         flood-opacity="1"
         flood-color="rgb(158,0,0)"
         result="flood1"
         id="feFlood4618" />
      <feBlend
         in="flood1"
         in2="colormatrix1"
         mode="multiply"
         result="blend1"
         id="feBlend4620" />
      <feBlend
         in2="blend1"
         mode="screen"
         result="blend2"
         id="feBlend4622" />
      <feColorMatrix
         in="blend2"
         values="1"
         type="saturate"
         result="colormatrix2"
         id="feColorMatrix4624" />
      <feComposite
         in="colormatrix2"
         in2="SourceGraphic"
         operator="in"
         k2="1"
         result="composite2"
         id="feComposite4626" />
    </filter>
    <filter
       style="color-interpolation-filters:sRGB;"
       inkscape:label="Sharpen More"
       id="filter5109"
       inkscape:menu="Image Effects"
       inkscape:menu-tooltip="Sharpen edges and boundaries within the object, force=0.3">
      <feComposite
         in2="SourceGraphic"
         operator="arithmetic"
         k1="0"
         k2="1"
         result="composite1"
         id="feComposite5095" />
      <feColorMatrix
         in="composite1"
         values="1"
         type="saturate"
         result="colormatrix1"
         id="feColorMatrix5097" />
      <feFlood
         flood-opacity="1"
         flood-color="rgb(158,67,0)"
         result="flood1"
         id="feFlood5099" />
      <feBlend
         in="flood1"
         in2="colormatrix1"
         mode="multiply"
         result="blend1"
         id="feBlend5101" />
      <feBlend
         in2="blend1"
         mode="screen"
         result="blend2"
         id="feBlend5103" />
      <feColorMatrix
         in="blend2"
         values="1"
         type="saturate"
         result="colormatrix2"
         id="feColorMatrix5105" />
      <feComposite
         in="colormatrix2"
         in2="SourceGraphic"
         operator="in"
         k2="1"
         result="fbSourceGraphic"
         id="feComposite5107" />
      <feColorMatrix
         result="fbSourceGraphicAlpha"
         in="fbSourceGraphic"
         values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
         id="feColorMatrix5111" />
      <feComposite
         in2="fbSourceGraphic"
         id="feComposite5113"
         operator="arithmetic"
         k1="0"
         k2="1"
         result="composite1"
         in="fbSourceGraphic" />
      <feColorMatrix
         id="feColorMatrix5115"
         in="composite1"
         values="1"
         type="saturate"
         result="colormatrix1" />
      <feFlood
         id="feFlood5117"
         flood-opacity="1"
         flood-color="rgb(158,0,0)"
         result="flood1" />
      <feBlend
         in2="colormatrix1"
         id="feBlend5119"
         in="flood1"
         mode="multiply"
         result="blend1" />
      <feBlend
         in2="blend1"
         id="feBlend5121"
         mode="screen"
         result="blend2" />
      <feColorMatrix
         id="feColorMatrix5123"
         in="blend2"
         values="1"
         type="saturate"
         result="colormatrix2" />
      <feComposite
         in2="fbSourceGraphic"
         id="feComposite5125"
         in="colormatrix2"
         operator="in"
         k2="1"
         result="fbSourceGraphic" />
      <feColorMatrix
         result="fbSourceGraphicAlpha"
         in="fbSourceGraphic"
         values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
         id="feColorMatrix7007" />
      <feConvolveMatrix
         id="feConvolveMatrix7009"
         order="3 3"
         kernelMatrix="0 -0.15 0 -0.15 1.6 -0.15 0 -0.15 0"
         divisor="1"
         in="fbSourceGraphic"
         targetX="1"
         targetY="1"
         result="fbSourceGraphic" />
      <feColorMatrix
         result="fbSourceGraphicAlpha"
         in="fbSourceGraphic"
         values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
         id="feColorMatrix7011" />
      <feConvolveMatrix
         id="feConvolveMatrix7013"
         targetY="1"
         targetX="1"
         in="fbSourceGraphic"
         divisor="1"
         kernelMatrix="0 -0.3 0 -0.3 2.2 -0.3 0 -0.3 0"
         order="3 3"
         result="result1" />
      <feBlend
         in2="fbSourceGraphic"
         id="feBlend7015"
         mode="normal"
         result="result2" />
    </filter>
    <marker
       style="overflow:visible"
       refY="0.0"
       refX="0.0"
       orient="auto"
       id="DistanceX">
      <path
         id="path7410"
         style="stroke:#000000; stroke-width:0.5"
         d="M 3,-3 L -3,3 M 0,-5 L  0,5" />
    </marker>
    <pattern
       y="0"
       x="0"
       width="8"
       patternUnits="userSpaceOnUse"
       id="Hatch"
       height="8">
      <path
         id="path7413"
         stroke-width="0.25"
         stroke="#000000"
         linecap="square"
         d="M8 4 l-4,4" />
      <path
         id="path7415"
         stroke-width="0.25"
         stroke="#000000"
         linecap="square"
         d="M6 2 l-4,4" />
      <path
         id="path7417"
         stroke-width="0.25"
         stroke="#000000"
         linecap="square"
         d="M4 0 l-4,4" />
    </pattern>
    <symbol
       id="*Model_Space" />
    <symbol
       id="*Paper_Space" />
    <symbol
       id="*Paper_Space0" />
    <filter
       style="color-interpolation-filters:sRGB;"
       inkscape:label="Colorize"
       id="filter4883">
      <feComposite
         in2="SourceGraphic"
         operator="arithmetic"
         k1="0"
         k2="1"
         result="composite1"
         id="feComposite4869" />
      <feColorMatrix
         in="composite1"
         values="1"
         type="saturate"
         result="colormatrix1"
         id="feColorMatrix4871" />
      <feFlood
         flood-opacity="1"
         flood-color="rgb(158,21,0)"
         result="flood1"
         id="feFlood4873" />
      <feBlend
         in="flood1"
         in2="colormatrix1"
         mode="multiply"
         result="blend1"
         id="feBlend4875" />
      <feBlend
         in2="blend1"
         mode="screen"
         result="blend2"
         id="feBlend4877" />
      <feColorMatrix
         in="blend2"
         values="1"
         type="saturate"
         result="colormatrix2"
         id="feColorMatrix4879" />
      <feComposite
         in="colormatrix2"
         in2="SourceGraphic"
         operator="in"
         k2="1"
         result="composite2"
         id="feComposite4881" />
    </filter>
  </defs>
  <sodipodi:namedview
     id="base"
     pagecolor="#404040"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:zoom="0.98994949"
     inkscape:cx="-341.34157"
     inkscape:cy="210.02973"
     inkscape:document-units="mm"
     inkscape:current-layer="layer2"
     showgrid="true"
     units="px"
     inkscape:window-width="1920"
     inkscape:window-height="1023"
     inkscape:window-x="0"
     inkscape:window-y="34"
     inkscape:window-maximized="1"
     inkscape:pagecheckerboard="false"
     inkscape:snap-grids="false"
     inkscape:snap-page="true"
     showguides="true"
     inkscape:snap-bbox="true"
     inkscape:snap-to-guides="true"
     inkscape:snap-object-midpoints="false"
     inkscape:snap-others="true"
     inkscape:snap-bbox-midpoints="true">
    <inkscape:grid
       type="xygrid"
       id="grid16"
       spacingx="0.26458333"
       spacingy="0.26458333"
       empspacing="4"
       color="#40ff40"
       opacity="0.1254902"
       empcolor="#40ff40"
       empopacity="0.25098039" />
  </sodipodi:namedview>
  <metadata
     id="metadata5">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
        <cc:license
           rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
      </cc:Work>
      <cc:License
         rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
        <cc:permits
           rdf:resource="http://creativecommons.org/ns#Reproduction" />
        <cc:permits
           rdf:resource="http://creativecommons.org/ns#Distribution" />
        <cc:requires
           rdf:resource="http://creativecommons.org/ns#Notice" />
        <cc:requires
           rdf:resource="http://creativecommons.org/ns#Attribution" />
        <cc:permits
           rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
        <cc:requires
           rdf:resource="http://creativecommons.org/ns#ShareAlike" />
      </cc:License>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:groupmode="layer"
     id="layer2"
     inkscape:label="Layer 2"
     style="display:inline">
    <path
       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       d=""
       id="path7055"
       inkscape:connector-curvature="0" />
    <path
       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       d=""
       id="path7035"
       inkscape:connector-curvature="0" />
    <path
       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       d=""
       id="path7005"
       inkscape:connector-curvature="0" />
    <path
       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       d=""
       id="path5127"
       inkscape:connector-curvature="0" />
    <text
       xml:space="preserve"
       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:48.47851181px;line-height:1.25;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#d9d9d9;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       x="67.78315"
       y="85.59491"
       id="text4716"
       transform="scale(1.0078883,0.99217343)"><tspan
         sodipodi:role="line"
         id="tspan4714"
         x="67.78315"
         y="85.59491"
         style="fill:#d9d9d9;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">AUX</tspan></text>
    <flowRoot
       xml:space="preserve"
       id="flowRoot4718"
       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"
       transform="scale(0.26458333)"><flowRegion
         id="flowRegion4720"
         style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><rect
           id="rect4722"
           width="157.5838"
           height="136.37059"
           x="264.65997"
           y="124.10143"
           style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" /></flowRegion><flowPara
         id="flowPara4724" /></flowRoot>  </g>
</svg>
ot; #include "client.h" #include "noise.h" // Distance of light extrapolation (for oversized nodes) // After this distance, it gives up and considers light level constant #define SMOOTH_LIGHTING_OVERSIZE 1.0 // Node edge count (for glasslike-framed) #define FRAMED_EDGE_COUNT 12 // Node neighbor count, including edge-connected, but not vertex-connected // (for glasslike-framed) // Corresponding offsets are listed in g_27dirs #define FRAMED_NEIGHBOR_COUNT 18 static const v3s16 light_dirs[8] = { v3s16(-1, -1, -1), v3s16(-1, -1, 1), v3s16(-1, 1, -1), v3s16(-1, 1, 1), v3s16( 1, -1, -1), v3s16( 1, -1, 1), v3s16( 1, 1, -1), v3s16( 1, 1, 1), }; // Standard index set to make a quad on 4 vertices static constexpr u16 quad_indices[] = {0, 1, 2, 2, 3, 0}; const std::string MapblockMeshGenerator::raillike_groupname = "connect_to_raillike"; MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output) { data = input; collector = output; nodedef = data->m_client->ndef(); meshmanip = RenderingEngine::get_scene_manager()->getMeshManipulator(); enable_mesh_cache = g_settings->getBool("enable_mesh_cache") && !data->m_smooth_lighting; // Mesh cache is not supported with smooth lighting blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE; } void MapblockMeshGenerator::useTile(int index, u8 set_flags, u8 reset_flags, bool special) { if (special) getSpecialTile(index, &tile, p == data->m_crack_pos_relative); else getTile(index, &tile); if (!data->m_smooth_lighting) color = encode_light(light, f->light_source); for (auto &layer : tile.layers) { layer.material_flags |= set_flags; layer.material_flags &= ~reset_flags; } } // Returns a tile, ready for use, non-rotated. void MapblockMeshGenerator::getTile(int index, TileSpec *tile) { getNodeTileN(n, p, index, data, *tile); } // Returns a tile, ready for use, rotated according to the node facedir. void MapblockMeshGenerator::getTile(v3s16 direction, TileSpec *tile) { getNodeTile(n, p, direction, data, *tile); } // Returns a special tile, ready for use, non-rotated. void MapblockMeshGenerator::getSpecialTile(int index, TileSpec *tile, bool apply_crack) { *tile = f->special_tiles[index]; TileLayer *top_layer = nullptr; for (auto &layernum : tile->layers) { TileLayer *layer = &layernum; if (layer->texture_id == 0) continue; top_layer = layer; if (!layer->has_color) n.getColor(*f, &layer->color); } if (apply_crack) top_layer->material_flags |= MATERIAL_FLAG_CRACK; } void MapblockMeshGenerator::drawQuad(v3f *coords, const v3s16 &normal, float vertical_tiling) { const v2f tcoords[4] = {v2f(0.0, 0.0), v2f(1.0, 0.0), v2f(1.0, vertical_tiling), v2f(0.0, vertical_tiling)}; video::S3DVertex vertices[4]; bool shade_face = !f->light_source && (normal != v3s16(0, 0, 0)); v3f normal2(normal.X, normal.Y, normal.Z); for (int j = 0; j < 4; j++) { vertices[j].Pos = coords[j] + origin; vertices[j].Normal = normal2; if (data->m_smooth_lighting) vertices[j].Color = blendLightColor(coords[j]); else vertices[j].Color = color; if (shade_face) applyFacesShading(vertices[j].Color, normal2); vertices[j].TCoords = tcoords[j]; } collector->append(tile, vertices, 4, quad_indices, 6); } // Create a cuboid. // tiles - the tiles (materials) to use (for all 6 faces) // tilecount - number of entries in tiles, 1<=tilecount<=6 // lights - vertex light levels. The order is the same as in light_dirs. // NULL may be passed if smooth lighting is disabled. // txc - texture coordinates - this is a list of texture coordinates // for the opposite corners of each face - therefore, there // should be (2+2)*6=24 values in the list. The order of // the faces in the list is up-down-right-left-back-front // (compatible with ContentFeatures). void MapblockMeshGenerator::drawCuboid(const aabb3f &box, TileSpec *tiles, int tilecount, const LightInfo *lights, const f32 *txc) { assert(tilecount >= 1 && tilecount <= 6); // pre-condition v3f min = box.MinEdge; v3f max = box.MaxEdge; video::SColor colors[6]; if (!data->m_smooth_lighting) { for (int face = 0; face != 6; ++face) { colors[face] = encode_light(light, f->light_source); } if (!f->light_source) { applyFacesShading(colors[0], v3f(0, 1, 0)); applyFacesShading(colors[1], v3f(0, -1, 0)); applyFacesShading(colors[2], v3f(1, 0, 0)); applyFacesShading(colors[3], v3f(-1, 0, 0)); applyFacesShading(colors[4], v3f(0, 0, 1)); applyFacesShading(colors[5], v3f(0, 0, -1)); } } video::S3DVertex vertices[24] = { // top video::S3DVertex(min.X, max.Y, max.Z, 0, 1, 0, colors[0], txc[0], txc[1]), video::S3DVertex(max.X, max.Y, max.Z, 0, 1, 0, colors[0], txc[2], txc[1]), video::S3DVertex(max.X, max.Y, min.Z, 0, 1, 0, colors[0], txc[2], txc[3]), video::S3DVertex(min.X, max.Y, min.Z, 0, 1, 0, colors[0], txc[0], txc[3]), // bottom video::S3DVertex(min.X, min.Y, min.Z, 0, -1, 0, colors[1], txc[4], txc[5]), video::S3DVertex(max.X, min.Y, min.Z, 0, -1, 0, colors[1], txc[6], txc[5]), video::S3DVertex(max.X, min.Y, max.Z, 0, -1, 0, colors[1], txc[6], txc[7]), video::S3DVertex(min.X, min.Y, max.Z, 0, -1, 0, colors[1], txc[4], txc[7]), // right video::S3DVertex(max.X, max.Y, min.Z, 1, 0, 0, colors[2], txc[ 8], txc[9]), video::S3DVertex(max.X, max.Y, max.Z, 1, 0, 0, colors[2], txc[10], txc[9]), video::S3DVertex(max.X, min.Y, max.Z, 1, 0, 0, colors[2], txc[10], txc[11]), video::S3DVertex(max.X, min.Y, min.Z, 1, 0, 0, colors[2], txc[ 8], txc[11]), // left video::S3DVertex(min.X, max.Y, max.Z, -1, 0, 0, colors[3], txc[12], txc[13]), video::S3DVertex(min.X, max.Y, min.Z, -1, 0, 0, colors[3], txc[14], txc[13]), video::S3DVertex(min.X, min.Y, min.Z, -1, 0, 0, colors[3], txc[14], txc[15]), video::S3DVertex(min.X, min.Y, max.Z, -1, 0, 0, colors[3], txc[12], txc[15]), // back video::S3DVertex(max.X, max.Y, max.Z, 0, 0, 1, colors[4], txc[16], txc[17]), video::S3DVertex(min.X, max.Y, max.Z, 0, 0, 1, colors[4], txc[18], txc[17]), video::S3DVertex(min.X, min.Y, max.Z, 0, 0, 1, colors[4], txc[18], txc[19]), video::S3DVertex(max.X, min.Y, max.Z, 0, 0, 1, colors[4], txc[16], txc[19]), // front video::S3DVertex(min.X, max.Y, min.Z, 0, 0, -1, colors[5], txc[20], txc[21]), video::S3DVertex(max.X, max.Y, min.Z, 0, 0, -1, colors[5], txc[22], txc[21]), video::S3DVertex(max.X, min.Y, min.Z, 0, 0, -1, colors[5], txc[22], txc[23]), video::S3DVertex(min.X, min.Y, min.Z, 0, 0, -1, colors[5], txc[20], txc[23]), }; static const u8 light_indices[24] = { 3, 7, 6, 2, 0, 4, 5, 1, 6, 7, 5, 4, 3, 2, 0, 1, 7, 3, 1, 5, 2, 6, 4, 0 }; for (int face = 0; face < 6; face++) { int tileindex = MYMIN(face, tilecount - 1); const TileSpec &tile = tiles[tileindex]; for (int j = 0; j < 4; j++) { video::S3DVertex &vertex = vertices[face * 4 + j]; v2f &tcoords = vertex.TCoords; switch (tile.rotation) { case 0: break; case 1: // R90 tcoords.rotateBy(90, irr::core::vector2df(0, 0)); break; case 2: // R180 tcoords.rotateBy(180, irr::core::vector2df(0, 0)); break; case 3: // R270 tcoords.rotateBy(270, irr::core::vector2df(0, 0)); break; case 4: // FXR90 tcoords.X = 1.0 - tcoords.X; tcoords.rotateBy(90, irr::core::vector2df(0, 0)); break; case 5: // FXR270 tcoords.X = 1.0 - tcoords.X; tcoords.rotateBy(270, irr::core::vector2df(0, 0)); break; case 6: // FYR90 tcoords.Y = 1.0 - tcoords.Y; tcoords.rotateBy(90, irr::core::vector2df(0, 0)); break; case 7: // FYR270 tcoords.Y = 1.0 - tcoords.Y; tcoords.rotateBy(270, irr::core::vector2df(0, 0)); break; case 8: // FX tcoords.X = 1.0 - tcoords.X; break; case 9: // FY tcoords.Y = 1.0 - tcoords.Y; break; default: break; } } } if (data->m_smooth_lighting) { for (int j = 0; j < 24; ++j) { video::S3DVertex &vertex = vertices[j]; vertex.Color = encode_light( lights[light_indices[j]].getPair(MYMAX(0.0f, vertex.Normal.Y)), f->light_source); if (!f->light_source) applyFacesShading(vertex.Color, vertex.Normal); } } // Add to mesh collector for (int k = 0; k < 6; ++k) { int tileindex = MYMIN(k, tilecount - 1); collector->append(tiles[tileindex], vertices + 4 * k, 4, quad_indices, 6); } } // Gets the base lighting values for a node void MapblockMeshGenerator::getSmoothLightFrame() { for (int k = 0; k < 8; ++k) frame.sunlight[k] = false; for (int k = 0; k < 8; ++k) { LightPair light(getSmoothLightTransparent(blockpos_nodes + p, light_dirs[k], data)); frame.lightsDay[k] = light.lightDay; frame.lightsNight[k] = light.lightNight; // If there is direct sunlight and no ambient occlusion at some corner, // mark the vertical edge (top and bottom corners) containing it. if (light.lightDay == 255) { frame.sunlight[k] = true; frame.sunlight[k ^ 2] = true; } } } // Calculates vertex light level // vertex_pos - vertex position in the node (coordinates are clamped to [0.0, 1.0] or so) LightInfo MapblockMeshGenerator::blendLight(const v3f &vertex_pos) { // Light levels at (logical) node corners are known. Here, // trilinear interpolation is used to calculate light level // at a given point in the node. f32 x = core::clamp(vertex_pos.X / BS + 0.5, 0.0 - SMOOTH_LIGHTING_OVERSIZE, 1.0 + SMOOTH_LIGHTING_OVERSIZE); f32 y = core::clamp(vertex_pos.Y / BS + 0.5, 0.0 - SMOOTH_LIGHTING_OVERSIZE, 1.0 + SMOOTH_LIGHTING_OVERSIZE); f32 z = core::clamp(vertex_pos.Z / BS + 0.5, 0.0 - SMOOTH_LIGHTING_OVERSIZE, 1.0 + SMOOTH_LIGHTING_OVERSIZE); f32 lightDay = 0.0; // daylight f32 lightNight = 0.0; f32 lightBoosted = 0.0; // daylight + direct sunlight, if any for (int k = 0; k < 8; ++k) { f32 dx = (k & 4) ? x : 1 - x; f32 dy = (k & 2) ? y : 1 - y; f32 dz = (k & 1) ? z : 1 - z; // Use direct sunlight (255), if any; use daylight otherwise. f32 light_boosted = frame.sunlight[k] ? 255 : frame.lightsDay[k]; lightDay += dx * dy * dz * frame.lightsDay[k]; lightNight += dx * dy * dz * frame.lightsNight[k]; lightBoosted += dx * dy * dz * light_boosted; } return LightInfo{lightDay, lightNight, lightBoosted}; } // Calculates vertex color to be used in mapblock mesh // vertex_pos - vertex position in the node (coordinates are clamped to [0.0, 1.0] or so) // tile_color - node's tile color video::SColor MapblockMeshGenerator::blendLightColor(const v3f &vertex_pos) { LightInfo light = blendLight(vertex_pos); return encode_light(light.getPair(), f->light_source); } video::SColor MapblockMeshGenerator::blendLightColor(const v3f &vertex_pos, const v3f &vertex_normal) { LightInfo light = blendLight(vertex_pos); video::SColor color = encode_light(light.getPair(MYMAX(0.0f, vertex_normal.Y)), f->light_source); if (!f->light_source) applyFacesShading(color, vertex_normal); return color; } void MapblockMeshGenerator::generateCuboidTextureCoords(const aabb3f &box, f32 *coords) { f32 tx1 = (box.MinEdge.X / BS) + 0.5; f32 ty1 = (box.MinEdge.Y / BS) + 0.5; f32 tz1 = (box.MinEdge.Z / BS) + 0.5; f32 tx2 = (box.MaxEdge.X / BS) + 0.5; f32 ty2 = (box.MaxEdge.Y / BS) + 0.5; f32 tz2 = (box.MaxEdge.Z / BS) + 0.5; f32 txc[24] = { tx1, 1 - tz2, tx2, 1 - tz1, // up tx1, tz1, tx2, tz2, // down tz1, 1 - ty2, tz2, 1 - ty1, // right 1 - tz2, 1 - ty2, 1 - tz1, 1 - ty1, // left 1 - tx2, 1 - ty2, 1 - tx1, 1 - ty1, // back tx1, 1 - ty2, tx2, 1 - ty1, // front }; for (int i = 0; i != 24; ++i) coords[i] = txc[i]; } void MapblockMeshGenerator::drawAutoLightedCuboid(aabb3f box, const f32 *txc, TileSpec *tiles, int tile_count) { bool scale = std::fabs(f->visual_scale - 1.0f) > 1e-3f; f32 texture_coord_buf[24]; f32 dx1 = box.MinEdge.X; f32 dy1 = box.MinEdge.Y; f32 dz1 = box.MinEdge.Z; f32 dx2 = box.MaxEdge.X; f32 dy2 = box.MaxEdge.Y; f32 dz2 = box.MaxEdge.Z; if (scale) { if (!txc) { // generate texture coords before scaling generateCuboidTextureCoords(box, texture_coord_buf); txc = texture_coord_buf; } box.MinEdge *= f->visual_scale; box.MaxEdge *= f->visual_scale; } box.MinEdge += origin; box.MaxEdge += origin; if (!txc) { generateCuboidTextureCoords(box, texture_coord_buf); txc = texture_coord_buf; } if (!tiles) { tiles = &tile; tile_count = 1; } if (data->m_smooth_lighting) { LightInfo lights[8]; for (int j = 0; j < 8; ++j) { v3f d; d.X = (j & 4) ? dx2 : dx1; d.Y = (j & 2) ? dy2 : dy1; d.Z = (j & 1) ? dz2 : dz1; lights[j] = blendLight(d); } drawCuboid(box, tiles, tile_count, lights, txc); } else { drawCuboid(box, tiles, tile_count, nullptr, txc); } } void MapblockMeshGenerator::prepareLiquidNodeDrawing() { getSpecialTile(0, &tile_liquid_top); getSpecialTile(1, &tile_liquid); MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(p.X, p.Y + 1, p.Z)); MapNode nbottom = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(p.X, p.Y - 1, p.Z)); c_flowing = f->liquid_alternative_flowing_id; c_source = f->liquid_alternative_source_id; top_is_same_liquid = (ntop.getContent() == c_flowing) || (ntop.getContent() == c_source); draw_liquid_bottom = (nbottom.getContent() != c_flowing) && (nbottom.getContent() != c_source); if (draw_liquid_bottom) { const ContentFeatures &f2 = nodedef->get(nbottom.getContent()); if (f2.solidness > 1) draw_liquid_bottom = false; } if (data->m_smooth_lighting) return; // don't need to pre-compute anything in this case if (f->light_source != 0) { // If this liquid emits light and doesn't contain light, draw // it at what it emits, for an increased effect u8 e = decode_light(f->light_source); light = LightPair(std::max(e, light.lightDay), std::max(e, light.lightNight)); } else if (nodedef->get(ntop).param_type == CPT_LIGHT) { // Otherwise, use the light of the node on top if possible light = LightPair(getInteriorLight(ntop, 0, nodedef)); } color_liquid_top = encode_light(light, f->light_source); color = encode_light(light, f->light_source); } void MapblockMeshGenerator::getLiquidNeighborhood() { u8 range = rangelim(nodedef->get(c_flowing).liquid_range, 1, 8); for (int w = -1; w <= 1; w++) for (int u = -1; u <= 1; u++) { NeighborData &neighbor = liquid_neighbors[w + 1][u + 1]; v3s16 p2 = p + v3s16(u, 0, w); MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); neighbor.content = n2.getContent(); neighbor.level = -0.5 * BS; neighbor.is_same_liquid = false; neighbor.top_is_same_liquid = false; if (neighbor.content == CONTENT_IGNORE) continue; if (neighbor.content == c_source) { neighbor.is_same_liquid = true; neighbor.level = 0.5 * BS; } else if (neighbor.content == c_flowing) { neighbor.is_same_liquid = true; u8 liquid_level = (n2.param2 & LIQUID_LEVEL_MASK); if (liquid_level <= LIQUID_LEVEL_MAX + 1 - range) liquid_level = 0; else liquid_level -= (LIQUID_LEVEL_MAX + 1 - range); neighbor.level = (-0.5 + (liquid_level + 0.5) / range) * BS; } // Check node above neighbor. // NOTE: This doesn't get executed if neighbor // doesn't exist p2.Y++; n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); if (n2.getContent() == c_source || n2.getContent() == c_flowing) neighbor.top_is_same_liquid = true; } } void MapblockMeshGenerator::calculateCornerLevels() { for (int k = 0; k < 2; k++) for (int i = 0; i < 2; i++) corner_levels[k][i] = getCornerLevel(i, k); } f32 MapblockMeshGenerator::getCornerLevel(int i, int k) { float sum = 0; int count = 0; int air_count = 0; for (int dk = 0; dk < 2; dk++) for (int di = 0; di < 2; di++) { NeighborData &neighbor_data = liquid_neighbors[k + dk][i + di]; content_t content = neighbor_data.content; // If top is liquid, draw starting from top of node if (neighbor_data.top_is_same_liquid) return 0.5 * BS; // Source always has the full height if (content == c_source) return 0.5 * BS; // Flowing liquid has level information if (content == c_flowing) { sum += neighbor_data.level; count++; } else if (content == CONTENT_AIR) { air_count++; if (air_count >= 2) return -0.5 * BS + 0.2; } } if (count > 0) return sum / count; return 0; } namespace { struct LiquidFaceDesc { v3s16 dir; // XZ v3s16 p[2]; // XZ only; 1 means +, 0 means - }; struct UV { int u, v; }; static const LiquidFaceDesc liquid_base_faces[4] = { {v3s16( 1, 0, 0), {v3s16(1, 0, 1), v3s16(1, 0, 0)}}, {v3s16(-1, 0, 0), {v3s16(0, 0, 0), v3s16(0, 0, 1)}}, {v3s16( 0, 0, 1), {v3s16(0, 0, 1), v3s16(1, 0, 1)}}, {v3s16( 0, 0, -1), {v3s16(1, 0, 0), v3s16(0, 0, 0)}}, }; static const UV liquid_base_vertices[4] = { {0, 1}, {1, 1}, {1, 0}, {0, 0} }; } void MapblockMeshGenerator::drawLiquidSides() { for (const auto &face : liquid_base_faces) { const NeighborData &neighbor = liquid_neighbors[face.dir.Z + 1][face.dir.X + 1]; // No face between nodes of the same liquid, unless there is node // at the top to which it should be connected. Again, unless the face // there would be inside the liquid if (neighbor.is_same_liquid) { if (!top_is_same_liquid) continue; if (neighbor.top_is_same_liquid) continue; } const ContentFeatures &neighbor_features = nodedef->get(neighbor.content); // Don't draw face if neighbor is blocking the view if (neighbor_features.solidness == 2) continue; video::S3DVertex vertices[4]; for (int j = 0; j < 4; j++) { const UV &vertex = liquid_base_vertices[j]; const v3s16 &base = face.p[vertex.u]; float v = vertex.v; v3f pos; pos.X = (base.X - 0.5f) * BS; pos.Z = (base.Z - 0.5f) * BS; if (vertex.v) { pos.Y = neighbor.is_same_liquid ? corner_levels[base.Z][base.X] : -0.5f * BS; } else if (top_is_same_liquid) { pos.Y = 0.5f * BS; } else { pos.Y = corner_levels[base.Z][base.X]; v += (0.5f * BS - corner_levels[base.Z][base.X]) / BS; } if (data->m_smooth_lighting) color = blendLightColor(pos); pos += origin; vertices[j] = video::S3DVertex(pos.X, pos.Y, pos.Z, 0, 0, 0, color, vertex.u, v); }; collector->append(tile_liquid, vertices, 4, quad_indices, 6); } } void MapblockMeshGenerator::drawLiquidTop() { // To get backface culling right, the vertices need to go // clockwise around the front of the face. And we happened to // calculate corner levels in exact reverse order. static const int corner_resolve[4][2] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}}; video::S3DVertex vertices[4] = { video::S3DVertex(-BS / 2, 0, BS / 2, 0, 0, 0, color_liquid_top, 0, 1), video::S3DVertex( BS / 2, 0, BS / 2, 0, 0, 0, color_liquid_top, 1, 1), video::S3DVertex( BS / 2, 0, -BS / 2, 0, 0, 0, color_liquid_top, 1, 0), video::S3DVertex(-BS / 2, 0, -BS / 2, 0, 0, 0, color_liquid_top, 0, 0), }; for (int i = 0; i < 4; i++) { int u = corner_resolve[i][0]; int w = corner_resolve[i][1]; vertices[i].Pos.Y += corner_levels[w][u]; if (data->m_smooth_lighting) vertices[i].Color = blendLightColor(vertices[i].Pos); vertices[i].Pos += origin; } // Default downwards-flowing texture animation goes from // -Z towards +Z, thus the direction is +Z. // Rotate texture to make animation go in flow direction // Positive if liquid moves towards +Z f32 dz = (corner_levels[0][0] + corner_levels[0][1]) - (corner_levels[1][0] + corner_levels[1][1]); // Positive if liquid moves towards +X f32 dx = (corner_levels[0][0] + corner_levels[1][0]) - (corner_levels[0][1] + corner_levels[1][1]); f32 tcoord_angle = atan2(dz, dx) * core::RADTODEG; v2f tcoord_center(0.5, 0.5); v2f tcoord_translate(blockpos_nodes.Z + p.Z, blockpos_nodes.X + p.X); tcoord_translate.rotateBy(tcoord_angle); tcoord_translate.X -= floor(tcoord_translate.X); tcoord_translate.Y -= floor(tcoord_translate.Y); for (video::S3DVertex &vertex : vertices) {