initial commit

This commit is contained in:
Jonas Maier 2023-02-12 14:01:05 +01:00
commit 07278a7e88
4 changed files with 435 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

212
Cargo.lock generated Normal file
View File

@ -0,0 +1,212 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "cc"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cmake"
version = "0.1.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c"
dependencies = [
"cc",
]
[[package]]
name = "fs_extra"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "fuss"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fe192ec76b82299899a106db5c1ae833d022dec6d3f848ac9fc17229b34c5e"
dependencies = [
"rand 0.3.23",
]
[[package]]
name = "getrandom"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "rand"
version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
dependencies = [
"libc",
"rand 0.4.6",
]
[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
"rdrand",
"winapi",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core 0.6.4",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "raylib"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb567269b7ea9ae3c4a5aab4dc95e0b4d8df2a49a25e1670a3bb17bc17504606"
dependencies = [
"cfg-if",
"lazy_static",
"libc",
"raylib-sys",
]
[[package]]
name = "raylib-sys"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20c97b5e251b73c52183914d4756104cab401050f244c19abe83fa05a4e86840"
dependencies = [
"cc",
"cmake",
"fs_extra",
]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "universe-gen"
version = "0.1.0"
dependencies = [
"fuss",
"rand 0.8.5",
"rand_chacha",
"raylib",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

12
Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "universe-gen"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
raylib = "3.7"
fuss = "0.2"
rand = "0.8.5"
rand_chacha = "0.3.1"

210
src/main.rs Normal file
View File

@ -0,0 +1,210 @@
use fuss::Simplex;
use rand::prelude::*;
use rand_chacha::*;
use raylib::{ffi::SetConfigFlags, prelude::*};
use std::ops::*;
type Rand = ChaCha8Rng;
fn lerp<T: Add<Output = T> + Mul<f32, Output = T>>(a: T, b: T, t: f32) -> T {
a * (1.0 - t) + b * t
}
fn lerpc(a: Color, b: Color, t: f32) -> Color {
Color::new(
lerp(a.r as f32, b.r as f32, t) as u8,
lerp(a.g as f32, b.g as f32, t) as u8,
lerp(a.b as f32, b.b as f32, t) as u8,
lerp(a.a as f32, b.a as f32, t) as u8,
)
}
fn stepstone(rng: &mut Rand, size: usize, iter: usize) -> Vec<Vec<f32>> {
let mut field = vec![vec![0.0; size]; size];
for x in 0..size {
for y in 0..size {
//field[x][y] = rand.gen();
//field[x][y] = if x > size / 4 && x < 3 * size / 4 { 1.0 } else { 0.0 };
field[x][y] = if rng.gen::<bool>() { 1.0 } else { 0.0 };
}
}
for _ in 0..iter {
let x = rng.gen::<usize>() % (size - 2) + 1;
let y = rng.gen::<usize>() % (size - 2) + 1;
let mut nx = x;
let mut ny = y;
if rng.gen() {
if rng.gen() {
nx += 1;
} else {
nx -= 1;
}
} else {
if rng.gen() {
ny += 1;
} else {
ny -= 1;
}
}
field[nx][ny] = lerp(field[x][y], field[nx][ny], 0.05);
}
field
}
fn test(tex: &Vec<Vec<f32>>, d: &mut RaylibDrawHandle) {
for x in 0..tex.len() {
for y in 0..tex.len() {
d.draw_pixel(x as _, y as _, lerpc(Color::BLACK, Color::WHITE, tex[x][y]));
}
}
}
fn planet_circle(center: Vector2, radius: f32, d: &mut RaylibDrawHandle, mask: bool) {
let noise = Simplex::from_seed(vec![5, 4, 4, 2, 1, 0]);
for k in 0..50_000 {
let t = k as f32 * 0.5;
let angle = t * 0.01;
let pi = std::f32::consts::PI;
let tau = 2.0 * pi;
let c_angle = angle % tau;
if (c_angle < 0.5 * pi || c_angle > 1.5 * pi) != mask {
continue;
}
let dir = Vector2::new(angle.sin(), 0.3 * angle.cos());
let dist = radius * 2.0 + noise.noise_2d(angle * 0.3, 0.0) * radius * 0.4;
let comet_size = 1.1 + noise.noise_2d(0.0, angle * 0.1);
let ct = (noise.noise_2d(0.5 * angle.sin(), 0.2 * angle.cos()) + 1.0) * 0.5;
let color = lerpc(Color::PINK, Color::WHITE, ct);
d.draw_circle_v(center + dir * dist, comet_size, color);
}
}
fn stars(rng: &mut Rand, d: &mut RaylibDrawHandle) {
for _ in 0..1000 {
let x = rng.gen::<f32>() * WIDTH as f32;
let y = rng.gen::<f32>() * HEIGHT as f32;
let radius = rng.gen::<f32>() * 1.5;
d.draw_circle_v(Vector2::new(x, y), radius, Color::WHITE);
}
}
fn planet(pat: &Vec<Vec<f32>>, center: Vector2, radius: f32, d: &mut RaylibDrawHandle) {
planet_circle(center, radius, d, false);
//d.draw_circle_v(center, radius, Color::VIOLET);
let diameter = 2 * radius as usize;
for x in 0..diameter {
for y in 0..diameter {
let xf = x as f32 - radius;
let yf = y as f32 - radius;
let p = Vector2::new(xf, yf);
if p.length_sqr() < radius * radius {
let zf = (radius * radius - xf * xf - yf * yf).sqrt();
let p3 = Vector3::new(xf, yf, zf).normalized();
let sun = Vector3::new(-2.5, -1.0, 1.0).normalized();
let p = p + center;
let col = lerpc(Color::PINK, Color::WHITE, pat[x][y]);
let col = lerpc(Color::BLACK, col, p3.dot(sun).max(0.0));
d.draw_pixel_v(p, col);
}
}
}
planet_circle(center, radius, d, true);
}
fn mountain(rng: &mut Rand, d: &mut RaylibDrawHandle) {
let peak_amt = 10;
let mut peak_pos = vec![];
let mut last = 0;
for _ in 0..peak_amt {
let x = rng.gen::<f32>() * 200.0 + 210.0;
let y = last;
last += WIDTH / (peak_amt - 1) as i32;
let pos = Vector2::new(y as f32, HEIGHT as f32 - x as f32);
peak_pos.push(pos);
peak(rng, d, pos);
}
}
fn peak(rng: &mut Rand, d: &mut RaylibDrawHandle, v: Vector2) {
let left = v + Vector2::new(-1.0, rng.gen::<f32>() * 0.5 + 0.5) * 500.0;
let middle = v + Vector2::new(1.0, 5.0) * 100.0;
let right = v + Vector2::new(1.0, 1.0) * 100.0;
d.draw_triangle(left, right, v, Color::BLACK);
d.draw_triangle(left, middle, v, Color::new(200, 200, 200, 0xFF));
let color0 = Color::new(200, 200, 200, 0xFF);
let color1 = Color::WHITE;
for _ in 0..100 {
let begin = lerp(v, middle, rng.gen());
let dir = (left - v).normalized();
let noise = Simplex::from_seed(vec![rng.gen(), rng.gen()]);
for t in 0..300 {
let t = t as f32;
let mut pos = begin + dir * t * 2.1;
pos.y += noise.noise_2d(t * 0.1, 0.0) * 5.0;
let col = lerpc(color0, color1, noise.noise_2d(0.0, t * 0.1).abs());
d.draw_circle_v(pos, 3.0, col);
}
}
}
fn plateau(rng: &mut Rand, d: &mut RaylibDrawHandle) {
d.draw_rectangle(0, HEIGHT * 9 / 10, WIDTH, HEIGHT, Color::WHITE);
}
const WIDTH: i32 = 1000;
const HEIGHT: i32 = 1000;
fn main() {
unsafe {
SetConfigFlags(ConfigFlags::FLAG_MSAA_4X_HINT as u32);
}
let (mut rl, thread) = raylib::init().size(WIDTH, HEIGHT).title("Universe").build();
rl.get_window_state().set_msaa(true);
let mut rng = ChaCha8Rng::seed_from_u64(0);
let tex = stepstone(&mut rng, 512, 30_000_000);
let pre_frame_rng = rng.clone();
while !rl.window_should_close() {
let mut d = rl.begin_drawing(&thread);
let mut rng = pre_frame_rng.clone();
let rng = &mut rng;
d.clear_background(Color::new(3, 3, 5, 0xFF));
stars(rng, &mut d);
planet(&tex, Vector2::new(330.0, 200.0), 130.0, &mut d);
mountain(rng, &mut d);
plateau(rng, &mut d);
}
}