Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge to master #218

Merged
merged 46 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
9b6fe7f
Improve buf doc comments and correctness
jdahlstrom Aug 10, 2024
2ceea2e
Add SDL2 frontend
jdahlstrom Jun 13, 2024
51a6c04
Improve frontend error handling
jdahlstrom Jul 21, 2024
6917fe1
Add dedicated error type to sdl2
jdahlstrom Jul 31, 2024
8b08363
Change crates demo to use sdl2
jdahlstrom Oct 9, 2024
4614b99
Add clear method to Frame
jdahlstrom Oct 9, 2024
c7cb7de
Fixup sdl2 feature for crates
jdahlstrom Dec 4, 2024
0b2f0e1
Move Debug impl for Real to correct module
jdahlstrom Dec 3, 2024
338360d
Tweak vector implementation details
jdahlstrom Dec 3, 2024
ef15a62
Add Point type
jdahlstrom Dec 3, 2024
017a57c
Impl Debug, Add, Sub, ApproxEq for Point
jdahlstrom Dec 4, 2024
b2eaf3d
Add alias, methods to Point
jdahlstrom Dec 4, 2024
2d9a345
Add Vertex2, Vertex3 type aliases
jdahlstrom Dec 4, 2024
d8c01f9
Add point-to-vec and vec-to-point conversion methods
jdahlstrom Dec 4, 2024
e4b0e2d
Index Buf with points rather than vecs
jdahlstrom Dec 4, 2024
fe8b9c0
Move lerping to its own trait Lerp
jdahlstrom Dec 7, 2024
4a089de
Add support for Bezier curves of affine types
jdahlstrom Dec 7, 2024
7f6fb60
Add preliminary matrix-point transform method
jdahlstrom Dec 4, 2024
f8bdf2f
Migrate to using points as vertex coordinates
jdahlstrom Dec 4, 2024
4b10f58
Add trait ZDiv for optional perspective correction
jdahlstrom Dec 5, 2024
557f876
Improve assert message
jdahlstrom Dec 7, 2024
0187910
Change pnm header to use Dims
jdahlstrom Dec 7, 2024
668f729
Remove lerp from Vary
jdahlstrom Dec 8, 2024
e62ad14
Use points as screen space positions
jdahlstrom Dec 4, 2024
728e77a
Use points as orthographic and viewport bounds
jdahlstrom Dec 4, 2024
a6626d5
Refactor clipping somewhat
jdahlstrom Dec 7, 2024
2930cb2
Add random distributions of points
jdahlstrom Dec 8, 2024
6a037a6
Remove RNG type parameter from Distrib for now
jdahlstrom Dec 8, 2024
3ae1785
Improve rand comments and doctests
jdahlstrom Dec 8, 2024
7ee0b1b
Add re-exports to render.rs root
jdahlstrom Dec 16, 2024
6094832
Impl Error trait unconditionally now that it's in core
jdahlstrom Dec 18, 2024
c0e0060
Rename read_from to read_obj for consistency
jdahlstrom Dec 18, 2024
36feadc
Improve obj comments and tests
jdahlstrom Dec 18, 2024
0a95bda
Add parse_pnm for consistency with OBJ loading
jdahlstrom Dec 18, 2024
1c7e9b3
Add P2 (text graymap) read support
jdahlstrom May 14, 2024
bff13e3
Fix edge case in read_pnm, improve pnm test coverage
jdahlstrom Jun 17, 2024
9bff5e4
Revamp math.rs re-exports
jdahlstrom Dec 19, 2024
4834d2b
Factor solids.rs to submodules
jdahlstrom Dec 16, 2024
b9fd2b0
Take IntoIterator rather than Vec in Lathe::new
jdahlstrom Dec 17, 2024
4ae5ecc
Add shortcut alias for run-demo
jdahlstrom Dec 20, 2024
d4a6356
Add segments parameter to Cylinder, Cone, and Capsule
jdahlstrom Dec 17, 2024
3d5f9b3
Add some missing operators and doc comments to Point
jdahlstrom Dec 22, 2024
4f8b65c
Change Distrib::samples to borrow the RNG
jdahlstrom Dec 22, 2024
e536a36
Add BezierSpline constructor from rays (point, dir pairs)
jdahlstrom Dec 8, 2024
718c4e1
Fix bug in github action
jdahlstrom Dec 23, 2024
3a31ab7
Fix embarrassing bug in Matrix::from_basis(), add tests
jdahlstrom Dec 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[alias]
run-demo = "run --release -p retrofire-demos -F minifb,re-geom --bin"
run-demo = "run --release -p retrofire-demos -F minifb,sdl2,re-geom --bin"
rd = "run --release -q -p retrofire-demos -F minifb,sdl2,re-geom --bin"
27 changes: 13 additions & 14 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,18 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Install libsdl
run: sudo apt-get update && sudo apt-get -y install libsdl2-dev
- uses: actions/checkout@v2
- name: Install libsdl
run: sudo apt-get update && sudo apt-get -y install libsdl2-dev

