Skip to content

Commit

Permalink
Default to f32 instead of f64, removing unnecessary casts
Browse files Browse the repository at this point in the history
  • Loading branch information
patowen committed Apr 14, 2024
1 parent 410372d commit 163aad7
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 74 deletions.
8 changes: 3 additions & 5 deletions client/src/graphics/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,11 +431,9 @@ impl Draw {
}

if let Some(sim) = sim.as_deref() {
for (node, transform) in nearby_nodes(
&sim.graph,
&view,
f64::from(self.cfg.local_simulation.view_distance),
) {
for (node, transform) in
nearby_nodes(&sim.graph, &view, self.cfg.local_simulation.view_distance)
{
for &entity in sim.graph_entities.get(node) {
if sim.local_character == Some(entity) {
// Don't draw ourself
Expand Down
6 changes: 3 additions & 3 deletions client/src/graphics/voxels/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ impl Voxels {
let mut nodes = nearby_nodes(
&sim.graph,
&view,
f64::from(self.config.local_simulation.view_distance),
self.config.local_simulation.view_distance,
);
histogram!("frame.cpu.voxels.graph_traversal").record(graph_traversal_started.elapsed());
// Sort nodes by distance to the view to prioritize loading closer data and improve early Z
Expand All @@ -142,7 +142,7 @@ impl Voxels {
for &(node, ref node_transform) in &nodes {
let node_to_view = local_to_view * node_transform;
let origin = node_to_view * math::origin();
if !frustum_planes.contain(&origin, dodeca::BOUNDING_SPHERE_RADIUS as f32) {
if !frustum_planes.contain(&origin, dodeca::BOUNDING_SPHERE_RADIUS) {
// Don't bother generating or drawing chunks from nodes that are wholly outside the
// frustum.
continue;
Expand Down Expand Up @@ -183,7 +183,7 @@ impl Voxels {
frame.drawn.push(slot);
// Transfer transform
frame.surface.transforms_mut()[slot.0 as usize] =
node_transform * vertex.chunk_to_node().map(|x| x as f32);
node_transform * vertex.chunk_to_node();
}
if let (None, &VoxelData::Dense(ref data)) = (&surface, voxels) {
// Extract a surface so it can be drawn in future frames
Expand Down
124 changes: 89 additions & 35 deletions common/src/dodeca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,32 @@ impl Side {

/// Outward normal vector of this side
#[inline]
pub fn normal(self) -> &'static na::Vector4<f64> {
&SIDE_NORMALS[self as usize]
pub fn normal(self) -> &'static na::Vector4<f32> {
&SIDE_NORMALS_F32[self as usize]
}

/// Outward normal vector of this side
#[inline]
pub fn normal_f64(self) -> &'static na::Vector4<f64> {
&SIDE_NORMALS_F64[self as usize]
}

/// Reflection across this side
#[inline]
pub fn reflection(self) -> &'static na::Matrix4<f32> {
&REFLECTIONS_F32[self as usize]
}

/// Reflection across this side
#[inline]
pub fn reflection(self) -> &'static na::Matrix4<f64> {
&REFLECTIONS[self as usize]
pub fn reflection_f64(self) -> &'static na::Matrix4<f64> {
&REFLECTIONS_F64[self as usize]
}

/// Whether `p` is opposite the dodecahedron across the plane containing `self`
#[inline]
pub fn is_facing<N: na::RealField + Copy>(self, p: &na::Vector4<N>) -> bool {
let r = na::convert::<_, na::RowVector4<N>>(self.reflection().row(3).clone_owned());
let r = na::convert::<_, na::RowVector4<N>>(self.reflection_f64().row(3).clone_owned());
(r * p).x < p.w
}
}
Expand Down Expand Up @@ -138,37 +150,71 @@ impl Vertex {
}

/// Transform from euclidean chunk coordinates to hyperbolic node space
pub fn chunk_to_node(self) -> na::Matrix4<f64> {
pub fn chunk_to_node(self) -> na::Matrix4<f32> {
self.dual_to_node() * na::Matrix4::new_scaling(1.0 / Self::dual_to_chunk_factor())
}

/// Transform from euclidean chunk coordinates to hyperbolic node space
pub fn chunk_to_node_f64(self) -> na::Matrix4<f64> {
self.dual_to_node_f64() * na::Matrix4::new_scaling(1.0 / Self::dual_to_chunk_factor_f64())
}

/// Transform from hyperbolic node space to euclidean chunk coordinates
pub fn node_to_chunk(self) -> na::Matrix4<f64> {
pub fn node_to_chunk(self) -> na::Matrix4<f32> {
na::Matrix4::new_scaling(Self::dual_to_chunk_factor()) * self.node_to_dual()
}

/// Transform from hyperbolic node space to euclidean chunk coordinates
pub fn node_to_chunk_f64(self) -> na::Matrix4<f64> {
na::Matrix4::new_scaling(Self::dual_to_chunk_factor_f64()) * self.node_to_dual_f64()
}

/// Transform from cube-centric coordinates to dodeca-centric coordinates
pub fn dual_to_node(self) -> &'static na::Matrix4<f64> {
&DUAL_TO_NODE[self as usize]
pub fn dual_to_node(self) -> &'static na::Matrix4<f32> {
&DUAL_TO_NODE_F32[self as usize]
}

/// Transform from cube-centric coordinates to dodeca-centric coordinates
pub fn dual_to_node_f64(self) -> &'static na::Matrix4<f64> {
&DUAL_TO_NODE_F64[self as usize]
}

/// Transform from dodeca-centric coordinates to cube-centric coordinates
pub fn node_to_dual(self) -> &'static na::Matrix4<f32> {
&NODE_TO_DUAL_F32[self as usize]
}

/// Transform from dodeca-centric coordinates to cube-centric coordinates
pub fn node_to_dual(self) -> &'static na::Matrix4<f64> {
&NODE_TO_DUAL[self as usize]
pub fn node_to_dual_f64(self) -> &'static na::Matrix4<f64> {
&NODE_TO_DUAL_F64[self as usize]
}

/// Scale factor used in conversion from cube-centric coordinates to euclidean chunk coordinates.
/// Scaling the x, y, and z components of a vector in cube-centric coordinates by this value
/// and dividing them by the w coordinate will yield euclidean chunk coordinates.
pub fn dual_to_chunk_factor() -> f64 {
*DUAL_TO_CHUNK_FACTOR
pub fn dual_to_chunk_factor() -> f32 {
*DUAL_TO_CHUNK_FACTOR_F32
}

/// Scale factor used in conversion from cube-centric coordinates to euclidean chunk coordinates.
/// Scaling the x, y, and z components of a vector in cube-centric coordinates by this value
/// and dividing them by the w coordinate will yield euclidean chunk coordinates.
pub fn dual_to_chunk_factor_f64() -> f64 {
*DUAL_TO_CHUNK_FACTOR_F64
}

/// Scale factor used in conversion from euclidean chunk coordinates to cube-centric coordinates.
/// Scaling the x, y, and z components of a vector in homogeneous euclidean chunk coordinates by this value
/// and lorentz-normalizing the result will yield cube-centric coordinates.
pub fn chunk_to_dual_factor() -> f64 {
*CHUNK_TO_DUAL_FACTOR
pub fn chunk_to_dual_factor() -> f32 {
*CHUNK_TO_DUAL_FACTOR_F32
}

/// Scale factor used in conversion from euclidean chunk coordinates to cube-centric coordinates.
/// Scaling the x, y, and z components of a vector in homogeneous euclidean chunk coordinates by this value
/// and lorentz-normalizing the result will yield cube-centric coordinates.
pub fn chunk_to_dual_factor_f64() -> f64 {
*CHUNK_TO_DUAL_FACTOR_F64
}

/// Convenience method for `self.chunk_to_node().determinant() < 0`.
Expand All @@ -179,15 +225,16 @@ impl Vertex {

pub const VERTEX_COUNT: usize = 20;
pub const SIDE_COUNT: usize = 12;
pub const BOUNDING_SPHERE_RADIUS: f64 = 1.2264568712514068;
pub const BOUNDING_SPHERE_RADIUS_F64: f64 = 1.2264568712514068;
pub const BOUNDING_SPHERE_RADIUS: f32 = BOUNDING_SPHERE_RADIUS_F64 as f32;

lazy_static! {
/// Whether two sides share an edge
static ref ADJACENT: [[bool; SIDE_COUNT]; SIDE_COUNT] = {
let mut result = [[false; SIDE_COUNT]; SIDE_COUNT];
for i in 0..SIDE_COUNT {
for j in 0..SIDE_COUNT {
let cosh_distance = (REFLECTIONS[i] * REFLECTIONS[j])[(3, 3)];
let cosh_distance = (REFLECTIONS_F64[i] * REFLECTIONS_F64[j])[(3, 3)];
// Possile cosh_distances: 1, 4.23606 = 2+sqrt(5), 9.47213 = 5+2*sqrt(5), 12.70820 = 6+3*sqrt(5);
// < 2.0 indicates identical faces; < 5.0 indicates adjacent faces; > 5.0 indicates non-adjacent faces
result[i][j] = (2.0..5.0).contains(&cosh_distance);
Expand All @@ -197,7 +244,7 @@ lazy_static! {
};

/// Vector corresponding to the outer normal of each side
static ref SIDE_NORMALS: [na::Vector4<f64>; SIDE_COUNT] = {
static ref SIDE_NORMALS_F64: [na::Vector4<f64>; SIDE_COUNT] = {
let phi = libm::sqrt(1.25) + 0.5; // golden ratio
let f = math::lorentz_normalize(&na::Vector4::new(1.0, phi, 0.0, libm::sqrt(phi)));

Expand All @@ -219,8 +266,8 @@ lazy_static! {
};

/// Transform that moves from a neighbor to a reference node, for each side
static ref REFLECTIONS: [na::Matrix4<f64>; SIDE_COUNT] = {
SIDE_NORMALS.map(|r| math::reflect(&r))
static ref REFLECTIONS_F64: [na::Matrix4<f64>; SIDE_COUNT] = {
SIDE_NORMALS_F64.map(|r| math::reflect(&r))
};

/// Sides incident to a vertex, in canonical order
Expand Down Expand Up @@ -267,26 +314,26 @@ lazy_static! {
};

/// Transform that converts from cube-centric coordinates to dodeca-centric coordinates
static ref DUAL_TO_NODE: [na::Matrix4<f64>; VERTEX_COUNT] = {
let mip_origin_normal = math::mip(&math::origin(), &SIDE_NORMALS[0]); // This value is the same for every side
static ref DUAL_TO_NODE_F64: [na::Matrix4<f64>; VERTEX_COUNT] = {
let mip_origin_normal = math::mip(&math::origin(), &SIDE_NORMALS_F64[0]); // This value is the same for every side
let mut result = [na::zero(); VERTEX_COUNT];
for i in 0..VERTEX_COUNT {
let [a, b, c] = VERTEX_SIDES[i];
let vertex_position = math::lorentz_normalize(
&(math::origin() - (a.normal() + b.normal() + c.normal()) * mip_origin_normal),
&(math::origin() - (a.normal_f64() + b.normal_f64() + c.normal_f64()) * mip_origin_normal),
);
result[i] = na::Matrix4::from_columns(&[-a.normal(), -b.normal(), -c.normal(), vertex_position]);
result[i] = na::Matrix4::from_columns(&[-a.normal_f64(), -b.normal_f64(), -c.normal_f64(), vertex_position]);
}
result
};

/// Transform that converts from dodeca-centric coordinates to cube-centric coordinates
static ref NODE_TO_DUAL: [na::Matrix4<f64>; VERTEX_COUNT] = {
DUAL_TO_NODE.map(|m| math::mtranspose(&m))
static ref NODE_TO_DUAL_F64: [na::Matrix4<f64>; VERTEX_COUNT] = {
DUAL_TO_NODE_F64.map(|m| math::mtranspose(&m))
};

static ref DUAL_TO_CHUNK_FACTOR: f64 = (2.0 + 5.0f64.sqrt()).sqrt();
static ref CHUNK_TO_DUAL_FACTOR: f64 = 1.0 / *DUAL_TO_CHUNK_FACTOR;
static ref DUAL_TO_CHUNK_FACTOR_F64: f64 = (2.0 + 5.0f64.sqrt()).sqrt();
static ref CHUNK_TO_DUAL_FACTOR_F64: f64 = 1.0 / *DUAL_TO_CHUNK_FACTOR_F64;

/// Vertex shared by 3 sides
static ref SIDES_TO_VERTEX: [[[Option<Vertex>; SIDE_COUNT]; SIDE_COUNT]; SIDE_COUNT] = {
Expand Down Expand Up @@ -321,11 +368,18 @@ lazy_static! {
let mut result = [false; VERTEX_COUNT];

for v in Vertex::iter() {
result[v as usize] = math::parity(&v.chunk_to_node());
result[v as usize] = math::parity(&v.chunk_to_node_f64());
}

result
};

static ref SIDE_NORMALS_F32: [na::Vector4<f32>; SIDE_COUNT] = SIDE_NORMALS_F64.map(|n| n.cast());
static ref REFLECTIONS_F32: [na::Matrix4<f32>; SIDE_COUNT] = REFLECTIONS_F64.map(|n| n.cast());
static ref DUAL_TO_NODE_F32: [na::Matrix4<f32>; VERTEX_COUNT] = DUAL_TO_NODE_F64.map(|n| n.cast());
static ref NODE_TO_DUAL_F32: [na::Matrix4<f32>; VERTEX_COUNT] = NODE_TO_DUAL_F64.map(|n| n.cast());
static ref DUAL_TO_CHUNK_FACTOR_F32: f32 = *DUAL_TO_CHUNK_FACTOR_F64 as f32;
static ref CHUNK_TO_DUAL_FACTOR_F32: f32 = *CHUNK_TO_DUAL_FACTOR_F64 as f32;
}

#[cfg(test)]
Expand Down Expand Up @@ -371,15 +425,15 @@ mod tests {

#[test]
fn radius() {
let corner = Vertex::A.chunk_to_node() * math::origin();
let corner = Vertex::A.chunk_to_node_f64() * math::origin();
assert_abs_diff_eq!(
BOUNDING_SPHERE_RADIUS,
BOUNDING_SPHERE_RADIUS_F64,
math::distance(&corner, &math::origin()),
epsilon = 1e-10
);
let phi = (1.0 + 5.0f64.sqrt()) / 2.0; // Golden ratio
assert_abs_diff_eq!(
BOUNDING_SPHERE_RADIUS,
BOUNDING_SPHERE_RADIUS_F64,
(1.5 * phi).sqrt().asinh(),
epsilon = 1e-10
);
Expand All @@ -389,7 +443,7 @@ mod tests {
fn chunk_to_node() {
// Chunk coordinates of (1, 1, 1) should be at the center of a dodecahedron.
let mut chunk_corner_in_node_coordinates =
Vertex::A.chunk_to_node() * na::Vector4::new(1.0, 1.0, 1.0, 1.0);
Vertex::A.chunk_to_node_f64() * na::Vector4::new(1.0, 1.0, 1.0, 1.0);
chunk_corner_in_node_coordinates /= chunk_corner_in_node_coordinates.w;
assert_abs_diff_eq!(
chunk_corner_in_node_coordinates,
Expand All @@ -401,8 +455,8 @@ mod tests {
#[test]
fn node_to_chunk() {
assert_abs_diff_eq!(
Vertex::A.chunk_to_node().try_inverse().unwrap(),
Vertex::A.node_to_chunk(),
Vertex::A.chunk_to_node_f64().try_inverse().unwrap(),
Vertex::A.node_to_chunk_f64(),
epsilon = 1e-10
);
}
Expand Down
2 changes: 1 addition & 1 deletion common/src/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ impl Graph {
None => continue,
Some(x) => x,
};
let mat = na::convert::<_, na::Matrix4<T>>(*side.reflection());
let mat = na::convert::<_, na::Matrix4<T>>(*side.reflection_f64());
location = mat * location;
transform = mat * transform;
continue 'outer;
Expand Down
8 changes: 4 additions & 4 deletions common/src/graph_collision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ mod tests {
let chosen_chunk_transform: na::Matrix4<f32> =
self.chosen_voxel.node_path.iter().fold(
na::Matrix4::identity(),
|transform: na::Matrix4<f32>, side| transform * side.reflection().cast::<f32>(),
) * self.chosen_voxel.vertex.dual_to_node().cast();
|transform: na::Matrix4<f32>, side| transform * side.reflection(),
) * self.chosen_voxel.vertex.dual_to_node();

let dual_to_grid_factor = graph.layout().dual_to_grid_factor();
let ray_target = chosen_chunk_transform
Expand All @@ -184,7 +184,7 @@ mod tests {
1.0,
));

let ray_position = Vertex::A.dual_to_node().cast()
let ray_position = Vertex::A.dual_to_node()
* math::lorentz_normalize(&na::Vector4::new(
self.start_chunk_relative_grid_ray_start[0] / dual_to_grid_factor,
self.start_chunk_relative_grid_ray_start[1] / dual_to_grid_factor,
Expand Down Expand Up @@ -435,7 +435,7 @@ mod tests {
}

// The node coordinates of the corner of the missing node
let vertex_pos = Vertex::A.dual_to_node().cast::<f32>() * math::origin();
let vertex_pos = Vertex::A.dual_to_node() * math::origin();

// Use a ray starting from the origin. The direction vector is vertex_pos with the w coordinate
// set to 0 and normalized
Expand Down
2 changes: 1 addition & 1 deletion common/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ impl ChunkLayout {
pub fn new(dimension: u8) -> Self {
ChunkLayout {
dimension,
dual_to_grid_factor: Vertex::dual_to_chunk_factor() as f32 * dimension as f32,
dual_to_grid_factor: Vertex::dual_to_chunk_factor() * dimension as f32,
}
}

Expand Down
6 changes: 3 additions & 3 deletions common/src/plane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl From<Side> for Plane<f64> {
/// A surface overlapping with a particular dodecahedron side
fn from(side: Side) -> Self {
Self {
normal: *side.normal(),
normal: *side.normal_f64(),
}
}
}
Expand All @@ -42,7 +42,7 @@ impl Mul<Plane<f64>> for Side {
type Output = Plane<f64>;
/// Reflect a plane across the side
fn mul(self, rhs: Plane<f64>) -> Plane<f64> {
self.reflection() * rhs
self.reflection_f64() * rhs
}
}

Expand Down Expand Up @@ -72,7 +72,7 @@ impl<N: na::RealField + Copy> Plane<N> {
impl Plane<f64> {
/// Like `distance_to`, but using chunk coordinates for a chunk in the same node space
pub fn distance_to_chunk(&self, chunk: Vertex, coord: &na::Vector3<f64>) -> f64 {
let pos = lorentz_normalize(&(chunk.chunk_to_node() * coord.push(1.0)));
let pos = lorentz_normalize(&(chunk.chunk_to_node_f64() * coord.push(1.0)));
self.distance_to(&pos)
}
}
Expand Down
4 changes: 2 additions & 2 deletions common/src/sim_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ fn meters_to_absolute(chunk_size: u8, voxel_size: f32) -> f32 {
let a = dodeca::Vertex::A.chunk_to_node() * na::Vector4::new(1.0, 0.5, 0.5, 1.0);
let b = dodeca::Vertex::A.chunk_to_node() * na::Vector4::new(0.0, 0.5, 0.5, 1.0);
let minimum_chunk_face_separation = math::distance(&a, &b);
let absolute_voxel_size = minimum_chunk_face_separation / f64::from(chunk_size);
absolute_voxel_size as f32 / voxel_size
let absolute_voxel_size = minimum_chunk_face_separation / f32::from(chunk_size);
absolute_voxel_size / voxel_size
}

/// Static configuration information relevant to character physics as provided in configuration files
Expand Down
Loading

0 comments on commit 163aad7

Please sign in to comment.