Skip to content

Commit a72b79f

Browse files
committed
move to rapier2d from ncollide2d; also implement visible selection of objects
1 parent 207657c commit a72b79f

15 files changed

Lines changed: 377 additions & 214 deletions

File tree

Cargo.lock

Lines changed: 180 additions & 83 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ lazy_static = "1"
3535
malloc_size_of_derive = "0.1"
3636
nalgebra = "0.33"
3737
nalgebra-glm = "0.19"
38-
ncollide2d = "0.33"
38+
rapier2d = "0.26"
39+
parry2d = "0.22.0-beta.1"
3940
nom = "7"
4041
notify = "7"
4142
once_cell = "1"

config/shader.vert

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
layout(location = 0) in ivec2 position;
55
layout(location = 1) in ivec2 normal;
66
layout(location = 2) in uint feature;
7+
layout(location = 3) in uint object_id;
78

89
layout(location = 0) out vec4 outColor;
910
layout(location = 1) out float d;
@@ -18,7 +19,8 @@ layout(std140) struct LayerData {
1819

1920
layout(std140, set = 0, binding = 0) uniform Locals {
2021
vec2 canvas_size;
21-
vec2 _unused;
22+
uint _unused;
23+
uint _unused1;
2224
LayerData layer_datas[1000];
2325
};
2426

@@ -34,6 +36,11 @@ layout(std140, set = 0, binding = 1) uniform Transform {
3436
TileData tile_datas[10];
3537
};
3638

39+
layout(std140, set = 0, binding = 2) uniform Selected {
40+
uint selected_tile_id;
41+
uint selected_object_id;
42+
};
43+
3744
void main() {
3845
// Are we handling an outline?
3946
bool is_outline = (gl_InstanceIndex & 0x01) == 0;
@@ -90,4 +97,9 @@ void main() {
9097
gl_Position.y = -gl_Position.y;
9198

9299
gl_Position.z = layer_data.z_index / 1000 + 0.001;
100+
101+
if(( selected_tile_id == tile_id && selected_object_id == object_id)) {
102+
outColor = vec4(1.0, 0.0, 0.0, 0.5);
103+
}
104+
gl_Position.z = 1;
93105
}

config/style.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ background {
33
}
44

55
layer[name="water"] {
6-
background-color: rgba(14, 181, 223, 1);
6+
background-color: rgba(14, 181, 223, 0.3);
77
border-width: 1px;
88
border-color: rgba(0, 0, 0, 0.952);
99
}
@@ -13,7 +13,7 @@ layer[name="park"] {
1313
}
1414

1515
layer[name="building"] {
16-
background-color: rgba(151, 46, 28, 1);
16+
background-color: rgba(151, 46, 28, 0.3);
1717
}
1818

1919
layer[name="landcover"] {
@@ -25,7 +25,7 @@ layer[name="landuse"].suburb {
2525
}
2626

2727
layer[name="transportation"] {
28-
background-color: rgba(21, 124, 102, 0.959);
28+
background-color: rgba(21, 124, 102, 0.3);
2929
line-width: 2px;
3030
}
3131

src/bin/app_state.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,21 +198,40 @@ impl AppState {
198198

199199
pub fn update_selected_from_hover_objects(&mut self) {
200200
let hovered_objects = self.hovered_objects.lock().unwrap();
201-
(self.selected_objects, self.selected_object_labels) = hovered_objects
201+
self.selected_objects = hovered_objects
202202
.iter()
203-
.map(|o| (EditableObject::new(o.clone()), format!("{}", o.selector())))
203+
.map(|o| (EditableObject::new(o.id, o.tile_id, o.clone())))
204204
.collect();
205-
205+
drop(hovered_objects);
206206
self.selected_object = 0;
207+
self.refresh_labels();
207208
}
208209

209210
pub fn advance_selected_object(&mut self) {
210211
let len = self.selected_objects.len();
211212
self.selected_object = (self.selected_object + 1) % len;
213+
self.refresh_labels();
212214
}
213215

214216
pub fn select_object(&mut self, index: usize) {
215217
self.selected_object = index;
218+
self.refresh_labels();
219+
}
220+
221+
fn refresh_labels(&mut self) {
222+
self.selected_object_labels = self
223+
.selected_objects
224+
.iter()
225+
.enumerate()
226+
.map(|(i, o)| {
227+
let selector = o.object.selector();
228+
if i == self.selected_object {
229+
format!("{selector} •")
230+
} else {
231+
format!("{selector}")
232+
}
233+
})
234+
.collect();
216235
}
217236

218237
pub(crate) fn selected_object(&self) -> Option<&EditableObject> {
@@ -252,11 +271,17 @@ impl AppState {
252271
}
253272

254273
pub struct EditableObject {
274+
pub id: u32,
275+
pub tile_id: TileId,
255276
pub object: Object,
256277
}
257278

258279
impl EditableObject {
259-
pub fn new(object: Object) -> Self {
260-
Self { object }
280+
pub fn new(id: u32, tile_id: TileId, object: Object) -> Self {
281+
Self {
282+
id,
283+
tile_id,
284+
object,
285+
}
261286
}
262287
}

src/bin/drawing/painter.rs

Lines changed: 86 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ use crate::app_state::AppState;
2323
use crate::config::CONFIG;
2424
use crate::drawing::helpers::load_glsl;
2525

26+
const TILE_DATA_BUFFER_BYTE_SIZE: u64 = 8;
27+
// TODO: Should be u64::from once stabilized for const.
28+
const UNIFORM_BUFFER_SIZE: u64 = 4 * 4 + 12 * 4 * (MAX_FEATURES as u64);
29+
2630
pub struct Painter {
2731
pub window: Arc<Window>,
2832
hidpi_factor: f64,
@@ -37,6 +41,7 @@ pub struct Painter {
3741
stencil: TextureView,
3842
uniform_buffer: Buffer,
3943
tile_transform_buffer: (Buffer, u64),
44+
tile_selection_buffer: Buffer,
4045
bind_group_layout: BindGroupLayout,
4146
bind_group: BindGroup,
4247
rx: Receiver<Result<notify::event::Event, notify::Error>>,
@@ -154,6 +159,16 @@ impl Painter {
154159
},
155160
count: None,
156161
},
162+
BindGroupLayoutEntry {
163+
binding: 2,
164+
visibility: wgpu::ShaderStages::VERTEX,
165+
ty: BindingType::Buffer {
166+
ty: BufferBindingType::Uniform,
167+
has_dynamic_offset: false,
168+
min_binding_size: None,
169+
},
170+
count: None,
171+
},
157172
],
158173
});
159174

@@ -184,6 +199,7 @@ impl Painter {
184199
app_state.zoom,
185200
std::iter::empty(),
186201
);
202+
let tile_selection_buffer = Self::create_tile_selection_buffer(&device, 0, 0);
187203

188204
let blend_pipeline = Self::create_layer_render_pipeline(
189205
&device,
@@ -220,6 +236,7 @@ impl Painter {
220236
&bind_group_layout,
221237
&uniform_buffer,
222238
&tile_transform_buffer,
239+
&tile_selection_buffer,
223240
);
224241

225242
let font_system = FontSystem::new();
@@ -254,6 +271,7 @@ impl Painter {
254271
uniform_buffer,
255272
stencil,
256273
tile_transform_buffer,
274+
tile_selection_buffer,
257275
bind_group_layout,
258276
bind_group,
259277
_watcher: watcher,
@@ -307,6 +325,11 @@ impl Painter {
307325
offset: 8,
308326
shader_location: 2,
309327
},
328+
VertexAttribute {
329+
format: VertexFormat::Uint32,
330+
offset: 12,
331+
shader_location: 3,
332+
},
310333
],
311334
}],
312335
compilation_options: PipelineCompilationOptions::default(),
@@ -378,6 +401,7 @@ impl Painter {
378401
let canvas_size_len = 4 * 4;
379402
let canvas_size_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
380403
label: Some("map canvas size data"),
404+
// screen width, screen height, selected tile, selected object
381405
contents: as_byte_slice(&[screen.width, screen.height, 0.0, 0.0]),
382406
usage: BufferUsages::UNIFORM | BufferUsages::COPY_SRC,
383407
});
@@ -402,7 +426,7 @@ impl Painter {
402426
}
403427

404428
fn create_uniform_buffer(device: &Device) -> Buffer {
405-
let data = [0; Self::uniform_buffer_size() as usize];
429+
let data = [0; UNIFORM_BUFFER_SIZE as usize];
406430
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
407431
label: Some("tile data"),
408432
contents: as_byte_slice(&data),
@@ -420,21 +444,24 @@ impl Painter {
420444
z: f32,
421445
visible_tiles: impl Iterator<Item = (TileId, f32)>,
422446
) -> (Buffer, u64) {
447+
#[derive(Copy, Clone, Debug, Default)]
448+
#[repr(C)]
449+
pub struct TileData {
450+
pub transform: [f32; 16],
451+
pub extent: f32,
452+
_unused: f32,
453+
_unused2: f32,
454+
_unused3: f32,
455+
}
456+
423457
const TILE_DATA_SIZE: usize = 20;
424458
const TILE_DATA_BUFFER_BYTE_SIZE: usize = TILE_DATA_SIZE * 4 * MAX_TILES;
425-
let mut data = [0f32; TILE_DATA_BUFFER_BYTE_SIZE];
459+
let mut data = [TileData::default(); MAX_TILES];
426460

427-
let mut i = 0;
428-
for (tile_id, extent) in visible_tiles {
461+
for (i, (tile_id, extent)) in visible_tiles.enumerate() {
429462
let matrix = screen.tile_to_screen(z, &tile_id);
430-
for float in matrix.as_slice() {
431-
data[i] = *float;
432-
i += 1;
433-
}
434-
for _ in 0..4 {
435-
data[i] = extent;
436-
i += 1;
437-
}
463+
data[i].transform.copy_from_slice(matrix.as_slice());
464+
data[i].extent = extent;
438465
}
439466
(
440467
{
@@ -449,6 +476,26 @@ impl Painter {
449476
)
450477
}
451478

479+
fn create_tile_selection_buffer(
480+
device: &Device,
481+
selected_tile_id: u32,
482+
selected_object_id: u32,
483+
) -> Buffer {
484+
#[derive(Copy, Clone, Debug, Default)]
485+
#[repr(C, packed)]
486+
pub struct SelectedData {
487+
pub selected_tile_id: u32,
488+
pub selected_object_id: u32,
489+
}
490+
491+
let buffer = device.create_buffer_init(&BufferInitDescriptor {
492+
label: Some("tile selection buffer"),
493+
contents: as_byte_slice(&[selected_tile_id, selected_object_id]),
494+
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
495+
});
496+
buffer
497+
}
498+
452499
fn copy_uniform_buffers(
453500
encoder: &mut CommandEncoder,
454501
source: &[(Buffer, usize)],
@@ -461,16 +508,12 @@ impl Painter {
461508
}
462509
}
463510

464-
const fn uniform_buffer_size() -> u64 {
465-
// TODO: Should be u64::from once stabilized for const.
466-
4 * 4 + 12 * 4 * (MAX_FEATURES as u64)
467-
}
468-
469511
pub fn create_blend_bind_group(
470512
device: &Device,
471513
bind_group_layout: &BindGroupLayout,
472514
uniform_buffer: &Buffer,
473515
tile_transform_buffer: &(Buffer, u64),
516+
tile_selection_buffer: &Buffer,
474517
) -> BindGroup {
475518
device.create_bind_group(&BindGroupDescriptor {
476519
label: Some("bind vertex stage buffers"),
@@ -481,7 +524,7 @@ impl Painter {
481524
resource: BindingResource::Buffer(BufferBinding {
482525
buffer: uniform_buffer,
483526
offset: 0,
484-
size: NonZeroU64::new(Self::uniform_buffer_size()),
527+
size: NonZeroU64::new(UNIFORM_BUFFER_SIZE),
485528
}),
486529
},
487530
wgpu::BindGroupEntry {
@@ -492,6 +535,14 @@ impl Painter {
492535
size: NonZeroU64::new(tile_transform_buffer.1),
493536
}),
494537
},
538+
wgpu::BindGroupEntry {
539+
binding: 2,
540+
resource: BindingResource::Buffer(BufferBinding {
541+
buffer: tile_selection_buffer,
542+
offset: 0,
543+
size: NonZeroU64::new(TILE_DATA_BUFFER_BYTE_SIZE),
544+
}),
545+
},
495546
],
496547
})
497548
}
@@ -618,12 +669,28 @@ impl Painter {
618669
let tile = app_state.tile_cache.get_tile(&tile_id);
619670
visible_tile_info.push((tile_id, tile.extent() as f32));
620671
}
672+
673+
let (selected_tile_id, selected_object_id) = app_state
674+
.selected_object()
675+
.and_then(|object| {
676+
visible_tile_info
677+
.iter()
678+
.enumerate()
679+
.find_map(|(i, (id, _))| {
680+
(id == &object.tile_id).then_some((i as u32, object.id))
681+
})
682+
})
683+
.unwrap_or((u32::MAX, u32::MAX));
684+
621685
self.tile_transform_buffer = Self::create_tile_transform_buffer(
622686
&self.device,
623687
&app_state.screen,
624688
app_state.zoom,
625689
visible_tile_info.into_iter(),
626690
);
691+
692+
self.tile_selection_buffer =
693+
Self::create_tile_selection_buffer(&self.device, selected_tile_id, selected_object_id);
627694
}
628695

629696
fn create_multisampled_framebuffer(
@@ -698,6 +765,7 @@ impl Painter {
698765
&self.bind_group_layout,
699766
&self.uniform_buffer,
700767
&self.tile_transform_buffer,
768+
&self.tile_selection_buffer,
701769
);
702770
{
703771
let view = frame

src/bin/drawing/ui/views/inspector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ fn selected_object(ui: &mut Ui, app_state: &mut AppState) {
2525
ui.label(RichText::from("press <tab> to cycle").small());
2626
});
2727

28-
if let Some(EditableObject { object }) = app_state.selected_object() {
28+
if let Some(EditableObject { object, .. }) = app_state.selected_object() {
2929
let selector = object.selector().clone();
3030
let tags = object.tags();
3131

0 commit comments

Comments
 (0)