- name: Build core, no features
run: cargo build -p retrofire-core --verbose --all-targets --no-default-features
- name: Build core, micromath
run: cargo build -p retrofire-core --verbose --all-targets --no-default-features --features "mm"
- name: Build core, libm
run: cargo build -p retrofire-core --verbose --all-targets --no-default-features --features "libm"

- name: Build workspace, std
run: cargo build --workspace --verbose --all-targets --features "std"
- name: Run tests, std
run: cargo test --workspace --verbose --features "std" --exclude 'retrofire-demos*'
- name: Build core, no features
run: cargo build -p retrofire-core --verbose --all-targets --no-default-features
- name: Build core, micromath
run: cargo build -p retrofire-core --verbose --all-targets --no-default-features --features "mm"
- name: Build core, libm
run: cargo build -p retrofire-core --verbose --all-targets --no-default-features --features "libm"

- name: Build workspace, std
run: cargo build --workspace --verbose --all-targets --all-features
- name: Run tests, std
run: cargo test --workspace --verbose --features "std" --exclude 'retrofire-demos*'
11 changes: 10 additions & 1 deletion core/src/geom.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Basic geometric primitives.

use crate::math::vec::{Vec2, Vec3};
use crate::math::{Point2, Point3, Vec2, Vec3};
use crate::render::Model;

pub use mesh::Mesh;

Expand All @@ -13,6 +14,12 @@ pub struct Vertex<P, A> {
pub attrib: A,
}

/// Two-dimensional vertex type.
pub type Vertex2<A, B = Model> = Vertex<Point2<B>, A>;

/// Three-dimensional vertex type.
pub type Vertex3<A, B = Model> = Vertex<Point3<B>, A>;

/// Triangle, defined by three vertices.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(transparent)]
Expand All @@ -31,3 +38,5 @@ pub type Normal2 = Vec2;
pub const fn vertex<P, A>(pos: P, attrib: A) -> Vertex<P, A> {
Vertex { pos, attrib }
}

pub struct Ray<Orig, Dir>(pub Orig, pub Dir);
73 changes: 35 additions & 38 deletions core/src/geom/mesh.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
//! Triangle meshes.

use alloc::{vec, vec::Vec};
use core::{
fmt::{Debug, Formatter},
iter::zip,
};

use alloc::{vec, vec::Vec};

