From ea404979e16ce769c640266039ca3d696189f9d1 Mon Sep 17 00:00:00 2001
From: Craig Robbins <kde.psych@gmail.com>
Date: Thu, 20 Nov 2014 13:36:58 +1000
Subject: [PATCH] Optimise getTileInfo()

getTileInfo() ~1.5x faster
getSmoothLight ~2.0x faster
---
 src/mapblock_mesh.cpp | 66 +++++++++++++++++++++----------------------
 src/mapnode.cpp       | 20 ++++++-------
 2 files changed, 40 insertions(+), 46 deletions(-)

diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp
index 99a5ce0dd..3324dd2b6 100644
--- a/src/mapblock_mesh.cpp
+++ b/src/mapblock_mesh.cpp
@@ -221,11 +221,11 @@ u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, INodeDefManager *ndef)
 
 /*
 	Calculate smooth lighting at the XYZ- corner of p.
-	Single light bank.
+	Both light banks
 */
-static u8 getSmoothLight(enum LightBank bank, v3s16 p, MeshMakeData *data)
+static u16 getSmoothLightCombined(v3s16 p, MeshMakeData *data)
 {
-	static v3s16 dirs8[8] = {
+	static const v3s16 dirs8[8] = {
 		v3s16(0,0,0),
 		v3s16(0,0,1),
 		v3s16(0,1,0),
@@ -239,10 +239,12 @@ static u8 getSmoothLight(enum LightBank bank, v3s16 p, MeshMakeData *data)
 	INodeDefManager *ndef = data->m_gamedef->ndef();
 
 	u16 ambient_occlusion = 0;
-	u16 light = 0;
 	u16 light_count = 0;
 	u8 light_source_max = 0;
-	for(u32 i=0; i<8; i++)
+	u16 light_day = 0;
+	u16 light_night = 0;
+
+	for(u32 i = 0; i < 8; i++)
 	{
 		MapNode n = data->m_vmanip.getNodeNoEx(p - dirs8[i]);
 
@@ -256,48 +258,44 @@ static u8 getSmoothLight(enum LightBank bank, v3s16 p, MeshMakeData *data)
 			light_source_max = f.light_source;
 		// Check f.solidness because fast-style leaves look
 		// better this way
-		if(f.param_type == CPT_LIGHT && f.solidness != 2)
-		{
-			light += decode_light(n.getLight(bank, ndef));
+		if (f.param_type == CPT_LIGHT && f.solidness != 2) {
+			light_day += decode_light(n.getLight(LIGHTBANK_DAY, ndef));
+			light_night += decode_light(n.getLight(LIGHTBANK_NIGHT, ndef));
 			light_count++;
-		}
-		else {
+		} else {
 			ambient_occlusion++;
 		}
 	}
 
 	if(light_count == 0)
-		return 255;
+		return 0xffff;
 
-	light /= light_count;
+	light_day /= light_count;
+	light_night /= light_count;
 
 	// Boost brightness around light sources
-	if(decode_light(light_source_max) >= light)
-		//return decode_light(undiminish_light(light_source_max));
-		return decode_light(light_source_max);
+	bool skip_ambient_occlusion = false;
+	if(decode_light(light_source_max) >= light_day) {
+		light_day = decode_light(light_source_max);
+		skip_ambient_occlusion = true;
+	}
+	if(decode_light(light_source_max) >= light_night) {
+		light_night = decode_light(light_source_max);
+		skip_ambient_occlusion = true;
+	}
 
-	if(ambient_occlusion > 4)
+	if(ambient_occlusion > 4 && !skip_ambient_occlusion)
 	{
 		//calculate table index for gamma space multiplier
 		ambient_occlusion -= 5;
 		//table of precalculated gamma space multiply factors
 		//light^2.2 * factor (0.75, 0.5, 0.25, 0.0), so table holds factor ^ (1 / 2.2)
-		const float light_amount[4] = {0.877424315, 0.729740053, 0.532520545, 0.0};
-		light = core::clamp(core::round32(light*light_amount[ambient_occlusion]), 0, 255);
+		static const float light_amount[4] = {0.877424315, 0.729740053, 0.532520545, 0.0};
+		light_day = rangelim(core::round32(light_day*light_amount[ambient_occlusion]), 0, 255);
+		light_night = rangelim(core::round32(light_night*light_amount[ambient_occlusion]), 0, 255);
 	}
 
-	return light;
-}
-
-/*
-	Calculate smooth lighting at the XYZ- corner of p.
-	Both light banks.
-*/
-static u16 getSmoothLight(v3s16 p, MeshMakeData *data)
-{
-	u16 day = getSmoothLight(LIGHTBANK_DAY, p, data);
-	u16 night = getSmoothLight(LIGHTBANK_NIGHT, p, data);
-	return day | (night << 8);
+	return light_day | (light_night << 8);
 }
 
 /*
@@ -307,13 +305,13 @@ static u16 getSmoothLight(v3s16 p, MeshMakeData *data)
 u16 getSmoothLight(v3s16 p, v3s16 corner, MeshMakeData *data)
 {
 	if(corner.X == 1) p.X += 1;
-	else              assert(corner.X == -1);
+	// else corner.X == -1
 	if(corner.Y == 1) p.Y += 1;
-	else              assert(corner.Y == -1);
+	// else corner.Y == -1
 	if(corner.Z == 1) p.Z += 1;
-	else              assert(corner.Z == -1);
+	// else corner.Z == -1
 
-	return getSmoothLight(p, data);
+	return getSmoothLightCombined(p, data);
 }
 
 /*
diff --git a/src/mapnode.cpp b/src/mapnode.cpp
index 786224240..fbf0ac8c9 100644
--- a/src/mapnode.cpp
+++ b/src/mapnode.cpp
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "serialization.h" // For ser_ver_supported
 #include "util/serialize.h"
 #include "log.h"
+#include "util/numeric.h"
 #include <string>
 #include <sstream>
 
@@ -77,19 +78,14 @@ u8 MapNode::getLight(enum LightBank bank, INodeDefManager *nodemgr) const
 {
 	// Select the brightest of [light source, propagated light]
 	const ContentFeatures &f = nodemgr->get(*this);
-	u8 light = 0;
+
+	u8 light;
 	if(f.param_type == CPT_LIGHT)
-	{
-		if(bank == LIGHTBANK_DAY)
-			light = param1 & 0x0f;
-		else if(bank == LIGHTBANK_NIGHT)
-			light = (param1>>4)&0x0f;
-		else
-			assert(0);
-	}
-	if(f.light_source > light)
-		light = f.light_source;
-	return light;
+		light = bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f;
+	else
+		light = 0;
+
+	return MYMAX(f.light_source, light);
 }
 
 bool MapNode::getLightBanks(u8 &lightday, u8 &lightnight, INodeDefManager *nodemgr) const
-- 
GitLab