Now the isometric mesher's walls get properly y sorted.

This commit is contained in:
Relintai 2022-03-03 17:57:59 +01:00
parent 324611fc46
commit 5567c7da33
5 changed files with 114 additions and 48 deletions

View File

@ -100,15 +100,18 @@ void Terrain2DMesherIsometric::mesh_base(Ref<Terrain2DChunkDefault> chunk) {
int margin_start = chunk->get_margin_start();
//z_size + margin_start is fine, x, and z are in data space.
for (int y = margin_start; y < y_size + margin_start; ++y) {
for (int x = margin_start; x < x_size + margin_start; ++x) {
for (int dy = margin_start; dy < y_size + margin_start; ++dy) {
for (int dx = margin_start; dx < x_size + margin_start; ++dx) {
int indexes[4] = {
chunk->get_data_index(x, y),
chunk->get_data_index(x + 1, y),
chunk->get_data_index(x, y + 1),
chunk->get_data_index(x + 1, y + 1)
chunk->get_data_index(dx, dy),
chunk->get_data_index(dx + 1, dy),
chunk->get_data_index(dx, dy + 1),
chunk->get_data_index(dx + 1, dy + 1)
};
int x = dx - margin_start;
int y = dy - margin_start;
uint8_t type = channel_type[indexes[0]];
if (type == 0)
@ -387,15 +390,18 @@ void Terrain2DMesherIsometric::mesh_walls(Ref<Terrain2DChunkDefault> chunk) {
int margin_start = chunk->get_margin_start();
//z_size + margin_start is fine, x, and z are in data space.
for (int y = margin_start; y < y_size + margin_start; ++y) {
for (int x = margin_start; x < x_size + margin_start; ++x) {
for (int dy = margin_start; dy < y_size + margin_start; ++dy) {
for (int dx = margin_start; dx < x_size + margin_start; ++dx) {
int indexes[4] = {
chunk->get_data_index(x, y),
chunk->get_data_index(x + 1, y),
chunk->get_data_index(x, y + 1),
chunk->get_data_index(x + 1, y + 1)
chunk->get_data_index(dx, dy),
chunk->get_data_index(dx + 1, dy),
chunk->get_data_index(dx, dy + 1),
chunk->get_data_index(dx + 1, dy + 1)
};
int x = dx - margin_start;
int y = dy - margin_start;
uint8_t type = channel_type[indexes[0]];
if (type == 0)
@ -460,31 +466,22 @@ void Terrain2DMesherIsometric::mesh_walls(Ref<Terrain2DChunkDefault> chunk) {
}
}
Vector2 verts_normal[] = {
Vector2(0, 0),
Vector2(cell_size_x, 0),
Vector2(0, cell_size_y),
Vector2(cell_size_x, cell_size_y)
};
// Note that +y is down!
Vector2 verts_wall[] = {
Vector2(0, -cell_size_y),
Vector2(cell_size_x, -cell_size_y),
Vector2(0, 0),
Vector2(cell_size_x, 0)
};
int vc = get_vertex_count();
if ((flags & Terrain2DChunkDefault::FLAG_CHANNEL_WALL_HOLE) != 0) {
continue;
}
_mesh_transform = Transform2D(0, mesh_transform_terrain.xform(Vector2(x * cell_size_x, y * cell_size_y)));
if ((flags & Terrain2DChunkDefault::FLAG_CHANNEL_WALL_NORTH) != 0) {
Vector2 vert_start_offset = mesh_transform_terrain.xform(Vector2(cell_size_x, cell_size_y));
int vc = get_vertex_count();
_mesh_transform = Transform2D(0, mesh_transform_terrain.xform(Vector2((x + 1) * cell_size_x, y * cell_size_y)));
// Note that +y is down!
Vector2 verts_wall_north[] = {
Vector2(-cell_size_x, -cell_size_y),
Vector2(0, -cell_size_y),
Vector2(-cell_size_x, 0),
Vector2(0, 0)
};
for (int i = 0; i < 4; ++i) {
if (use_lighting) {
@ -494,7 +491,7 @@ void Terrain2DMesherIsometric::mesh_walls(Ref<Terrain2DChunkDefault> chunk) {
}
add_uv(uvs[i]);
add_vertex(mesh_transform_wall_north.xform(verts_wall[i]) + vert_start_offset);
add_vertex(mesh_transform_wall_north.xform(verts_wall_north[i]));
}
add_indices(vc + 0);
@ -504,11 +501,24 @@ void Terrain2DMesherIsometric::mesh_walls(Ref<Terrain2DChunkDefault> chunk) {
add_indices(vc + 2);
add_indices(vc + 3);
vc += 4;
if ((chunk->get_build_flags() & Terrain2DChunkDefault::BUILD_FLAG_USE_LIGHTING) != 0) {
bake_colors(chunk);
}
store_mesh();
}
if ((flags & Terrain2DChunkDefault::FLAG_CHANNEL_WALL_WEST) != 0) {
Vector2 vert_start_offset = mesh_transform_terrain.xform(Vector2(cell_size_x, cell_size_y + cell_size_y));
int vc = get_vertex_count();
_mesh_transform = Transform2D(0, mesh_transform_terrain.xform(Vector2(x * cell_size_x, (y + 1) * cell_size_y)));
Vector2 verts_wall_west[] = {
Vector2(0, -cell_size_y),
Vector2(cell_size_x, -cell_size_y),
Vector2(0, 0),
Vector2(cell_size_x, 0)
};
for (int i = 0; i < 4; ++i) {
if (use_lighting) {
@ -519,7 +529,8 @@ void Terrain2DMesherIsometric::mesh_walls(Ref<Terrain2DChunkDefault> chunk) {
add_uv(uvs[i]);
add_vertex(mesh_transform_wall_west.xform(verts_wall[i]) + vert_start_offset);
//add_vertex(mesh_transform_wall_west.xform(verts_wall[i]));
add_vertex(mesh_transform_wall_west.xform(verts_wall_west[i]));
}
add_indices(vc + 0);
@ -529,11 +540,24 @@ void Terrain2DMesherIsometric::mesh_walls(Ref<Terrain2DChunkDefault> chunk) {
add_indices(vc + 2);
add_indices(vc + 3);
vc += 4;
if ((chunk->get_build_flags() & Terrain2DChunkDefault::BUILD_FLAG_USE_LIGHTING) != 0) {
bake_colors(chunk);
}
store_mesh();
}
if ((flags & Terrain2DChunkDefault::FLAG_CHANNEL_WALL_SOUTH) != 0) {
Vector2 vert_start_offset = mesh_transform_terrain.xform(Vector2(cell_size_x, cell_size_y + cell_size_y));
int vc = get_vertex_count();
_mesh_transform = Transform2D(0, mesh_transform_terrain.xform(Vector2((x)*cell_size_x, (y + 1) * cell_size_y)));
Vector2 verts_wall_south[] = {
Vector2(0, -cell_size_y),
Vector2(cell_size_x, -cell_size_y),
Vector2(0, 0),
Vector2(cell_size_x, 0)
};
for (int i = 0; i < 4; ++i) {
if (use_lighting) {
@ -543,7 +567,8 @@ void Terrain2DMesherIsometric::mesh_walls(Ref<Terrain2DChunkDefault> chunk) {
}
add_uv(uvs[i]);
add_vertex(mesh_transform_wall_south.xform(verts_wall[i]) + vert_start_offset);
add_vertex(mesh_transform_wall_south.xform(verts_wall_south[i]));
//add_vertex((verts_wall_south[i]));
}
add_indices(vc + 0);
@ -553,11 +578,24 @@ void Terrain2DMesherIsometric::mesh_walls(Ref<Terrain2DChunkDefault> chunk) {
add_indices(vc + 2);
add_indices(vc + 3);
vc += 4;
if ((chunk->get_build_flags() & Terrain2DChunkDefault::BUILD_FLAG_USE_LIGHTING) != 0) {
bake_colors(chunk);
}
store_mesh();
}
if ((flags & Terrain2DChunkDefault::FLAG_CHANNEL_WALL_EAST) != 0) {
Vector2 vert_start_offset = mesh_transform_terrain.xform(Vector2(cell_size_x + cell_size_x, cell_size_y + cell_size_y));
int vc = get_vertex_count();
_mesh_transform = Transform2D(0, mesh_transform_terrain.xform(Vector2((x + 1)*cell_size_x, (y ) * cell_size_y)));
Vector2 verts_wall_east[] = {
Vector2(-cell_size_x, -cell_size_y),
Vector2(0, -cell_size_y),
Vector2(-cell_size_x, 0),
Vector2(0, 0)
};
for (int i = 0; i < 4; ++i) {
if (use_lighting) {
@ -567,7 +605,8 @@ void Terrain2DMesherIsometric::mesh_walls(Ref<Terrain2DChunkDefault> chunk) {
}
add_uv(uvs[i]);
add_vertex(mesh_transform_wall_east.xform(verts_wall[i]) + vert_start_offset);
add_vertex(mesh_transform_wall_east.xform(verts_wall_east[i]));
//add_vertex((verts_wall_east[i]));
}
add_indices(vc + 0);
@ -577,10 +616,6 @@ void Terrain2DMesherIsometric::mesh_walls(Ref<Terrain2DChunkDefault> chunk) {
add_indices(vc + 2);
add_indices(vc + 3);
vc += 4;
}
if (_vertices.size() > 0) {
if ((chunk->get_build_flags() & Terrain2DChunkDefault::BUILD_FLAG_USE_LIGHTING) != 0) {
bake_colors(chunk);
}

View File

@ -492,6 +492,28 @@ void Terrain2DMesher::build_stored_mesh_into(const int index, RID mesh) {
VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VisualServer::PRIMITIVE_TRIANGLES, arr);
}
AABB Terrain2DMesher::calculate_stored_mesh_aabb(const int index) {
ERR_FAIL_INDEX_V(index, _stored_meshes.size(), AABB());
const Terrain2DMesherStoredMesh &md = _stored_meshes[index];
if (md.vertices.size() == 0) {
//Nothing to do
return AABB();
}
AABB aabb;
int len = md.vertices.size();
aabb.position = Vector3(md.vertices[0].vertex.x, md.vertices[0].vertex.y, 0);
for (int i = 0; i < len; i++) {
aabb.expand_to(Vector3(md.vertices[i].vertex.x, md.vertices[i].vertex.y, 0));
}
return aabb;
}
void Terrain2DMesher::reset() {
_vertices.resize(0);
_indices.resize(0);

View File

@ -157,6 +157,7 @@ public:
Array build_stored_mesh(const int index);
Transform2D get_stored_mesh_transform(const int index);
void build_stored_mesh_into(const int index, RID mesh);
AABB calculate_stored_mesh_aabb(const int index);
PoolVector<Vector2> get_vertices() const;
void set_vertices(const PoolVector<Vector2> &values);

View File

@ -698,10 +698,16 @@ void Terrain2DChunkDefault::_draw() {
if (terrain_mesh_rid != RID()) {
RID terrain_texture_rid = mesh_rid_get(MESH_INDEX_TERRAIN, MESH_TYPE_INDEX_TEXTURE_RID);
VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(i), get_transform() * _mesh_transforms[i]);
VisualServer::get_singleton()->canvas_item_clear(get_canvas_item(i));
Transform2D t = get_transform() * _mesh_transforms[i];
VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(i), t);
//if (i != 0) {
// VisualServer::get_singleton()->canvas_item_set_custom_rect(get_canvas_item(i), true, Rect2(t.xform(Vector2()), Vector2(128, 128)));
//}
//Note: the transform parameter is not implemented in gles2
VisualServer::get_singleton()->canvas_item_add_mesh(get_canvas_item(i), terrain_mesh_rid, Transform2D(), Color(1, 1, 1, 1), terrain_texture_rid, RID());
}

View File

@ -411,6 +411,8 @@ void Terrain2DTerrain2DJob::step_type_normal() {
VS::get_singleton()->mesh_add_surface_from_arrays(mesh_rid, VisualServer::PRIMITIVE_TRIANGLES, arr);
chunk->_mesh_transforms.write[i + 1] = _mesher->get_stored_mesh_transform(i);
//AABB aabb = _mesher->calculate_stored_mesh_aabb(i);
//VS::get_singleton()->mesh_set_custom_aabb(mesh_rid, aabb);
}
}