#include "nodedef.h"
#include "tile.h"
#include "gamedef.h"
+#include "util/numeric.h"
+#include "util/serialize.h"
+#include "util/directiontables.h"
// Create a cuboid.
// collector - the MeshCollector for the resulting polygons
pa_liquid.x0(), pa_liquid.y0()),
};
- // This fixes a strange bug
+ // 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 += corner_levels[j];
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
+ int dz = (corner_levels[side_corners[2][0]] +
+ corner_levels[side_corners[2][1]] <
+ corner_levels[side_corners[3][0]] +
+ corner_levels[side_corners[3][1]]);
+ // Positive if liquid moves towards +X
+ int dx = (corner_levels[side_corners[0][0]] +
+ corner_levels[side_corners[0][1]] <
+ corner_levels[side_corners[1][0]] +
+ corner_levels[side_corners[1][1]]);
+ // -X
+ if(-dx >= abs(dz))
+ {
+ v2f t = vertices[0].TCoords;
+ vertices[0].TCoords = vertices[1].TCoords;
+ vertices[1].TCoords = vertices[2].TCoords;
+ vertices[2].TCoords = vertices[3].TCoords;
+ vertices[3].TCoords = t;
+ }
+ // +X
+ if(dx >= abs(dz))
+ {
+ v2f t = vertices[0].TCoords;
+ vertices[0].TCoords = vertices[3].TCoords;
+ vertices[3].TCoords = vertices[2].TCoords;
+ vertices[2].TCoords = vertices[1].TCoords;
+ vertices[1].TCoords = t;
+ }
+ // -Z
+ if(-dz >= abs(dx))
+ {
+ v2f t = vertices[0].TCoords;
+ vertices[0].TCoords = vertices[3].TCoords;
+ vertices[3].TCoords = vertices[2].TCoords;
+ vertices[2].TCoords = vertices[1].TCoords;
+ vertices[1].TCoords = t;
+ t = vertices[0].TCoords;
+ vertices[0].TCoords = vertices[3].TCoords;
+ vertices[3].TCoords = vertices[2].TCoords;
+ vertices[2].TCoords = vertices[1].TCoords;
+ vertices[1].TCoords = t;
+ }
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
if(n_plus_z_plus_y.getContent() == thiscontent)
is_rail_z_plus_y[1] = true;
-
bool is_rail_x_all[] = {false, false};
bool is_rail_z_all[] = {false, false};
is_rail_x_all[0]=is_rail_x[0] || is_rail_x_minus_y[0] || is_rail_x_plus_y[0];
is_rail_z_all[0]=is_rail_z[0] || is_rail_z_minus_y[0] || is_rail_z_plus_y[0];
is_rail_z_all[1]=is_rail_z[1] || is_rail_z_minus_y[1] || is_rail_z_plus_y[1];
- bool is_straight = (is_rail_x_all[0] && is_rail_x_all[1]) || (is_rail_z_all[0] && is_rail_z_all[1]);//is really straight, rails on both sides
- int adjacencies = is_rail_x_all[0] + is_rail_x_all[1] + is_rail_z_all[0] + is_rail_z_all[1];
+ // reasonable default, flat straight unrotated rail
+ bool is_straight = true;
+ int adjacencies = 0;
+ int angle = 0;
+ u8 tileindex = 0;
- if (is_rail_x_plus_y[0] || is_rail_x_plus_y[1] || is_rail_z_plus_y[0] || is_rail_z_plus_y[1]) //is straight because sloped
+ // check for sloped rail
+ if (is_rail_x_plus_y[0] || is_rail_x_plus_y[1] || is_rail_z_plus_y[0] || is_rail_z_plus_y[1])
{
adjacencies = 5; //5 means sloped
- is_straight = true;
+ is_straight = true; // sloped is always straight
}
-
- // Assign textures
- u8 tileindex = 0; // straight
- if(adjacencies < 2)
- tileindex = 0; // straight
- else if(adjacencies == 2)
+ else
{
- if(is_straight)
- tileindex = 0; // straight
- else
- tileindex = 1; // curved
+ // is really straight, rails on both sides
+ is_straight = (is_rail_x_all[0] && is_rail_x_all[1]) || (is_rail_z_all[0] && is_rail_z_all[1]);
+ adjacencies = is_rail_x_all[0] + is_rail_x_all[1] + is_rail_z_all[0] + is_rail_z_all[1];
}
- else if(adjacencies == 3)
+
+ switch (adjacencies) {
+ case 1:
+ if(is_rail_x_all[0] || is_rail_x_all[1])
+ angle = 90;
+ break;
+ case 2:
+ if(!is_straight)
+ tileindex = 1; // curved
+ if(is_rail_x_all[0] && is_rail_x_all[1])
+ angle = 90;
+ if(is_rail_z_all[0] && is_rail_z_all[1]){
+ if (n_minus_z_plus_y.getContent() == thiscontent) angle = 180;
+ }
+ else if(is_rail_x_all[0] && is_rail_z_all[0])
+ angle = 270;
+ else if(is_rail_x_all[0] && is_rail_z_all[1])
+ angle = 180;
+ else if(is_rail_x_all[1] && is_rail_z_all[1])
+ angle = 90;
+ break;
+ case 3:
+ // here is where the potential to 'switch' a junction is, but not implemented at present
tileindex = 2; // t-junction
- else if(adjacencies == 4)
+ if(!is_rail_x_all[1])
+ angle=180;
+ if(!is_rail_z_all[0])
+ angle=90;
+ if(!is_rail_z_all[1])
+ angle=270;
+ break;
+ case 4:
tileindex = 3; // crossing
+ break;
+ case 5: //sloped
+ if(is_rail_z_plus_y[0])
+ angle = 180;
+ if(is_rail_x_plus_y[0])
+ angle = 90;
+ if(is_rail_x_plus_y[1])
+ angle = -90;
+ break;
+ default:
+ break;
+ }
TileSpec tile = getNodeTileN(n, p, tileindex, data);
tile.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
ap.x0(), ap.y0()),
};
-
- // Rotate textures
- int angle = 0;
-
- if(adjacencies == 1)
- {
- if(is_rail_x_all[0] || is_rail_x_all[1])
- angle = 90;
- }
- if(adjacencies == 2)
- {
- if(is_rail_x_all[0] && is_rail_x_all[1])
- {
- angle = 90;
- }
- if(is_rail_z_all[0] && is_rail_z_all[1])
- {
- if (n_minus_z_plus_y.getContent() == thiscontent) angle = 180;
- }
- else if(is_rail_x_all[0] && is_rail_z_all[0])
- angle = 270;
- else if(is_rail_x_all[0] && is_rail_z_all[1])
- angle = 180;
- else if(is_rail_x_all[1] && is_rail_z_all[1])
- angle = 90;
- }
- if(adjacencies == 3)
+ for(s32 i=0; i<4; i++)
{
- if(!is_rail_x_all[0])
- angle=0;
- if(!is_rail_x_all[1])
- angle=180;
- if(!is_rail_z_all[0])
- angle=90;
- if(!is_rail_z_all[1])
- angle=270;
+ if(angle != 0)
+ vertices[i].Pos.rotateXZBy(angle);
+ vertices[i].Pos += intToFloat(p, BS);
}
- //adjacencies 4: Crossing
- if(adjacencies == 5) //sloped
+
+ u16 indices[] = {0,1,2,2,3,0};
+ collector.append(tile, vertices, 4, indices, 6);
+ break;}
+ case NDT_NODEBOX:
+ {
+ static const v3s16 tile_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[6];
+ for(int i = 0; i < 6; i++)
{
- if(is_rail_z_plus_y[0])
- angle = 180;
- if(is_rail_x_plus_y[0])
- angle = 90;
- if(is_rail_x_plus_y[1])
- angle = -90;
+ // Handles facedir rotation for textures
+ tiles[i] = getNodeTile(n, p, tile_dirs[i], data);
}
- if(angle != 0) {
- for(u16 i=0; i<4; i++)
- vertices[i].Pos.rotateXZBy(angle);
- }
+ u16 l = getInteriorLight(n, 0, data);
+ video::SColor c = MapBlock_LightColor(255, l);
- for(s32 i=0; i<4; i++)
+ v3f pos = intToFloat(p, BS);
+
+ std::vector<aabb3f> boxes = n.getNodeBoxes(nodedef);
+ for(std::vector<aabb3f>::iterator
+ i = boxes.begin();
+ i != boxes.end(); i++)
{
- vertices[i].Pos += intToFloat(p, BS);
- }
+ aabb3f box = *i;
+ box.MinEdge += pos;
+ box.MaxEdge += pos;
+
+ // Compute texture coords
+ f32 tx1 = (i->MinEdge.X/BS)+0.5;
+ f32 ty1 = (i->MinEdge.Y/BS)+0.5;
+ f32 tz1 = (i->MinEdge.Z/BS)+0.5;
+ f32 tx2 = (i->MaxEdge.X/BS)+0.5;
+ f32 ty2 = (i->MaxEdge.Y/BS)+0.5;
+ f32 tz2 = (i->MaxEdge.Z/BS)+0.5;
+ f32 txc[24] = {
+ // up
+ tx1, 1-tz2, tx2, 1-tz1,
+ // down
+ tx1, tz1, tx2, tz2,
+ // right
+ tz1, 1-ty2, tz2, 1-ty1,
+ // left
+ 1-tz2, 1-ty2, 1-tz1, 1-ty1,
+ // back
+ 1-tx2, 1-ty2, 1-tx1, 1-ty1,
+ // front
+ tx1, 1-ty2, tx2, 1-ty1,
+ };
- u16 indices[] = {0,1,2,2,3,0};
- collector.append(tile, vertices, 4, indices, 6);
+ makeCuboid(&collector, box, tiles, 6, c, txc);
+ }
break;}
}
}