mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Add hardware node coloring. Includes:
- Increase ContentFeatures serialization version - Color property and palettes for nodes - paramtype2 = "color", "colored facedir" or "colored wallmounted"
This commit is contained in:
parent
43822de5c6
commit
d04d8aba70
27 changed files with 1207 additions and 554 deletions
|
@ -32,28 +32,29 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
|
||||
// Create a cuboid.
|
||||
// collector - the MeshCollector for the resulting polygons
|
||||
// box - the position and size of the box
|
||||
// tiles - the tiles (materials) to use (for all 6 faces)
|
||||
// tilecount - number of entries in tiles, 1<=tilecount<=6
|
||||
// c - vertex colour - used for all
|
||||
// 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. Alternatively, pass
|
||||
// NULL to use the entire texture for each face. The order of
|
||||
// the faces in the list is up-down-right-left-back-front
|
||||
// (compatible with ContentFeatures). If you specified 0,0,1,1
|
||||
// for each face, that would be the same as passing NULL.
|
||||
// collector - the MeshCollector for the resulting polygons
|
||||
// box - the position and size of the box
|
||||
// tiles - the tiles (materials) to use (for all 6 faces)
|
||||
// tilecount - number of entries in tiles, 1<=tilecount<=6
|
||||
// c - colors of the cuboid's six sides
|
||||
// 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. Alternatively,
|
||||
// pass NULL to use the entire texture for each face. The
|
||||
// order of the faces in the list is up-down-right-left-back-
|
||||
// front (compatible with ContentFeatures). If you specified
|
||||
// 0,0,1,1 for each face, that would be the same as
|
||||
// passing NULL.
|
||||
// light source - if greater than zero, the box's faces will not be shaded
|
||||
void makeCuboid(MeshCollector *collector, const aabb3f &box,
|
||||
TileSpec *tiles, int tilecount, video::SColor &c, const f32* txc)
|
||||
TileSpec *tiles, int tilecount, const video::SColor *c,
|
||||
const f32* txc, const u8 light_source)
|
||||
{
|
||||
assert(tilecount >= 1 && tilecount <= 6); // pre-condition
|
||||
|
||||
v3f min = box.MinEdge;
|
||||
v3f max = box.MaxEdge;
|
||||
|
||||
|
||||
|
||||
if(txc == NULL) {
|
||||
static const f32 txc_default[24] = {
|
||||
0,0,1,1,
|
||||
|
@ -66,38 +67,53 @@ void makeCuboid(MeshCollector *collector, const aabb3f &box,
|
|||
txc = txc_default;
|
||||
}
|
||||
|
||||
video::SColor c1 = c[0];
|
||||
video::SColor c2 = c[1];
|
||||
video::SColor c3 = c[2];
|
||||
video::SColor c4 = c[3];
|
||||
video::SColor c5 = c[4];
|
||||
video::SColor c6 = c[5];
|
||||
if (!light_source) {
|
||||
applyFacesShading(c1, v3f(0, 1, 0));
|
||||
applyFacesShading(c2, v3f(0, -1, 0));
|
||||
applyFacesShading(c3, v3f(1, 0, 0));
|
||||
applyFacesShading(c4, v3f(-1, 0, 0));
|
||||
applyFacesShading(c5, v3f(0, 0, 1));
|
||||
applyFacesShading(c6, v3f(0, 0, -1));
|
||||
}
|
||||
|
||||
video::S3DVertex vertices[24] =
|
||||
{
|
||||
// up
|
||||
video::S3DVertex(min.X,max.Y,max.Z, 0,1,0, c, txc[0],txc[1]),
|
||||
video::S3DVertex(max.X,max.Y,max.Z, 0,1,0, c, txc[2],txc[1]),
|
||||
video::S3DVertex(max.X,max.Y,min.Z, 0,1,0, c, txc[2],txc[3]),
|
||||
video::S3DVertex(min.X,max.Y,min.Z, 0,1,0, c, txc[0],txc[3]),
|
||||
video::S3DVertex(min.X,max.Y,max.Z, 0,1,0, c1, txc[0],txc[1]),
|
||||
video::S3DVertex(max.X,max.Y,max.Z, 0,1,0, c1, txc[2],txc[1]),
|
||||
video::S3DVertex(max.X,max.Y,min.Z, 0,1,0, c1, txc[2],txc[3]),
|
||||
video::S3DVertex(min.X,max.Y,min.Z, 0,1,0, c1, txc[0],txc[3]),
|
||||
// down
|
||||
video::S3DVertex(min.X,min.Y,min.Z, 0,-1,0, c, txc[4],txc[5]),
|
||||
video::S3DVertex(max.X,min.Y,min.Z, 0,-1,0, c, txc[6],txc[5]),
|
||||
video::S3DVertex(max.X,min.Y,max.Z, 0,-1,0, c, txc[6],txc[7]),
|
||||
video::S3DVertex(min.X,min.Y,max.Z, 0,-1,0, c, txc[4],txc[7]),
|
||||
video::S3DVertex(min.X,min.Y,min.Z, 0,-1,0, c2, txc[4],txc[5]),
|
||||
video::S3DVertex(max.X,min.Y,min.Z, 0,-1,0, c2, txc[6],txc[5]),
|
||||
video::S3DVertex(max.X,min.Y,max.Z, 0,-1,0, c2, txc[6],txc[7]),
|
||||
video::S3DVertex(min.X,min.Y,max.Z, 0,-1,0, c2, txc[4],txc[7]),
|
||||
// right
|
||||
video::S3DVertex(max.X,max.Y,min.Z, 1,0,0, c, txc[ 8],txc[9]),
|
||||
video::S3DVertex(max.X,max.Y,max.Z, 1,0,0, c, txc[10],txc[9]),
|
||||
video::S3DVertex(max.X,min.Y,max.Z, 1,0,0, c, txc[10],txc[11]),
|
||||
video::S3DVertex(max.X,min.Y,min.Z, 1,0,0, c, txc[ 8],txc[11]),
|
||||
video::S3DVertex(max.X,max.Y,min.Z, 1,0,0, c3, txc[ 8],txc[9]),
|
||||
video::S3DVertex(max.X,max.Y,max.Z, 1,0,0, c3, txc[10],txc[9]),
|
||||
video::S3DVertex(max.X,min.Y,max.Z, 1,0,0, c3, txc[10],txc[11]),
|
||||
video::S3DVertex(max.X,min.Y,min.Z, 1,0,0, c3, txc[ 8],txc[11]),
|
||||
// left
|
||||
video::S3DVertex(min.X,max.Y,max.Z, -1,0,0, c, txc[12],txc[13]),
|
||||
video::S3DVertex(min.X,max.Y,min.Z, -1,0,0, c, txc[14],txc[13]),
|
||||
video::S3DVertex(min.X,min.Y,min.Z, -1,0,0, c, txc[14],txc[15]),
|
||||
video::S3DVertex(min.X,min.Y,max.Z, -1,0,0, c, txc[12],txc[15]),
|
||||
video::S3DVertex(min.X,max.Y,max.Z, -1,0,0, c4, txc[12],txc[13]),
|
||||
video::S3DVertex(min.X,max.Y,min.Z, -1,0,0, c4, txc[14],txc[13]),
|
||||
video::S3DVertex(min.X,min.Y,min.Z, -1,0,0, c4, txc[14],txc[15]),
|
||||
video::S3DVertex(min.X,min.Y,max.Z, -1,0,0, c4, txc[12],txc[15]),
|
||||
// back
|
||||
video::S3DVertex(max.X,max.Y,max.Z, 0,0,1, c, txc[16],txc[17]),
|
||||
video::S3DVertex(min.X,max.Y,max.Z, 0,0,1, c, txc[18],txc[17]),
|
||||
video::S3DVertex(min.X,min.Y,max.Z, 0,0,1, c, txc[18],txc[19]),
|
||||
video::S3DVertex(max.X,min.Y,max.Z, 0,0,1, c, txc[16],txc[19]),
|
||||
video::S3DVertex(max.X,max.Y,max.Z, 0,0,1, c5, txc[16],txc[17]),
|
||||
video::S3DVertex(min.X,max.Y,max.Z, 0,0,1, c5, txc[18],txc[17]),
|
||||
video::S3DVertex(min.X,min.Y,max.Z, 0,0,1, c5, txc[18],txc[19]),
|
||||
video::S3DVertex(max.X,min.Y,max.Z, 0,0,1, c5, txc[16],txc[19]),
|
||||
// front
|
||||
video::S3DVertex(min.X,max.Y,min.Z, 0,0,-1, c, txc[20],txc[21]),
|
||||
video::S3DVertex(max.X,max.Y,min.Z, 0,0,-1, c, txc[22],txc[21]),
|
||||
video::S3DVertex(max.X,min.Y,min.Z, 0,0,-1, c, txc[22],txc[23]),
|
||||
video::S3DVertex(min.X,min.Y,min.Z, 0,0,-1, c, txc[20],txc[23]),
|
||||
video::S3DVertex(min.X,max.Y,min.Z, 0,0,-1, c6, txc[20],txc[21]),
|
||||
video::S3DVertex(max.X,max.Y,min.Z, 0,0,-1, c6, txc[22],txc[21]),
|
||||
video::S3DVertex(max.X,min.Y,min.Z, 0,0,-1, c6, txc[22],txc[23]),
|
||||
video::S3DVertex(min.X,min.Y,min.Z, 0,0,-1, c6, txc[20],txc[23]),
|
||||
};
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
|
@ -164,6 +180,31 @@ void makeCuboid(MeshCollector *collector, const aabb3f &box,
|
|||
}
|
||||
}
|
||||
|
||||
// Create a cuboid.
|
||||
// collector - the MeshCollector for the resulting polygons
|
||||
// box - the position and size of the box
|
||||
// tiles - the tiles (materials) to use (for all 6 faces)
|
||||
// tilecount - number of entries in tiles, 1<=tilecount<=6
|
||||
// c - color of the cuboid
|
||||
// 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. Alternatively,
|
||||
// pass NULL to use the entire texture for each face. The
|
||||
// order of the faces in the list is up-down-right-left-back-
|
||||
// front (compatible with ContentFeatures). If you specified
|
||||
// 0,0,1,1 for each face, that would be the same as
|
||||
// passing NULL.
|
||||
// light source - if greater than zero, the box's faces will not be shaded
|
||||
void makeCuboid(MeshCollector *collector, const aabb3f &box, TileSpec *tiles,
|
||||
int tilecount, const video::SColor &c, const f32* txc,
|
||||
const u8 light_source)
|
||||
{
|
||||
video::SColor color[6];
|
||||
for (u8 i = 0; i < 6; i++)
|
||||
color[i] = c;
|
||||
makeCuboid(collector, box, tiles, tilecount, color, txc, light_source);
|
||||
}
|
||||
|
||||
static inline void getNeighborConnectingFace(v3s16 p, INodeDefManager *nodedef,
|
||||
MeshMakeData *data, MapNode n, int v, int *neighbors)
|
||||
{
|
||||
|
@ -181,6 +222,18 @@ static inline int NeighborToIndex(const v3s16 &pos)
|
|||
return 9 * pos.X + 3 * pos.Y + pos.Z + 13;
|
||||
}
|
||||
|
||||
/*!
|
||||
* 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];
|
||||
if (!copy.has_color)
|
||||
n.getColor(f, ©.color);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Fix alpha blending for special nodes
|
||||
Currently only the last element rendered is blended correct
|
||||
|
@ -227,8 +280,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
/*
|
||||
Add water sources to mesh if using new style
|
||||
*/
|
||||
TileSpec tile_liquid = f.special_tiles[0];
|
||||
TileSpec tile_liquid = getSpecialTile(f, n, 0);
|
||||
TileSpec tile_liquid_bfculled = getNodeTile(n, p, v3s16(0,0,0), data);
|
||||
u16 l = getInteriorLight(n, 0, nodedef);
|
||||
video::SColor c1 = encode_light_and_color(l,
|
||||
tile_liquid.color, f.light_source);
|
||||
video::SColor c2 = encode_light_and_color(l,
|
||||
tile_liquid_bfculled.color, f.light_source);
|
||||
|
||||
bool top_is_same_liquid = false;
|
||||
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
|
||||
|
@ -237,9 +295,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
if(ntop.getContent() == c_flowing || ntop.getContent() == c_source)
|
||||
top_is_same_liquid = true;
|
||||
|
||||
u16 l = getInteriorLight(n, 0, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(f.alpha, l, f.light_source);
|
||||
|
||||
/*
|
||||
Generate sides
|
||||
*/
|
||||
|
@ -285,15 +340,18 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
// Use backface culled material if neighbor doesn't have a
|
||||
// solidness of 0
|
||||
const TileSpec *current_tile = &tile_liquid;
|
||||
if(n_feat.solidness != 0 || n_feat.visual_solidness != 0)
|
||||
video::SColor *c = &c1;
|
||||
if(n_feat.solidness != 0 || n_feat.visual_solidness != 0) {
|
||||
current_tile = &tile_liquid_bfculled;
|
||||
c = &c2;
|
||||
}
|
||||
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(-BS/2,0,BS/2,0,0,0, c, 0,1),
|
||||
video::S3DVertex(BS/2,0,BS/2,0,0,0, c, 1,1),
|
||||
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0),
|
||||
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),
|
||||
video::S3DVertex(-BS/2,0,BS/2,0,0,0, *c, 0,1),
|
||||
video::S3DVertex(BS/2,0,BS/2,0,0,0, *c, 1,1),
|
||||
video::S3DVertex(BS/2,0,BS/2, 0,0,0, *c, 1,0),
|
||||
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, *c, 0,0),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -359,10 +417,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, 1,0),
|
||||
video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,0),
|
||||
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c1, 0,1),
|
||||
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c1, 1,1),
|
||||
video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c1, 1,0),
|
||||
video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c1, 0,0),
|
||||
};
|
||||
|
||||
v3f offset(p.X * BS, (p.Y + 0.5) * BS, p.Z * BS);
|
||||
|
@ -380,8 +438,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
/*
|
||||
Add flowing liquid to mesh
|
||||
*/
|
||||
TileSpec tile_liquid = f.special_tiles[0];
|
||||
TileSpec tile_liquid_bfculled = f.special_tiles[1];
|
||||
TileSpec tile_liquid = getSpecialTile(f, n, 0);
|
||||
TileSpec tile_liquid_bfculled = getSpecialTile(f, n, 1);
|
||||
|
||||
bool top_is_same_liquid = false;
|
||||
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
|
||||
|
@ -404,7 +462,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
// Otherwise use the light of this node (the liquid)
|
||||
else
|
||||
l = getInteriorLight(n, 0, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(f.alpha, l, f.light_source);
|
||||
video::SColor c1 = encode_light_and_color(l,
|
||||
tile_liquid.color, f.light_source);
|
||||
video::SColor c2 = encode_light_and_color(l,
|
||||
tile_liquid_bfculled.color, f.light_source);
|
||||
|
||||
u8 range = rangelim(nodedef->get(c_flowing).liquid_range, 1, 8);
|
||||
|
||||
|
@ -552,7 +613,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
is liquid, don't draw side face
|
||||
*/
|
||||
if (top_is_same_liquid &&
|
||||
neighbor_data.flags & neighborflag_top_is_same_liquid)
|
||||
(neighbor_data.flags & neighborflag_top_is_same_liquid))
|
||||
continue;
|
||||
|
||||
content_t neighbor_content = neighbor_data.content;
|
||||
|
@ -574,15 +635,18 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
// Use backface culled material if neighbor doesn't have a
|
||||
// solidness of 0
|
||||
const TileSpec *current_tile = &tile_liquid;
|
||||
if(n_feat.solidness != 0 || n_feat.visual_solidness != 0)
|
||||
video::SColor *c = &c1;
|
||||
if(n_feat.solidness != 0 || n_feat.visual_solidness != 0) {
|
||||
current_tile = &tile_liquid_bfculled;
|
||||
c = &c2;
|
||||
}
|
||||
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0),
|
||||
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),
|
||||
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, *c, 0,1),
|
||||
video::S3DVertex(BS/2,0,BS/2, 0,0,0, *c, 1,1),
|
||||
video::S3DVertex(BS/2,0,BS/2, 0,0,0, *c, 1,0),
|
||||
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, *c, 0,0),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -656,10 +720,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
{
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, 1,0),
|
||||
video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,0),
|
||||
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c1, 0,1),
|
||||
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c1, 1,1),
|
||||
video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c1, 1,0),
|
||||
video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c1, 0,0),
|
||||
};
|
||||
|
||||
// To get backface culling right, the vertices need to go
|
||||
|
@ -720,8 +784,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
TileSpec tile = getNodeTile(n, p, v3s16(0,0,0), data);
|
||||
|
||||
u16 l = getInteriorLight(n, 1, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(255, l, f.light_source);
|
||||
|
||||
video::SColor c = encode_light_and_color(l, tile.color,
|
||||
f.light_source);
|
||||
for(u32 j=0; j<6; j++)
|
||||
{
|
||||
// Check this neighbor
|
||||
|
@ -731,13 +795,17 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
// Don't make face if neighbor is of same type
|
||||
if(n2.getContent() == n.getContent())
|
||||
continue;
|
||||
video::SColor c2=c;
|
||||
if(!f.light_source)
|
||||
applyFacesShading(c2, v3f(dir.X, dir.Y, dir.Z));
|
||||
|
||||
|
||||
// The face at Z+
|
||||
video::S3DVertex vertices[4] = {
|
||||
video::S3DVertex(-BS/2,-BS/2,BS/2, dir.X,dir.Y,dir.Z, c, 1,1),
|
||||
video::S3DVertex(BS/2,-BS/2,BS/2, dir.X,dir.Y,dir.Z, c, 0,1),
|
||||
video::S3DVertex(BS/2,BS/2,BS/2, dir.X,dir.Y,dir.Z, c, 0,0),
|
||||
video::S3DVertex(-BS/2,BS/2,BS/2, dir.X,dir.Y,dir.Z, c, 1,0),
|
||||
video::S3DVertex(-BS/2,-BS/2,BS/2, dir.X,dir.Y,dir.Z, c2, 1,1),
|
||||
video::S3DVertex(BS/2,-BS/2,BS/2, dir.X,dir.Y,dir.Z, c2, 0,1),
|
||||
video::S3DVertex(BS/2,BS/2,BS/2, dir.X,dir.Y,dir.Z, c2, 0,0),
|
||||
video::S3DVertex(-BS/2,BS/2,BS/2, dir.X,dir.Y,dir.Z, c2, 1,0),
|
||||
};
|
||||
|
||||
// Rotations in the g_6dirs format
|
||||
|
@ -784,12 +852,20 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
v3s16( 0, 0,-1)
|
||||
};
|
||||
|
||||
u16 l = getInteriorLight(n, 1, nodedef);
|
||||
u8 i;
|
||||
TileSpec tiles[6];
|
||||
for (i = 0; i < 6; i++)
|
||||
tiles[i] = getNodeTile(n, p, dirs[i], data);
|
||||
|
||||
video::SColor tile0color = encode_light_and_color(l,
|
||||
tiles[0].color, f.light_source);
|
||||
video::SColor tile0colors[6];
|
||||
for (i = 0; i < 6; i++)
|
||||
tile0colors[i] = tile0color;
|
||||
|
||||
TileSpec glass_tiles[6];
|
||||
video::SColor glasscolor[6];
|
||||
if (tiles[1].texture && tiles[2].texture && tiles[3].texture) {
|
||||
glass_tiles[0] = tiles[2];
|
||||
glass_tiles[1] = tiles[3];
|
||||
|
@ -801,14 +877,15 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
for (i = 0; i < 6; i++)
|
||||
glass_tiles[i] = tiles[1];
|
||||
}
|
||||
for (i = 0; i < 6; i++)
|
||||
glasscolor[i] = encode_light_and_color(l, glass_tiles[i].color,
|
||||
f.light_source);
|
||||
|
||||
u8 param2 = n.getParam2();
|
||||
bool H_merge = ! bool(param2 & 128);
|
||||
bool V_merge = ! bool(param2 & 64);
|
||||
param2 = param2 & 63;
|
||||
|
||||
u16 l = getInteriorLight(n, 1, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(255, l, f.light_source);
|
||||
v3f pos = intToFloat(p, BS);
|
||||
static const float a = BS / 2;
|
||||
static const float g = a - 0.003;
|
||||
|
@ -947,7 +1024,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
1-tx2, 1-ty2, 1-tx1, 1-ty1,
|
||||
tx1, 1-ty2, tx2, 1-ty1,
|
||||
};
|
||||
makeCuboid(&collector, box, &tiles[0], 1, c, txc1);
|
||||
makeCuboid(&collector, box, &tiles[0], 1, tile0colors,
|
||||
txc1, f.light_source);
|
||||
}
|
||||
|
||||
for(i = 0; i < 6; i++)
|
||||
|
@ -971,16 +1049,21 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
1-tx2, 1-ty2, 1-tx1, 1-ty1,
|
||||
tx1, 1-ty2, tx2, 1-ty1,
|
||||
};
|
||||
makeCuboid(&collector, box, &glass_tiles[i], 1, c, txc2);
|
||||
makeCuboid(&collector, box, &glass_tiles[i], 1, glasscolor,
|
||||
txc2, f.light_source);
|
||||
}
|
||||
|
||||
if (param2 > 0 && f.special_tiles[0].texture) {
|
||||
// Interior volume level is in range 0 .. 63,
|
||||
// convert it to -0.5 .. 0.5
|
||||
float vlev = (((float)param2 / 63.0 ) * 2.0 - 1.0);
|
||||
TileSpec tile=getSpecialTile(f, n, 0);
|
||||
video::SColor special_color = encode_light_and_color(l,
|
||||
tile.color, f.light_source);
|
||||
TileSpec interior_tiles[6];
|
||||
for (i = 0; i < 6; i++)
|
||||
interior_tiles[i] = f.special_tiles[0];
|
||||
interior_tiles[i] = tile;
|
||||
|
||||
float offset = 0.003;
|
||||
box = aabb3f(visible_faces[3] ? -b : -a + offset,
|
||||
visible_faces[1] ? -b : -a + offset,
|
||||
|
@ -1004,22 +1087,24 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
1-tx2, 1-ty2, 1-tx1, 1-ty1,
|
||||
tx1, 1-ty2, tx2, 1-ty1,
|
||||
};
|
||||
makeCuboid(&collector, box, interior_tiles, 6, c, txc3);
|
||||
makeCuboid(&collector, box, interior_tiles, 6, special_color,
|
||||
txc3, f.light_source);
|
||||
}
|
||||
break;}
|
||||
case NDT_ALLFACES:
|
||||
{
|
||||
TileSpec tile_leaves = getNodeTile(n, p,
|
||||
v3s16(0,0,0), data);
|
||||
|
||||
u16 l = getInteriorLight(n, 1, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(255, l, f.light_source);
|
||||
video::SColor c = encode_light_and_color(l,
|
||||
tile_leaves.color, f.light_source);
|
||||
|
||||
v3f pos = intToFloat(p, BS);
|
||||
aabb3f box(-BS/2,-BS/2,-BS/2,BS/2,BS/2,BS/2);
|
||||
box.MinEdge += pos;
|
||||
box.MaxEdge += pos;
|
||||
makeCuboid(&collector, box, &tile_leaves, 1, c, NULL);
|
||||
makeCuboid(&collector, box, &tile_leaves, 1, c, NULL,
|
||||
f.light_source);
|
||||
break;}
|
||||
case NDT_ALLFACES_OPTIONAL:
|
||||
// This is always pre-converted to something else
|
||||
|
@ -1046,7 +1131,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY;
|
||||
|
||||
u16 l = getInteriorLight(n, 1, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(255, l, f.light_source);
|
||||
video::SColor c = encode_light_and_color(l, tile.color,
|
||||
f.light_source);
|
||||
|
||||
float s = BS/2*f.visual_scale;
|
||||
// Wall at X+ of node
|
||||
|
@ -1087,7 +1173,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY;
|
||||
|
||||
u16 l = getInteriorLight(n, 0, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(255, l, f.light_source);
|
||||
video::SColor c = encode_light_and_color(l, tile.color,
|
||||
f.light_source);
|
||||
|
||||
float d = (float)BS/16;
|
||||
float s = BS/2*f.visual_scale;
|
||||
|
@ -1132,7 +1219,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY;
|
||||
|
||||
u16 l = getInteriorLight(n, 1, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(255, l, f.light_source);
|
||||
video::SColor c = encode_light_and_color(l, tile.color,
|
||||
f.light_source);
|
||||
|
||||
float s = BS / 2 * f.visual_scale;
|
||||
// add sqrt(2) visual scale
|
||||
|
@ -1302,7 +1390,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY;
|
||||
|
||||
u16 l = getInteriorLight(n, 1, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(255, l, f.light_source);
|
||||
video::SColor c = encode_light_and_color(l, tile.color,
|
||||
f.light_source);
|
||||
|
||||
float s = BS / 2 * f.visual_scale;
|
||||
|
||||
|
@ -1437,7 +1526,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
tile_rot.rotation = 1;
|
||||
|
||||
u16 l = getInteriorLight(n, 1, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(255, l, f.light_source);
|
||||
video::SColor c = encode_light_and_color(l, tile.color,
|
||||
f.light_source);
|
||||
|
||||
const f32 post_rad=(f32)BS/8;
|
||||
const f32 bar_rad=(f32)BS/16;
|
||||
|
@ -1456,7 +1546,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
4/16.,0,8/16.,1,
|
||||
8/16.,0,12/16.,1,
|
||||
12/16.,0,16/16.,1};
|
||||
makeCuboid(&collector, post, &tile_rot, 1, c, postuv);
|
||||
makeCuboid(&collector, post, &tile_rot, 1, c, postuv,
|
||||
f.light_source);
|
||||
|
||||
// Now a section of fence, +X, if there's a post there
|
||||
v3s16 p2 = p;
|
||||
|
@ -1477,11 +1568,11 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
0/16.,8/16.,16/16.,10/16.,
|
||||
0/16.,14/16.,16/16.,16/16.};
|
||||
makeCuboid(&collector, bar, &tile_nocrack, 1,
|
||||
c, xrailuv);
|
||||
c, xrailuv, f.light_source);
|
||||
bar.MinEdge.Y -= BS/2;
|
||||
bar.MaxEdge.Y -= BS/2;
|
||||
makeCuboid(&collector, bar, &tile_nocrack, 1,
|
||||
c, xrailuv);
|
||||
c, xrailuv, f.light_source);
|
||||
}
|
||||
|
||||
// Now a section of fence, +Z, if there's a post there
|
||||
|
@ -1503,11 +1594,11 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
6/16.,6/16.,8/16.,8/16.,
|
||||
10/16.,10/16.,12/16.,12/16.};
|
||||
makeCuboid(&collector, bar, &tile_nocrack, 1,
|
||||
c, zrailuv);
|
||||
c, zrailuv, f.light_source);
|
||||
bar.MinEdge.Y -= BS/2;
|
||||
bar.MaxEdge.Y -= BS/2;
|
||||
makeCuboid(&collector, bar, &tile_nocrack, 1,
|
||||
c, zrailuv);
|
||||
c, zrailuv, f.light_source);
|
||||
}
|
||||
break;}
|
||||
case NDT_RAILLIKE:
|
||||
|
@ -1616,7 +1707,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY;
|
||||
|
||||
u16 l = getInteriorLight(n, 0, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(255, l, f.light_source);
|
||||
video::SColor c = encode_light_and_color(l, tile.color,
|
||||
f.light_source);
|
||||
|
||||
float d = (float)BS/64;
|
||||
float s = BS/2;
|
||||
|
@ -1627,10 +1719,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(-s, -s+d,-s, 0,0,0, c,0,1),
|
||||
video::S3DVertex( s, -s+d,-s, 0,0,0, c,1,1),
|
||||
video::S3DVertex( s, g*s+d, s, 0,0,0, c,1,0),
|
||||
video::S3DVertex(-s, g*s+d, s, 0,0,0, c,0,0),
|
||||
video::S3DVertex(-s, -s+d, -s, 0, 0, 0, c, 0, 1),
|
||||
video::S3DVertex( s, -s+d, -s, 0, 0, 0, c, 1, 1),
|
||||
video::S3DVertex( s, g*s+d, s, 0, 0, 0, c, 1, 0),
|
||||
video::S3DVertex(-s, g*s+d, s, 0, 0, 0, c, 0, 0),
|
||||
};
|
||||
|
||||
for(s32 i=0; i<4; i++)
|
||||
|
@ -1653,10 +1745,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
v3s16(0, 0, 1),
|
||||
v3s16(0, 0, -1)
|
||||
};
|
||||
TileSpec tiles[6];
|
||||
|
||||
u16 l = getInteriorLight(n, 1, nodedef);
|
||||
video::SColor c = MapBlock_LightColor(255, l, f.light_source);
|
||||
TileSpec tiles[6];
|
||||
video::SColor colors[6];
|
||||
for(int j = 0; j < 6; j++) {
|
||||
// Handles facedir rotation for textures
|
||||
tiles[j] = getNodeTile(n, p, tile_dirs[j], data);
|
||||
colors[j]= encode_light_and_color(l, tiles[j].color,
|
||||
f.light_source);
|
||||
}
|
||||
|
||||
v3f pos = intToFloat(p, BS);
|
||||
|
||||
|
@ -1696,11 +1794,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
i = boxes.begin();
|
||||
i != boxes.end(); ++i)
|
||||
{
|
||||
for(int j = 0; j < 6; j++)
|
||||
{
|
||||
// Handles facedir rotation for textures
|
||||
tiles[j] = getNodeTile(n, p, tile_dirs[j], data);
|
||||
}
|
||||
aabb3f box = *i;
|
||||
box.MinEdge += pos;
|
||||
box.MaxEdge += pos;
|
||||
|
@ -1747,18 +1840,19 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
// front
|
||||
tx1, 1-ty2, tx2, 1-ty1,
|
||||
};
|
||||
makeCuboid(&collector, box, tiles, 6, c, txc);
|
||||
makeCuboid(&collector, box, tiles, 6, colors, txc, f.light_source);
|
||||
}
|
||||
break;}
|
||||
case NDT_MESH:
|
||||
{
|
||||
v3f pos = intToFloat(p, BS);
|
||||
video::SColor c = MapBlock_LightColor(255, getInteriorLight(n, 1, nodedef), f.light_source);
|
||||
|
||||
u16 l = getInteriorLight(n, 1, nodedef);
|
||||
u8 facedir = 0;
|
||||
if (f.param_type_2 == CPT2_FACEDIR) {
|
||||
if (f.param_type_2 == CPT2_FACEDIR ||
|
||||
f.param_type_2 == CPT2_COLORED_FACEDIR) {
|
||||
facedir = n.getFaceDir(nodedef);
|
||||
} else if (f.param_type_2 == CPT2_WALLMOUNTED) {
|
||||
} else if (f.param_type_2 == CPT2_WALLMOUNTED ||
|
||||
f.param_type_2 == CPT2_COLORED_WALLMOUNTED) {
|
||||
//convert wallmounted to 6dfacedir.
|
||||
//when cache enabled, it is already converted
|
||||
facedir = n.getWallMounted(nodedef);
|
||||
|
@ -1771,10 +1865,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
if (f.mesh_ptr[facedir]) {
|
||||
// use cached meshes
|
||||
for(u16 j = 0; j < f.mesh_ptr[0]->getMeshBufferCount(); j++) {
|
||||
const TileSpec &tile = getNodeTileN(n, p, j, data);
|
||||
scene::IMeshBuffer *buf = f.mesh_ptr[facedir]->getMeshBuffer(j);
|
||||
collector.append(getNodeTileN(n, p, j, data),
|
||||
(video::S3DVertex *)buf->getVertices(), buf->getVertexCount(),
|
||||
buf->getIndices(), buf->getIndexCount(), pos, c);
|
||||
collector.append(tile, (video::S3DVertex *)
|
||||
buf->getVertices(), buf->getVertexCount(),
|
||||
buf->getIndices(), buf->getIndexCount(), pos,
|
||||
encode_light_and_color(l, tile.color, f.light_source),
|
||||
f.light_source);
|
||||
}
|
||||
} else if (f.mesh_ptr[0]) {
|
||||
// no cache, clone and rotate mesh
|
||||
|
@ -1783,10 +1880,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
recalculateBoundingBox(mesh);
|
||||
meshmanip->recalculateNormals(mesh, true, false);
|
||||
for(u16 j = 0; j < mesh->getMeshBufferCount(); j++) {
|
||||
const TileSpec &tile = getNodeTileN(n, p, j, data);
|
||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||
collector.append(getNodeTileN(n, p, j, data),
|
||||
(video::S3DVertex *)buf->getVertices(), buf->getVertexCount(),
|
||||
buf->getIndices(), buf->getIndexCount(), pos, c);
|
||||
collector.append(tile, (video::S3DVertex *)
|
||||
buf->getVertices(), buf->getVertexCount(),
|
||||
buf->getIndices(), buf->getIndexCount(), pos,
|
||||
encode_light_and_color(l, tile.color, f.light_source),
|
||||
f.light_source);
|
||||
}
|
||||
mesh->drop();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue