Dynamic render images when visiting webpage at /.
This commit is contained in:
parent
639c50a3de
commit
67ba66bdf7
1055
rtiow/Cargo.lock
generated
1055
rtiow/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,9 @@ log = "0.4.5"
|
|||||||
cpuprofiler = "0.0.3"
|
cpuprofiler = "0.0.3"
|
||||||
lazy_static = "1.1.0"
|
lazy_static = "1.1.0"
|
||||||
askama = "0.7.1"
|
askama = "0.7.1"
|
||||||
|
actix-web = "0.7.8"
|
||||||
|
serde = "1.0.79"
|
||||||
|
serde_derive = "1.0.79"
|
||||||
|
|
||||||
# For better profiling support.
|
# For better profiling support.
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|||||||
@ -2,8 +2,12 @@
|
|||||||
extern crate askama;
|
extern crate askama;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
extern crate actix_web;
|
||||||
extern crate image;
|
extern crate image;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
extern crate serde;
|
||||||
extern crate stderrlog;
|
extern crate stderrlog;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -11,11 +15,18 @@ extern crate structopt;
|
|||||||
|
|
||||||
extern crate rtiow;
|
extern crate rtiow;
|
||||||
|
|
||||||
|
use actix_web::Path as WebPath;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
use actix_web::middleware;
|
||||||
|
use actix_web::server;
|
||||||
|
use actix_web::App;
|
||||||
|
use actix_web::HttpRequest;
|
||||||
|
use actix_web::HttpResponse;
|
||||||
|
use actix_web::Result;
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use rand::XorShiftRng;
|
use rand::XorShiftRng;
|
||||||
@ -34,6 +45,10 @@ struct Opt {
|
|||||||
#[structopt(parse(from_os_str), default_value = "/tmp/perlin")]
|
#[structopt(parse(from_os_str), default_value = "/tmp/perlin")]
|
||||||
pub output: PathBuf,
|
pub output: PathBuf,
|
||||||
|
|
||||||
|
/// HTTP listen address
|
||||||
|
#[structopt(long = "addr", default_value = "0.0.0.0:8889")]
|
||||||
|
pub addr: String,
|
||||||
|
|
||||||
/// Width of noise images
|
/// Width of noise images
|
||||||
#[structopt(short = "w", long = "width", default_value = "128")]
|
#[structopt(short = "w", long = "width", default_value = "128")]
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
@ -42,9 +57,11 @@ struct Opt {
|
|||||||
pub height: u32,
|
pub height: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
enum NoiseType {
|
enum NoiseType {
|
||||||
Scale(f32),
|
Scale(f32),
|
||||||
Turbulance(usize),
|
Turbulence(usize),
|
||||||
Marble {
|
Marble {
|
||||||
period: Vec3,
|
period: Vec3,
|
||||||
power: f32,
|
power: f32,
|
||||||
@ -52,12 +69,55 @@ enum NoiseType {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NoiseType {
|
||||||
|
fn to_url(&self) -> String {
|
||||||
|
match &self {
|
||||||
|
NoiseType::Scale(scale) => format!("scale/{}", scale),
|
||||||
|
NoiseType::Turbulence(turbulence) => format!("turbulence/{}", turbulence),
|
||||||
|
NoiseType::Marble {
|
||||||
|
period,
|
||||||
|
power,
|
||||||
|
size,
|
||||||
|
} => format!(
|
||||||
|
"marble/period/{},{},{}/power/{}/size/{}",
|
||||||
|
period.x, period.y, period.z, power, size,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
struct NoiseParams {
|
struct NoiseParams {
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
noise: NoiseType,
|
noise: NoiseType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct NoiseParamsScale {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
scale: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct NoiseParamsTurbulence {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
turbulence: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct NoiseParamsMarble {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
z: f32,
|
||||||
|
power: f32,
|
||||||
|
size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl NoiseParams {
|
impl NoiseParams {
|
||||||
fn compact_string(&self) -> String {
|
fn compact_string(&self) -> String {
|
||||||
let mut s = format!("w{}-h{}", self.width, self.height);
|
let mut s = format!("w{}-h{}", self.width, self.height);
|
||||||
@ -65,7 +125,7 @@ impl NoiseParams {
|
|||||||
match self.noise {
|
match self.noise {
|
||||||
NoiseType::Scale(scale) => s.push_str(&format!("-s{:.2}", scale)),
|
NoiseType::Scale(scale) => s.push_str(&format!("-s{:.2}", scale)),
|
||||||
|
|
||||||
NoiseType::Turbulance(turbulence) => s.push_str(&format!("-t{}", turbulence)),
|
NoiseType::Turbulence(turbulence) => s.push_str(&format!("-t{}", turbulence)),
|
||||||
NoiseType::Marble {
|
NoiseType::Marble {
|
||||||
period,
|
period,
|
||||||
power,
|
power,
|
||||||
@ -79,19 +139,28 @@ impl NoiseParams {
|
|||||||
}
|
}
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn url(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"/noise/{}/{}/{}",
|
||||||
|
self.width,
|
||||||
|
self.height,
|
||||||
|
self.noise.to_url(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn big_url(&self) -> String {
|
||||||
|
format!("/noise/1024/1024/{}", self.noise.to_url())
|
||||||
|
}
|
||||||
|
|
||||||
fn image_name(&self) -> String {
|
fn image_name(&self) -> String {
|
||||||
format!("noise-{}.png", self.compact_string())
|
format!("noise-{}.png", self.compact_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_noise_to_disk<P>(output_dir: P, noise_params: &NoiseParams) -> Result<(), std::io::Error>
|
fn render_noise(noise_params: &NoiseParams) -> image::GrayImage {
|
||||||
where
|
|
||||||
P: AsRef<Path>,
|
|
||||||
{
|
|
||||||
const SEED: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
const SEED: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
||||||
let ref mut rng: XorShiftRng = SeedableRng::from_seed(SEED);
|
let ref mut rng: XorShiftRng = SeedableRng::from_seed(SEED);
|
||||||
let ref output_dir: &Path = output_dir.as_ref();
|
|
||||||
fs::create_dir_all(output_dir)?;
|
|
||||||
let mut img = image::GrayImage::new(noise_params.width, noise_params.height);
|
let mut img = image::GrayImage::new(noise_params.width, noise_params.height);
|
||||||
let tex = Noise::new(rng);
|
let tex = Noise::new(rng);
|
||||||
|
|
||||||
@ -103,7 +172,7 @@ where
|
|||||||
let luma = match noise_params.noise {
|
let luma = match noise_params.noise {
|
||||||
NoiseType::Scale(scale) => tex.value(p, scale),
|
NoiseType::Scale(scale) => tex.value(p, scale),
|
||||||
|
|
||||||
NoiseType::Turbulance(turbulence) => tex.turbulence(p, turbulence),
|
NoiseType::Turbulence(turbulence) => tex.turbulence(p, turbulence),
|
||||||
NoiseType::Marble {
|
NoiseType::Marble {
|
||||||
period,
|
period,
|
||||||
power,
|
power,
|
||||||
@ -122,6 +191,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_noise_to_disk<P>(output_dir: P, noise_params: &NoiseParams) -> Result<(), std::io::Error>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let img = render_noise(noise_params);
|
||||||
|
let ref output_dir: &Path = output_dir.as_ref();
|
||||||
|
fs::create_dir_all(output_dir)?;
|
||||||
let path = output_dir.join(noise_params.image_name());
|
let path = output_dir.join(noise_params.image_name());
|
||||||
info!("Saving {}", path.display());
|
info!("Saving {}", path.display());
|
||||||
img.save(path)
|
img.save(path)
|
||||||
@ -139,10 +218,7 @@ struct IndexTemplate {
|
|||||||
specimens: Vec<Specimen>,
|
specimens: Vec<Specimen>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_html<P>(output_dir: P, specimens: Vec<Specimen>) -> Result<(), std::io::Error>
|
fn render_html(specimens: Vec<Specimen>) -> Result<String, askama::Error> {
|
||||||
where
|
|
||||||
P: AsRef<Path>,
|
|
||||||
{
|
|
||||||
let index = IndexTemplate {
|
let index = IndexTemplate {
|
||||||
render_time: SystemTime::now()
|
render_time: SystemTime::now()
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
@ -150,20 +226,10 @@ where
|
|||||||
.as_secs(),
|
.as_secs(),
|
||||||
specimens,
|
specimens,
|
||||||
};
|
};
|
||||||
fs::write(
|
index.render()
|
||||||
output_dir.as_ref().join("index.html"),
|
|
||||||
index.render().unwrap(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), std::io::Error> {
|
fn build_specimens(width: u32, height: u32) -> Vec<Specimen> {
|
||||||
stderrlog::new()
|
|
||||||
.verbosity(3)
|
|
||||||
.timestamp(stderrlog::Timestamp::Millisecond)
|
|
||||||
.init()
|
|
||||||
.unwrap();
|
|
||||||
let opt = Opt::from_args();
|
|
||||||
|
|
||||||
let mut specimens = Vec::new();
|
let mut specimens = Vec::new();
|
||||||
let mut specimen = Specimen {
|
let mut specimen = Specimen {
|
||||||
title: "Unperturbed".into(),
|
title: "Unperturbed".into(),
|
||||||
@ -171,11 +237,10 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
};
|
};
|
||||||
{
|
{
|
||||||
let params = NoiseParams {
|
let params = NoiseParams {
|
||||||
width: opt.width,
|
width,
|
||||||
height: opt.height,
|
height,
|
||||||
noise: NoiseType::Scale(1.),
|
noise: NoiseType::Scale(1.),
|
||||||
};
|
};
|
||||||
render_noise_to_disk(&opt.output, ¶ms)?;
|
|
||||||
specimen.params.push(params);
|
specimen.params.push(params);
|
||||||
}
|
}
|
||||||
specimens.push(specimen);
|
specimens.push(specimen);
|
||||||
@ -188,11 +253,10 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
if !debug {
|
if !debug {
|
||||||
for scale in 1..10 {
|
for scale in 1..10 {
|
||||||
let params = NoiseParams {
|
let params = NoiseParams {
|
||||||
width: opt.width,
|
width,
|
||||||
height: opt.height,
|
height,
|
||||||
noise: NoiseType::Scale(scale as f32 / 10.),
|
noise: NoiseType::Scale(scale as f32 / 10.),
|
||||||
};
|
};
|
||||||
render_noise_to_disk(&opt.output, ¶ms)?;
|
|
||||||
specimen.params.push(params);
|
specimen.params.push(params);
|
||||||
}
|
}
|
||||||
specimens.push(specimen);
|
specimens.push(specimen);
|
||||||
@ -203,11 +267,10 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
};
|
};
|
||||||
for scale in 1..10 {
|
for scale in 1..10 {
|
||||||
let params = NoiseParams {
|
let params = NoiseParams {
|
||||||
width: opt.width,
|
width,
|
||||||
height: opt.height,
|
height,
|
||||||
noise: NoiseType::Scale(scale as f32),
|
noise: NoiseType::Scale(scale as f32),
|
||||||
};
|
};
|
||||||
render_noise_to_disk(&opt.output, ¶ms)?;
|
|
||||||
specimen.params.push(params);
|
specimen.params.push(params);
|
||||||
}
|
}
|
||||||
specimens.push(specimen);
|
specimens.push(specimen);
|
||||||
@ -218,11 +281,10 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
};
|
};
|
||||||
for turbulence in 0..9 {
|
for turbulence in 0..9 {
|
||||||
let params = NoiseParams {
|
let params = NoiseParams {
|
||||||
width: opt.width,
|
width,
|
||||||
height: opt.height,
|
height,
|
||||||
noise: NoiseType::Turbulance(1 << turbulence),
|
noise: NoiseType::Turbulence(1 << turbulence),
|
||||||
};
|
};
|
||||||
render_noise_to_disk(&opt.output, ¶ms)?;
|
|
||||||
specimen.params.push(params);
|
specimen.params.push(params);
|
||||||
}
|
}
|
||||||
specimens.push(specimen);
|
specimens.push(specimen);
|
||||||
@ -234,32 +296,188 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
for power in 1..10 {
|
for power in 1..10 {
|
||||||
for size in 1..6 {
|
for size in 1..6 {
|
||||||
let params = NoiseParams {
|
let params = NoiseParams {
|
||||||
width: opt.width,
|
width,
|
||||||
height: opt.height,
|
height,
|
||||||
noise: NoiseType::Marble {
|
noise: NoiseType::Marble {
|
||||||
period: Vec3::new(5., 10., 0.),
|
period: Vec3::new(5., 10., 0.),
|
||||||
power: power as f32,
|
power: power as f32,
|
||||||
size: 1 << size,
|
size: 1 << size,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
render_noise_to_disk(&opt.output, ¶ms)?;
|
|
||||||
specimen.params.push(params);
|
specimen.params.push(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for power in 1..10 {
|
for power in 1..10 {
|
||||||
let params = NoiseParams {
|
let params = NoiseParams {
|
||||||
width: opt.width,
|
width,
|
||||||
height: opt.height,
|
height,
|
||||||
noise: NoiseType::Marble {
|
noise: NoiseType::Marble {
|
||||||
period: Vec3::new(0., 1., 0.),
|
period: Vec3::new(0., 1., 0.),
|
||||||
power: power as f32,
|
power: power as f32,
|
||||||
size: 32,
|
size: 32,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
render_noise_to_disk(&opt.output, ¶ms)?;
|
|
||||||
specimen.params.push(params);
|
specimen.params.push(params);
|
||||||
}
|
}
|
||||||
specimens.push(specimen);
|
specimens.push(specimen);
|
||||||
}
|
}
|
||||||
render_html(&opt.output, specimens)
|
specimens
|
||||||
|
}
|
||||||
|
|
||||||
|
fn style(_req: &HttpRequest) -> Result<HttpResponse> {
|
||||||
|
let bytes = include_bytes!("../../templates/style.css");
|
||||||
|
Ok(HttpResponse::Ok().content_type("text/css").body(&bytes[..]))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(_req: &HttpRequest) -> Result<HttpResponse> {
|
||||||
|
// TODO(wathiede): get these from app state?
|
||||||
|
let width = 128;
|
||||||
|
let height = 128;
|
||||||
|
let specimens = build_specimens(width, height);
|
||||||
|
Ok(HttpResponse::Ok()
|
||||||
|
.content_type("text/html")
|
||||||
|
.body(render_html(specimens).unwrap()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn noise(np: NoiseParams) -> Result<HttpResponse> {
|
||||||
|
let img = render_noise(&np);
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
let img = image::DynamicImage::ImageLuma8(img);
|
||||||
|
// TODO(wathiede): remove unwrap with proper error propagation.
|
||||||
|
img.write_to(&mut buf, image::ImageOutputFormat::PNG)
|
||||||
|
.unwrap();
|
||||||
|
Ok(HttpResponse::Ok().content_type("image/png").body(buf))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn noise_scale(np: WebPath<NoiseParamsScale>) -> Result<HttpResponse> {
|
||||||
|
noise(NoiseParams {
|
||||||
|
width: np.width,
|
||||||
|
height: np.height,
|
||||||
|
noise: NoiseType::Scale(np.scale),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn noise_turbulence(np: WebPath<NoiseParamsTurbulence>) -> Result<HttpResponse> {
|
||||||
|
noise(NoiseParams {
|
||||||
|
width: np.width,
|
||||||
|
height: np.height,
|
||||||
|
noise: NoiseType::Turbulence(np.turbulence),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn noise_marble(np: WebPath<NoiseParamsMarble>) -> Result<HttpResponse> {
|
||||||
|
noise(NoiseParams {
|
||||||
|
width: np.width,
|
||||||
|
height: np.height,
|
||||||
|
noise: NoiseType::Marble {
|
||||||
|
period: Vec3::new(np.x, np.y, np.z),
|
||||||
|
power: np.power,
|
||||||
|
size: np.size,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), std::io::Error> {
|
||||||
|
stderrlog::new()
|
||||||
|
.verbosity(2)
|
||||||
|
.timestamp(stderrlog::Timestamp::Millisecond)
|
||||||
|
.init()
|
||||||
|
.unwrap();
|
||||||
|
let opt = Opt::from_args();
|
||||||
|
|
||||||
|
server::new(|| {
|
||||||
|
App::new()
|
||||||
|
.resource("/noise/{width}/{height}/scale/{scale}", |r| {
|
||||||
|
r.with(noise_scale);
|
||||||
|
}).resource("/noise/{width}/{height}/turbulence/{turbulence}", |r| {
|
||||||
|
r.with(noise_turbulence);
|
||||||
|
}).resource(
|
||||||
|
"/noise/{width}/{height}/marble/period/{x},{y},{z}/power/{power}/size/{size}",
|
||||||
|
|r| {
|
||||||
|
r.with(noise_marble);
|
||||||
|
},
|
||||||
|
).resource("/style.css", |r| r.f(style))
|
||||||
|
.resource("/", |r| r.f(index))
|
||||||
|
.middleware(middleware::Logger::default())
|
||||||
|
}).bind(opt.addr)
|
||||||
|
.unwrap()
|
||||||
|
.run();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::str;
|
||||||
|
|
||||||
|
use actix_web::http::Method;
|
||||||
|
use actix_web::test::TestServer;
|
||||||
|
use actix_web::HttpMessage;
|
||||||
|
use actix_web::Path;
|
||||||
|
|
||||||
|
use super::NoiseParamsMarble;
|
||||||
|
use super::NoiseParamsScale;
|
||||||
|
use super::NoiseParamsTurbulence;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn noise_param_from_req() {
|
||||||
|
let mut srv = TestServer::build().start(|app| {
|
||||||
|
app.resource("/noise/{width}/{height}/scale/{scale}", |r| {
|
||||||
|
r.with(|p: Path<NoiseParamsScale>| format!("{:?}", p));
|
||||||
|
});
|
||||||
|
app.resource("/noise/{width}/{height}/turbulence/{turbulence}", |r| {
|
||||||
|
r.with(|p: Path<NoiseParamsTurbulence>| format!("{:?}", p));
|
||||||
|
});
|
||||||
|
app.resource(
|
||||||
|
"/noise/{width}/{height}/marble/period/{x},{y},{z}/power/{power}/size/{size}",
|
||||||
|
|r| {
|
||||||
|
r.with(|p: Path<NoiseParamsMarble>| format!("{:?}", p));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
let request = srv
|
||||||
|
.client(Method::GET, "/noise/32/32/scale/1")
|
||||||
|
.finish()
|
||||||
|
.unwrap();
|
||||||
|
let response = srv.execute(request.send()).unwrap();
|
||||||
|
assert!(response.status().is_success(), "Response {:?}", response);
|
||||||
|
|
||||||
|
let bytes = srv.execute(response.body()).unwrap();
|
||||||
|
let body = str::from_utf8(&bytes).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
body,
|
||||||
|
"NoiseParamsScale { width: 32, height: 32, scale: 1.0 }"
|
||||||
|
);
|
||||||
|
|
||||||
|
let request = srv
|
||||||
|
.client(Method::GET, "/noise/32/32/turbulence/5")
|
||||||
|
.finish()
|
||||||
|
.unwrap();
|
||||||
|
let response = srv.execute(request.send()).unwrap();
|
||||||
|
assert!(response.status().is_success(), "Response {:?}", response);
|
||||||
|
|
||||||
|
let bytes = srv.execute(response.body()).unwrap();
|
||||||
|
let body = str::from_utf8(&bytes).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
body,
|
||||||
|
"NoiseParamsTurbulence { width: 32, height: 32, turbulence: 5 }"
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO(wathiede): this isn't working, probably because Vec3 Deserialize is not working.
|
||||||
|
let request = srv
|
||||||
|
.client(
|
||||||
|
Method::GET,
|
||||||
|
"/noise/32/32/marble/period/1.,2.,3./power/32./size/4",
|
||||||
|
).finish()
|
||||||
|
.unwrap();
|
||||||
|
let response = srv.execute(request.send()).unwrap();
|
||||||
|
assert!(response.status().is_success(), "Response {:?}", response);
|
||||||
|
|
||||||
|
let bytes = srv.execute(response.body()).unwrap();
|
||||||
|
let body = str::from_utf8(&bytes).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
body,
|
||||||
|
"NoiseParamsMarble { width: 32, height: 32, x: 1.0, y: 2.0, z: 3.0, power: 32.0, size: 4 }"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,3 +30,5 @@ extern crate rand;
|
|||||||
extern crate rayon;
|
extern crate rayon;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate structopt;
|
extern crate structopt;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|||||||
@ -5,9 +5,10 @@ use rand;
|
|||||||
|
|
||||||
use vec3::Vec3;
|
use vec3::Vec3;
|
||||||
|
|
||||||
const NOISE_SIZE: usize = 64;
|
const NOISE_SIZE: usize = 128;
|
||||||
pub struct Noise {
|
pub struct Noise {
|
||||||
noise: [[[f32; NOISE_SIZE]; NOISE_SIZE]; NOISE_SIZE],
|
// Using fixed array causes stack overflow.
|
||||||
|
noise: Vec<Vec<Vec<f32>>>, //[[[f32; NOISE_SIZE]; NOISE_SIZE]; NOISE_SIZE],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Noise {
|
impl Noise {
|
||||||
@ -15,7 +16,7 @@ impl Noise {
|
|||||||
where
|
where
|
||||||
R: rand::Rng,
|
R: rand::Rng,
|
||||||
{
|
{
|
||||||
let mut noise = [[[0.; NOISE_SIZE]; NOISE_SIZE]; NOISE_SIZE];
|
let mut noise = vec![vec![vec![0.; NOISE_SIZE]; NOISE_SIZE]; NOISE_SIZE];
|
||||||
for x in 0..NOISE_SIZE {
|
for x in 0..NOISE_SIZE {
|
||||||
for y in 0..NOISE_SIZE {
|
for y in 0..NOISE_SIZE {
|
||||||
for z in 0..NOISE_SIZE {
|
for z in 0..NOISE_SIZE {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use std::ops::Neg;
|
|||||||
use std::ops::Sub;
|
use std::ops::Sub;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
#[derive(Default, Debug, PartialEq, Copy, Clone)]
|
#[derive(Default, Debug, Deserialize, Serialize, PartialEq, Copy, Clone)]
|
||||||
pub struct Vec3 {
|
pub struct Vec3 {
|
||||||
pub x: f32,
|
pub x: f32,
|
||||||
pub y: f32,
|
pub y: f32,
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Noise test</title>
|
<title>Noise test</title>
|
||||||
<link rel="stylesheet" type="text/css" href="perlin.css" media="screen" />
|
<link rel="stylesheet" type="text/css" href="style.css" media="screen" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% for s in specimens %}
|
{% for s in specimens %}
|
||||||
@ -11,8 +11,8 @@
|
|||||||
{% for np in s.params %}
|
{% for np in s.params %}
|
||||||
<figure>
|
<figure>
|
||||||
<p>
|
<p>
|
||||||
<a href="{{ np.image_name() }}">
|
<a href="{{ np.big_url()|safe }}">
|
||||||
<img width="{{ np.width }}" height="{{ np.height }}" src="{{ np.image_name() }}?t={{ render_time }}"/>
|
<img width="{{ np.width }}" height="{{ np.height }}" src="{{ np.url()|safe }}"/>
|
||||||
</a>
|
</a>
|
||||||
<figcaption>{{ np.compact_string() }}</figcaption>
|
<figcaption>{{ np.compact_string() }}</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user