- /*
- Generate top side, if appropriate
- */
-
- if(top_is_same_liquid == false)
- {
- video::S3DVertex vertices[4] =
- {
- video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c1, 0,1),
- video::S3DVertex(BS/2,0,BS/2, 0,0,0, c1, 1,1),
- video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c1, 1,0),
- video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c1, 0,0),
- };
-
- // To get backface culling right, the vertices need to go
- // clockwise around the front of the face. And we happened to
- // calculate corner levels in exact reverse order.
- s32 corner_resolve[4] = {3,2,1,0};
-
- for(s32 i=0; i<4; i++)
- {
- //vertices[i].Pos.Y += liquid_level;
- //vertices[i].Pos.Y += neighbor_levels[v3s16(0,0,0)];
- s32 j = corner_resolve[i];
- vertices[i].Pos.Y += corner_levels[j];
- if (data->m_smooth_lighting)
- vertices[i].Color = blendLight(frame, vertices[i].Pos, tile_liquid.color);
- vertices[i].Pos += intToFloat(p, BS);
- }
-
- // Default downwards-flowing texture animation goes from
- // -Z towards +Z, thus the direction is +Z.
- // Rotate texture to make animation go in flow direction
- // Positive if liquid moves towards +Z
- f32 dz = (corner_levels[side_corners[3][0]] +
- corner_levels[side_corners[3][1]]) -
- (corner_levels[side_corners[2][0]] +
- corner_levels[side_corners[2][1]]);
- // Positive if liquid moves towards +X
- f32 dx = (corner_levels[side_corners[1][0]] +
- corner_levels[side_corners[1][1]]) -
- (corner_levels[side_corners[0][0]] +
- corner_levels[side_corners[0][1]]);
- f32 tcoord_angle = atan2(dz, dx) * core::RADTODEG ;
- v2f tcoord_center(0.5, 0.5);
- v2f tcoord_translate(
- blockpos_nodes.Z + z,
- blockpos_nodes.X + x);
- tcoord_translate.rotateBy(tcoord_angle);
- tcoord_translate.X -= floor(tcoord_translate.X);
- tcoord_translate.Y -= floor(tcoord_translate.Y);
-
- for(s32 i=0; i<4; i++)
- {
- vertices[i].TCoords.rotateBy(
- tcoord_angle,
- tcoord_center);
- vertices[i].TCoords += tcoord_translate;
- }
-
- v2f t = vertices[0].TCoords;
- vertices[0].TCoords = vertices[2].TCoords;
- vertices[2].TCoords = t;
-
- u16 indices[] = {0,1,2,2,3,0};
- // Add to mesh collector
- collector.append(tile_liquid, vertices, 4, indices, 6);
- }
- break;}
- case NDT_GLASSLIKE:
- {
- TileSpec tile = getNodeTile(n, p, v3s16(0,0,0), data);
-
- u16 l = getInteriorLight(n, 1, nodedef);
- video::SColor c = encode_light_and_color(l, tile.color,
- f.light_source);
- for(u32 j=0; j<6; j++)
- {
- // Check this neighbor
- v3s16 dir = g_6dirs[j];
- v3s16 n2p = blockpos_nodes + p + dir;
- MapNode n2 = data->m_vmanip.getNodeNoEx(n2p);
- // Don't make face if neighbor is of same type
- if(n2.getContent() == n.getContent())
- continue;
- video::SColor c2=c;
- if(!f.light_source)
- applyFacesShading(c2, v3f(dir.X, dir.Y, dir.Z));
-
-
- // The face at Z+
- video::S3DVertex vertices[4] = {
- video::S3DVertex(-BS/2,-BS/2,BS/2, dir.X,dir.Y,dir.Z, c2, 1,1),
- video::S3DVertex(BS/2,-BS/2,BS/2, dir.X,dir.Y,dir.Z, c2, 0,1),
- video::S3DVertex(BS/2,BS/2,BS/2, dir.X,dir.Y,dir.Z, c2, 0,0),
- video::S3DVertex(-BS/2,BS/2,BS/2, dir.X,dir.Y,dir.Z, c2, 1,0),
- };
-
- // Rotations in the g_6dirs format
- if(j == 0) // Z+
- for(u16 i=0; i<4; i++)
- vertices[i].Pos.rotateXZBy(0);
- else if(j == 1) // Y+
- for(u16 i=0; i<4; i++)
- vertices[i].Pos.rotateYZBy(-90);
- else if(j == 2) // X+
- for(u16 i=0; i<4; i++)
- vertices[i].Pos.rotateXZBy(-90);
- else if(j == 3) // Z-
- for(u16 i=0; i<4; i++)
- vertices[i].Pos.rotateXZBy(180);
- else if(j == 4) // Y-
- for(u16 i=0; i<4; i++)
- vertices[i].Pos.rotateYZBy(90);
- else if(j == 5) // X-
- for(u16 i=0; i<4; i++)
- vertices[i].Pos.rotateXZBy(90);
-
- for (u16 i = 0; i < 4; i++) {
- if (data->m_smooth_lighting)
- vertices[i].Color = blendLight(frame, vertices[i].Pos, vertices[i].Normal, tile.color);
- vertices[i].Pos += intToFloat(p, BS);
- }
-
- u16 indices[] = {0,1,2,2,3,0};
- // Add to mesh collector
- collector.append(tile, vertices, 4, indices, 6);
- }
- break;}
- case NDT_GLASSLIKE_FRAMED_OPTIONAL:
- // This is always pre-converted to something else
- FATAL_ERROR("NDT_GLASSLIKE_FRAMED_OPTIONAL not pre-converted as expected");
- 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)
- };
-
- u16 l = getInteriorLight(n, 1, nodedef);
- u8 i;
- TileSpec tiles[6];
- for (i = 0; i < 6; i++)
- tiles[i] = getNodeTile(n, p, dirs[i], data);
-
- video::SColor tile0color = encode_light_and_color(l,
- tiles[0].color, f.light_source);
-
- TileSpec glass_tiles[6];
- video::SColor glasscolor[6];
- if (tiles[1].texture && tiles[2].texture && tiles[3].texture) {
- glass_tiles[0] = tiles[2];
- glass_tiles[1] = tiles[3];
- glass_tiles[2] = tiles[1];
- glass_tiles[3] = tiles[1];
- glass_tiles[4] = tiles[1];
- glass_tiles[5] = tiles[1];
- } else {
- for (i = 0; i < 6; i++)
- glass_tiles[i] = tiles[1];
- }
- for (i = 0; i < 6; i++)
- glasscolor[i] = encode_light_and_color(l, glass_tiles[i].color,
- f.light_source);
-
- u8 param2 = n.getParam2();
- bool H_merge = ! bool(param2 & 128);
- bool V_merge = ! bool(param2 & 64);
- param2 = param2 & 63;
-
- v3f pos = intToFloat(p, BS);
- static const float a = BS / 2;
- static const float g = a - 0.003;
- 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-
- };
- static const aabb3f glass_faces[6] = {
- aabb3f(-g, g,-g, g, g, g), // y+
- aabb3f(-g,-g,-g, g,-g, g), // y-
- aabb3f( g,-g,-g, g, g, g), // x+
- aabb3f(-g,-g,-g,-g, g, g), // x-
- aabb3f(-g,-g, g, g, g, g), // z+
- aabb3f(-g,-g,-g, g, g,-g) // z-
- };
-
- // table of node visible faces, 0 = invisible
- int visible_faces[6] = {0,0,0,0,0,0};
-
- // table of neighbours, 1 = same type, checked with g_26dirs
- int nb[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
- // g_26dirs to check when only horizontal merge is allowed
- int nb_H_dirs[8] = {0,2,3,5,10,11,12,13};
-
- content_t current = n.getContent();
- content_t n2c;
- MapNode n2;
- v3s16 n2p;
-
- // neighbours checks for frames visibility
-
- if (!H_merge && V_merge) {
- n2p = blockpos_nodes + p + g_26dirs[1];
- n2 = data->m_vmanip.getNodeNoEx(n2p);
- n2c = n2.getContent();
- if (n2c == current || n2c == CONTENT_IGNORE)
- nb[1] = 1;
- n2p = blockpos_nodes + p + g_26dirs[4];
- n2 = data->m_vmanip.getNodeNoEx(n2p);
- n2c = n2.getContent();
- if (n2c == current || n2c == CONTENT_IGNORE)
- nb[4] = 1;
- } else if (H_merge && !V_merge) {
- for(i = 0; i < 8; i++) {
- n2p = blockpos_nodes + p + g_26dirs[nb_H_dirs[i]];
- n2 = data->m_vmanip.getNodeNoEx(n2p);
- n2c = n2.getContent();
- if (n2c == current || n2c == CONTENT_IGNORE)
- nb[nb_H_dirs[i]] = 1;
- }
- } else if (H_merge && V_merge) {
- for(i = 0; i < 18; i++) {
- n2p = blockpos_nodes + p + g_26dirs[i];
- n2 = data->m_vmanip.getNodeNoEx(n2p);
- n2c = n2.getContent();
- if (n2c == current || n2c == CONTENT_IGNORE)
- nb[i] = 1;
- }
- }