From 625a4c2e662f6b69b73a2a828d1b08d72e53ff73 Mon Sep 17 00:00:00 2001
From: RealBadAngel <mk@realbadangel.pl>
Date: Thu, 25 Apr 2013 02:39:21 +0200
Subject: [PATCH] Add new drawtype GLASSLIKE_FRAMED

---
 doc/lua_api.txt          |   1 +
 src/content_mapblock.cpp | 129 ++++++++++++++++++++++++++++++++++++++-
 src/nodedef.cpp          |   4 ++
 src/nodedef.h            |   2 +
 src/scriptapi_node.cpp   |   1 +
 5 files changed, 135 insertions(+), 2 deletions(-)

diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index b2106b64c..5b1942aef 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -329,6 +329,7 @@ Look for examples in games/minimal or games/minetest_game.
 - liquid
 - flowingliquid
 - glasslike
+- glasslike_framed
 - allfaces
 - allfaces_optional
 - torchlike
diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp
index 84d5f067c..155b39ab6 100644
--- a/src/content_mapblock.cpp
+++ b/src/content_mapblock.cpp
@@ -740,8 +740,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
 					continue;
 
 				// The face at Z+
-				video::S3DVertex vertices[4] =
-				{
+				video::S3DVertex vertices[4] = {
 					video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c,
 						ap.x0(), ap.y1()),
 					video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c,
@@ -781,6 +780,132 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
 				collector.append(tile, vertices, 4, indices, 6);
 			}
 		break;}
