From ef285b2815962a7a01791059ed984cb12fdba4dd Mon Sep 17 00:00:00 2001 From: number Zero Date: Thu, 11 May 2017 23:24:12 +0300 Subject: [PATCH] Add 'plantlike_rooted' drawtype Useful for underwater plants. Node consists of a base cube plus a plantlike extension that can pass through liquid nodes above without creating air bubbles or interfering with liquid flow. Uses paramtype2 'leveled', param2 defines height of plantlike extension. --- doc/lua_api.txt | 1 + src/content_mapblock.cpp | 129 +++++++++++++++++++------------- src/content_mapblock.h | 13 +++- src/nodedef.cpp | 34 +++++---- src/nodedef.h | 2 + src/script/common/c_content.cpp | 1 + src/script/cpp_api/s_node.cpp | 1 + src/shader.cpp | 3 +- src/wieldmesh.cpp | 128 +++++++++++++++++++------------ 9 files changed, 192 insertions(+), 120 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 56f8dbaae..3fc815272 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -860,6 +860,7 @@ Look for examples in `games/minimal` or `games/minetest_game`. * `raillike` * `nodebox` -- See below. (**Experimental!**) * `mesh` -- use models for nodes +* `plantlike_rooted` `*_optional` drawtypes need less rendering time if deactivated (always client side). diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 1077c2382..8eedade6e 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -73,33 +73,49 @@ MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE; } -void MapblockMeshGenerator::useTile(int index, bool disable_backface_culling) +void MapblockMeshGenerator::useTile(int index, u8 set_flags, u8 reset_flags, bool special) { - getNodeTileN(n, p, index, data, tile); + if (special) + getSpecialTile(index, &tile, p == data->m_crack_pos_relative); + else + getNodeTileN(n, p, index, data, tile); if (!data->m_smooth_lighting) color = encode_light(light, f->light_source); for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) { - tile.layers[layer].material_flags |= MATERIAL_FLAG_CRACK_OVERLAY; - if (disable_backface_culling) - tile.layers[layer].material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING; + tile.layers[layer].material_flags |= set_flags; + tile.layers[layer].material_flags &= ~reset_flags; } } -void MapblockMeshGenerator::useDefaultTile(bool set_color) +void MapblockMeshGenerator::getTile(v3s16 direction, TileSpec *tile) { - getNodeTile(n, p, v3s16(0, 0, 0), data, tile); - if (set_color && !data->m_smooth_lighting) - color = encode_light(light, f->light_source); + getNodeTile(n, p, direction, data, *tile); } -void MapblockMeshGenerator::getTile(const v3s16& direction, TileSpec &tile) +/*! + * Returns the i-th special tile for a map node. + */ +void MapblockMeshGenerator::getSpecialTile(int index, TileSpec *tile, bool apply_crack) { - getNodeTile(n, p, direction, data, tile); + *tile = f->special_tiles[index]; + TileLayer *top_layer = NULL; + for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { + TileLayer *layer = &tile->layers[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) +void MapblockMeshGenerator::drawQuad(v3f *coords, const v3s16 &normal, + float vertical_tiling) { - static const v2f tcoords[4] = {v2f(0, 0), v2f(1, 0), v2f(1, 1), v2f(0, 1)}; + 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); @@ -358,27 +374,10 @@ void MapblockMeshGenerator::drawAutoLightedCuboid(aabb3f box, const f32 *txc, } } -/*! - * Returns the i-th special tile for a map node. - */ -static TileSpec getSpecialTile(const ContentFeatures &f, - const MapNode &n, u8 i) -{ - TileSpec copy = f.special_tiles[i]; - for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { - TileLayer *layer = ©.layers[layernum]; - if (layer->texture_id == 0) - continue; - if (!layer->has_color) - n.getColor(f, &(layer->color)); - } - return copy; -} - void MapblockMeshGenerator::prepareLiquidNodeDrawing() { - tile_liquid_top = getSpecialTile(*f, n, 0); - tile_liquid = getSpecialTile(*f, n, 1); + 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)); c_flowing = nodedef->getId(f->liquid_alternative_flowing); @@ -603,7 +602,7 @@ void MapblockMeshGenerator::drawLiquidNode() void MapblockMeshGenerator::drawGlasslikeNode() { - useDefaultTile(); + useTile(0, 0, 0); for (int face = 0; face < 6; face++) { // Check this neighbor @@ -638,7 +637,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode() { TileSpec tiles[6]; for (int face = 0; face < 6; face++) - getTile(g_6dirs[face], tiles[face]); + getTile(g_6dirs[face], &tiles[face]); TileSpec glass_tiles[6]; if (tiles[1].layers[0].texture && @@ -751,7 +750,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode() // Internal liquid level has param2 range 0 .. 63, // convert it to -0.5 .. 0.5 float vlev = (param2 / 63.0) * 2.0 - 1.0; - tile = getSpecialTile(*f, n, 0); + getSpecialTile(0, &tile); drawAutoLightedCuboid(aabb3f(-(nb[5] ? g : b), -(nb[4] ? g : b), -(nb[3] ? g : b), @@ -764,7 +763,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode() void MapblockMeshGenerator::drawAllfacesNode() { static const aabb3f box(-BS / 2, -BS / 2, -BS / 2, BS / 2, BS / 2, BS / 2); - useDefaultTile(false); + useTile(0, 0, 0); drawAutoLightedCuboid(box); } @@ -777,7 +776,7 @@ void MapblockMeshGenerator::drawTorchlikeNode() case DWM_YN: tileindex = 0; break; // floor default: tileindex = 2; // side (or invalid—should we care?) } - useTile(tileindex, true); + useTile(tileindex, MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING); float size = BS / 2 * f->visual_scale; v3f vertices[4] = { @@ -802,7 +801,7 @@ void MapblockMeshGenerator::drawTorchlikeNode() void MapblockMeshGenerator::drawSignlikeNode() { u8 wall = n.getWallMounted(nodedef); - useTile(0, true); + useTile(0, MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING); static const float offset = BS / 16; float size = BS / 2 * f->visual_scale; // Wall at X+ of node @@ -829,8 +828,8 @@ void MapblockMeshGenerator::drawPlantlikeQuad(float rotation, float quad_offset, bool offset_top_only) { v3f vertices[4] = { - v3f(-scale, -BS / 2 + scale * 2, 0), - v3f( scale, -BS / 2 + scale * 2, 0), + v3f(-scale, -BS / 2 + 2.0 * scale * plant_height, 0), + v3f( scale, -BS / 2 + 2.0 * scale * plant_height, 0), v3f( scale, -BS / 2, 0), v3f(-scale, -BS / 2, 0), }; @@ -845,18 +844,18 @@ void MapblockMeshGenerator::drawPlantlikeQuad(float rotation, float quad_offset, vertices[i].rotateXZBy(rotation + rotate_degree); vertices[i] += offset; } - drawQuad(vertices); + drawQuad(vertices, v3s16(0, 0, 0), plant_height); } -void MapblockMeshGenerator::drawPlantlikeNode() +void MapblockMeshGenerator::drawPlantlike() { - useTile(0, false); draw_style = PLANT_STYLE_CROSS; scale = BS / 2 * f->visual_scale; offset = v3f(0, 0, 0); rotate_degree = 0; random_offset_Y = false; face_num = 0; + plant_height = 1.0; switch (f->param_type_2) { case CPT2_MESHOPTIONS: @@ -876,6 +875,10 @@ void MapblockMeshGenerator::drawPlantlikeNode() rotate_degree = n.param2 * 2; break; + case CPT2_LEVELED: + plant_height = n.param2 / 16.0; + break; + default: break; } @@ -913,6 +916,27 @@ void MapblockMeshGenerator::drawPlantlikeNode() } } +void MapblockMeshGenerator::drawPlantlikeNode() +{ + useTile(); + drawPlantlike(); +} + +void MapblockMeshGenerator::drawPlantlikeRootedNode() +{ + useTile(0, MATERIAL_FLAG_CRACK_OVERLAY, 0, true); + origin += v3f(0.0, BS, 0.0); + p.Y++; + if (data->m_smooth_lighting) { + getSmoothLightFrame(); + } else { + MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + p); + light = getInteriorLight(ntop, 1, nodedef); + } + drawPlantlike(); + p.Y--; +} + void MapblockMeshGenerator::drawFirelikeQuad(float rotation, float opening_angle, float offset_h, float offset_v) { @@ -933,7 +957,7 @@ void MapblockMeshGenerator::drawFirelikeQuad(float rotation, float opening_angle void MapblockMeshGenerator::drawFirelikeNode() { - useTile(0, false); + useTile(); scale = BS / 2 * f->visual_scale; // Check for adjacent nodes @@ -980,7 +1004,7 @@ void MapblockMeshGenerator::drawFirelikeNode() void MapblockMeshGenerator::drawFencelikeNode() { - useDefaultTile(false); + useTile(0, 0, 0); TileSpec tile_nocrack = tile; for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) tile_nocrack.layers[layer].material_flags &= ~MATERIAL_FLAG_CRACK; @@ -1130,7 +1154,7 @@ void MapblockMeshGenerator::drawRaillikeNode() angle = rail_kinds[code].angle; } - useTile(tile_index, true); + useTile(tile_index, MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING); static const float offset = BS / 64; static const float size = BS / 2; @@ -1171,7 +1195,7 @@ void MapblockMeshGenerator::drawNodeboxNode() TileSpec tiles[6]; for (int face = 0; face < 6; face++) { // Handles facedir rotation for textures - getTile(tile_dirs[face], tiles[face]); + getTile(tile_dirs[face], &tiles[face]); } // locate possible neighboring nodes to connect to @@ -1228,7 +1252,7 @@ void MapblockMeshGenerator::drawMeshNode() int mesh_buffer_count = mesh->getMeshBufferCount(); for (int j = 0; j < mesh_buffer_count; j++) { - useTile(j, false); + useTile(j); scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices(); int vertex_count = buf->getVertexCount(); @@ -1269,6 +1293,9 @@ void MapblockMeshGenerator::drawNode() else light = getInteriorLight(n, 1, nodedef); switch (f->drawtype) { + case NDT_NORMAL: break; // Drawn by MapBlockMesh + case NDT_AIRLIKE: break; // Not drawn at all + case NDT_LIQUID: break; // Drawn by MapBlockMesh case NDT_FLOWINGLIQUID: drawLiquidNode(); break; case NDT_GLASSLIKE: drawGlasslikeNode(); break; case NDT_GLASSLIKE_FRAMED: drawGlasslikeFramedNode(); break; @@ -1276,6 +1303,7 @@ void MapblockMeshGenerator::drawNode() case NDT_TORCHLIKE: drawTorchlikeNode(); break; case NDT_SIGNLIKE: drawSignlikeNode(); break; case NDT_PLANTLIKE: drawPlantlikeNode(); break; + case NDT_PLANTLIKE_ROOTED: drawPlantlikeRootedNode(); break; case NDT_FIRELIKE: drawFirelikeNode(); break; case NDT_FENCELIKE: drawFencelikeNode(); break; case NDT_RAILLIKE: drawRaillikeNode(); break; @@ -1296,11 +1324,6 @@ void MapblockMeshGenerator::generate() for (p.X = 0; p.X < MAP_BLOCKSIZE; p.X++) { n = data->m_vmanip.getNodeNoEx(blockpos_nodes + p); f = &nodedef->get(n); - // Solid nodes are drawn by MapBlockMesh - if (f->solidness != 0) - continue; - if (f->drawtype == NDT_AIRLIKE) - continue; origin = intToFloat(p, BS); drawNode(); } diff --git a/src/content_mapblock.h b/src/content_mapblock.h index 0a0b12a80..51c5fc6ea 100644 --- a/src/content_mapblock.h +++ b/src/content_mapblock.h @@ -62,12 +62,14 @@ public: video::SColor blendLightColor(const v3f &vertex_pos); video::SColor blendLightColor(const v3f &vertex_pos, const v3f &vertex_normal); - void useTile(int index, bool disable_backface_culling); - void useDefaultTile(bool set_color = true); - void getTile(const v3s16 &direction, TileSpec &tile); + void useTile(int index = 0, u8 set_flags = MATERIAL_FLAG_CRACK_OVERLAY, + u8 reset_flags = 0, bool special = false); + void getTile(v3s16 direction, TileSpec *tile); + void getSpecialTile(int index, TileSpec *tile, bool apply_crack = false); // face drawing - void drawQuad(v3f *vertices, const v3s16 &normal = v3s16(0, 0, 0)); + void drawQuad(v3f *vertices, const v3s16 &normal = v3s16(0, 0, 0), + float vertical_tiling = 1.0); // cuboid drawing! void drawCuboid(const aabb3f &box, TileSpec *tiles, int tilecount, @@ -111,9 +113,11 @@ public: int rotate_degree; bool random_offset_Y; int face_num; + float plant_height; void drawPlantlikeQuad(float rotation, float quad_offset = 0, bool offset_top_only = false); + void drawPlantlike(); // firelike-specific void drawFirelikeQuad(float rotation, float opening_angle, @@ -127,6 +131,7 @@ public: void drawTorchlikeNode(); void drawSignlikeNode(); void drawPlantlikeNode(); + void drawPlantlikeRootedNode(); void drawFirelikeNode(); void drawFencelikeNode(); void drawRaillikeNode(); diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 6ccbc1557..6bb2bf904 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -772,6 +772,9 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc case NDT_RAILLIKE: solidness = 0; break; + case NDT_PLANTLIKE_ROOTED: + solidness = 2; + break; } if (is_liquid) { @@ -783,38 +786,41 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT; } - u32 tile_shader[6]; - for (u16 j = 0; j < 6; j++) { - tile_shader[j] = shdsrc->getShader("nodes_shader", - material_type, drawtype); - } + u32 tile_shader = shdsrc->getShader("nodes_shader", material_type, drawtype); + u8 overlay_material = material_type; if (overlay_material == TILE_MATERIAL_OPAQUE) overlay_material = TILE_MATERIAL_BASIC; else if (overlay_material == TILE_MATERIAL_LIQUID_OPAQUE) overlay_material = TILE_MATERIAL_LIQUID_TRANSPARENT; - u32 overlay_shader[6]; - for (u16 j = 0; j < 6; j++) { - overlay_shader[j] = shdsrc->getShader("nodes_shader", - overlay_material, drawtype); - } + + u32 overlay_shader = shdsrc->getShader("nodes_shader", overlay_material, drawtype); // Tiles (fill in f->tiles[]) for (u16 j = 0; j < 6; j++) { - fillTileAttribs(tsrc, &tiles[j].layers[0], &tdef[j], tile_shader[j], + fillTileAttribs(tsrc, &tiles[j].layers[0], &tdef[j], tile_shader, tsettings.use_normal_texture, tdef[j].backface_culling, material_type); if (tdef_overlay[j].name != "") fillTileAttribs(tsrc, &tiles[j].layers[1], &tdef_overlay[j], - overlay_shader[j], tsettings.use_normal_texture, + overlay_shader, tsettings.use_normal_texture, tdef[j].backface_culling, overlay_material); } + u8 special_material = material_type; + if (drawtype == NDT_PLANTLIKE_ROOTED) { + if (waving == 1) + special_material = TILE_MATERIAL_WAVING_PLANTS; + else if (waving == 2) + special_material = TILE_MATERIAL_WAVING_LEAVES; + } + u32 special_shader = shdsrc->getShader("nodes_shader", special_material, drawtype); + // Special tiles (fill in f->special_tiles[]) for (u16 j = 0; j < CF_SPECIAL_COUNT; j++) { fillTileAttribs(tsrc, &special_tiles[j].layers[0], &tdef_spec[j], - tile_shader[j], tsettings.use_normal_texture, - tdef_spec[j].backface_culling, material_type); + special_shader, tsettings.use_normal_texture, + tdef_spec[j].backface_culling, special_material); } if (param_type_2 == CPT2_COLOR || diff --git a/src/nodedef.h b/src/nodedef.h index a0b5fc69e..66296016a 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -187,6 +187,8 @@ enum NodeDrawType NDT_GLASSLIKE_FRAMED_OPTIONAL, // Uses static meshes NDT_MESH, + // Combined plantlike-on-solid + NDT_PLANTLIKE_ROOTED, }; // Mesh options for NDT_PLANTLIKE with CPT2_MESHOPTIONS diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 3ee6913c9..8d94235ce 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -362,6 +362,7 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) bool default_culling = true; switch (drawtype) { case NDT_PLANTLIKE: + case NDT_PLANTLIKE_ROOTED: case NDT_FIRELIKE: default_tiling = false; // "break" is omitted here intentionaly, as PLANTLIKE diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index d1b2723df..aa28e3fb5 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -47,6 +47,7 @@ struct EnumString ScriptApiNode::es_DrawType[] = {NDT_FIRELIKE, "firelike"}, {NDT_GLASSLIKE_FRAMED_OPTIONAL, "glasslike_framed_optional"}, {NDT_MESH, "mesh"}, + {NDT_PLANTLIKE_ROOTED, "plantlike_rooted"}, {0, NULL}, }; diff --git a/src/shader.cpp b/src/shader.cpp index ac0745cb4..e6e5e7b1f 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -618,7 +618,8 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp "NDT_NODEBOX", "NDT_GLASSLIKE_FRAMED", "NDT_FIRELIKE", - "NDT_GLASSLIKE_FRAMED_OPTIONAL" + "NDT_GLASSLIKE_FRAMED_OPTIONAL", + "NDT_PLANTLIKE_ROOTED", }; for (int i = 0; i < 14; i++){ diff --git a/src/wieldmesh.cpp b/src/wieldmesh.cpp index aa5f04b8d..e0d6b7e0d 100644 --- a/src/wieldmesh.cpp +++ b/src/wieldmesh.cpp @@ -327,28 +327,45 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client) m_meshnode->setScale( def.wield_scale * WIELD_SCALE_FACTOR / (BS * f.visual_scale)); - } else if (f.drawtype == NDT_AIRLIKE) { - changeToMesh(nullptr); - } else if (f.drawtype == NDT_PLANTLIKE) { - setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id), - def.wield_scale, tsrc, - f.tiles[0].layers[0].animation_frame_count); - } else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES) { - setCube(f, def.wield_scale); } else { - MeshMakeData mesh_make_data(client, false); - MapNode mesh_make_node(id, 255, 0); - mesh_make_data.fillSingleNode(&mesh_make_node); - MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); - scene::SMesh *mesh = cloneMesh(mapblock_mesh.getMesh()); - translateMesh(mesh, v3f(-BS, -BS, -BS)); - postProcessNodeMesh(mesh, f, m_enable_shaders, true, - &m_material_type, &m_colors); - changeToMesh(mesh); - mesh->drop(); - m_meshnode->setScale( - def.wield_scale * WIELD_SCALE_FACTOR - / (BS * f.visual_scale)); + switch (f.drawtype) { + case NDT_AIRLIKE: { + changeToMesh(nullptr); + break; + } + case NDT_PLANTLIKE: { + setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id), + def.wield_scale, tsrc, + f.tiles[0].layers[0].animation_frame_count); + break; + } + case NDT_PLANTLIKE_ROOTED: { + setExtruded(tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), + def.wield_scale, tsrc, + f.special_tiles[0].layers[0].animation_frame_count); + break; + } + case NDT_NORMAL: + case NDT_ALLFACES: { + setCube(f, def.wield_scale); + break; + } + default: { + MeshMakeData mesh_make_data(client, false); + MapNode mesh_make_node(id, 255, 0); + mesh_make_data.fillSingleNode(&mesh_make_node); + MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); + scene::SMesh *mesh = cloneMesh(mapblock_mesh.getMesh()); + translateMesh(mesh, v3f(-BS, -BS, -BS)); + postProcessNodeMesh(mesh, f, m_enable_shaders, true, + &m_material_type, &m_colors); + changeToMesh(mesh); + mesh->drop(); + m_meshnode->setScale( + def.wield_scale * WIELD_SCALE_FACTOR + / (BS * f.visual_scale)); + } + } } u32 material_count = m_meshnode->getMaterialCount(); for (u32 i = 0; i < material_count; ++i) { @@ -446,35 +463,50 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) if (f.mesh_ptr[0]) { mesh = cloneMesh(f.mesh_ptr[0]); scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); - } else if (f.drawtype == NDT_PLANTLIKE) { - mesh = getExtrudedMesh(tsrc, - tsrc->getTextureName(f.tiles[0].layers[0].texture_id)); - } else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES - || f.drawtype == NDT_LIQUID || f.drawtype == NDT_FLOWINGLIQUID) { - scene::IMesh *cube = g_extrusion_mesh_cache->createCube(); - mesh = cloneMesh(cube); - cube->drop(); - scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); } else { - MeshMakeData mesh_make_data(client, false); - MapNode mesh_make_node(id, 255, 0); - mesh_make_data.fillSingleNode(&mesh_make_node); - MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); - mesh = cloneMesh(mapblock_mesh.getMesh()); - translateMesh(mesh, v3f(-BS, -BS, -BS)); - scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); + switch (f.drawtype) { + case NDT_PLANTLIKE: { + mesh = getExtrudedMesh(tsrc, + tsrc->getTextureName(f.tiles[0].layers[0].texture_id)); + break; + } + case NDT_PLANTLIKE_ROOTED: { + mesh = getExtrudedMesh(tsrc, + tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id)); + break; + } + case NDT_NORMAL: + case NDT_ALLFACES: + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: { + scene::IMesh *cube = g_extrusion_mesh_cache->createCube(); + mesh = cloneMesh(cube); + cube->drop(); + scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); + break; + } + default: { + MeshMakeData mesh_make_data(client, false); + MapNode mesh_make_node(id, 255, 0); + mesh_make_data.fillSingleNode(&mesh_make_node); + MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); + mesh = cloneMesh(mapblock_mesh.getMesh()); + translateMesh(mesh, v3f(-BS, -BS, -BS)); + scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); - u32 mc = mesh->getMeshBufferCount(); - for (u32 i = 0; i < mc; ++i) { - video::SMaterial &material1 = - mesh->getMeshBuffer(i)->getMaterial(); - video::SMaterial &material2 = - mapblock_mesh.getMesh()->getMeshBuffer(i)->getMaterial(); - material1.setTexture(0, material2.getTexture(0)); - material1.setTexture(1, material2.getTexture(1)); - material1.setTexture(2, material2.getTexture(2)); - material1.setTexture(3, material2.getTexture(3)); - material1.MaterialType = material2.MaterialType; + u32 mc = mesh->getMeshBufferCount(); + for (u32 i = 0; i < mc; ++i) { + video::SMaterial &material1 = + mesh->getMeshBuffer(i)->getMaterial(); + video::SMaterial &material2 = + mapblock_mesh.getMesh()->getMeshBuffer(i)->getMaterial(); + material1.setTexture(0, material2.getTexture(0)); + material1.setTexture(1, material2.getTexture(1)); + material1.setTexture(2, material2.getTexture(2)); + material1.setTexture(3, material2.getTexture(3)); + material1.MaterialType = material2.MaterialType; + } + } } }