Skip to content

Commit f297bf2

Browse files
committed
WIP improve plane demo
1 parent afab4ff commit f297bf2

File tree

2 files changed

+168
-35
lines changed

2 files changed

+168
-35
lines changed

core/src/util/buf.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ pub mod inner {
431431

432432
/// Returns the linear index corresponding to the coordinates,
433433
/// or panics if either x or y is out of bounds.
434+
#[track_caller]
434435
#[inline]
435436
fn to_index_strict(&self, x: u32, y: u32) -> usize {
436437
match self.to_index_checked(x, y) {

demos/src/bin/plane.rs

Lines changed: 167 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use re::prelude::*;
44

55
use re::core::math::color::gray;
66
use re::core::render::{
7-
cam::{FirstPerson, Fov, PitchYawRoll},
7+
cam::{Fov, PitchYawRoll},
88
clip::Status::*,
99
scene::Obj,
1010
tex::SamplerClamp,
@@ -14,6 +14,7 @@ use re::core::util::{pixfmt::Rgba8888, pnm::read_pnm};
1414

1515
use re::front::sdl2::Window;
1616
use re::geom::solids::{Build, Cube};
17+
use re::prelude::rand::{DefaultRng, Distrib, Uniform};
1718

1819
fn main() {
1920
let mut win = Window::builder()
@@ -25,16 +26,19 @@ fn main() {
2526
let tex_data = *include_bytes!("../../assets/crate.ppm");
2627
let tex = Texture::from(read_pnm(&tex_data[..]).expect("data exists"));
2728

28-
let light_dir = vec3(-2.0, 1.0, -4.0).normalize();
29+
let light_dir = vec3(-2.0, 5.0, -4.0).normalize();
2930

30-
let floor_shader = shader::new(
31-
|v: Vertex3<_>, mvp: &ProjMat3<_>| vertex(mvp.apply(&v.pos), v.attrib),
32-
|frag: Frag<Vec2>| {
33-
let even_odd = (frag.var.x() > 0.5) ^ (frag.var.y() > 0.5);
34-
gray(if even_odd { 0.8 } else { 0.1 }).to_color4()
31+
let terrain_shader = shader::new(
32+
|v: Vertex3<Normal3>, mvp: &ProjMat3<_>| {
33+
vertex(mvp.apply(&v.pos), (v.pos, v.attrib))
34+
},
35+
|frag: Frag<(Point3<Model>, Normal3)>| {
36+
let l = frag.var.1.dot(&light_dir).max(0.2);
37+
let h = (frag.var.0.y() / 4.0).rem_euclid(1.0);
38+
gray(if h > 0.95 { 0.1 } else { l }).to_color4()
3539
},
3640
);
37-
let crate_shader = shader::new(
41+
let _crate_shader = shader::new(
3842
|v: Vertex3<(Normal3, TexCoord)>, mvp: &ProjMat3<_>| {
3943
vertex(mvp.apply(&v.pos), v.attrib)
4044
},
@@ -54,7 +58,6 @@ fn main() {
5458
.perspective(Fov::Diagonal(degs(90.0)), 0.1..1000.0);
5559

5660
let floor = floor();
57-
let crates = crates();
5861

5962
let mut target_vel_z = 0.0;
6063
let mut cam_vel = Vec3::zero();
@@ -75,8 +78,8 @@ fn main() {
7578
for key in ep.keyboard_state().pressed_scancodes() {
7679
use sdl2::keyboard::Scancode as Sc;
7780
match key {
78-
Sc::W => target_vel_z += 0.1,
79-
Sc::S => target_vel_z -= 0.05,
81+
Sc::W => target_vel_z += 10.0,
82+
Sc::S => target_vel_z -= 10.0,
8083
Sc::A => tr = rv,
8184
Sc::D => tr = -rv,
8285

@@ -99,8 +102,8 @@ fn main() {
99102
.view_to_world()
100103
.apply(&(target_vel_z * Vec3::Z));
101104

102-
let acc = 8.0;
103-
cam_vel = cam_vel.lerp(&target_vel, acc * dt);
105+
let acc = 20.0;
106+
cam_vel = cam_vel.lerp(&target_vel, (acc * dt).min(1.0));
104107

105108
cam.transform.rotate(p, y, r);
106109

@@ -126,15 +129,15 @@ fn main() {
126129
let mut b = batch
127130
.clone()
128131
.mesh(geom)
129-
.shader(floor_shader)
132+
.shader(terrain_shader)
130133
.uniform(&model_to_project);
131134
b.render();
132135
}
133136
}
134137

135138
// Crates
136139

137-
for Obj { geom, bbox, tf } in &crates {
140+
/*for Obj { geom, bbox, tf } in &crates {
138141
frame.ctx.stats.borrow_mut().objs.i += 1;
139142
140143
let model_to_project = tf.then(&world_to_project);
@@ -153,41 +156,170 @@ fn main() {
153156
.render();
154157
155158
frame.ctx.stats.borrow_mut().objs.o += 1;
156-
}
159+
}*/
157160

158161
Continue(())
159162
})
160163
.expect("should run");
161164
}
162165

163-
fn crates() -> Vec<Obj<(Normal3, TexCoord)>> {
164-
let obj = Obj::new(Cube { side_len: 2.0 }.build());
165-
166-
let mut res = vec![];
167-
let n = 30;
168-
for i in (-n..=n).step_by(5) {
169-
for j in (-n..=n).step_by(5) {
170-
res.push(Obj {
171-
tf: translate3(i as f32, 0.0, j as f32).to(),
172-
// TODO Same geometry cloned many times
173-
..obj.clone()
174-
});
166+
#[inline(never)]
167+
fn diamond_square(n: u32) -> Buf2<f32> {
168+
let mut buf = Buf2::new_with((n + 1, n + 1), |_, _| f32::NAN);
169+
let rng = &mut DefaultRng::from_time();
170+
let heights = Uniform(-1.0..1.0);
171+
172+
buf[[0, 0]] = 0.0; //dbg!(heights.sample(rng));
173+
buf[[0, n]] = 0.0; //dbg!(heights.sample(rng));
174+
buf[[n, 0]] = 0.0; //dbg!(heights.sample(rng));
175+
buf[[n, n]] = 0.0; //dbg!(heights.sample(rng));
176+
let mut s = n;
177+
178+
let mut scale = 1.0;
179+
180+
while s > 0 {
181+
// Diamond phase
182+
eprintln!("Starting diamond phase {s}...");
183+
184+
for j in (0..n).step_by(s as usize) {
185+
for i in (0..n).step_by(s as usize) {
186+
let p0 = pt2(i, j);
187+
let p1 = pt2(i + s, j + s);
188+
let c = pt2(p0.x().midpoint(p1.x()), p0.y().midpoint(p1.y()));
189+
190+
let mean = (buf[p0]
191+
+ buf[pt2(p1.x(), p0.y())]
192+
+ buf[pt2(p0.x(), p1.y())]
193+
+ buf[p1])
194+
/ 4.0;
195+
196+
buf[c] = mean + heights.sample(rng) * scale;
197+
}
175198
}
199+
200+
// eprintln!("After diamond phase {s}:");
201+
// for row in buf.rows() {
202+
// for &c in row {
203+
// if c.is_nan() {
204+
// eprint!(" ____");
205+
// } else {
206+
// eprint!(" {c:-4.1}");
207+
// }
208+
// }
209+
// eprintln!();
210+
// }
211+
212+
eprintln!("Starting square phase {s}...");
213+
// Square phase
214+
for j in (0..n).step_by(s as usize) {
215+
for i in (0..n).step_by(s as usize) {
216+
//
217+
// / \
218+
// / \
219+
// (i,j)---(i+s,j)
220+
// / | \ /
221+
// / | \ /
222+
// \ | /
223+
// \ | /
224+
// (i,j+s)
225+
//
226+
227+
let mean_u = if s / 2 <= j {
228+
(buf[[i, j]]
229+
+ buf[[i + s, j]]
230+
+ buf[[i + s / 2, j - s / 2]]
231+
+ buf[[i + s / 2, j + s / 2]])
232+
/ 4.0
233+
} else {
234+
(buf[[i, j]]
235+
+ buf[[i + s, j]]
236+
+ buf[[i + s / 2, j + s / 2]])
237+
/ 3.0
238+
};
239+
let mean_d = if j + s + s / 2 <= n {
240+
(buf[[i, j + s]]
241+
+ buf[[i + s, j + s]]
242+
+ buf[[i + s / 2, j + s / 2]]
243+
+ buf[[i + s / 2, j + s + s / 2]])
244+
/ 4.0
245+
} else {
246+
(buf[[i, j + s]]
247+
+ buf[[i + s, j + s]]
248+
+ buf[[i + s / 2, j + s / 2]])
249+
/ 3.0
250+
};
251+
let mean_l = if s / 2 <= i {
252+
(buf[[i, j]]
253+
+ buf[[i, j + s]]
254+
+ buf[[i - s / 2, j + s / 2]]
255+
+ buf[[i + s / 2, j + s / 2]])
256+
/ 4.0
257+
} else {
258+
(buf[[i, j]]
259+
+ buf[[i, j + s]]
260+
+ buf[[i + s / 2, j + s / 2]])
261+
/ 3.0
262+
};
263+
let mean_r = if i + s + s / 2 <= n {
264+
(buf[[i + s, j]]
265+
+ buf[[i + s, j + s]]
266+
+ buf[[i + s / 2, j + s / 2]]
267+
+ buf[[i + s + s / 2, j + s / 2]])
268+
/ 4.0
269+
} else {
270+
(buf[[i + s, j]]
271+
+ buf[[i + s, j + s]]
272+
+ buf[[i + s / 2, j + s / 2]])
273+
/ 3.0
274+
};
275+
276+
buf[[i, j + s / 2]] = mean_l + heights.sample(rng) * scale;
277+
buf[[i + s / 2, j]] = mean_u + heights.sample(rng) * scale;
278+
buf[[i + s, j + s / 2]] = mean_r + heights.sample(rng) * scale;
279+
buf[[i + s / 2, j + s]] = mean_d + heights.sample(rng) * scale;
280+
}
281+
}
282+
283+
// eprintln!("After square phase {s}:");
284+
// for row in buf.rows() {
285+
// for &c in row {
286+
// if c.is_nan() {
287+
// eprint!(" ____");
288+
// } else {
289+
// eprint!(" {c:-4.1}");
290+
// }
291+
// }
292+
// eprintln!();
293+
// }
294+
295+
scale /= 2.0;
296+
s /= 2;
176297
}
177-
res
298+
299+
buf
178300
}
179-
fn floor() -> Obj<Vec2> {
301+
302+
#[inline(never)]
303+
fn floor() -> Obj<Normal3> {
180304
let mut bld = Mesh::builder();
181305

182-
let size = 50;
306+
let hf = diamond_square(512);
307+
308+
let size = 256;
183309
for j in -size..=size {
184310
for i in -size..=size {
185311
let i_odd = i & 1;
186312
let j_odd = j & 1;
187313

188-
let pos = pt3(i as f32, -1.0, j as f32);
189-
let attrib = vec2(i_odd as f32, j_odd as f32);
190-
bld.push_vert(pos, attrib);
314+
let h = -32.0
315+
+ 64.0
316+
* smoothstep(smootherstep(
317+
hf[[(i + size) as u32, (j + size) as u32]] * 0.5 + 0.5,
318+
));
319+
320+
let pos = pt3(i as f32, -1.0 + h, j as f32);
321+
//let attrib = vec2(i_odd as f32, j_odd as f32);
322+
bld.push_vert(pos, ());
191323

192324
if j > -size && i > -size {
193325
let w = size * 2 + 1;
@@ -211,5 +343,5 @@ fn floor() -> Obj<Vec2> {
211343
}
212344
}
213345
}
214-
Obj::new(bld.build())
346+
Obj::new(bld.with_vertex_normals().build())
215347
}

0 commit comments

Comments
 (0)