+v3s16 dirs8[8] = {
+ v3s16(0,0,0),
+ v3s16(0,0,1),
+ v3s16(0,1,0),
+ v3s16(0,1,1),
+ v3s16(1,0,0),
+ v3s16(1,1,0),
+ v3s16(1,0,1),
+ v3s16(1,1,1),
+};
+
+// Calculate lighting at the XYZ- corner of p
+u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
+{
+ u16 ambient_occlusion = 0;
+ u16 light = 0;
+ u16 light_count = 0;
+ for(u32 i=0; i<8; i++)
+ {
+ MapNode n = vmanip.getNodeNoEx(p - dirs8[i]);
+ if(content_features(n.d).param_type == CPT_LIGHT)
+ {
+ light += decode_light(n.getLightBlend(daynight_ratio));
+ light_count++;
+ }
+ else
+ {
+ if(n.d != CONTENT_IGNORE)
+ ambient_occlusion++;
+ }
+ }
+
+ if(light_count == 0)
+ return 255;
+
+ light /= light_count;
+
+ if(ambient_occlusion > 4)
+ {
+ ambient_occlusion -= 4;
+ light = (float)light / ((float)ambient_occlusion * 0.5 + 1.0);
+ }
+
+ return light;
+}
+
+// Calculate lighting at the given corner of p
+u8 getSmoothLight(v3s16 p, v3s16 corner,
+ VoxelManipulator &vmanip, u32 daynight_ratio)
+{
+ if(corner.X == 1) p.X += 1;
+ else assert(corner.X == -1);
+ if(corner.Y == 1) p.Y += 1;
+ else assert(corner.Y == -1);
+ if(corner.Z == 1) p.Z += 1;
+ else assert(corner.Z == -1);
+
+ return getSmoothLight(p, vmanip, daynight_ratio);
+}
+
+void getTileInfo(
+ // Input:
+ v3s16 blockpos_nodes,
+ v3s16 p,
+ v3s16 face_dir,
+ u32 daynight_ratio,
+ VoxelManipulator &vmanip,
+ NodeModMap &temp_mods,
+ bool smooth_lighting,
+ // Output:
+ bool &makes_face,
+ v3s16 &p_corrected,
+ v3s16 &face_dir_corrected,
+ u8 *lights,
+ TileSpec &tile
+ )
+{
+ MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p);
+ MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir);
+ TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods);
+ TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods);
+
+ // This is hackish
+ u8 content0 = getNodeContent(p, n0, temp_mods);
+ u8 content1 = getNodeContent(p + face_dir, n1, temp_mods);
+ u8 mf = face_contents(content0, content1);
+
+ if(mf == 0)
+ {
+ makes_face = false;
+ return;
+ }
+
+ makes_face = true;
+
+ if(mf == 1)
+ {
+ tile = tile0;
+ p_corrected = p;
+ face_dir_corrected = face_dir;
+ }
+ else
+ {
+ tile = tile1;
+ p_corrected = p + face_dir;
+ face_dir_corrected = -face_dir;
+ }
+
+ if(smooth_lighting == false)
+ {
+ lights[0] = lights[1] = lights[2] = lights[3] =
+ decode_light(getFaceLight(daynight_ratio, n0, n1, face_dir));
+ }
+ else
+ {
+ v3s16 vertex_dirs[4];
+ getNodeVertexDirs(face_dir_corrected, vertex_dirs);
+ for(u16 i=0; i<4; i++)
+ {
+ lights[i] = getSmoothLight(blockpos_nodes + p_corrected,
+ vertex_dirs[i], vmanip, daynight_ratio);
+ }
+ }
+
+ return;
+}
+