+		case NDT_GLASSLIKE_FRAMED:
+		{
+			static const v3s16 dirs[6] = {
+				v3s16( 0, 1, 0),
+				v3s16( 0,-1, 0),
+				v3s16( 1, 0, 0),
+				v3s16(-1, 0, 0),
+				v3s16( 0, 0, 1),
+				v3s16( 0, 0,-1)
+			};
+			TileSpec tiles[2];
+			tiles[0] = getNodeTile(n, p, dirs[0], data);
+			tiles[1] = getNodeTile(n, p, dirs[1], data);
+			u16 l = getInteriorLight(n, 1, data);
+			video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
+			v3f pos = intToFloat(p, BS);
+			static const float a=BS/2;
+			static const float b=.876*(BS/2);
+			static const aabb3f frame_edges[12] = {
+				aabb3f( b, b,-a, a, a, a), // y+
+				aabb3f(-a, b,-a,-b, a, a), // y+
+				aabb3f( b,-a,-a, a,-b, a), // y-
+				aabb3f(-a,-a,-a,-b,-b, a), // y-
+				aabb3f( b,-a, b, a, a, a), // x+
+				aabb3f( b,-a,-a, a, a,-b), // x+
+				aabb3f(-a,-a, b,-b, a, a), // x-
+				aabb3f(-a,-a,-a,-b, a,-b), // x-
+				aabb3f(-a, b, b, a, a, a), // z+
+				aabb3f(-a,-a, b, a,-b, a), // z+
+				aabb3f(-a,-a,-a, a,-b,-b), // z-
+				aabb3f(-a, b,-a, a, a,-b)  // z-
+			};
+			aabb3f glass_faces[6] = {
+				aabb3f(-a, a,-a, a, a, a), // y+
+				aabb3f(-a,-a,-a, a,-a, a), // y-
+				aabb3f( a,-a,-a, a, a, a), // x+
+				aabb3f(-a,-a,-a,-a, a, a), // x-
+				aabb3f(-a,-a, a, a, a, a), // z+
+				aabb3f(-a,-a,-a, a, a,-a)  // z-
+			};
+			
+			int visible_faces[6] = {0,0,0,0,0,0};
+			int nb[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+			u8 i;
+			content_t current = n.getContent();
+			content_t content;
+			MapNode n2;
+			v3s16 n2p;
+			for(i=0; i<18; i++)
+			{
+				n2p = blockpos_nodes + p + g_26dirs[i];
+				n2 = data->m_vmanip.getNodeNoEx(n2p);
+				content_t n2c = n2.getContent();
+				//TODO: remove CONTENT_IGNORE check when getNodeNoEx is fixed
+				if (n2c == current || n2c == CONTENT_IGNORE)
+					nb[i]=1;
+			}
+			for(i=0; i<6; i++)
+			{
+				n2p = blockpos_nodes + p + dirs[i];
+				n2 = data->m_vmanip.getNodeNoEx(n2p);
+				content = n2.getContent();
+				const ContentFeatures &f2 = nodedef->get(content);
+				if (content == CONTENT_AIR || f2.isLiquid())
+					visible_faces[i]=1;
+			}
+			static const u8 nb_triplet[12*3] = {
+				1,2, 7,  1,5, 6,  4,2,15,  4,5,14,
+				2,0,11,  2,3,13,  5,0,10,  5,3,12,
+				0,1, 8,  0,4,16,  3,4,17,  3,1, 9
+			};
+
+			f32 tx1,ty1,tz1,tx2,ty2,tz2;
+			aabb3f box;
+			for(i=0; i<12; i++)
+			{
+				int edge_invisible;
+				if (nb[nb_triplet[i*3+2]]==1)
+					edge_invisible=nb[nb_triplet[i*3]] & nb[nb_triplet[i*3+1]];
+				else
+					edge_invisible=nb[nb_triplet[i*3]] ^ nb[nb_triplet[i*3+1]];
+				if (edge_invisible)
+					continue;
+				box=frame_edges[i];
+				box.MinEdge += pos;
+				box.MaxEdge += pos;
+				tx1 = (box.MinEdge.X/BS)+0.5;
+				ty1 = (box.MinEdge.Y/BS)+0.5;
+				tz1 = (box.MinEdge.Z/BS)+0.5;
+				tx2 = (box.MaxEdge.X/BS)+0.5;
+				ty2 = (box.MaxEdge.Y/BS)+0.5;
+				tz2 = (box.MaxEdge.Z/BS)+0.5;
+				f32 txc1[24] = {
+					tx1,   1-tz2,   tx2, 1-tz1,
+					tx1,     tz1,   tx2,   tz2,
+					tz1,   1-ty2,   tz2, 1-ty1,
+					1-tz2, 1-ty2, 1-tz1, 1-ty1,
+					1-tx2, 1-ty2, 1-tx1, 1-ty1,
+					tx1,   1-ty2,   tx2, 1-ty1,
+				};
+				makeCuboid(&collector, box, &tiles[0], 1, c, txc1);
+			}
+			for(i=0; i<6; i++)
+			{
+				if (visible_faces[i]==0)
+					continue;
+				box=glass_faces[i];
+				box.MinEdge += pos;
+				box.MaxEdge += pos;
+				tx1 = (box.MinEdge.X/BS)+0.5;
+				ty1 = (box.MinEdge.Y/BS)+0.5;
+				tz1 = (box.MinEdge.Z/BS)+0.5;
+				tx2 = (box.MaxEdge.X/BS)+0.5;
+				ty2 = (box.MaxEdge.Y/BS)+0.5;
+				tz2 = (box.MaxEdge.Z/BS)+0.5;
+				f32 txc2[24] = {
+					tx1,   1-tz2,   tx2, 1-tz1,
+					tx1,     tz1,   tx2,   tz2,
+					tz1,   1-ty2,   tz2, 1-ty1,
+					1-tz2, 1-ty2, 1-tz1, 1-ty1,
+					1-tx2, 1-ty2, 1-tx1, 1-ty1,
+					tx1,   1-ty2,   tx2, 1-ty1,
+				};
+				makeCuboid(&collector, box, &tiles[1], 1, c, txc2);
+			}
+		break;}
 		case NDT_ALLFACES:
 		{
 			TileSpec tile_leaves = getNodeTile(n, p,
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index e09c1910d..ba3e42e98 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -628,6 +628,10 @@ class CNodeDefManager: public IWritableNodeDefManager
 				f->solidness = 0;
 				f->visual_solidness = 1;
 				break;
+			case NDT_GLASSLIKE_FRAMED:
+				f->solidness = 0;
+				f->visual_solidness = 1;
+				break;
 			case NDT_ALLFACES:
 				f->solidness = 0;
 				f->visual_solidness = 1;
diff --git a/src/nodedef.h b/src/nodedef.h
index d846489ae..8be18f9cb 100644
--- a/src/nodedef.h
+++ b/src/nodedef.h
@@ -133,6 +133,8 @@ enum NodeDrawType
 	NDT_LIQUID, // Do not draw face towards same kind of flowing/source liquid
 	NDT_FLOWINGLIQUID, // A very special kind of thing
 	NDT_GLASSLIKE, // Glass-like, don't draw faces towards other glass
+	NDT_GLASSLIKE_FRAMED, // Glass-like, draw connected frames and all all visible faces
+						  // uses 2 textures, one for frames, second for faces
 	NDT_ALLFACES, // Leaves-like, draw all faces no matter what
 	NDT_ALLFACES_OPTIONAL, // Fancy -> allfaces, fast -> normal
 	NDT_TORCHLIKE,
diff --git a/src/scriptapi_node.cpp b/src/scriptapi_node.cpp
index 5ffcaeb9d..2fea50fa1 100644
--- a/src/scriptapi_node.cpp
+++ b/src/scriptapi_node.cpp
@@ -34,6 +34,7 @@ struct EnumString es_DrawType[] =
 	{NDT_LIQUID, "liquid"},
 	{NDT_FLOWINGLIQUID, "flowingliquid"},
 	{NDT_GLASSLIKE, "glasslike"},
+	{NDT_GLASSLIKE_FRAMED, "glasslike_framed"},
 	{NDT_ALLFACES, "allfaces"},
 	{NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
 	{NDT_TORCHLIKE, "torchlike"},
-- 
GitLab