Stop using 100% CPU; fix bug when splitting line segments at Y extrema

This commit is contained in:
Patrick Walton 2019-01-29 15:35:07 -08:00
parent e958363872
commit e3bf703105
5 changed files with 66 additions and 38 deletions

View File

@ -92,6 +92,8 @@ fn main() {
let mut base_scene = load_scene(&options, &window_size);
let mut dump_transformed_scene = false;
let mut events = vec![];
while !exit {
let mut scene = base_scene.clone();
@ -113,6 +115,8 @@ fn main() {
let perspective = Perspective::new(&transform, &window_size);
scene.apply_perspective(&perspective);
} else {
scene.prepare();
}
if dump_transformed_scene {
@ -130,39 +134,49 @@ fn main() {
window.gl_swap_window();
for event in sdl_event_pump.poll_iter() {
match event {
Event::Quit { .. } | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
exit = true;
let mut event_handled = false;
while !event_handled {
events.push(sdl_event_pump.wait_event());
for event in sdl_event_pump.poll_iter() {
events.push(event);
}
for event in events.drain(..) {
match event {
Event::Quit { .. } | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
exit = true;
}
Event::MouseMotion { xrel, yrel, .. } => {
camera_yaw += xrel as f32 * MOUSELOOK_ROTATION_SPEED;
camera_pitch -= yrel as f32 * MOUSELOOK_ROTATION_SPEED;
}
Event::KeyDown { keycode: Some(Keycode::W), .. } => {
camera_velocity.set_z(-CAMERA_VELOCITY)
}
Event::KeyDown { keycode: Some(Keycode::S), .. } => {
camera_velocity.set_z(CAMERA_VELOCITY)
}
Event::KeyDown { keycode: Some(Keycode::A), .. } => {
camera_velocity.set_x(-CAMERA_VELOCITY)
}
Event::KeyDown { keycode: Some(Keycode::D), .. } => {
camera_velocity.set_x(CAMERA_VELOCITY)
}
Event::KeyDown { keycode: Some(Keycode::T), .. } => {
dump_transformed_scene = true;
}
Event::KeyUp { keycode: Some(Keycode::W), .. } |
Event::KeyUp { keycode: Some(Keycode::S), .. } => {
camera_velocity.set_z(0.0);
}
Event::KeyUp { keycode: Some(Keycode::A), .. } |
Event::KeyUp { keycode: Some(Keycode::D), .. } => {
camera_velocity.set_x(0.0);
}
_ => continue,
}
Event::MouseMotion { xrel, yrel, .. } => {
camera_yaw += xrel as f32 * MOUSELOOK_ROTATION_SPEED;
camera_pitch -= yrel as f32 * MOUSELOOK_ROTATION_SPEED;
}
Event::KeyDown { keycode: Some(Keycode::W), .. } => {
camera_velocity.set_z(-CAMERA_VELOCITY)
}
Event::KeyDown { keycode: Some(Keycode::S), .. } => {
camera_velocity.set_z(CAMERA_VELOCITY)
}
Event::KeyDown { keycode: Some(Keycode::A), .. } => {
camera_velocity.set_x(-CAMERA_VELOCITY)
}
Event::KeyDown { keycode: Some(Keycode::D), .. } => {
camera_velocity.set_x(CAMERA_VELOCITY)
}
Event::KeyDown { keycode: Some(Keycode::T), .. } => {
dump_transformed_scene = true;
}
Event::KeyUp { keycode: Some(Keycode::W), .. } |
Event::KeyUp { keycode: Some(Keycode::S), .. } => {
camera_velocity.set_z(0.0);
}
Event::KeyUp { keycode: Some(Keycode::A), .. } |
Event::KeyUp { keycode: Some(Keycode::D), .. } => {
camera_velocity.set_x(0.0);
}
_ => {}
event_handled = true;
}
}
}

View File

@ -116,7 +116,10 @@ impl LineSegmentF32 {
#[inline]
pub fn split_at_y(&self, y: f32) -> (LineSegmentF32, LineSegmentF32) {
let (min_part, max_part) = self.split(self.solve_t_for_y(y));
if min_part.from_y() < max_part.from_y() {
// Make sure we compare `from_y` and `to_y` to properly handle the case in which one of the
// two segments is zero-length.
if min_part.from_y() < max_part.to_y() {
(min_part, max_part)
} else {
(max_part, min_part)

View File

@ -101,6 +101,11 @@ impl Outline {
&self.bounds
}
#[inline]
pub fn make_monotonic(&mut self) {
self.contours.iter_mut().for_each(|contour| contour.make_monotonic());
}
#[inline]
pub fn transform(&mut self, transform: &Transform2DF32) {
self.contours.iter_mut().for_each(|contour| contour.transform(transform));

View File

@ -102,6 +102,12 @@ impl Scene {
.collect()
}
pub fn prepare(&mut self) {
for object in &mut self.objects {
object.outline.make_monotonic();
}
}
pub fn transform(&mut self, transform: &Transform2DF32) {
let mut bounds = Rect::zero();
for (object_index, object) in self.objects.iter_mut().enumerate() {

View File

@ -121,8 +121,8 @@ impl<'o, 'z> Tiler<'o, 'z> {
let mut last_segment_x = -9999.0;
let tile_top = (i32::from(tile_y) * TILE_HEIGHT as i32) as f32;
//println!("---------- tile y {}({}) ----------", tile_y, tile_top);
//println!("old active edges: {:#?}", self.old_active_edges);
/*println!("---------- tile y {}({}) ----------", tile_y, tile_top);
println!("old active edges: {:#?}", self.old_active_edges);*/
for mut active_edge in self.old_active_edges.drain(..) {
// Determine x-intercept and winding.
@ -134,8 +134,7 @@ impl<'o, 'z> Tiler<'o, 'z> {
-1
};
/*
println!("tile Y {}({}): segment_x={} edge_winding={} current_tile_x={} \
/*println!("tile Y {}({}): segment_x={} edge_winding={} current_tile_x={} \
current_subtile_x={} current_winding={}",
tile_y,
tile_top,
@ -325,6 +324,7 @@ fn process_active_segment(
//println!("... process_active_segment({:#?})", active_edge);
active_edge.process(built_object, tile_y);
if !active_edge.segment.is_none() {
//println!("... ... pushing resulting active edge: {:#?}", active_edge);
active_edges.push(active_edge);
}
}
@ -374,7 +374,7 @@ impl ActiveEdge {
fn process(&mut self, built_object: &mut BuiltObject, tile_y: i16) {
let tile_bottom = ((i32::from(tile_y) + 1) * TILE_HEIGHT as i32) as f32;
// println!("process_active_edge({:#?}, tile_y={}({}))", self, tile_y, tile_bottom);
//println!("process_active_edge({:#?}, tile_y={}({}))", self, tile_y, tile_bottom);
let mut segment = self.segment;
let winding = segment.baseline.y_winding();