mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
draw on map
This commit is contained in:
parent
31b56b03b5
commit
91ed3c6a84
@ -81,6 +81,7 @@ fn main() {
|
||||
sample_pos(
|
||||
config,
|
||||
sampler,
|
||||
index,
|
||||
samples,
|
||||
uniform_idx_as_vec2(map_size_lg, posi),
|
||||
)
|
||||
|
@ -1626,6 +1626,8 @@ impl Site {
|
||||
}
|
||||
|
||||
pub fn is_castle(&self) -> bool { matches!(self.kind, SiteKind::Castle) }
|
||||
|
||||
pub fn is_bridge(&self) -> bool { matches!(self.kind, SiteKind::Bridge(_, _)) }
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
column::ColumnSample,
|
||||
sim::{RiverKind, WorldSim},
|
||||
CONFIG,
|
||||
CONFIG, IndexRef, site::SiteKind,
|
||||
};
|
||||
use common::{
|
||||
terrain::{
|
||||
@ -71,6 +71,7 @@ pub fn sample_wpos(config: &MapConfig, sampler: &WorldSim, wpos: Vec2<i32>) -> f
|
||||
pub fn sample_pos(
|
||||
config: &MapConfig,
|
||||
sampler: &WorldSim,
|
||||
index: IndexRef,
|
||||
samples: Option<&[Option<ColumnSample>]>,
|
||||
pos: Vec2<i32>,
|
||||
) -> MapSample {
|
||||
@ -102,6 +103,7 @@ pub fn sample_pos(
|
||||
river_kind,
|
||||
spline_derivative,
|
||||
is_path,
|
||||
is_bridge,
|
||||
) = sampler
|
||||
.get(pos)
|
||||
.map(|sample| {
|
||||
@ -116,6 +118,17 @@ pub fn sample_pos(
|
||||
sample.river.river_kind,
|
||||
sample.river.spline_derivative,
|
||||
sample.path.0.is_way(),
|
||||
sample.sites.iter().any(|site| match &index.sites.get(*site).kind {
|
||||
SiteKind::Bridge(bridge) => if let Some(plot) = bridge.wpos_tile(TerrainChunkSize::center_wpos(pos)).plot {
|
||||
match bridge.plot(plot).kind {
|
||||
crate::site2::PlotKind::Bridge(_) => true,
|
||||
_ => false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
},
|
||||
_ => false,
|
||||
}),
|
||||
)
|
||||
})
|
||||
.unwrap_or((
|
||||
@ -129,6 +142,7 @@ pub fn sample_pos(
|
||||
None,
|
||||
Vec2::zero(),
|
||||
false,
|
||||
false,
|
||||
));
|
||||
|
||||
let humidity = humidity.clamp(0.0, 1.0);
|
||||
@ -246,7 +260,9 @@ pub fn sample_pos(
|
||||
}
|
||||
};
|
||||
// TODO: Make principled.
|
||||
let rgb = if is_path {
|
||||
let rgb = if is_bridge {
|
||||
Rgb::new(0x80, 0x80, 0x80)
|
||||
} else if is_path {
|
||||
Rgb::new(0x37, 0x29, 0x23)
|
||||
} else {
|
||||
rgb
|
||||
|
@ -28,7 +28,7 @@ pub(crate) use self::{
|
||||
use crate::{
|
||||
all::{Environment, ForestKind, TreeAttr},
|
||||
block::BlockGen,
|
||||
civ::{Place, PointOfInterest},
|
||||
civ::{Place, PointOfInterest, self},
|
||||
column::ColumnGen,
|
||||
layer::spot::Spot,
|
||||
site::Site,
|
||||
@ -1657,7 +1657,7 @@ impl WorldSim {
|
||||
map_config.is_shaded = false;
|
||||
|
||||
map_config.generate(
|
||||
|pos| sample_pos(&map_config, self, Some(&samples_data), pos),
|
||||
|pos| sample_pos(&map_config, self, index, Some(&samples_data), pos),
|
||||
|pos| sample_wpos(&map_config, self, pos),
|
||||
|pos, (r, g, b, _a)| {
|
||||
// We currently ignore alpha and replace it with the height at pos, scaled to
|
||||
|
@ -1058,40 +1058,6 @@ impl Site {
|
||||
hard_alt: None,
|
||||
});
|
||||
|
||||
|
||||
let size = (1.5 + rng.gen::<f32>().powf(5.0) * 1.0).round() as u32;
|
||||
if let Some((aabr, door_tile, door_dir)) = attempt(32, || {
|
||||
site.find_roadside_aabr(
|
||||
&mut rng,
|
||||
4..(size + 1).pow(2),
|
||||
Extent2::broadcast(size),
|
||||
)
|
||||
}) {
|
||||
let house = plot::House::generate(
|
||||
land,
|
||||
&mut reseed(&mut rng),
|
||||
&site,
|
||||
door_tile,
|
||||
door_dir,
|
||||
aabr,
|
||||
);
|
||||
let house_alt = house.alt;
|
||||
let plot = site.create_plot(Plot {
|
||||
kind: PlotKind::House(house),
|
||||
root_tile: aabr.center(),
|
||||
tiles: aabr_tiles(aabr).collect(),
|
||||
seed: rng.gen(),
|
||||
});
|
||||
|
||||
site.blit_aabr(aabr, Tile {
|
||||
kind: TileKind::Building,
|
||||
plot: Some(plot),
|
||||
hard_alt: Some(house_alt),
|
||||
});
|
||||
} else {
|
||||
site.make_plaza(land, &mut rng);
|
||||
}
|
||||
|
||||
site
|
||||
}
|
||||
|
||||
|
@ -11,10 +11,33 @@ enum RoofKind {
|
||||
Hipped,
|
||||
}
|
||||
|
||||
struct HeightenedViaduct {
|
||||
slope_inv: i32,
|
||||
bridge_start_offset: i32,
|
||||
vault_spacing: i32,
|
||||
vault_size: (i32, i32),
|
||||
side_vault_size: (i32, i32),
|
||||
holes: bool,
|
||||
}
|
||||
|
||||
impl HeightenedViaduct {
|
||||
fn random(rng: &mut impl Rng) -> Self {
|
||||
Self {
|
||||
slope_inv: rng.gen_range(6..=8),
|
||||
bridge_start_offset: rng.gen_range(5..=12),
|
||||
vault_spacing: rng.gen_range(3..=4),
|
||||
vault_size: *[(3, 16), (1, 4), (1, 4), (1, 4), (5, 32), (5, 32)].choose(rng).unwrap(),
|
||||
side_vault_size: *[(4, 5), (7, 10), (7, 10), (13, 20)].choose(rng).unwrap(),
|
||||
holes: rng.gen_bool(0.5),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum BridgeKind {
|
||||
Flat,
|
||||
Tower(RoofKind),
|
||||
Short,
|
||||
HeightenedViaduct(HeightenedViaduct),
|
||||
}
|
||||
|
||||
fn aabb(min: Vec3<i32>, max: Vec3<i32>) -> Aabb<i32> {
|
||||
@ -180,6 +203,169 @@ fn render_flat(bridge: &Bridge, painter: &Painter) {
|
||||
.fill(rock);
|
||||
}
|
||||
|
||||
fn render_heightened_viaduct(bridge: &Bridge, painter: &Painter, data: &HeightenedViaduct) {
|
||||
let rock = Fill::Block(Block::new(BlockKind::Rock, Rgb::gray(50)));
|
||||
let light_rock = Fill::Block(Block::new(BlockKind::Rock, Rgb::gray(130)));
|
||||
let orth_dir = bridge.dir.orthogonal();
|
||||
|
||||
let orthogonal = orth_dir.to_vec2();
|
||||
let forward = bridge.dir.to_vec2();
|
||||
|
||||
let slope_inv = data.slope_inv;
|
||||
|
||||
let len = (bridge.start.xy() - bridge.end.xy())
|
||||
.map(|e| e.abs())
|
||||
.reduce_max();
|
||||
|
||||
let bridge_start_z = bridge.end.z + data.bridge_start_offset;
|
||||
let bridge_top = bridge_start_z + len / slope_inv / 2;
|
||||
|
||||
// painter.ramp(aabb(
|
||||
// bridge.start - side,
|
||||
// (bridge.start.xy() + side + forward * (bridge_start_z -
|
||||
// bridge.start.z)).with_z(bridge_start_z), ), bridge_start_z -
|
||||
// bridge.start.z, bridge.dir).fill(rock);
|
||||
|
||||
let bridge_width = bridge.width;
|
||||
let side = orthogonal * bridge_width;
|
||||
|
||||
let aabr = Aabr {
|
||||
min: bridge.start.xy() - side,
|
||||
max: bridge.end.xy() + side,
|
||||
}
|
||||
.made_valid();
|
||||
|
||||
let [_start_aabr, rest] = bridge.dir.split_aabr(aabr, bridge_start_z - bridge.start.z);
|
||||
let [_end_aabr, bridge_aabr] = (-bridge.dir).split_aabr(rest, bridge_start_z - bridge.end.z);
|
||||
let under = bridge.center.z - 15;
|
||||
|
||||
let bridge_prim = |bridge_width: i32| {
|
||||
let side = orthogonal * bridge_width;
|
||||
|
||||
let aabr = Aabr {
|
||||
min: bridge.start.xy() - side,
|
||||
max: bridge.end.xy() + side,
|
||||
}
|
||||
.made_valid();
|
||||
|
||||
let [start_aabr, rest] = bridge.dir.split_aabr(aabr, bridge_start_z - bridge.start.z);
|
||||
let [end_aabr, bridge_aabr] = (-bridge.dir).split_aabr(rest, bridge_start_z - bridge.end.z);
|
||||
let [bridge_start, bridge_end] = bridge
|
||||
.dir
|
||||
.split_aabr(bridge_aabr, bridge.dir.select(bridge_aabr.size()) / 2);
|
||||
|
||||
let ramp_in_aabr = |aabr: Aabr<i32>, dir: Dir, zmin, zmax| {
|
||||
let inset = dir.select(aabr.size());
|
||||
painter.ramp(
|
||||
aabb(aabr.min.with_z(zmin), aabr.max.with_z(zmax)),
|
||||
inset,
|
||||
dir,
|
||||
)
|
||||
};
|
||||
|
||||
ramp_in_aabr(start_aabr, bridge.dir, bridge.start.z, bridge_start_z)
|
||||
.union(
|
||||
ramp_in_aabr(end_aabr, -bridge.dir, bridge.end.z, bridge_start_z)
|
||||
.union(ramp_in_aabr(
|
||||
bridge_start,
|
||||
bridge.dir,
|
||||
bridge_start_z + 1,
|
||||
bridge_top,
|
||||
))
|
||||
.union(ramp_in_aabr(
|
||||
bridge_end,
|
||||
-bridge.dir,
|
||||
bridge_start_z + 1,
|
||||
bridge_top,
|
||||
)),
|
||||
)
|
||||
.union(
|
||||
painter
|
||||
.aabb(aabb(
|
||||
start_aabr.min.with_z(under),
|
||||
start_aabr.max.with_z(bridge.start.z - 1),
|
||||
))
|
||||
.union(painter.aabb(aabb(
|
||||
end_aabr.min.with_z(under),
|
||||
end_aabr.max.with_z(bridge.end.z - 1),
|
||||
))),
|
||||
)
|
||||
.union(painter.aabb(aabb(
|
||||
bridge_aabr.min.with_z(under),
|
||||
bridge_aabr.max.with_z(bridge_start_z),
|
||||
)))
|
||||
};
|
||||
|
||||
let b = bridge_prim(bridge_width - 1);
|
||||
let b = b.without(b.translate(-Vec3::unit_z()));
|
||||
|
||||
let c = bridge_aabr.center();
|
||||
let len = bridge.dir.select(bridge_aabr.size());
|
||||
let vault_size = data.vault_size.0 * len / data.vault_size.1;
|
||||
let side_vault = data.side_vault_size.0 * vault_size / data.side_vault_size.1;
|
||||
let vertical = 5;
|
||||
let spacing = data.vault_spacing;
|
||||
let vault_top = bridge_top - vertical;
|
||||
let side_vault_top = vault_top - (vault_size + spacing + 1 + side_vault) / slope_inv;
|
||||
let side_vault_offset = vault_size + spacing + 1;
|
||||
|
||||
let mut remove = painter.vault(
|
||||
aabb(
|
||||
(c - side - forward * vault_size).with_z(under),
|
||||
(c + side + forward * vault_size).with_z(vault_top),
|
||||
),
|
||||
orth_dir,
|
||||
);
|
||||
|
||||
if side_vault * 2 + side_vault_offset < len / 2 + 5 {
|
||||
remove = remove.union(
|
||||
painter
|
||||
.vault(
|
||||
aabb(
|
||||
(c - side + forward * side_vault_offset).with_z(under),
|
||||
(c + side + forward * (side_vault * 2 + side_vault_offset))
|
||||
.with_z(side_vault_top),
|
||||
),
|
||||
orth_dir,
|
||||
)
|
||||
.union(
|
||||
painter.vault(
|
||||
aabb(
|
||||
(c - side - forward * side_vault_offset).with_z(under),
|
||||
(c + side - forward * (side_vault * 2 + side_vault_offset))
|
||||
.with_z(side_vault_top),
|
||||
),
|
||||
orth_dir,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if data.holes {
|
||||
remove = remove.union(
|
||||
painter.vault(aabb(
|
||||
(c - side + forward * (vault_size + 1)).with_z(side_vault_top - 4),
|
||||
(c + side + forward * (vault_size + spacing)).with_z(side_vault_top + 2),
|
||||
), orth_dir).union(
|
||||
painter.vault(aabb(
|
||||
(c - side - forward * (vault_size + 1)).with_z(side_vault_top - 4),
|
||||
(c + side - forward * (vault_size + spacing)).with_z(side_vault_top + 2),
|
||||
), orth_dir)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bridge_prim(bridge_width)
|
||||
.without(b)
|
||||
.without(remove)
|
||||
.fill(rock.clone());
|
||||
b.translate(-Vec3::unit_z()).fill(light_rock.clone());
|
||||
|
||||
b.translate(Vec3::unit_z() * 5)
|
||||
.without(b.translate(-Vec3::unit_z()))
|
||||
.clear();
|
||||
}
|
||||
|
||||
fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
|
||||
let rock = Fill::Block(Block::new(BlockKind::Rock, Rgb::gray(50)));
|
||||
let wood = Fill::Block(Block::new(BlockKind::Wood, Rgb::new(40, 28, 20)));
|
||||
@ -485,13 +671,15 @@ impl Bridge {
|
||||
end,
|
||||
center,
|
||||
dir: Dir::from_vector(end.xy() - start.xy()),
|
||||
kind: if end.z - start.z > 14 {
|
||||
kind: if end.z - start.z > 17 {
|
||||
BridgeKind::Tower(match rng.gen_range(0..=2) {
|
||||
0 => RoofKind::Crenelated,
|
||||
_ => RoofKind::Hipped,
|
||||
})
|
||||
} else if len < 40 {
|
||||
BridgeKind::Short
|
||||
} else if end.z - start.z < 5 && start.z - center.z < 16 {
|
||||
BridgeKind::HeightenedViaduct(HeightenedViaduct::random(rng))
|
||||
} else {
|
||||
BridgeKind::Flat
|
||||
},
|
||||
@ -509,6 +697,7 @@ impl Structure for Bridge {
|
||||
BridgeKind::Flat => render_flat(self, painter),
|
||||
BridgeKind::Tower(roof) => render_tower(self, painter, roof),
|
||||
BridgeKind::Short => render_short(self, painter),
|
||||
BridgeKind::HeightenedViaduct(data) => render_heightened_viaduct(self, painter, data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
pub mod gradient;
|
||||
|
||||
use std::ops::{Add, Sub};
|
||||
|
||||
use rand::Rng;
|
||||
use vek::*;
|
||||
|
||||
@ -168,7 +170,8 @@ impl Dir {
|
||||
pub fn is_y(self) -> bool { matches!(self, Dir::Y | Dir::NegY) }
|
||||
|
||||
/// Returns the component that the direction is parallell to
|
||||
pub fn select(self, vec: Vec2<i32>) -> i32 {
|
||||
pub fn select(self, vec: impl Into<Vec2<i32>>) -> i32 {
|
||||
let vec = vec.into();
|
||||
match self {
|
||||
Dir::X | Dir::NegX => vec.x,
|
||||
Dir::Y | Dir::NegY => vec.y,
|
||||
@ -177,7 +180,9 @@ impl Dir {
|
||||
|
||||
/// Select one component the direction is parallel to from vec and select
|
||||
/// the other component from other
|
||||
pub fn select_with(self, vec: Vec2<i32>, other: Vec2<i32>) -> Vec2<i32> {
|
||||
pub fn select_with(self, vec: impl Into<Vec2<i32>>, other: impl Into<Vec2<i32>>) -> Vec2<i32> {
|
||||
let vec = vec.into();
|
||||
let other = other.into();
|
||||
match self {
|
||||
Dir::X | Dir::NegX => Vec2::new(vec.x, other.y),
|
||||
Dir::Y | Dir::NegY => Vec2::new(other.x, vec.y),
|
||||
@ -185,7 +190,7 @@ impl Dir {
|
||||
}
|
||||
|
||||
/// Returns the side of an aabr that the direction is pointing to
|
||||
pub fn select_aabr(self, aabr: Aabr<i32>) -> i32 {
|
||||
pub fn select_aabr<T>(self, aabr: Aabr<T>) -> T {
|
||||
match self {
|
||||
Dir::X => aabr.max.x,
|
||||
Dir::NegX => aabr.min.x,
|
||||
@ -196,7 +201,8 @@ impl Dir {
|
||||
|
||||
/// Select one component from the side the direction is pointing to from
|
||||
/// aabr and select the other component from other
|
||||
pub fn select_aabr_with(self, aabr: Aabr<i32>, other: Vec2<i32>) -> Vec2<i32> {
|
||||
pub fn select_aabr_with<T>(self, aabr: Aabr<T>, other: impl Into<Vec2<T>>) -> Vec2<T> {
|
||||
let other = other.into();
|
||||
match self {
|
||||
Dir::X => Vec2::new(aabr.max.x, other.y),
|
||||
Dir::NegX => Vec2::new(aabr.min.x, other.y),
|
||||
@ -215,7 +221,7 @@ impl Dir {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn split_aabr(self, aabr: Aabr<i32>, offset: i32) -> [Aabr<i32>; 2] {
|
||||
pub fn split_aabr<T>(self, aabr: Aabr<T>, offset: T) -> [Aabr<T>; 2] where T: Copy + PartialOrd + Add<T, Output = T> + Sub<T, Output = T> {
|
||||
match self {
|
||||
Dir::X => aabr.split_at_x(aabr.min.x + offset),
|
||||
Dir::Y => aabr.split_at_y(aabr.min.y + offset),
|
||||
|
Loading…
Reference in New Issue
Block a user