mirror of
https://github.com/minetest/minetest.git
synced 2024-11-05 07:13:46 +01:00
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.
This commit is contained in:
parent
f871852f13
commit
ef285b2815
@ -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).
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
if (special)
|
||||||
|
getSpecialTile(index, &tile, p == data->m_crack_pos_relative);
|
||||||
|
else
|
||||||
getNodeTileN(n, p, index, data, tile);
|
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 = ©.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();
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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 ||
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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++){
|
||||||
|
@ -327,15 +327,30 @@ 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) {
|
} else {
|
||||||
|
switch (f.drawtype) {
|
||||||
|
case NDT_AIRLIKE: {
|
||||||
changeToMesh(nullptr);
|
changeToMesh(nullptr);
|
||||||
} else if (f.drawtype == NDT_PLANTLIKE) {
|
break;
|
||||||
|
}
|
||||||
|
case NDT_PLANTLIKE: {
|
||||||
setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id),
|
setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id),
|
||||||
def.wield_scale, tsrc,
|
def.wield_scale, tsrc,
|
||||||
f.tiles[0].layers[0].animation_frame_count);
|
f.tiles[0].layers[0].animation_frame_count);
|
||||||
} else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES) {
|
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);
|
setCube(f, def.wield_scale);
|
||||||
} else {
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
MeshMakeData mesh_make_data(client, false);
|
MeshMakeData mesh_make_data(client, false);
|
||||||
MapNode mesh_make_node(id, 255, 0);
|
MapNode mesh_make_node(id, 255, 0);
|
||||||
mesh_make_data.fillSingleNode(&mesh_make_node);
|
mesh_make_data.fillSingleNode(&mesh_make_node);
|
||||||
@ -350,6 +365,8 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
|
|||||||
def.wield_scale * WIELD_SCALE_FACTOR
|
def.wield_scale * WIELD_SCALE_FACTOR
|
||||||
/ (BS * f.visual_scale));
|
/ (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) {
|
||||||
video::SMaterial &material = m_meshnode->getMaterial(i);
|
video::SMaterial &material = m_meshnode->getMaterial(i);
|
||||||
@ -446,16 +463,29 @@ 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) {
|
} else {
|
||||||
|
switch (f.drawtype) {
|
||||||
|
case NDT_PLANTLIKE: {
|
||||||
mesh = getExtrudedMesh(tsrc,
|
mesh = getExtrudedMesh(tsrc,
|
||||||
tsrc->getTextureName(f.tiles[0].layers[0].texture_id));
|
tsrc->getTextureName(f.tiles[0].layers[0].texture_id));
|
||||||
} else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES
|
break;
|
||||||
|| f.drawtype == NDT_LIQUID || f.drawtype == NDT_FLOWINGLIQUID) {
|
}
|
||||||
|
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();
|
scene::IMesh *cube = g_extrusion_mesh_cache->createCube();
|
||||||
mesh = cloneMesh(cube);
|
mesh = cloneMesh(cube);
|
||||||
cube->drop();
|
cube->drop();
|
||||||
scaleMesh(mesh, v3f(1.2, 1.2, 1.2));
|
scaleMesh(mesh, v3f(1.2, 1.2, 1.2));
|
||||||
} else {
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
MeshMakeData mesh_make_data(client, false);
|
MeshMakeData mesh_make_data(client, false);
|
||||||
MapNode mesh_make_node(id, 255, 0);
|
MapNode mesh_make_node(id, 255, 0);
|
||||||
mesh_make_data.fillSingleNode(&mesh_make_node);
|
mesh_make_data.fillSingleNode(&mesh_make_node);
|
||||||
@ -477,6 +507,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
|
|||||||
material1.MaterialType = material2.MaterialType;
|
material1.MaterialType = material2.MaterialType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u32 mc = mesh->getMeshBufferCount();
|
u32 mc = mesh->getMeshBufferCount();
|
||||||
for (u32 i = 0; i < mc; ++i) {
|
for (u32 i = 0; i < mc; ++i) {
|
||||||
|
Loading…
Reference in New Issue
Block a user