use crate::math::{
mat::{Mat4x4, RealToReal},
space::Linear,
vec::Vec3,
use crate::{
math::{mat::RealToReal, Linear, Mat4x4, Point3},
render::Model,
};
use crate::render::Model;

use super::{vertex, Normal3, Tri};

/// Convenience type alias for a mesh vertex.
pub type Vertex<A, B = Model> = super::Vertex<Vec3<B>, A>;
use super::{vertex, Normal3, Tri, Vertex3};

/// A triangle mesh.
///
Expand All @@ -32,7 +26,7 @@ pub struct Mesh<Attrib, Basis = Model> {
/// to the `verts` vector. Several faces can share a vertex.
pub faces: Vec<Tri<usize>>,
/// The vertices of the mesh.
pub verts: Vec<Vertex<Attrib, Basis>>,
pub verts: Vec<Vertex3<Attrib, Basis>>,
}

/// A builder type for creating meshes.
Expand All @@ -53,17 +47,19 @@ impl<A, B> Mesh<A, B> {
///
/// # Examples
/// ```
/// # use retrofire_core::geom::{Tri, Mesh, vertex};
/// # use retrofire_core::math::vec3;
/// use retrofire_core::geom::{Tri, Mesh, vertex};
/// use retrofire_core::math::pt3;
///
/// let verts = [
/// vec3(0.0, 0.0, 0.0),
/// vec3(1.0, 0.0, 0.0),
/// vec3(0.0, 1.0, 0.0),
/// vec3(0.0, 0.0, 1.0)
/// pt3(0.0, 0.0, 0.0),
/// pt3(1.0, 0.0, 0.0),
/// pt3(0.0, 1.0, 0.0),
/// pt3(0.0, 0.0, 1.0)
/// ]
/// .map(|v| vertex(v, ()));
///
/// let faces = [
/// // Indices point to the verts array
/// Tri([0, 1, 2]),
/// Tri([0, 1, 3]),
/// Tri([0, 2, 3]),
Expand All @@ -78,7 +74,7 @@ impl<A, B> Mesh<A, B> {
pub fn new<F, V>(faces: F, verts: V) -> Self
where
F: IntoIterator<Item = Tri<usize>>,
V: IntoIterator<Item = Vertex<A, B>>,
V: IntoIterator<Item = Vertex3<A, B>>,
{
let faces: Vec<_> = faces.into_iter().collect();
let verts: Vec<_> = verts.into_iter().collect();
Expand Down Expand Up @@ -129,16 +125,16 @@ impl<A> Builder<A> {
}

/// Appends a vertex with the given position and attribute.
pub fn push_vert(&mut self, pos: Vec3, attrib: A) {
pub fn push_vert(&mut self, pos: Point3, attrib: A) {
self.mesh.verts.push(vertex(pos.to(), attrib));
}

/// Appends all the vertices yielded by the given iterator.
pub fn push_verts<Vs>(&mut self, verts: Vs)
where
Vs: IntoIterator<Item = (Vec3, A)>,
Vs: IntoIterator<Item = (Point3, A)>,
{
let vs = verts.into_iter().map(|(v, a)| vertex(v.to(), a));
let vs = verts.into_iter().map(|(p, a)| vertex(p.to(), a));
self.mesh.verts.extend(vs);
}

Expand Down Expand Up @@ -167,7 +163,7 @@ impl Builder<()> {
.mesh
.verts
.into_iter()
.map(|v| vertex(tf.apply(&v.pos), v.attrib))
.map(|v| vertex(tf.apply_pt(&v.pos), v.attrib))
.collect(),
};
mesh.into_builder()
Expand All @@ -191,8 +187,8 @@ impl Builder<()> {

// Compute weighted face normals...
let face_normals = faces.iter().map(|Tri(vs)| {
// TODO If n-gonal faces are supported some day,
// the cross product is not proportional to area anymore
// TODO If n-gonal faces are supported some day, the cross
// product is not proportional to area anymore
let [a, b, c] = vs.map(|i| verts[i].pos);
(b - a).cross(&(c - a)).to()
});
Expand Down Expand Up @@ -256,9 +252,10 @@ impl<A> Default for Builder<A> {
mod tests {
use core::f32::consts::FRAC_1_SQRT_2;

use crate::geom::vertex;
use crate::math::vec3;
use crate::prelude::splat;
use crate::{
geom::vertex,
math::{pt3, splat, vec3},
};

use super::*;

Expand All @@ -268,9 +265,9 @@ mod tests {
let _: Mesh<()> = Mesh::new(
[Tri([0, 1, 2]), Tri([1, 2, 3])],
[
vertex(vec3(0.0, 0.0, 0.0), ()),
vertex(vec3(1.0, 1.0, 1.0), ()),
vertex(vec3(2.0, 2.0, 2.0), ()),
vertex(pt3(0.0, 0.0, 0.0), ()),
vertex(pt3(1.0, 1.0, 1.0), ()),
vertex(pt3(2.0, 2.0, 2.0), ()),
],
);
}
Expand All @@ -281,9 +278,9 @@ mod tests {
let mut b = Mesh::builder();
b.push_faces([[0, 1, 2], [1, 2, 3]]);
b.push_verts([
(vec3(0.0, 0.0, 0.0), ()),
(vec3(1.0, 1.0, 1.0), ()),
(vec3(2.0, 2.0, 2.0), ()),
(pt3(0.0, 0.0, 0.0), ()),
(pt3(1.0, 1.0, 1.0), ()),
(pt3(2.0, 2.0, 2.0), ()),
]);
_ = b.build();
}
Expand All @@ -295,10 +292,10 @@ mod tests {
let mut b = Mesh::builder();
b.push_faces([[0, 2, 1], [0, 1, 3], [0, 3, 2]]);
b.push_verts([
(vec3(0.0, 0.0, 0.0), ()),
(vec3(1.0, 0.0, 0.0), ()),
(vec3(0.0, 1.0, 0.0), ()),
(vec3(0.0, 0.0, 1.0), ()),
(pt3(0.0, 0.0, 0.0), ()),
(pt3(1.0, 0.0, 0.0), ()),
(pt3(0.0, 1.0, 0.0), ()),
(pt3(0.0, 0.0, 1.0), ()),
]);
let b = b.with_vertex_normals();

Expand Down
25 changes: 5 additions & 20 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,10 @@ pub mod util;

/// Prelude module exporting many frequently used items.
pub mod prelude {
#[cfg(feature = "fp")]
pub use crate::math::mat::{rotate_x, rotate_y, rotate_z};
pub use crate::math::{
angle::{degs, rads, turns, Angle},
color::{hsl, hsla, rgb, rgba, Color3, Color3f, Color4, Color4f},
mat::{
perspective, scale, translate, viewport, Mat3x3, Mat4x4, Matrix,
},
rand::Distrib,
space::{Affine, Linear},
vary::{lerp, Vary},
vec::{splat, vec2, vec3, Vec2, Vec2i, Vec2u, Vec3, Vec3i, Vector},
};

pub use crate::geom::{vertex, Mesh, Normal2, Normal3, Tri, Vertex};

pub use crate::render::{raster::Frag, shader::Shader};

pub use crate::util::buf::{
AsMutSlice2, AsSlice2, Buf2, MutSlice2, Slice2,
pub use crate::{
geom::{vertex, Mesh, Normal2, Normal3, Tri, Vertex, Vertex2, Vertex3},
math::*,
render::{raster::Frag, shader::Shader, *},
util::buf::{AsMutSlice2, AsSlice2, Buf2, MutSlice2, Slice2},
};
}
86 changes: 79 additions & 7 deletions core/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,93 @@
//! to matching vectors. Angles are strongly typed as well, to allow working
//! with different angular units without confusion.

pub use angle::{degs, polar, rads, spherical, turns, Angle};
pub use approx::ApproxEq;
pub use mat::{Mat3x3, Mat4x4, Matrix};
pub use space::{Affine, Linear};
pub use vary::{lerp, Vary};
pub use vec::{vec2, vec3};
pub use vec::{Vec2, Vec2i, Vec3, Vec3i, Vector};
#[cfg(feature = "fp")]
pub use {
angle::{acos, asin, atan2},
mat::{orient_y, orient_z, rotate_x, rotate_y, rotate_z},
};
pub use {
angle::{
degs, polar, rads, spherical, turns, Angle, PolarVec, SphericalVec,
},
approx::ApproxEq,
color::{rgb, rgba, Color, Color3, Color3f, Color4, Color4f},
mat::{
orthographic, perspective, scale, translate, viewport, Mat3x3, Mat4x4,
Matrix,
},
point::{pt2, pt3, Point, Point2, Point2u, Point3},
space::{Affine, Linear},
spline::{smootherstep, smoothstep, BezierSpline, CubicBezier},
vary::Vary,
vec::{splat, vec2, vec3, Vec2, Vec2i, Vec2u, Vec3, Vec3i, Vector},
};

pub mod angle;
pub mod approx;
pub mod color;
pub mod float;
pub mod mat;
pub mod point;
pub mod rand;
pub mod space;
pub mod spline;
pub mod vary;
pub mod vec;

/// Trait for linear interpolation between two values.
pub trait Lerp {
fn lerp(&self, other: &Self, t: f32) -> Self;
}

impl<T> Lerp for T
where
T: Affine<Diff: Linear<Scalar = f32>>,
{
/// Linearly interpolates between `self` and `other`.
///
/// if `t` = 0, returns `self`; if `t` = 1, returns `other`.
/// For 0 < `t` < 1, returns the affine combination
/// ```text
/// self * (1 - t) + other * t
/// ```
/// or rearranged:
/// ```text
/// self + t * (other - self)
/// ```
///
/// This method does not panic if `t < 0.0` or `t > 1.0`, or if `t`
/// is a `NaN`, but the return value in those cases is unspecified.
/// Individual implementations may offer stronger guarantees.
///
/// # Examples
/// ```
/// use retrofire_core::math::*;
///
/// assert_eq!(2.0.lerp(&5.0, 0.0), 2.0);
/// assert_eq!(2.0.lerp(&5.0, 0.25), 2.75);
/// assert_eq!(2.0.lerp(&5.0, 0.75), 4.25);
/// assert_eq!(2.0.lerp(&5.0, 1.0), 5.0);
///
/// let v0: Vec2 = vec2(-2.0, 1.0);
/// let v1 = vec2(3.0, -1.0);
/// assert_eq!(v0.lerp(&v1, 0.8), vec2(2.0, -0.6));
///
/// let p0: Point2 = pt2(-10.0, 5.0);
/// let p1 = pt2(-5.0, 0.0);
/// assert_eq!(p0.lerp(&p1, 0.4),pt2(-8.0, 3.0));
/// ```
fn lerp(&self, other: &Self, t: f32) -> Self {
self.add(&other.sub(self).mul(t))
}
}

impl Lerp for () {
fn lerp(&self, _: &Self, _: f32) {}
}

impl<U: Lerp, V: Lerp> Lerp for (U, V) {
fn lerp(&self, (u, v): &Self, t: f32) -> Self {
(self.0.lerp(&u, t), self.1.lerp(&v, t))
}
}
Loading
Loading