Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 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
54af9e8
Add X, Y, Z constants for basis vectors
jdahlstrom Dec 27, 2024
fb56691
Add a few tests
jdahlstrom Dec 26, 2024
e4ab41a
Add transform to rotate about an arbitrary axis
jdahlstrom Dec 27, 2024
7330a61
Improve doc comments, tidy up tests a bit
jdahlstrom Dec 27, 2024
eb7476e
Improve camera typing and comments to clarify transforms
jdahlstrom Dec 27, 2024
aa35eec
Add scale3() and translate3() convenience functions
jdahlstrom Dec 27, 2024
ca812d2
Parameterize to_cart() and from_basis() by basis
jdahlstrom Dec 27, 2024
91bac87
Add mat! macro for a nice way to write matrices
jdahlstrom Dec 27, 2024
414b8d1
Add orbiting camera mode
jdahlstrom Jul 23, 2024
50fd6e9
Rename cam::Mode to Transform which is more descriptive
jdahlstrom Dec 29, 2024
fcd43bb
Update, improve doc comments
jdahlstrom Jan 5, 2025
8dbf3ec
Add basis type parameter to Spherical
jdahlstrom Jan 5, 2025
a2286cf
Add Parametric trait
jdahlstrom Dec 22, 2024
4cefb9d
Allow Diff::Scalar to differ from Point's scalar in Affine impl
jdahlstrom Dec 25, 2024
dd44cec
Change From<Range> for Rect to take points rather than vectors
jdahlstrom Dec 25, 2024
1edffbf
Add texture atlas type
jdahlstrom May 14, 2024
71e3514
Remove obsolete feature gates
jdahlstrom Jan 12, 2025
3e76b4c
Add bitmap font assets
jdahlstrom Jun 19, 2024
9de7ec3
Add Text type for rendering text made of character sprites
jdahlstrom Jul 5, 2024
8a9635f
Add text demo
jdahlstrom May 14, 2024
5d94d13
Add tests for Point, improve doc comment
jdahlstrom Jan 12, 2025
498dabe
Improve doc comments a bit
jdahlstrom Jan 12, 2025
c860b2c
Add missing IndexMut impl for Point
jdahlstrom Jan 12, 2025
d9fb850
Add support for non-triangle primitives, line rendering
jdahlstrom Dec 16, 2024
78da0cf
Solve Shader vs Shader naming issue
jdahlstrom Dec 29, 2024
10e41e6
Make Camera::render generic over primitive type
jdahlstrom Jan 14, 2025
aee3ab8
Move to_screen() to prim
jdahlstrom Jan 14, 2025
f7befe9
Add Polyline type, a chain of line segments
jdahlstrom Jan 11, 2025
bd2c322
Impl Lerp for Vertex
jdahlstrom Jan 11, 2025
b9ddb3a
Adjust epsilon in assert
jdahlstrom Jan 11, 2025
58c2f9c
Fix long-time off-by-one bug in vary_to
jdahlstrom Jan 11, 2025
40bdf02
Put lathe solids behind feature gate
jdahlstrom Jan 11, 2025
f998f3b
Change Lathe to take any Parametric
jdahlstrom Jan 14, 2025
218ff5a
Optimize Lathe a bit
jdahlstrom Jan 11, 2025
59ab95b
Test Lathe solids vertex and face counts
jdahlstrom Jan 11, 2025
fbe98c6
Make Cube its own type
jdahlstrom Jan 11, 2025
99a323a
Rewrite Lathe caps code a bit
jdahlstrom Jan 12, 2025
9b07e86
Add doc comment, test for `from_rays`
jdahlstrom Jan 9, 2025
47afc94
WIP frames iterator
jdahlstrom Jan 10, 2025
65a82d6
Add merge method to Mesh
jdahlstrom Jan 18, 2025
5e15cd0
Add constructor method to Box
jdahlstrom Jan 18, 2025
3acc2d4
Fixup frames iterator
jdahlstrom Jan 22, 2025
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*'
Binary file added assets/font_16x24.pbm
Binary file not shown.
Binary file added assets/font_6x10.pbm
Binary file not shown.
Binary file added assets/font_6x8.pbm
Binary file not shown.
Binary file added assets/font_8x10.pbm
Binary file not shown.
Binary file added assets/font_8x12.pbm
Binary file not shown.
163 changes: 161 additions & 2 deletions core/src/geom.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! Basic geometric primitives.

use crate::math::vec::{Vec2, Vec3};
use alloc::vec::Vec;

use crate::math::{
Affine, Lerp, Linear, Parametric, Point2, Point3, Vec2, Vec3,
};
use crate::render::Model;

pub use mesh::Mesh;

Expand All @@ -13,6 +18,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 @@ -23,11 +34,159 @@ pub struct Tri<V>(pub [V; 3]);
#[repr(transparent)]
pub struct Plane<V>(pub(crate) V);

/// A surface normal.
/// A ray, or a half line, composed of an initial point and a direction vector.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Ray<T: Affine>(pub T, pub T::Diff);

