Skip to content

Commit 2e9e6a8

Browse files
everything but the kitchen sink
1 parent 045569e commit 2e9e6a8

18 files changed

Lines changed: 628 additions & 1128 deletions

common/src/main/rust/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/src/main/rust/marten/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ log.workspace = true
99
fern.workspace = true
1010
humantime.workspace = true
1111
colored.workspace = true
12+
glamx = { version = "0.1" }
1213

1314
#rapier3d = { git = "https://github.com/ryanhcode/rapier", rev = "a728067629d4f85cef99f388e12c9b0ee8cd1164", features = ["simd-nightly", "parallel"] }
1415
#parry3d = { version = "0.26.0", features = ["simd-nightly"] }

common/src/main/rust/marten/src/level.rs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
//! A sparse voxel world.
22
33
use crate::octree::SubLevelOctree;
4+
use glamx::{IVec3, Vec3};
45
use jni::JNIEnv;
56
use jni::descriptors::Desc;
67
use jni::objects::{GlobalRef, JMethodID};
8+
use jni::sys::jdouble;
79

810
/// log_2 of the size of a chunk
911
pub const CHUNK_SHIFT: u8 = 4;
@@ -40,7 +42,7 @@ impl ChunkSection {
4042
/// # Safety
4143
/// This method assumes that the coordinate is > than 0 and < than `CHUNK_SIZE` on all axes.
4244
#[inline(always)]
43-
fn get_index(&self, x: i32, y: i32, z: i32) -> usize {
45+
fn get_index(&self, IVec3 { x, y, z }: IVec3) -> usize {
4446
(x + (z << 4) + (y << 8)) as usize
4547
}
4648

@@ -49,8 +51,8 @@ impl ChunkSection {
4951
/// # Safety
5052
/// This method assumes that the coordinate is > than 0 and < than `CHUNK_SIZE` on all axes.
5153
/// If the coordinate is out of bounds, behavior is undefined.
52-
pub fn set_block(&mut self, x: i32, y: i32, z: i32, state: BlockState) {
53-
let index = self.get_index(x, y, z);
54+
pub fn set_block(&mut self, pos: IVec3, state: BlockState) {
55+
let index = self.get_index(pos);
5456
self.blocks[index] = state;
5557
}
5658

@@ -59,8 +61,8 @@ impl ChunkSection {
5961
/// # Safety
6062
/// This method assumes that the coordinate is >= than 0 and < than `CHUNK_SIZE` on all axes.
6163
/// If the coordinate is out of bounds, behavior is undefined.
62-
pub fn get_block(&self, x: i32, y: i32, z: i32) -> BlockState {
63-
let index = self.get_index(x, y, z);
64+
pub fn get_block(&self, pos: IVec3) -> BlockState {
65+
let index = self.get_index(pos);
6466
unsafe { *self.blocks.get_unchecked(index) }
6567
}
6668
}
@@ -76,12 +78,26 @@ unsafe impl<'local> Desc<'local, JMethodID> for &SableMethodID {
7678
}
7779
}
7880

81+
#[derive(Debug, Clone, Copy)]
82+
pub struct CollisionBox {
83+
pub min: Vec3,
84+
pub max: Vec3,
85+
}
86+
impl From<[jdouble; 6]> for CollisionBox {
87+
fn from(value: [jdouble; 6]) -> Self {
88+
let [min_x, min_y, min_z, max_x, max_y, max_z] = value.map(|v| v as f32);
89+
Self {
90+
min: Vec3::new(min_x, min_y, min_z),
91+
max: Vec3::new(max_x, max_y, max_z),
92+
}
93+
}
94+
}
95+
7996
/// The physics data of a blockstate
8097
#[derive(Debug)]
8198
pub struct VoxelColliderData {
8299
/// Collision boxes within the 0-1 voxel space.
83-
/// Formatted [min_x, min_y, min_z, max_x, max_y, max_z]
84-
pub collision_boxes: Vec<(f32, f32, f32, f32, f32, f32)>,
100+
pub collision_boxes: Vec<CollisionBox>,
85101

86102
/// If this should be treated as a fluid for buoyancy
87103
pub is_fluid: bool,
@@ -133,6 +149,12 @@ impl OctreeChunkSection {
133149
}
134150
}
135151

152+
impl Default for OctreeChunkSection {
153+
fn default() -> Self {
154+
Self::new()
155+
}
156+
}
157+
136158
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
137159
pub enum VoxelPhysicsState {
138160
Empty,

common/src/main/rust/marten/src/octree.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Flat octree for integer data
22
3+
use glamx::IVec3;
4+
35
/// The max size we allow an octree buffer to occupy
46
const MAX_SIZE: i32 = i32::MAX - 8 * 2;
57

@@ -55,7 +57,7 @@ impl SubLevelOctree {
5557

5658
/// @return a unique 0-7 index from a given x, y, z position in 0-1 ranges
5759
#[inline(always)]
58-
fn get_octant_index(x: i32, y: i32, z: i32) -> i32 {
60+
fn get_octant_index(IVec3 { x, y, z }: IVec3) -> i32 {
5961
(x & 1) | ((y & 1) << 1) | ((z & 1) << 2)
6062
}
6163

@@ -146,15 +148,13 @@ impl SubLevelOctree {
146148
///
147149
/// # Arguments
148150
///
149-
/// * `x` - the x position
150-
/// * `y` - the y position
151-
/// * `z` - the z position
151+
/// * `pos` - the position
152152
/// * `block` - the block ID
153153
///
154154
/// # Returns
155155
///
156156
/// * `bool` - if the insert modified the tree
157-
pub fn insert(&mut self, x: i32, y: i32, z: i32, block: i32) -> bool {
157+
pub fn insert(&mut self, pos: IVec3, block: i32) -> bool {
158158
let mut shift = self.log_size - 1;
159159
let mut index = 0;
160160
let mut node = self.buffer[index as usize];
@@ -167,7 +167,7 @@ impl SubLevelOctree {
167167
return false; // already equivalent
168168
}
169169

170-
let octant_index = Self::get_octant_index(x >> shift, y >> shift, z >> shift);
170+
let octant_index = Self::get_octant_index(pos >> shift);
171171

172172
if node > 0 {
173173
branches_visited[branch_index as usize] = index;
@@ -197,18 +197,17 @@ impl SubLevelOctree {
197197
///
198198
/// # Arguments
199199
///
200-
/// * `x` - the x position
201-
/// * `y` - the y position
202-
/// * `z` - the z position
200+
/// * `pos` - the position
203201
/// * `log_size_of_target` - the log size of the target
204202
///
205203
/// # Returns
206204
///
207205
/// * `i32` - the block ID at the position, or -2 if the position is empty
208-
pub fn query(&self, x: i32, y: i32, z: i32, log_size_of_target: i32) -> i32 {
206+
pub fn query(&self, pos: IVec3, log_size_of_target: i32) -> i32 {
209207
let size = 1 << self.log_size;
208+
210209
// check if out of bounds
211-
if x < 0 || y < 0 || z < 0 || x >= size || y >= size || z >= size {
210+
if pos.cmplt(IVec3::ZERO).any() || pos.cmpge(IVec3::splat(size)).any() {
212211
return -2;
213212
}
214213

@@ -223,7 +222,7 @@ impl SubLevelOctree {
223222
return -2;
224223
}
225224

226-
let octant_index = Self::get_octant_index(x >> shift, y >> shift, z >> shift);
225+
let octant_index = Self::get_octant_index(pos >> shift);
227226

228227
index = node + octant_index;
229228
node = *unsafe { self.buffer.get_unchecked(index as usize) };

common/src/main/rust/rapier/benches/collision_benchmark.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use criterion::{Criterion, criterion_group, criterion_main};
22
use marten::Real;
33
use marten::octree::SubLevelOctree;
4+
use rapier3d::glamx::{DVec3, IVec3};
45
use rapier3d::math::Pose3;
5-
use rapier3d::na::Vector3;
66
use rapier3d::prelude::ColliderHandle;
77
use sable_rapier::ActiveLevelColliderInfo;
88
use sable_rapier::algo::{DEFAULT_COLLISION_PARALLEL_CUTOFF, find_collision_pairs};
@@ -15,9 +15,9 @@ fn setup_dummy_sable_handle_a() -> ActiveLevelColliderInfo {
1515
ActiveLevelColliderInfo {
1616
static_mount: None,
1717
collider: ColliderHandle::default(),
18-
local_bounds_min: Some(Vector3::<i32>::new(0, 0, 0)),
19-
local_bounds_max: Some(Vector3::<i32>::new(128, 128, 128)),
20-
center_of_mass: Some(Vector3::<f64>::new(62.5, 62.5, 62.5)),
18+
local_bounds_min: Some(IVec3::ZERO),
19+
local_bounds_max: Some(IVec3::splat(128)),
20+
center_of_mass: Some(DVec3::splat(62.5)),
2121
octree: Some(octree),
2222
chunk_map: None,
2323
scene_id: 0,
@@ -32,9 +32,9 @@ fn setup_dummy_sable_handle_b() -> ActiveLevelColliderInfo {
3232
ActiveLevelColliderInfo {
3333
static_mount: None,
3434
collider: ColliderHandle::default(),
35-
local_bounds_min: Some(Vector3::<i32>::new(128, 0, 0)),
36-
local_bounds_max: Some(Vector3::<i32>::new(256, 128, 128)),
37-
center_of_mass: Some(Vector3::<f64>::new(128.0 + 64.5, 64.5, 64.5)),
35+
local_bounds_min: Some(IVec3::new(128, 0, 0)),
36+
local_bounds_max: Some(IVec3::new(256, 128, 128)),
37+
center_of_mass: Some(DVec3::new(128.0 + 64.5, 64.5, 64.5)),
3838
octree: Some(octree),
3939
chunk_map: None,
4040
scene_id: 0,
@@ -51,7 +51,7 @@ fn setup_sphere(octree: &mut SubLevelOctree) {
5151
let dy = y as f64 - 64.5;
5252
let dz = z as f64 - 64.5;
5353
if dx * dx + dy * dy + dz * dz <= 63.5 * 63.5 {
54-
octree.insert(x, y, z, 1);
54+
octree.insert(IVec3::new(x, y, z), 1);
5555
}
5656
}
5757
}

0 commit comments

Comments
 (0)