Skip to content

Commit

Permalink
Patched all remaining element processors to new elevation logic (exce…
Browse files Browse the repository at this point in the history
…pt for bridges)
  • Loading branch information
louis-e committed Jan 6, 2025
1 parent 66819a5 commit f50e108
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 117 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 14 additions & 7 deletions src/data_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,18 @@ pub fn generate_world(
} else if way.tags.contains_key("barrier") {
barriers::generate_barriers(&mut editor, element, &ground);
} else if way.tags.contains_key("waterway") {
//waterways::generate_waterways(&mut editor, way, &ground); //TODO
waterways::generate_waterways(&mut editor, way, &ground);
} else if way.tags.contains_key("bridge") {
bridges::generate_bridges(&mut editor, way, &ground);
} else if way.tags.contains_key("railway") {
//railways::generate_railways(&mut editor, way, &ground); //TODO
railways::generate_railways(&mut editor, way, &ground);
} else if way.tags.get("service") == Some(&"siding".to_string()) {
//highways::generate_siding(&mut editor, way, &ground); //TODO
highways::generate_siding(&mut editor, way, &ground);
}
}
ProcessedElement::Node(node) => {
if node.tags.contains_key("door") || node.tags.contains_key("entrance") {
//doors::generate_doors(&mut editor, node, &ground); //TODO
doors::generate_doors(&mut editor, node, &ground);
} else if node.tags.contains_key("natural")
&& node.tags.get("natural") == Some(&"tree".to_string())
{
Expand All @@ -107,12 +107,19 @@ pub fn generate_world(
} else if node.tags.contains_key("highway") {
highways::generate_highways(&mut editor, element, &ground, args);
} else if node.tags.contains_key("tourism") {
//tourisms::generate_tourisms(&mut editor, node, &ground); //TODO
tourisms::generate_tourisms(&mut editor, node, &ground);
}
}
ProcessedElement::Relation(rel) => {
if rel.tags.contains_key("water") {
//water_areas::generate_water_areas(&mut editor, rel, &ground); //TODO
if rel.tags.contains_key("building") || rel.tags.contains_key("building:part") {
buildings::generate_building_from_relation(
&mut editor,
rel,
&ground,
args,
);
} else if rel.tags.contains_key("water") {
water_areas::generate_water_areas(&mut editor, rel, &ground);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/element_processing/amenities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ pub fn generate_amenities(
let y = ground.level(pt) + 1;

editor.set_block(SMOOTH_STONE, pt.x, y, pt.z, None, None);
editor.set_block(OAK_LOG, pt.x + 1, y + 1, pt.z, None, None);
editor.set_block(OAK_LOG, pt.x - 1, y + 1, pt.z, None, None);
editor.set_block(OAK_LOG, pt.x + 1, y, pt.z, None, None);
editor.set_block(OAK_LOG, pt.x - 1, y, pt.z, None, None);
}
}
"vending" => {
Expand Down
2 changes: 1 addition & 1 deletion src/element_processing/bridges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn generate_bridges(editor: &mut WorldEditor, element: &ProcessedWay, ground
let y2: i32 = ground.level(cur.xz());
let z2: i32 = cur.z;

let ground_level = 60; // FIXME TODO
let ground_level = 60; // ELEVATION TODO

// Generate the line of coordinates between the two nodes
let bresenham_points: Vec<(i32, i32, i32)> = bresenham_line(x1, 0, z1, x2, 0, z2);
Expand Down
25 changes: 3 additions & 22 deletions src/element_processing/buildings.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::args::Args;
use crate::block_definitions::*;
use crate::bresenham::bresenham_line;
use crate::cartesian::XZPoint;
use crate::colors::{color_text_to_rgb_tuple, rgb_distance, RGBTuple};
use crate::floodfill::flood_fill_area;
use crate::ground::Ground;
Expand Down Expand Up @@ -409,27 +410,7 @@ pub fn generate_building_from_relation(
// Process the outer way to create the building walls
for member in &relation.members {
if member.role == ProcessedMemberRole::Outer {
generate_buildings(editor, &member.way, &ground, args);
}
}

// Handle inner ways (holes, courtyards, etc.)
for member in &relation.members {
if member.role == ProcessedMemberRole::Inner {
let polygon_coords: Vec<(i32, i32)> =
member.way.nodes.iter().map(|n| (n.x, n.z)).collect();
let hole_area: Vec<(i32, i32)> =
flood_fill_area(&polygon_coords, args.timeout.as_ref());

let Some(ground_level) = ground.min_level(member.way.nodes.iter().map(|n| n.xz()))
else {
return;
};

for (x, z) in hole_area {
// Remove blocks in the inner area to create a hole
editor.set_block(AIR, x, ground_level, z, None, Some(&[SPONGE]));
}
generate_buildings(editor, &member.way, ground, args);
}
}
}
Expand All @@ -452,7 +433,7 @@ fn generate_bridge(
floodfill_timeout: Option<&Duration>,
) {
// Calculate the bridge level
let mut bridge_level: i32 = 60; // TODO
let mut bridge_level: i32 = 60; // ELEVATION TODO
if let Some(level_str) = element.tags.get("level") {
if let Ok(level) = level_str.parse::<i32>() {
bridge_level += (level * 3) + 1; // Adjust height by levels
Expand Down
7 changes: 6 additions & 1 deletion src/element_processing/doors.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::block_definitions::*;
use crate::cartesian::XZPoint;
use crate::osm_parser::ProcessedNode;
use crate::ground::Ground;
use crate::world_editor::WorldEditor;

pub fn generate_doors(editor: &mut WorldEditor, element: &ProcessedNode, ground_level: i32) {
pub fn generate_doors(editor: &mut WorldEditor, element: &ProcessedNode, ground: &Ground) {
// Check if the element is a door or entrance
if element.tags.contains_key("door") || element.tags.contains_key("entrance") {
// Check for the "level" tag and skip doors that are not at ground level
Expand All @@ -17,6 +19,9 @@ pub fn generate_doors(editor: &mut WorldEditor, element: &ProcessedNode, ground_
let x: i32 = element.x;
let z: i32 = element.z;

// Calculate the dynamic ground level
let ground_level = ground.level(XZPoint::new(x, z));

// Set the ground block and the door blocks
editor.set_block(GRAY_CONCRETE, x, ground_level, z, None, None);
editor.set_block(DARK_OAK_DOOR_LOWER, x, ground_level + 1, z, None, None);
Expand Down
29 changes: 12 additions & 17 deletions src/element_processing/highways.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,31 +284,26 @@ pub fn generate_highways(
}

/// Generates a siding using stone brick slabs
pub fn generate_siding(editor: &mut WorldEditor, element: &ProcessedWay, ground_level: i32) {
let mut previous_node: Option<(i32, i32)> = None;
pub fn generate_siding(editor: &mut WorldEditor, element: &ProcessedWay, ground: &Ground) {
let mut previous_node: Option<XZPoint> = None;
let siding_block: Block = STONE_BRICK_SLAB;

for node in &element.nodes {
let x: i32 = node.x;
let z: i32 = node.z;
let current_node = node.xz();

// Draw the siding using Bresenham's line algorithm between nodes
if let Some(prev) = previous_node {
let bresenham_points: Vec<(i32, i32, i32)> =
bresenham_line(prev.0, ground_level + 1, prev.1, x, ground_level + 1, z);
for (bx, by, bz) in bresenham_points {
if !editor.check_for_block(
bx,
by - 1,
bz,
None,
Some(&[BLACK_CONCRETE, WHITE_CONCRETE]),
) {
editor.set_block(siding_block, bx, by, bz, None, None);
if let Some(prev_node) = previous_node {
let bresenham_points: Vec<(i32, i32, i32)> = bresenham_line(prev_node.x, 0, prev_node.z, current_node.x, 0, current_node.z);

for (bx, _, bz) in bresenham_points {
let ground_level = ground.level(XZPoint::new(bx, bz)) + 1;

if !editor.check_for_block(bx, ground_level - 1, bz, None, Some(&[BLACK_CONCRETE, WHITE_CONCRETE])) {
editor.set_block(siding_block, bx, ground_level, bz, None, None);
}
}
}

previous_node = Some((x, z));
previous_node = Some(current_node);
}
}
4 changes: 2 additions & 2 deletions src/element_processing/leisure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ pub fn generate_leisure(
0 => {
// Benches
editor.set_block(OAK_LOG, x, ground_level + 1, z, None, None);
editor.set_block(OAK_LOG, x + 1, ground_level + 1, z, None, None);
editor.set_block(OAK_LOG, x - 1, ground_level + 1, z, None, None);
editor.set_block(OAK_LOG, x + 1, ground_level, z, None, None);
editor.set_block(OAK_LOG, x - 1, ground_level, z, None, None);
}
1..=30 => {
// Flowers
Expand Down
18 changes: 8 additions & 10 deletions src/element_processing/railways.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::block_definitions::*;
use crate::bresenham::bresenham_line;
use crate::cartesian::XZPoint;
use crate::ground::Ground;
use crate::osm_parser::ProcessedWay;
use crate::world_editor::WorldEditor;

pub fn generate_railways(editor: &mut WorldEditor, element: &ProcessedWay, ground_level: i32) {
pub fn generate_railways(editor: &mut WorldEditor, element: &ProcessedWay, ground: &Ground) {
if let Some(railway_type) = element.tags.get("railway") {
if ["proposed", "abandoned", "subway", "construction"].contains(&railway_type.as_str()) {
return;
Expand All @@ -22,19 +24,15 @@ pub fn generate_railways(editor: &mut WorldEditor, element: &ProcessedWay, groun
}

for i in 1..element.nodes.len() {
let prev: &crate::osm_parser::ProcessedNode = &element.nodes[i - 1];
let x1: i32 = prev.x;
let z1: i32 = prev.z;

let cur: &crate::osm_parser::ProcessedNode = &element.nodes[i];
let x2: i32 = cur.x;
let z2: i32 = cur.z;
let prev_node = element.nodes[i - 1].xz();
let cur_node = element.nodes[i].xz();

// Generate the line of coordinates between the two nodes
let bresenham_points: Vec<(i32, i32, i32)> =
bresenham_line(x1, ground_level, z1, x2, ground_level, z2);
let bresenham_points: Vec<(i32, i32, i32)> = bresenham_line(prev_node.x, 0, prev_node.z, cur_node.x, 0, cur_node.z);

for (bx, _, bz) in bresenham_points {
let ground_level = ground.level(XZPoint::new(bx, bz));

// TODO: Set direction of rail
editor.set_block(IRON_BLOCK, bx, ground_level, bz, None, None);
editor.set_block(RAIL, bx, ground_level + 1, bz, None, None);
Expand Down
9 changes: 7 additions & 2 deletions src/element_processing/tourisms.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::block_definitions::*;
use crate::cartesian::XZPoint;
use crate::osm_parser::ProcessedNode;
use crate::ground::Ground;
use crate::world_editor::WorldEditor;

pub fn generate_tourisms(editor: &mut WorldEditor, element: &ProcessedNode, ground_level: i32) {
pub fn generate_tourisms(editor: &mut WorldEditor, element: &ProcessedNode, ground: &Ground) {
// Skip if 'layer' or 'level' is negative in the tags
if let Some(layer) = element.tags.get("layer") {
if layer.parse::<i32>().unwrap_or(0) < 0 {
Expand All @@ -20,9 +22,12 @@ pub fn generate_tourisms(editor: &mut WorldEditor, element: &ProcessedNode, grou
let x: i32 = element.x;
let z: i32 = element.z;

// Calculate the dynamic ground level
let ground_level = ground.level(XZPoint::new(x, z));

if tourism_type == "information" {
if let Some("board") = element.tags.get("information").map(|x: &String| x.as_str()) {
// TODO draw a sign
// Draw an information board
editor.set_block(OAK_PLANKS, x, ground_level + 1, z, None, None);
}
}
Expand Down
Loading

0 comments on commit f50e108

Please sign in to comment.