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.
master
number Zero 2017-05-11 23:24:12 +03:00 committed by paramat
parent f871852f13
commit ef285b2815
9 changed files with 192 additions and 120 deletions

View File

@ -860,6 +860,7 @@ Look for examples in `games/minimal` or `games/minetest_game`.
* `raillike` * `raillike`
* `nodebox` -- See below. (**Experimental!**) * `nodebox` -- See below. (**Experimental!**)
* `mesh` -- use models for nodes * `mesh` -- use models for nodes
* `plantlike_rooted`
`*_optional` drawtypes need less rendering time if deactivated (always client side). `*_optional` drawtypes need less rendering time if deactivated (always client side).

View File

@ -73,33 +73,49 @@ MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector
blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE; 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) if (!data->m_smooth_lighting)
color = encode_light(light, f->light_source); color = encode_light(light, f->light_source);
for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) { for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
tile.layers[layer].material_flags |= MATERIAL_FLAG_CRACK_OVERLAY; tile.layers[layer].material_flags |= set_flags;
if (disable_backface_culling) tile.layers[layer].material_flags &= ~reset_flags;
tile.layers[layer].material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
} }
} }
void MapblockMeshGenerator::useDefaultTile(bool set_color) void MapblockMeshGenerator::getTile(v3s16 direction, TileSpec *tile)
{ {
getNodeTile(n, p, v3s16(0, 0, 0), data, tile); getNodeTile(n, p, direction, data, *tile);
if (set_color && !data->m_smooth_lighting)
color = encode_light(light, f->light_source);
} }
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]; video::S3DVertex vertices[4];
bool shade_face = !f->light_source && (normal != v3s16(0, 0, 0)); bool shade_face = !f->light_source && (normal != v3s16(0, 0, 0));
v3f normal2(normal.X, normal.Y, normal.Z); 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 = &copy.layers[layernum];
if (layer->texture_id == 0)
continue;
if (!layer->has_color)
n.getColor(f, &(layer->color));
}
return copy;
}
void MapblockMeshGenerator::prepareLiquidNodeDrawing() void MapblockMeshGenerator::prepareLiquidNodeDrawing()
{ {
tile_liquid_top = getSpecialTile(*f, n, 0); getSpecialTile(0, &tile_liquid_top);
tile_liquid = getSpecialTile(*f, n, 1); getSpecialTile(1, &tile_liquid);
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(p.X, p.Y + 1, p.Z)); MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(p.X, p.Y + 1, p.Z));
c_flowing = nodedef->getId(f->liquid_alternative_flowing); c_flowing = nodedef->getId(f->liquid_alternative_flowing);
@ -603,7 +602,7 @@ void MapblockMeshGenerator::drawLiquidNode()
void MapblockMeshGenerator::drawGlasslikeNode() void MapblockMeshGenerator::drawGlasslikeNode()
{ {
useDefaultTile(); useTile(0, 0, 0);
for (int face = 0; face < 6; face++) { for (int face = 0; face < 6; face++) {
// Check this neighbor // Check this neighbor
@ -638,7 +637,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode()
{ {
TileSpec tiles[6]; TileSpec tiles[6];
for (int face = 0; face < 6; face++) for (int face = 0; face < 6; face++)
getTile(g_6dirs[face], tiles[face]); getTile(g_6dirs[face], &tiles[face]);
TileSpec glass_tiles[6]; TileSpec glass_tiles[6];
if (tiles[1].layers[0].texture && if (tiles[1].layers[0].texture &&
@ -751,7 +750,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode()
// Internal liquid level has param2 range 0 .. 63, // Internal liquid level has param2 range 0 .. 63,
// convert it to -0.5 .. 0.5 // convert it to -0.5 .. 0.5
float vlev = (param2 / 63.0) * 2.0 - 1.0; float vlev = (param2 / 63.0) * 2.0 - 1.0;
tile = getSpecialTile(*f, n, 0); getSpecialTile(0, &tile);
drawAutoLightedCuboid(aabb3f(-(nb[5] ? g : b), drawAutoLightedCuboid(aabb3f(-(nb[5] ? g : b),
-(nb[4] ? g : b), -(nb[4] ? g : b),
-(nb[3] ? g : b), -(nb[3] ? g : b),
@ -764,7 +763,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode()
void MapblockMeshGenerator::drawAllfacesNode() void MapblockMeshGenerator::drawAllfacesNode()
{ {
static const aabb3f box(-BS / 2, -BS / 2, -BS / 2, BS / 2, BS / 2, BS / 2); static const aabb3f box(-BS / 2, -BS / 2, -BS / 2, BS / 2, BS / 2, BS / 2);
useDefaultTile(false); useTile(0, 0, 0);
drawAutoLightedCuboid(box); drawAutoLightedCuboid(box);
} }
@ -777,7 +776,7 @@ void MapblockMeshGenerator::drawTorchlikeNode()
case DWM_YN: tileindex = 0; break; // floor case DWM_YN: tileindex = 0; break; // floor
default: tileindex = 2; // side (or invalid—should we care?) 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; float size = BS / 2 * f->visual_scale;
v3f vertices[4] = { v3f vertices[4] = {
@ -802,7 +801,7 @@ void MapblockMeshGenerator::drawTorchlikeNode()
void MapblockMeshGenerator::drawSignlikeNode() void MapblockMeshGenerator::drawSignlikeNode()
{ {
u8 wall = n.getWallMounted(nodedef); u8 wall = n.getWallMounted(nodedef);
useTile(0, true); useTile(0, MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING);
static const float offset = BS / 16; static const float offset = BS / 16;
float size = BS / 2 * f->visual_scale; float size = BS / 2 * f->visual_scale;
// Wall at X+ of node // Wall at X+ of node
@ -829,8 +828,8 @@ void MapblockMeshGenerator::drawPlantlikeQuad(float rotation, float quad_offset,
bool offset_top_only) bool offset_top_only)
{ {
v3f vertices[4] = { v3f vertices[4] = {
v3f(-scale, -BS / 2 + scale * 2, 0), v3f(-scale, -BS / 2 + 2.0 * scale * plant_height, 0),
v3f( scale, -BS / 2 + scale * 2, 0), v3f( scale, -BS / 2 + 2.0 * scale * plant_height, 0),
v3f( scale, -BS / 2, 0), v3f( scale, -BS / 2, 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].rotateXZBy(rotation + rotate_degree);
vertices[i] += offset; 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; draw_style = PLANT_STYLE_CROSS;
scale = BS / 2 * f->visual_scale; scale = BS / 2 * f->visual_scale;
offset = v3f(0, 0, 0); offset = v3f(0, 0, 0);
rotate_degree = 0; rotate_degree = 0;
random_offset_Y = false; random_offset_Y = false;
face_num = 0; face_num = 0;
plant_height = 1.0;
switch (f->param_type_2) { switch (f->param_type_2) {
case CPT2_MESHOPTIONS: case CPT2_MESHOPTIONS:
@ -876,6 +875,10 @@ void MapblockMeshGenerator::drawPlantlikeNode()
rotate_degree = n.param2 * 2; rotate_degree = n.param2 * 2;
break; break;
case CPT2_LEVELED:
plant_height = n.param2 / 16.0;
break;
default: default:
break; 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, void MapblockMeshGenerator::drawFirelikeQuad(float rotation, float opening_angle,
float offset_h, float offset_v) float offset_h, float offset_v)
{ {
@ -933,7 +957,7 @@ void MapblockMeshGenerator::drawFirelikeQuad(float rotation, float opening_angle
void MapblockMeshGenerator::drawFirelikeNode() void MapblockMeshGenerator::drawFirelikeNode()
{ {
useTile(0, false); useTile();
scale = BS / 2 * f->visual_scale; scale = BS / 2 * f->visual_scale;
// Check for adjacent nodes // Check for adjacent nodes
@ -980,7 +1004,7 @@ void MapblockMeshGenerator::drawFirelikeNode()
void MapblockMeshGenerator::drawFencelikeNode() void MapblockMeshGenerator::drawFencelikeNode()
{ {
useDefaultTile(false); useTile(0, 0, 0);
TileSpec tile_nocrack = tile; TileSpec tile_nocrack = tile;
for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) for (int layer = 0; layer < MAX_TILE_LAYERS; layer++)
tile_nocrack.layers[layer].material_flags &= ~MATERIAL_FLAG_CRACK; tile_nocrack.layers[layer].material_flags &= ~MATERIAL_FLAG_CRACK;
@ -1130,7 +1154,7 @@ void MapblockMeshGenerator::drawRaillikeNode()
angle = rail_kinds[code].angle; 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 offset = BS / 64;
static const float size = BS / 2; static const float size = BS / 2;
@ -1171,7 +1195,7 @@ void MapblockMeshGenerator::drawNodeboxNode()
TileSpec tiles[6]; TileSpec tiles[6];
for (int face = 0; face < 6; face++) { for (int face = 0; face < 6; face++) {
// Handles facedir rotation for textures // Handles facedir rotation for textures
getTile(tile_dirs[face], tiles[face]); getTile(tile_dirs[face], &tiles[face]);
} }
// locate possible neighboring nodes to connect to // locate possible neighboring nodes to connect to
@ -1228,7 +1252,7 @@ void MapblockMeshGenerator::drawMeshNode()
int mesh_buffer_count = mesh->getMeshBufferCount(); int mesh_buffer_count = mesh->getMeshBufferCount();
for (int j = 0; j < mesh_buffer_count; j++) { for (int j = 0; j < mesh_buffer_count; j++) {
useTile(j, false); useTile(j);
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices(); video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices();
int vertex_count = buf->getVertexCount(); int vertex_count = buf->getVertexCount();
@ -1269,6 +1293,9 @@ void MapblockMeshGenerator::drawNode()
else else
light = getInteriorLight(n, 1, nodedef); light = getInteriorLight(n, 1, nodedef);
switch (f->drawtype) { 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_FLOWINGLIQUID: drawLiquidNode(); break;
case NDT_GLASSLIKE: drawGlasslikeNode(); break; case NDT_GLASSLIKE: drawGlasslikeNode(); break;
case NDT_GLASSLIKE_FRAMED: drawGlasslikeFramedNode(); break; case NDT_GLASSLIKE_FRAMED: drawGlasslikeFramedNode(); break;
@ -1276,6 +1303,7 @@ void MapblockMeshGenerator::drawNode()
case NDT_TORCHLIKE: drawTorchlikeNode(); break; case NDT_TORCHLIKE: drawTorchlikeNode(); break;
case NDT_SIGNLIKE: drawSignlikeNode(); break; case NDT_SIGNLIKE: drawSignlikeNode(); break;
case NDT_PLANTLIKE: drawPlantlikeNode(); break; case NDT_PLANTLIKE: drawPlantlikeNode(); break;
case NDT_PLANTLIKE_ROOTED: drawPlantlikeRootedNode(); break;
case NDT_FIRELIKE: drawFirelikeNode(); break; case NDT_FIRELIKE: drawFirelikeNode(); break;
case NDT_FENCELIKE: drawFencelikeNode(); break; case NDT_FENCELIKE: drawFencelikeNode(); break;
case NDT_RAILLIKE: drawRaillikeNode(); break; case NDT_RAILLIKE: drawRaillikeNode(); break;
@ -1296,11 +1324,6 @@ void MapblockMeshGenerator::generate()
for (p.X = 0; p.X < MAP_BLOCKSIZE; p.X++) { for (p.X = 0; p.X < MAP_BLOCKSIZE; p.X++) {
n = data->m_vmanip.getNodeNoEx(blockpos_nodes + p); n = data->m_vmanip.getNodeNoEx(blockpos_nodes + p);
f = &nodedef->get(n); 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); origin = intToFloat(p, BS);
drawNode(); drawNode();
} }

View File

@ -62,12 +62,14 @@ public:
video::SColor blendLightColor(const v3f &vertex_pos); video::SColor blendLightColor(const v3f &vertex_pos);
video::SColor blendLightColor(const v3f &vertex_pos, const v3f &vertex_normal); video::SColor blendLightColor(const v3f &vertex_pos, const v3f &vertex_normal);
void useTile(int index, bool disable_backface_culling); void useTile(int index = 0, u8 set_flags = MATERIAL_FLAG_CRACK_OVERLAY,
void useDefaultTile(bool set_color = true); u8 reset_flags = 0, bool special = false);
void getTile(const v3s16 &direction, TileSpec &tile); void getTile(v3s16 direction, TileSpec *tile);
void getSpecialTile(int index, TileSpec *tile, bool apply_crack = false);
// face drawing // 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! // cuboid drawing!
void drawCuboid(const aabb3f &box, TileSpec *tiles, int tilecount, void drawCuboid(const aabb3f &box, TileSpec *tiles, int tilecount,
@ -111,9 +113,11 @@ public:
int rotate_degree; int rotate_degree;
bool random_offset_Y; bool random_offset_Y;
int face_num; int face_num;
float plant_height;
void drawPlantlikeQuad(float rotation, float quad_offset = 0, void drawPlantlikeQuad(float rotation, float quad_offset = 0,
bool offset_top_only = false); bool offset_top_only = false);
void drawPlantlike();
// firelike-specific // firelike-specific
void drawFirelikeQuad(float rotation, float opening_angle, void drawFirelikeQuad(float rotation, float opening_angle,
@ -127,6 +131,7 @@ public:
void drawTorchlikeNode(); void drawTorchlikeNode();
void drawSignlikeNode(); void drawSignlikeNode();
void drawPlantlikeNode(); void drawPlantlikeNode();
void drawPlantlikeRootedNode();
void drawFirelikeNode(); void drawFirelikeNode();
void drawFencelikeNode(); void drawFencelikeNode();
void drawRaillikeNode(); void drawRaillikeNode();

View File

@ -772,6 +772,9 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
case NDT_RAILLIKE: case NDT_RAILLIKE:
solidness = 0; solidness = 0;
break; break;
case NDT_PLANTLIKE_ROOTED:
solidness = 2;
break;
} }
if (is_liquid) { if (is_liquid) {
@ -783,38 +786,41 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT; TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT;
} }
u32 tile_shader[6]; u32 tile_shader = shdsrc->getShader("nodes_shader", material_type, drawtype);
for (u16 j = 0; j < 6; j++) {
tile_shader[j] = shdsrc->getShader("nodes_shader",
material_type, drawtype);
}
u8 overlay_material = material_type; u8 overlay_material = material_type;
if (overlay_material == TILE_MATERIAL_OPAQUE) if (overlay_material == TILE_MATERIAL_OPAQUE)
overlay_material = TILE_MATERIAL_BASIC; overlay_material = TILE_MATERIAL_BASIC;
else if (overlay_material == TILE_MATERIAL_LIQUID_OPAQUE) else if (overlay_material == TILE_MATERIAL_LIQUID_OPAQUE)
overlay_material = TILE_MATERIAL_LIQUID_TRANSPARENT; overlay_material = TILE_MATERIAL_LIQUID_TRANSPARENT;
u32 overlay_shader[6];
for (u16 j = 0; j < 6; j++) { u32 overlay_shader = shdsrc->getShader("nodes_shader", overlay_material, drawtype);
overlay_shader[j] = shdsrc->getShader("nodes_shader",
overlay_material, drawtype);
}
// Tiles (fill in f->tiles[]) // Tiles (fill in f->tiles[])
for (u16 j = 0; j < 6; j++) { 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, tsettings.use_normal_texture,
tdef[j].backface_culling, material_type); tdef[j].backface_culling, material_type);
if (tdef_overlay[j].name != "") if (tdef_overlay[j].name != "")
fillTileAttribs(tsrc, &tiles[j].layers[1], &tdef_overlay[j], 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); 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[]) // Special tiles (fill in f->special_tiles[])
for (u16 j = 0; j < CF_SPECIAL_COUNT; j++) { for (u16 j = 0; j < CF_SPECIAL_COUNT; j++) {
fillTileAttribs(tsrc, &special_tiles[j].layers[0], &tdef_spec[j], fillTileAttribs(tsrc, &special_tiles[j].layers[0], &tdef_spec[j],
tile_shader[j], tsettings.use_normal_texture, special_shader, tsettings.use_normal_texture,
tdef_spec[j].backface_culling, material_type); tdef_spec[j].backface_culling, special_material);
} }
if (param_type_2 == CPT2_COLOR || if (param_type_2 == CPT2_COLOR ||

View File

@ -187,6 +187,8 @@ enum NodeDrawType
NDT_GLASSLIKE_FRAMED_OPTIONAL, NDT_GLASSLIKE_FRAMED_OPTIONAL,
// Uses static meshes // Uses static meshes
NDT_MESH, NDT_MESH,
// Combined plantlike-on-solid
NDT_PLANTLIKE_ROOTED,
}; };
// Mesh options for NDT_PLANTLIKE with CPT2_MESHOPTIONS // Mesh options for NDT_PLANTLIKE with CPT2_MESHOPTIONS

View File

@ -362,6 +362,7 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
bool default_culling = true; bool default_culling = true;
switch (drawtype) { switch (drawtype) {
case NDT_PLANTLIKE: case NDT_PLANTLIKE:
case NDT_PLANTLIKE_ROOTED:
case NDT_FIRELIKE: case NDT_FIRELIKE:
default_tiling = false; default_tiling = false;
// "break" is omitted here intentionaly, as PLANTLIKE // "break" is omitted here intentionaly, as PLANTLIKE

View File

@ -47,6 +47,7 @@ struct EnumString ScriptApiNode::es_DrawType[] =
{NDT_FIRELIKE, "firelike"}, {NDT_FIRELIKE, "firelike"},
{NDT_GLASSLIKE_FRAMED_OPTIONAL, "glasslike_framed_optional"}, {NDT_GLASSLIKE_FRAMED_OPTIONAL, "glasslike_framed_optional"},
{NDT_MESH, "mesh"}, {NDT_MESH, "mesh"},
{NDT_PLANTLIKE_ROOTED, "plantlike_rooted"},
{0, NULL}, {0, NULL},
}; };

View File

@ -618,7 +618,8 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp
"NDT_NODEBOX", "NDT_NODEBOX",
"NDT_GLASSLIKE_FRAMED", "NDT_GLASSLIKE_FRAMED",
"NDT_FIRELIKE", "NDT_FIRELIKE",
"NDT_GLASSLIKE_FRAMED_OPTIONAL" "NDT_GLASSLIKE_FRAMED_OPTIONAL",
"NDT_PLANTLIKE_ROOTED",
}; };
for (int i = 0; i < 14; i++){ for (int i = 0; i < 14; i++){

View File

@ -327,28 +327,45 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
m_meshnode->setScale( m_meshnode->setScale(
def.wield_scale * WIELD_SCALE_FACTOR def.wield_scale * WIELD_SCALE_FACTOR
/ (BS * f.visual_scale)); / (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 { } else {
MeshMakeData mesh_make_data(client, false); switch (f.drawtype) {
MapNode mesh_make_node(id, 255, 0); case NDT_AIRLIKE: {
mesh_make_data.fillSingleNode(&mesh_make_node); changeToMesh(nullptr);
MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); break;
scene::SMesh *mesh = cloneMesh(mapblock_mesh.getMesh()); }
translateMesh(mesh, v3f(-BS, -BS, -BS)); case NDT_PLANTLIKE: {
postProcessNodeMesh(mesh, f, m_enable_shaders, true, setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id),
&m_material_type, &m_colors); def.wield_scale, tsrc,
changeToMesh(mesh); f.tiles[0].layers[0].animation_frame_count);
mesh->drop(); break;
m_meshnode->setScale( }
def.wield_scale * WIELD_SCALE_FACTOR case NDT_PLANTLIKE_ROOTED: {
/ (BS * f.visual_scale)); 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(); u32 material_count = m_meshnode->getMaterialCount();
for (u32 i = 0; i < material_count; ++i) { 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]) { if (f.mesh_ptr[0]) {
mesh = cloneMesh(f.mesh_ptr[0]); mesh = cloneMesh(f.mesh_ptr[0]);
scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); 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 { } else {
MeshMakeData mesh_make_data(client, false); switch (f.drawtype) {
MapNode mesh_make_node(id, 255, 0); case NDT_PLANTLIKE: {
mesh_make_data.fillSingleNode(&mesh_make_node); mesh = getExtrudedMesh(tsrc,
MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); tsrc->getTextureName(f.tiles[0].layers[0].texture_id));
mesh = cloneMesh(mapblock_mesh.getMesh()); break;
translateMesh(mesh, v3f(-BS, -BS, -BS)); }
scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); 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(); u32 mc = mesh->getMeshBufferCount();
for (u32 i = 0; i < mc; ++i) { for (u32 i = 0; i < mc; ++i) {
video::SMaterial &material1 = video::SMaterial &material1 =
mesh->getMeshBuffer(i)->getMaterial(); mesh->getMeshBuffer(i)->getMaterial();
video::SMaterial &material2 = video::SMaterial &material2 =
mapblock_mesh.getMesh()->getMeshBuffer(i)->getMaterial(); mapblock_mesh.getMesh()->getMeshBuffer(i)->getMaterial();
material1.setTexture(0, material2.getTexture(0)); material1.setTexture(0, material2.getTexture(0));
material1.setTexture(1, material2.getTexture(1)); material1.setTexture(1, material2.getTexture(1));
material1.setTexture(2, material2.getTexture(2)); material1.setTexture(2, material2.getTexture(2));
material1.setTexture(3, material2.getTexture(3)); material1.setTexture(3, material2.getTexture(3));
material1.MaterialType = material2.MaterialType; material1.MaterialType = material2.MaterialType;
}
}
} }
} }