forked from Mirrorlandia_minetest/minetest
Optimize updateFastFaceRow processing by removing some TileSpec copy (#5678)
* Optimize updateFastFaceRow processing by removing some TileSpec copy It permit to decrease this function from 54% runtime to 45% and reduce copy from 14% runtime to 12.5% getTileInfo also reduced from 27% to 23% * makeFastFace should use a const ref too this trigger a const pointer need in the underlying function Also fix some code style and prevent calculating 4 times the same position at a point * Reduce a comparison cost for lights in updateFastFaceRow
This commit is contained in:
parent
c729543ec4
commit
95409da87d
@ -76,7 +76,7 @@ MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector
|
|||||||
|
|
||||||
void MapblockMeshGenerator::useTile(int index, bool disable_backface_culling)
|
void MapblockMeshGenerator::useTile(int index, bool disable_backface_culling)
|
||||||
{
|
{
|
||||||
tile = getNodeTileN(n, p, index, data);
|
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++) {
|
||||||
@ -88,14 +88,14 @@ void MapblockMeshGenerator::useTile(int index, bool disable_backface_culling)
|
|||||||
|
|
||||||
void MapblockMeshGenerator::useDefaultTile(bool set_color)
|
void MapblockMeshGenerator::useDefaultTile(bool set_color)
|
||||||
{
|
{
|
||||||
tile = getNodeTile(n, p, v3s16(0, 0, 0), data);
|
getNodeTile(n, p, v3s16(0, 0, 0), data, tile);
|
||||||
if (set_color && !data->m_smooth_lighting)
|
if (set_color && !data->m_smooth_lighting)
|
||||||
color = encode_light(light, f->light_source);
|
color = encode_light(light, f->light_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
TileSpec MapblockMeshGenerator::getTile(const v3s16& direction)
|
void MapblockMeshGenerator::getTile(const v3s16& direction, TileSpec &tile)
|
||||||
{
|
{
|
||||||
return getNodeTile(n, p, direction, data);
|
getNodeTile(n, p, direction, data, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapblockMeshGenerator::drawQuad(v3f *coords, const v3s16 &normal)
|
void MapblockMeshGenerator::drawQuad(v3f *coords, const v3s16 &normal)
|
||||||
@ -660,7 +660,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode()
|
|||||||
{
|
{
|
||||||
TileSpec tiles[6];
|
TileSpec tiles[6];
|
||||||
for (int face = 0; face < 6; face++)
|
for (int face = 0; face < 6; face++)
|
||||||
tiles[face] = getTile(g_6dirs[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 &&
|
||||||
@ -1193,7 +1193,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
|
||||||
tiles[face] = getTile(tile_dirs[face]);
|
getTile(tile_dirs[face], tiles[face]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// locate possible neighboring nodes to connect to
|
// locate possible neighboring nodes to connect to
|
||||||
|
@ -65,7 +65,7 @@ public:
|
|||||||
|
|
||||||
void useTile(int index, bool disable_backface_culling);
|
void useTile(int index, bool disable_backface_culling);
|
||||||
void useDefaultTile(bool set_color = true);
|
void useDefaultTile(bool set_color = true);
|
||||||
TileSpec getTile(const v3s16 &direction);
|
void getTile(const v3s16 &direction, TileSpec &tile);
|
||||||
|
|
||||||
// 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));
|
||||||
|
@ -433,7 +433,7 @@ struct FastFace
|
|||||||
u8 layernum;
|
u8 layernum;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3,
|
static void makeFastFace(const TileSpec &tile, u16 li0, u16 li1, u16 li2, u16 li3,
|
||||||
v3f p, v3s16 dir, v3f scale, std::vector<FastFace> &dest)
|
v3f p, v3s16 dir, v3f scale, std::vector<FastFace> &dest)
|
||||||
{
|
{
|
||||||
// Position is at the center of the cube.
|
// Position is at the center of the cube.
|
||||||
@ -603,7 +603,7 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3,
|
|||||||
core::vector2d<f32>(x0 + w * abs_scale, y0) };
|
core::vector2d<f32>(x0 + w * abs_scale, y0) };
|
||||||
|
|
||||||
for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) {
|
for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) {
|
||||||
TileLayer *layer = &tile.layers[layernum];
|
const TileLayer *layer = &tile.layers[layernum];
|
||||||
if (layer->texture_id == 0)
|
if (layer->texture_id == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -689,11 +689,11 @@ static u8 face_contents(content_t m1, content_t m2, bool *equivalent,
|
|||||||
/*
|
/*
|
||||||
Gets nth node tile (0 <= n <= 5).
|
Gets nth node tile (0 <= n <= 5).
|
||||||
*/
|
*/
|
||||||
TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data)
|
void getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data, TileSpec &tile)
|
||||||
{
|
{
|
||||||
INodeDefManager *ndef = data->m_client->ndef();
|
INodeDefManager *ndef = data->m_client->ndef();
|
||||||
const ContentFeatures &f = ndef->get(mn);
|
const ContentFeatures &f = ndef->get(mn);
|
||||||
TileSpec tile = f.tiles[tileindex];
|
tile = f.tiles[tileindex];
|
||||||
TileLayer *top_layer = NULL;
|
TileLayer *top_layer = NULL;
|
||||||
for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) {
|
for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) {
|
||||||
TileLayer *layer = &tile.layers[layernum];
|
TileLayer *layer = &tile.layers[layernum];
|
||||||
@ -706,13 +706,12 @@ TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data)
|
|||||||
// Apply temporary crack
|
// Apply temporary crack
|
||||||
if (p == data->m_crack_pos_relative)
|
if (p == data->m_crack_pos_relative)
|
||||||
top_layer->material_flags |= MATERIAL_FLAG_CRACK;
|
top_layer->material_flags |= MATERIAL_FLAG_CRACK;
|
||||||
return tile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Gets node tile given a face direction.
|
Gets node tile given a face direction.
|
||||||
*/
|
*/
|
||||||
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data)
|
void getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data, TileSpec &tile)
|
||||||
{
|
{
|
||||||
INodeDefManager *ndef = data->m_client->ndef();
|
INodeDefManager *ndef = data->m_client->ndef();
|
||||||
|
|
||||||
@ -769,9 +768,8 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data)
|
|||||||
|
|
||||||
};
|
};
|
||||||
u16 tile_index=facedir*16 + dir_i;
|
u16 tile_index=facedir*16 + dir_i;
|
||||||
TileSpec tile = getNodeTileN(mn, p, dir_to_tile[tile_index], data);
|
getNodeTileN(mn, p, dir_to_tile[tile_index], data, tile);
|
||||||
tile.rotation = dir_to_tile[tile_index + 1];
|
tile.rotation = dir_to_tile[tile_index + 1];
|
||||||
return tile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getTileInfo(
|
static void getTileInfo(
|
||||||
@ -791,7 +789,7 @@ static void getTileInfo(
|
|||||||
INodeDefManager *ndef = data->m_client->ndef();
|
INodeDefManager *ndef = data->m_client->ndef();
|
||||||
v3s16 blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE;
|
v3s16 blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE;
|
||||||
|
|
||||||
MapNode &n0 = vmanip.getNodeRefUnsafe(blockpos_nodes + p);
|
const MapNode &n0 = vmanip.getNodeRefUnsafe(blockpos_nodes + p);
|
||||||
|
|
||||||
// Don't even try to get n1 if n0 is already CONTENT_IGNORE
|
// Don't even try to get n1 if n0 is already CONTENT_IGNORE
|
||||||
if (n0.getContent() == CONTENT_IGNORE) {
|
if (n0.getContent() == CONTENT_IGNORE) {
|
||||||
@ -799,8 +797,7 @@ static void getTileInfo(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MapNode &n1 = vmanip.getNodeRefUnsafeCheckFlags(
|
const MapNode &n1 = vmanip.getNodeRefUnsafeCheckFlags(blockpos_nodes + p + face_dir);
|
||||||
blockpos_nodes + p + face_dir);
|
|
||||||
|
|
||||||
if (n1.getContent() == CONTENT_IGNORE) {
|
if (n1.getContent() == CONTENT_IGNORE) {
|
||||||
makes_face = false;
|
makes_face = false;
|
||||||
@ -812,8 +809,7 @@ static void getTileInfo(
|
|||||||
u8 mf = face_contents(n0.getContent(), n1.getContent(),
|
u8 mf = face_contents(n0.getContent(), n1.getContent(),
|
||||||
&equivalent, ndef);
|
&equivalent, ndef);
|
||||||
|
|
||||||
if(mf == 0)
|
if (mf == 0) {
|
||||||
{
|
|
||||||
makes_face = false;
|
makes_face = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -830,34 +826,31 @@ static void getTileInfo(
|
|||||||
p_corrected = p + face_dir;
|
p_corrected = p + face_dir;
|
||||||
face_dir_corrected = -face_dir;
|
face_dir_corrected = -face_dir;
|
||||||
}
|
}
|
||||||
tile = getNodeTile(n, p_corrected, face_dir_corrected, data);
|
|
||||||
|
getNodeTile(n, p_corrected, face_dir_corrected, data, tile);
|
||||||
const ContentFeatures &f = ndef->get(n);
|
const ContentFeatures &f = ndef->get(n);
|
||||||
tile.emissive_light = f.light_source;
|
tile.emissive_light = f.light_source;
|
||||||
|
|
||||||
// eg. water and glass
|
// eg. water and glass
|
||||||
if (equivalent)
|
if (equivalent) {
|
||||||
for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++)
|
for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++)
|
||||||
tile.layers[layernum].material_flags |=
|
tile.layers[layernum].material_flags |=
|
||||||
MATERIAL_FLAG_BACKFACE_CULLING;
|
MATERIAL_FLAG_BACKFACE_CULLING;
|
||||||
|
}
|
||||||
|
|
||||||
if (data->m_smooth_lighting == false)
|
if (!data->m_smooth_lighting) {
|
||||||
{
|
|
||||||
lights[0] = lights[1] = lights[2] = lights[3] =
|
lights[0] = lights[1] = lights[2] = lights[3] =
|
||||||
getFaceLight(n0, n1, face_dir, ndef);
|
getFaceLight(n0, n1, face_dir, ndef);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
v3s16 vertex_dirs[4];
|
v3s16 vertex_dirs[4];
|
||||||
getNodeVertexDirs(face_dir_corrected, vertex_dirs);
|
getNodeVertexDirs(face_dir_corrected, vertex_dirs);
|
||||||
for(u16 i=0; i<4; i++)
|
|
||||||
{
|
|
||||||
lights[i] = getSmoothLight(
|
|
||||||
blockpos_nodes + p_corrected,
|
|
||||||
vertex_dirs[i], data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
v3s16 light_p = blockpos_nodes + p_corrected;
|
||||||
|
for (u16 i = 0; i < 4; i++) {
|
||||||
|
lights[i] = getSmoothLight(light_p, vertex_dirs[i], data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -914,10 +907,7 @@ static void updateFastFaceRow(
|
|||||||
if (next_makes_face == makes_face
|
if (next_makes_face == makes_face
|
||||||
&& next_p_corrected == p_corrected + translate_dir
|
&& next_p_corrected == p_corrected + translate_dir
|
||||||
&& next_face_dir_corrected == face_dir_corrected
|
&& next_face_dir_corrected == face_dir_corrected
|
||||||
&& next_lights[0] == lights[0]
|
&& memcmp(next_lights, lights, ARRLEN(lights) * sizeof(u16)) == 0
|
||||||
&& next_lights[1] == lights[1]
|
|
||||||
&& next_lights[2] == lights[2]
|
|
||||||
&& next_lights[3] == lights[3]
|
|
||||||
&& next_tile.isTileable(tile)) {
|
&& next_tile.isTileable(tile)) {
|
||||||
next_is_different = false;
|
next_is_different = false;
|
||||||
continuous_tiles_count++;
|
continuous_tiles_count++;
|
||||||
@ -932,7 +922,8 @@ static void updateFastFaceRow(
|
|||||||
// Floating point conversion of the position vector
|
// Floating point conversion of the position vector
|
||||||
v3f pf(p_corrected.X, p_corrected.Y, p_corrected.Z);
|
v3f pf(p_corrected.X, p_corrected.Y, p_corrected.Z);
|
||||||
// Center point of face (kind of)
|
// Center point of face (kind of)
|
||||||
v3f sp = pf - ((f32)continuous_tiles_count / 2.0 - 0.5) * translate_dir_f;
|
v3f sp = pf -
|
||||||
|
((f32)continuous_tiles_count / 2.0f - 0.5f) * translate_dir_f;
|
||||||
v3f scale(1,1,1);
|
v3f scale(1,1,1);
|
||||||
|
|
||||||
if(translate_dir.X != 0) {
|
if(translate_dir.X != 0) {
|
||||||
@ -1148,8 +1139,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
|
|||||||
m_animation_frame_offsets[std::pair<u8, u32>(layer, i)] = 0;
|
m_animation_frame_offsets[std::pair<u8, u32>(layer, i)] = 0;
|
||||||
}
|
}
|
||||||
// Replace tile texture with the first animation frame
|
// Replace tile texture with the first animation frame
|
||||||
FrameSpec animation_frame = p.layer.frames[0];
|
p.layer.texture = p.layer.frames[0].texture;
|
||||||
p.layer.texture = animation_frame.texture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_enable_shaders) {
|
if (!m_enable_shaders) {
|
||||||
@ -1337,7 +1327,7 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
|
|||||||
scene::IMeshBuffer *buf = m_mesh[i->first.first]->
|
scene::IMeshBuffer *buf = m_mesh[i->first.first]->
|
||||||
getMeshBuffer(i->first.second);
|
getMeshBuffer(i->first.second);
|
||||||
|
|
||||||
FrameSpec animation_frame = tile.frames[frame];
|
const FrameSpec &animation_frame = tile.frames[frame];
|
||||||
buf->getMaterial().setTexture(0, animation_frame.texture);
|
buf->getMaterial().setTexture(0, animation_frame.texture);
|
||||||
if (m_enable_shaders) {
|
if (m_enable_shaders) {
|
||||||
if (animation_frame.normal_texture) {
|
if (animation_frame.normal_texture) {
|
||||||
|
@ -267,8 +267,10 @@ void final_color_blend(video::SColor *result,
|
|||||||
|
|
||||||
// Retrieves the TileSpec of a face of a node
|
// Retrieves the TileSpec of a face of a node
|
||||||
// Adds MATERIAL_FLAG_CRACK if the node is cracked
|
// Adds MATERIAL_FLAG_CRACK if the node is cracked
|
||||||
TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data);
|
// TileSpec should be passed as reference due to the underlying TileFrame and its vector
|
||||||
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data);
|
// TileFrame vector copy cost very much to client
|
||||||
|
void getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data, TileSpec &tile);
|
||||||
|
void getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data, TileSpec &tile);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user