Skip to content

Commit 788ca89

Browse files
authored
QOL Pass & doc improvements (#30)
* feat: improve docs & public api for index buffer stuff this is a breaking change for the public api of IndexBuffer, since it uses generics for the format instead of a runtime enum * feat: vertex buffer accessor api overhaul + docs * feat: more module level one liner docs * feat: add IndexBuffer::into_inner * feat: animation module docs * chore: elide a lifetime * chore: document/cleanup league-primitives * chore: document render/texture top-level modules * fix: remove unused types * feat: move tex surface stuff to `tex::surface` * feat: document render module * fix: broken doc links
1 parent 00c0f8a commit 788ca89

File tree

28 files changed

+353
-253
lines changed

28 files changed

+353
-253
lines changed

crates/league-primitives/src/aabb.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
use super::Sphere;
22
use glam::{vec3, Vec3};
33

4+
/// Axis-aligned bounding box
45
#[derive(Default, Debug, Clone, Copy, PartialEq)]
56
pub struct AABB {
67
pub min: Vec3,
78
pub max: Vec3,
89
}
910

1011
impl AABB {
11-
pub fn new(min: Vec3, max: Vec3) -> Self {
12+
/// Creates a new axis-aligned bounding box from min and max corner points
13+
pub fn from_corners(min: Vec3, max: Vec3) -> Self {
1214
Self { min, max }
1315
}
1416
}
@@ -18,19 +20,28 @@ fn dist(a: &Vec3, b: &Vec3) -> f32 {
1820
}
1921

2022
impl AABB {
23+
/// Compute the center point of the axis-aligned bounding box
24+
#[inline]
25+
#[must_use]
2126
pub fn center(&self) -> Vec3 {
2227
Vec3::new(
2328
0.5 * (self.min[0] + self.max[0]),
2429
0.5 * (self.min[1] + self.max[1]),
2530
0.5 * (self.min[2] + self.max[2]),
2631
)
2732
}
33+
34+
/// Compute the smallest sphere that contains this AABB
35+
#[inline]
36+
#[must_use]
2837
pub fn bounding_sphere(&self) -> Sphere {
2938
let center = self.center();
3039
Sphere::new(center, dist(&center, &self.max))
3140
}
3241

33-
pub fn from_vertex_iter(verts: impl IntoIterator<Item = Vec3>) -> Self {
42+
/// Calculate the AABB of a set of points
43+
#[must_use]
44+
pub fn of_points(verts: impl IntoIterator<Item = Vec3>) -> Self {
3445
let mut min = vec3(f32::INFINITY, f32::INFINITY, f32::INFINITY);
3546
let mut max = vec3(f32::NEG_INFINITY, f32::NEG_INFINITY, f32::NEG_INFINITY);
3647
for v in verts {

crates/league-primitives/src/color.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use byteorder::{ByteOrder, ReadBytesExt, WriteBytesExt};
22
use std::io::{self, Write};
33

4+
/// Generic RGBA Color struct
45
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
56
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
67
pub struct Color<T = f32> {
@@ -12,7 +13,7 @@ pub struct Color<T = f32> {
1213

1314
impl<T> AsRef<Color<T>> for Color<T> {
1415
fn as_ref(&self) -> &Color<T> {
15-
&self
16+
self
1617
}
1718
}
1819

@@ -32,6 +33,7 @@ impl Color<u8> {
3233
Ok(())
3334
}
3435

36+
#[inline]
3537
pub fn from_reader<R: io::Read + ?Sized>(reader: &mut R) -> io::Result<Self> {
3638
Ok(Self {
3739
r: reader.read_u8()?,
@@ -55,6 +57,7 @@ impl Color<f32> {
5557
Ok(())
5658
}
5759

60+
#[inline]
5861
pub fn from_reader<E: ByteOrder, R: io::Read + ?Sized>(reader: &mut R) -> io::Result<Self> {
5962
Ok(Self {
6063
r: reader.read_f32::<E>()?,
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
pub mod color;
1+
mod color;
22
pub use color::*;
33

4-
pub mod sphere;
4+
mod sphere;
55
pub use sphere::*;
66

7-
pub mod aabb;
7+
mod aabb;
88
pub use aabb::*;

crates/league-primitives/src/sphere.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use glam::Vec3;
22

3+
/// A sphere. Origin and radius.
34
#[derive(Debug, Clone, Copy, PartialEq)]
45
pub struct Sphere {
56
pub origin: Vec3,
@@ -9,6 +10,8 @@ pub struct Sphere {
910
impl Sphere {
1011
pub const INFINITE: Sphere = Self::new(Vec3::ZERO, f32::INFINITY);
1112

13+
#[inline]
14+
#[must_use]
1215
pub const fn new(origin: Vec3, radius: f32) -> Self {
1316
Self { origin, radius }
1417
}

crates/league-toolkit/src/core/animation/asset/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//! Animation assets
12
mod compressed;
23

34
pub use compressed::*;
@@ -15,12 +16,15 @@ use error::AssetParseError::UnknownAssetType;
1516
use std::io;
1617
use std::io::{Read, Seek, SeekFrom};
1718

19+
/// Encapsulates a .anm file
1820
#[derive(Clone, Debug)]
1921
pub enum AnimationAsset {
2022
Uncompressed(Uncompressed),
2123
Compressed(Compressed),
2224
}
2325

26+
/// The type of animation asset
27+
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
2428
pub enum AnimationAssetType {
2529
Uncompressed,
2630
Compressed,
@@ -40,6 +44,7 @@ impl AnimationAsset {
4044
}
4145
}
4246

47+
/// Reads the animation magic (8 bytes), and identifies the animation asset type
4348
pub fn identify_from_reader<R: Read + ?Sized>(
4449
reader: &mut R,
4550
) -> io::Result<AnimationAssetType> {

crates/league-toolkit/src/core/animation/rig/builder.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::core::animation::{joint, Joint, RigResource};
22
use std::collections::VecDeque;
33

4+
/// Builder for [`RigResource`]
45
pub struct Builder {
56
name: String,
67
asset_name: String,
@@ -15,11 +16,13 @@ impl Builder {
1516
root_joints: vec![],
1617
}
1718
}
19+
1820
pub fn with_root_joint(mut self, child: joint::Builder) -> Self {
1921
self.add_root_joint(child);
2022
self
2123
}
2224

25+
/// Mutably add a root joint
2326
pub fn add_root_joint(&mut self, child: joint::Builder) {
2427
self.root_joints.push(child);
2528
}

crates/league-toolkit/src/core/animation/rig/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
//! Read/write .skl
12
mod builder;
23
mod read;
34
mod write;
45
pub use builder::Builder;
56

67
use super::Joint;
78

9+
/// Encapsulates a .skl file
810
#[derive(Debug, Clone, PartialEq)]
911
pub struct RigResource {
1012
flags: u16,
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//! Index buffer types
2+
use std::{fmt::Debug, io, marker::PhantomData, mem::size_of};
3+
4+
/// Trait to read from an index buffer, in a given format. (u16, u32)
5+
pub trait Format {
6+
type Item;
7+
#[must_use]
8+
fn get(buf: &[u8], index: usize) -> Self::Item;
9+
}
10+
11+
/// Wrapper around a raw buffer of indices, supporting either u16 or u32 indices.
12+
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
13+
pub struct IndexBuffer<F: Format> {
14+
count: usize,
15+
16+
buffer: Vec<u8>,
17+
18+
_format: PhantomData<F>,
19+
}
20+
21+
impl<F: Format> Debug for IndexBuffer<F> {
22+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23+
f.debug_struct("IndexBuffer")
24+
.field("count", &self.count)
25+
.field("stride", &self.stride())
26+
.field("buffer (size)", &self.buffer.len())
27+
.finish()
28+
}
29+
}
30+
31+
impl Format for u32 {
32+
type Item = u32;
33+
fn get(buf: &[u8], index: usize) -> u32 {
34+
let off = index * size_of::<u32>();
35+
u32::from_le_bytes(buf[off..off + 4].try_into().unwrap())
36+
}
37+
}
38+
impl Format for u16 {
39+
type Item = u16;
40+
fn get(buf: &[u8], index: usize) -> u16 {
41+
let off = index * size_of::<u16>();
42+
u16::from_le_bytes(buf[off..off + 2].try_into().unwrap())
43+
}
44+
}
45+
impl<F: Format> IndexBuffer<F> {
46+
#[must_use]
47+
/// Creates a new index buffer from a buffer
48+
pub fn new(buffer: Vec<u8>) -> Self {
49+
let stride = size_of::<F>();
50+
if buffer.len() % stride != 0 {
51+
panic!("Index buffer size must be a multiple of index size!");
52+
}
53+
Self {
54+
count: buffer.len() / stride,
55+
buffer,
56+
_format: PhantomData,
57+
}
58+
}
59+
60+
/// Reads an index buffer from a reader.
61+
///
62+
/// # Arguments
63+
/// * `reader` - The reader to read from.
64+
/// * `count` - The number of indices to read.
65+
pub fn read<R: io::Read>(reader: &mut R, count: usize) -> Result<Self, io::Error> {
66+
let mut buffer = vec![0u8; size_of::<F>() * count];
67+
reader.read_exact(&mut buffer)?;
68+
Ok(Self::new(buffer))
69+
}
70+
71+
#[inline(always)]
72+
#[must_use]
73+
/// The size in bytes of a single index.
74+
pub fn stride(&self) -> usize {
75+
size_of::<F>()
76+
}
77+
78+
#[inline(always)]
79+
#[must_use]
80+
/// An iterator over the indices in the buffer.
81+
pub fn iter(&self) -> IndexBufferIter<F> {
82+
IndexBufferIter {
83+
buffer: self,
84+
counter: 0,
85+
}
86+
}
87+
88+
#[inline]
89+
#[must_use]
90+
/// Get an item from the buffer, at a given index.
91+
pub fn get(&self, index: usize) -> F::Item {
92+
F::get(&self.buffer, index)
93+
}
94+
95+
#[inline(always)]
96+
#[must_use]
97+
/// The number of indices in the buffer.
98+
pub fn count(&self) -> usize {
99+
self.count
100+
}
101+
102+
#[inline(always)]
103+
#[must_use]
104+
/// The raw underlying bytes.
105+
pub fn as_bytes(&self) -> &[u8] {
106+
&self.buffer
107+
}
108+
#[inline(always)]
109+
#[must_use]
110+
/// Take ownership of the underlying bytes.
111+
pub fn into_inner(self) -> Vec<u8> {
112+
self.buffer
113+
}
114+
}
115+
116+
pub struct IndexBufferIter<'a, F: Format> {
117+
buffer: &'a IndexBuffer<F>,
118+
counter: usize,
119+
}
120+
121+
impl<'a, F: Format> Iterator for IndexBufferIter<'a, F> {
122+
type Item = F::Item;
123+
124+
fn next(&mut self) -> Option<Self::Item> {
125+
if self.counter >= self.buffer.count {
126+
return None;
127+
}
128+
let item = F::get(self.buffer.as_bytes(), self.counter);
129+
self.counter += 1;
130+
Some(item)
131+
}
132+
}

0 commit comments

Comments
 (0)