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 @@ public: 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"},