/// A curve composed of a chain of line segments.
///
/// The polyline is represented as a list of points, or vertices, with each
/// pair of consecutive vertices sharing an edge.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Polyline<T>(pub Vec<T>);

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Edge<T>(pub T, pub T);

/// A surface normal in 3D.
// TODO Use distinct type rather than alias
pub type Normal3 = Vec3;
/// A surface normal in 2D.
pub type Normal2 = Vec2;

pub const fn vertex<P, A>(pos: P, attrib: A) -> Vertex<P, A> {
Vertex { pos, attrib }
}

impl<T> Polyline<T> {
pub fn new(verts: impl IntoIterator<Item = T>) -> Self {
Self(verts.into_iter().collect())
}

/// Returns an iterator over the line segments of `self`.
///
/// # Example
/// ```
/// use retrofire_core::{geom::{Polyline, Edge}, math::{pt2, Point2}};
///
/// let pl = Polyline::<Point2>(
/// vec![pt2(0.0, 0.0), pt2(1.0, 1.0), pt2(2.0, 1.0)]);
/// let mut edges = pl.edges();
///
/// assert_eq!(edges.next(), Some(Edge(pl.0[0], pl.0[1])));
/// assert_eq!(edges.next(), Some(Edge(pl.0[1], pl.0[2])));
/// assert_eq!(edges.next(), None);
/// ```
pub fn edges(&self) -> impl Iterator<Item = Edge<T>> + '_
where
T: Clone,
{
self.0
.windows(2)
.map(|e| Edge(e[0].clone(), e[1].clone()))
}
}

impl<T> Parametric<T> for Ray<T>
where
T: Affine<Diff: Linear<Scalar = f32>>,
{
fn eval(&self, t: f32) -> T {
self.0.add(&self.1.mul(t))
}
}

impl<T: Lerp + Clone> Parametric<T> for Polyline<T> {
/// Returns the point on `self` at `t`.
///
/// If the number of vertices in `self` is `n`, the vertex at index
/// `k` < `n` corresponds to `t` = `k` / (`n` - 1). Intermediate values
/// of `t` are linearly interpolated between the two closest vertices.
/// Values `t` < 0 and `t` > 1 are clamped to 0 and 1 respectively.
///
/// # Panics
/// If `self` has no vertices.
///
/// # Examples
/// ```
/// use retrofire_core::{
/// geom::{Polyline, Edge},
/// math::{pt2, Point2, Parametric}
/// };
///
/// let pl = Polyline::<Point2>(
/// vec![pt2(0.0, 0.0), pt2(1.0, 2.0), pt2(2.0, 1.0)]);
///
/// assert_eq!(pl.eval(0.0), pl.0[0]);
/// assert_eq!(pl.eval(0.5), pl.0[1]);
/// assert_eq!(pl.eval(1.0), pl.0[2]);
///
/// // Values not corresponding to a vertex are interpolated:
/// assert_eq!(pl.eval(0.25), pt2(0.5, 1.0));
/// assert_eq!(pl.eval(0.75), pt2(1.5, 1.5));
///
/// // Values of t outside 0.0..=1.0 are clamped:
/// assert_eq!(pl.eval(-1.23), pl.eval(0.0));
/// assert_eq!(pl.eval(7.68), pl.eval(1.0));
/// ```
fn eval(&self, t: f32) -> T {
assert!(self.0.len() > 0, "cannot eval an empty polyline");

let max = self.0.len() as f32 - 1.0;
let i = 0.0.lerp(&max, t.clamp(0.0, 1.0));
let t_rem = i % 1.0;
let i = i as usize;

if i == max as usize {
self.0[i].clone()
} else {
let p0 = &self.0[i];
let p1 = &self.0[i + 1];
p0.lerp(p1, t_rem)
}
}
}

impl<P: Lerp, A: Lerp> Lerp for Vertex<P, A> {
fn lerp(&self, other: &Self, t: f32) -> Self {
vertex(
self.pos.lerp(&other.pos, t),
// TODO Normals shouldn't be lerped
self.attrib.lerp(&other.attrib, t),
)
}
}

#[cfg(test)]
mod tests {
use alloc::vec;

use super::*;
use crate::math::Parametric;

#[test]
fn polyline_eval_f32() {
let pl = Polyline(vec![0.0, 1.0, -0.5]);

assert_eq!(pl.eval(-5.0), 0.0);
assert_eq!(pl.eval(0.00), 0.0);
assert_eq!(pl.eval(0.25), 0.5);
assert_eq!(pl.eval(0.50), 1.0);
assert_eq!(pl.eval(0.75), 0.25);
assert_eq!(pl.eval(1.00), -0.5);
assert_eq!(pl.eval(5.00), -0.5);
}

#[test]
#[should_panic]
fn empty_polyline_eval() {
Polyline::<f32>(vec![]).eval(0.5);
}

#[test]
fn singleton_polyline_eval() {
let pl = Polyline(vec![3.14]);
assert_eq!(pl.eval(0.0), 3.14);
assert_eq!(pl.eval(1.0), 3.14);
}
}
Loading
Loading