@@ -73,33 +73,49 @@ MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector
73
73
blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE;
74
74
}
75
75
76
- void MapblockMeshGenerator::useTile (int index, bool disable_backface_culling )
76
+ void MapblockMeshGenerator::useTile (int index, u8 set_flags, u8 reset_flags, bool special )
77
77
{
78
- getNodeTileN (n, p, index , data, tile);
78
+ if (special)
79
+ getSpecialTile (index , &tile, p == data->m_crack_pos_relative );
80
+ else
81
+ getNodeTileN (n, p, index , data, tile);
79
82
if (!data->m_smooth_lighting )
80
83
color = encode_light (light, f->light_source );
81
84
for (int layer = 0 ; layer < MAX_TILE_LAYERS; layer++) {
82
- tile.layers [layer].material_flags |= MATERIAL_FLAG_CRACK_OVERLAY;
83
- if (disable_backface_culling)
84
- tile.layers [layer].material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
85
+ tile.layers [layer].material_flags |= set_flags;
86
+ tile.layers [layer].material_flags &= ~reset_flags;
85
87
}
86
88
}
87
89
88
- void MapblockMeshGenerator::useDefaultTile ( bool set_color )
90
+ void MapblockMeshGenerator::getTile (v3s16 direction, TileSpec *tile )
89
91
{
90
- getNodeTile (n, p, v3s16 (0 , 0 , 0 ), data, tile);
91
- if (set_color && !data->m_smooth_lighting )
92
- color = encode_light (light, f->light_source );
92
+ getNodeTile (n, p, direction, data, *tile);
93
93
}
94
94
95
- void MapblockMeshGenerator::getTile (const v3s16& direction, TileSpec &tile)
95
+ /* !
96
+ * Returns the i-th special tile for a map node.
97
+ */
98
+ void MapblockMeshGenerator::getSpecialTile (int index, TileSpec *tile, bool apply_crack)
96
99
{
97
- getNodeTile (n, p, direction, data, tile);
100
+ *tile = f->special_tiles [index ];
101
+ TileLayer *top_layer = NULL ;
102
+ for (int layernum = 0 ; layernum < MAX_TILE_LAYERS; layernum++) {
103
+ TileLayer *layer = &tile->layers [layernum];
104
+ if (layer->texture_id == 0 )
105
+ continue ;
106
+ top_layer = layer;
107
+ if (!layer->has_color )
108
+ n.getColor (*f, &layer->color );
109
+ }
110
+ if (apply_crack)
111
+ top_layer->material_flags |= MATERIAL_FLAG_CRACK;
98
112
}
99
113
100
- void MapblockMeshGenerator::drawQuad (v3f *coords, const v3s16 &normal )
114
+ void MapblockMeshGenerator::drawQuad (v3f *coords, const v3s16 &normal ,
115
+ float vertical_tiling)
101
116
{
102
- static const v2f tcoords[4 ] = {v2f (0 , 0 ), v2f (1 , 0 ), v2f (1 , 1 ), v2f (0 , 1 )};
117
+ const v2f tcoords[4 ] = {v2f (0.0 , 0.0 ), v2f (1.0 , 0.0 ),
118
+ v2f (1.0 , vertical_tiling), v2f (0.0 , vertical_tiling)};
103
119
video::S3DVertex vertices[4 ];
104
120
bool shade_face = !f->light_source && (normal != v3s16 (0 , 0 , 0 ));
105
121
v3f normal2 (normal .X , normal .Y , normal .Z );
@@ -358,27 +374,10 @@ void MapblockMeshGenerator::drawAutoLightedCuboid(aabb3f box, const f32 *txc,
358
374
}
359
375
}
360
376
361
- /* !
362
- * Returns the i-th special tile for a map node.
363
- */
364
- static TileSpec getSpecialTile (const ContentFeatures &f,
365
- const MapNode &n, u8 i)
366
- {
367
- TileSpec copy = f.special_tiles [i];
368
- for (int layernum = 0 ; layernum < MAX_TILE_LAYERS; layernum++) {
369
- TileLayer *layer = ©.layers [layernum];
370
- if (layer->texture_id == 0 )
371
- continue ;
372
- if (!layer->has_color )
373
- n.getColor (f, &(layer->color ));
374
- }
375
- return copy;
376
- }
377
-
378
377
void MapblockMeshGenerator::prepareLiquidNodeDrawing ()
379
378
{
380
- tile_liquid_top = getSpecialTile (*f, n, 0 );
381
- tile_liquid = getSpecialTile (*f, n, 1 );
379
+ getSpecialTile (0 , &tile_liquid_top );
380
+ getSpecialTile (1 , &tile_liquid );
382
381
383
382
MapNode ntop = data->m_vmanip .getNodeNoEx (blockpos_nodes + v3s16 (p.X , p.Y + 1 , p.Z ));
384
383
c_flowing = nodedef->getId (f->liquid_alternative_flowing );
@@ -603,7 +602,7 @@ void MapblockMeshGenerator::drawLiquidNode()
603
602
604
603
void MapblockMeshGenerator::drawGlasslikeNode ()
605
604
{
606
- useDefaultTile ( );
605
+ useTile ( 0 , 0 , 0 );
607
606
608
607
for (int face = 0 ; face < 6 ; face++) {
609
608
// Check this neighbor
@@ -638,7 +637,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode()
638
637
{
639
638
TileSpec tiles[6 ];
640
639
for (int face = 0 ; face < 6 ; face++)
641
- getTile (g_6dirs[face], tiles[face]);
640
+ getTile (g_6dirs[face], & tiles[face]);
642
641
643
642
TileSpec glass_tiles[6 ];
644
643
if (tiles[1 ].layers [0 ].texture &&
@@ -751,7 +750,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode()
751
750
// Internal liquid level has param2 range 0 .. 63,
752
751
// convert it to -0.5 .. 0.5
753
752
float vlev = (param2 / 63.0 ) * 2.0 - 1.0 ;
754
- tile = getSpecialTile (*f, n, 0 );
753
+ getSpecialTile (0 , &tile );
755
754
drawAutoLightedCuboid (aabb3f (-(nb[5 ] ? g : b),
756
755
-(nb[4 ] ? g : b),
757
756
-(nb[3 ] ? g : b),
@@ -764,7 +763,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode()
764
763
void MapblockMeshGenerator::drawAllfacesNode ()
765
764
{
766
765
static const aabb3f box (-BS / 2 , -BS / 2 , -BS / 2 , BS / 2 , BS / 2 , BS / 2 );
767
- useDefaultTile ( false );
766
+ useTile ( 0 , 0 , 0 );
768
767
drawAutoLightedCuboid (box);
769
768
}
770
769
@@ -777,7 +776,7 @@ void MapblockMeshGenerator::drawTorchlikeNode()
777
776
case DWM_YN: tileindex = 0 ; break ; // floor
778
777
default : tileindex = 2 ; // side (or invalid—should we care?)
779
778
}
780
- useTile (tileindex, true );
779
+ useTile (tileindex, MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING );
781
780
782
781
float size = BS / 2 * f->visual_scale ;
783
782
v3f vertices[4 ] = {
@@ -802,7 +801,7 @@ void MapblockMeshGenerator::drawTorchlikeNode()
802
801
void MapblockMeshGenerator::drawSignlikeNode ()
803
802
{
804
803
u8 wall = n.getWallMounted (nodedef);
805
- useTile (0 , true );
804
+ useTile (0 , MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING );
806
805
static const float offset = BS / 16 ;
807
806
float size = BS / 2 * f->visual_scale ;
808
807
// Wall at X+ of node
@@ -829,8 +828,8 @@ void MapblockMeshGenerator::drawPlantlikeQuad(float rotation, float quad_offset,
829
828
bool offset_top_only)
830
829
{
831
830
v3f vertices[4 ] = {
832
- v3f (-scale, -BS / 2 + scale * 2 , 0 ),
833
- v3f ( scale, -BS / 2 + scale * 2 , 0 ),
831
+ v3f (-scale, -BS / 2 + 2.0 * scale * plant_height , 0 ),
832
+ v3f ( scale, -BS / 2 + 2.0 * scale * plant_height , 0 ),
834
833
v3f ( scale, -BS / 2 , 0 ),
835
834
v3f (-scale, -BS / 2 , 0 ),
836
835
};
@@ -845,18 +844,18 @@ void MapblockMeshGenerator::drawPlantlikeQuad(float rotation, float quad_offset,
845
844
vertices[i].rotateXZBy (rotation + rotate_degree);
846
845
vertices[i] += offset;
847
846
}
848
- drawQuad (vertices);
847
+ drawQuad (vertices, v3s16 ( 0 , 0 , 0 ), plant_height );
849
848
}
850
849
851
- void MapblockMeshGenerator::drawPlantlikeNode ()
850
+ void MapblockMeshGenerator::drawPlantlike ()
852
851
{
853
- useTile (0 , false );
854
852
draw_style = PLANT_STYLE_CROSS;
855
853
scale = BS / 2 * f->visual_scale ;
856
854
offset = v3f (0 , 0 , 0 );
857
855
rotate_degree = 0 ;
858
856
random_offset_Y = false ;
859
857
face_num = 0 ;
858
+ plant_height = 1.0 ;
860
859
861
860
switch (f->param_type_2 ) {
862
861
case CPT2_MESHOPTIONS:
@@ -876,6 +875,10 @@ void MapblockMeshGenerator::drawPlantlikeNode()
876
875
rotate_degree = n.param2 * 2 ;
877
876
break ;
878
877
878
+ case CPT2_LEVELED:
879
+ plant_height = n.param2 / 16.0 ;
880
+ break ;
881
+
879
882
default :
880
883
break ;
881
884
}
@@ -913,6 +916,27 @@ void MapblockMeshGenerator::drawPlantlikeNode()
913
916
}
914
917
}
915
918
919
+ void MapblockMeshGenerator::drawPlantlikeNode ()
920
+ {
921
+ useTile ();
922
+ drawPlantlike ();
923
+ }
924
+
925
+ void MapblockMeshGenerator::drawPlantlikeRootedNode ()
926
+ {
927
+ useTile (0 , MATERIAL_FLAG_CRACK_OVERLAY, 0 , true );
928
+ origin += v3f (0.0 , BS, 0.0 );
929
+ p.Y ++;
930
+ if (data->m_smooth_lighting ) {
931
+ getSmoothLightFrame ();
932
+ } else {
933
+ MapNode ntop = data->m_vmanip .getNodeNoEx (blockpos_nodes + p);
934
+ light = getInteriorLight (ntop, 1 , nodedef);
935
+ }
936
+ drawPlantlike ();
937
+ p.Y --;
938
+ }
939
+
916
940
void MapblockMeshGenerator::drawFirelikeQuad (float rotation, float opening_angle,
917
941
float offset_h, float offset_v)
918
942
{
@@ -933,7 +957,7 @@ void MapblockMeshGenerator::drawFirelikeQuad(float rotation, float opening_angle
933
957
934
958
void MapblockMeshGenerator::drawFirelikeNode ()
935
959
{
936
- useTile (0 , false );
960
+ useTile ();
937
961
scale = BS / 2 * f->visual_scale ;
938
962
939
963
// Check for adjacent nodes
@@ -980,7 +1004,7 @@ void MapblockMeshGenerator::drawFirelikeNode()
980
1004
981
1005
void MapblockMeshGenerator::drawFencelikeNode ()
982
1006
{
983
- useDefaultTile ( false );
1007
+ useTile ( 0 , 0 , 0 );
984
1008
TileSpec tile_nocrack = tile;
985
1009
for (int layer = 0 ; layer < MAX_TILE_LAYERS; layer++)
986
1010
tile_nocrack.layers [layer].material_flags &= ~MATERIAL_FLAG_CRACK;
@@ -1130,7 +1154,7 @@ void MapblockMeshGenerator::drawRaillikeNode()
1130
1154
angle = rail_kinds[code].angle ;
1131
1155
}
1132
1156
1133
- useTile (tile_index, true );
1157
+ useTile (tile_index, MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING );
1134
1158
1135
1159
static const float offset = BS / 64 ;
1136
1160
static const float size = BS / 2 ;
@@ -1171,7 +1195,7 @@ void MapblockMeshGenerator::drawNodeboxNode()
1171
1195
TileSpec tiles[6 ];
1172
1196
for (int face = 0 ; face < 6 ; face++) {
1173
1197
// Handles facedir rotation for textures
1174
- getTile (tile_dirs[face], tiles[face]);
1198
+ getTile (tile_dirs[face], & tiles[face]);
1175
1199
}
1176
1200
1177
1201
// locate possible neighboring nodes to connect to
@@ -1228,7 +1252,7 @@ void MapblockMeshGenerator::drawMeshNode()
1228
1252
1229
1253
int mesh_buffer_count = mesh->getMeshBufferCount ();
1230
1254
for (int j = 0 ; j < mesh_buffer_count; j++) {
1231
- useTile (j, false );
1255
+ useTile (j);
1232
1256
scene::IMeshBuffer *buf = mesh->getMeshBuffer (j);
1233
1257
video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices ();
1234
1258
int vertex_count = buf->getVertexCount ();
@@ -1269,13 +1293,17 @@ void MapblockMeshGenerator::drawNode()
1269
1293
else
1270
1294
light = getInteriorLight (n, 1 , nodedef);
1271
1295
switch (f->drawtype ) {
1296
+ case NDT_NORMAL: break ; // Drawn by MapBlockMesh
1297
+ case NDT_AIRLIKE: break ; // Not drawn at all
1298
+ case NDT_LIQUID: break ; // Drawn by MapBlockMesh
1272
1299
case NDT_FLOWINGLIQUID: drawLiquidNode (); break ;
1273
1300
case NDT_GLASSLIKE: drawGlasslikeNode (); break ;
1274
1301
case NDT_GLASSLIKE_FRAMED: drawGlasslikeFramedNode (); break ;
1275
1302
case NDT_ALLFACES: drawAllfacesNode (); break ;
1276
1303
case NDT_TORCHLIKE: drawTorchlikeNode (); break ;
1277
1304
case NDT_SIGNLIKE: drawSignlikeNode (); break ;
1278
1305
case NDT_PLANTLIKE: drawPlantlikeNode (); break ;
1306
+ case NDT_PLANTLIKE_ROOTED: drawPlantlikeRootedNode (); break ;
1279
1307
case NDT_FIRELIKE: drawFirelikeNode (); break ;
1280
1308
case NDT_FENCELIKE: drawFencelikeNode (); break ;
1281
1309
case NDT_RAILLIKE: drawRaillikeNode (); break ;
@@ -1296,11 +1324,6 @@ void MapblockMeshGenerator::generate()
1296
1324
for (p.X = 0 ; p.X < MAP_BLOCKSIZE; p.X ++) {
1297
1325
n = data->m_vmanip .getNodeNoEx (blockpos_nodes + p);
1298
1326
f = &nodedef->get (n);
1299
- // Solid nodes are drawn by MapBlockMesh
1300
- if (f->solidness != 0 )
1301
- continue ;
1302
- if (f->drawtype == NDT_AIRLIKE)
1303
- continue ;
1304
1327
origin = intToFloat (p, BS);
1305
1328
drawNode ();
1306
1329
}
0 commit comments