From 577701cabd6382bb97dc05e9c9244b5ce8202ca3 Mon Sep 17 00:00:00 2001
From: gregorycu <gregory.currie@gmail.com>
Date: Mon, 23 Feb 2015 23:20:06 +1000
Subject: [PATCH] Optimise MapBlockMesh related functions

Directely or indirectly optimises the following functions:

* MapBlockMesh::MapBlockMesh
* MapBlockMesh::getTileInfo
* MapBlockMesh::makeFastFace
* MapBlockMesh::getSmoothLightCombined
---
 src/mapblock_mesh.cpp | 26 +++++++++++++++++---------
 src/mapnode.cpp       |  2 +-
 src/mapnode.h         |  2 +-
 src/voxel.cpp         |  2 ++
 src/voxel.h           | 15 ++++++++++++++-
 5 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp
index b3a1a73d7..d95b8d286 100644
--- a/src/mapblock_mesh.cpp
+++ b/src/mapblock_mesh.cpp
@@ -248,7 +248,7 @@ static u16 getSmoothLightCombined(v3s16 p, MeshMakeData *data)
 
 	for (u32 i = 0; i < 8; i++)
 	{
-		MapNode n = data->m_vmanip.getNodeNoEx(p - dirs8[i]);
+		const MapNode &n = data->m_vmanip.getNodeRefUnsafeCheckFlags(p - dirs8[i]);
 
 		// if it's CONTENT_IGNORE we can't do any light calculations
 		if (n.getContent() == CONTENT_IGNORE) {
@@ -438,8 +438,6 @@ struct FastFace
 static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3,
 		v3f p, v3s16 dir, v3f scale, u8 light_source, std::vector<FastFace> &dest)
 {
-	FastFace face;
-
 	// Position is at the center of the cube.
 	v3f pos = p * BS;
 
@@ -590,6 +588,10 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3,
 
 	u8 alpha = tile.alpha;
 
+	dest.push_back(FastFace());
+
+	FastFace& face = *dest.rbegin();
+
 	face.vertices[0] = video::S3DVertex(vertex_pos[0], normal,
 			MapBlock_LightColor(alpha, li0, light_source),
 			core::vector2d<f32>(x0+w*abs_scale, y0+h));
@@ -604,7 +606,6 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3,
 			core::vector2d<f32>(x0+w*abs_scale, y0));
 
 	face.tile = tile;
-	dest.push_back(face);
 }
 
 /*
@@ -745,8 +746,8 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data)
 static void getTileInfo(
 		// Input:
 		MeshMakeData *data,
-		v3s16 p,
-		v3s16 face_dir,
+		const v3s16 &p,
+		const v3s16 &face_dir,
 		// Output:
 		bool &makes_face,
 		v3s16 &p_corrected,
@@ -760,14 +761,20 @@ static void getTileInfo(
 	INodeDefManager *ndef = data->m_gamedef->ndef();
 	v3s16 blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE;
 
-	MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p);
+	MapNode &n0 = vmanip.getNodeRefUnsafe(blockpos_nodes + p);
 
 	// Don't even try to get n1 if n0 is already CONTENT_IGNORE
-	if (n0.getContent() == CONTENT_IGNORE ) {
+	if (n0.getContent() == CONTENT_IGNORE) {
+		makes_face = false;
+		return;
+	}
+
+	const MapNode &n1 = vmanip.getNodeRefUnsafeCheckFlags(blockpos_nodes + p + face_dir);
+
+	if (n1.getContent() == CONTENT_IGNORE) {
 		makes_face = false;
 		return;
 	}
-	MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir);
 
 	// This is hackish
 	bool equivalent = false;
@@ -1037,6 +1044,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
 	//TimeTaker timer1("MapBlockMesh()");
 
 	std::vector<FastFace> fastfaces_new;
+	fastfaces_new.reserve(512);
 
 	/*
 		We are including the faces of the trailing edges of the block.
diff --git a/src/mapnode.cpp b/src/mapnode.cpp
index 388071a17..44525b644 100644
--- a/src/mapnode.cpp
+++ b/src/mapnode.cpp
@@ -104,7 +104,7 @@ u8 MapNode::getLight(enum LightBank bank, INodeDefManager *nodemgr) const
 	return MYMAX(f.light_source, light);
 }
 
-u8 MapNode::getLightNoChecks(enum LightBank bank, const ContentFeatures *f)
+u8 MapNode::getLightNoChecks(enum LightBank bank, const ContentFeatures *f) const
 {
 	return MYMAX(f->light_source,
 	             bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f);
diff --git a/src/mapnode.h b/src/mapnode.h
index b7d9f3acd..7cc25c60c 100644
--- a/src/mapnode.h
+++ b/src/mapnode.h
@@ -217,7 +217,7 @@ struct MapNode
 	 * @pre f != NULL
 	 * @pre f->param_type == CPT_LIGHT
 	 */
-	u8 getLightNoChecks(LightBank bank, const ContentFeatures *f);
+	u8 getLightNoChecks(LightBank bank, const ContentFeatures *f) const;
 
 	bool getLightBanks(u8 &lightday, u8 &lightnight, INodeDefManager *nodemgr) const;
 
diff --git a/src/voxel.cpp b/src/voxel.cpp
index 8ac786aab..a5e0b09fe 100644
--- a/src/voxel.cpp
+++ b/src/voxel.cpp
@@ -621,6 +621,8 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
 }
 #endif
 
+const MapNode VoxelManipulator::ContentIgnoreNode = MapNode(CONTENT_IGNORE);
+
 #if 1
 /*
 	Lights neighbors of from_nodes, collects all them and then
diff --git a/src/voxel.h b/src/voxel.h
index 52274ac19..054644889 100644
--- a/src/voxel.h
+++ b/src/voxel.h
@@ -413,10 +413,21 @@ class VoxelManipulator /*: public NodeContainer*/
 	}
 	// Stuff explodes if non-emerged area is touched with this.
 	// Emerge first, and check VOXELFLAG_NO_DATA if appropriate.
-	MapNode & getNodeRefUnsafe(v3s16 p)
+	MapNode & getNodeRefUnsafe(const v3s16 &p)
 	{
 		return m_data[m_area.index(p)];
 	}
+
+	const MapNode & getNodeRefUnsafeCheckFlags(const v3s16 &p)
+	{
+		s32 index = m_area.index(p);
+
+		if (m_flags[index] & VOXELFLAG_NO_DATA)
+			return ContentIgnoreNode;
+
+		return m_data[index];
+	}
+
 	u8 & getFlagsRefUnsafe(v3s16 p)
 	{
 		return m_flags[m_area.index(p)];
@@ -569,6 +580,8 @@ class VoxelManipulator /*: public NodeContainer*/
 	*/
 	u8 *m_flags;
 
+	static const MapNode ContentIgnoreNode;
+
 	//TODO: Use these or remove them
 	//TODO: Would these make any speed improvement?
 	//bool m_pressure_route_valid;
-- 
GitLab