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

Rasmusgo/quadrics gallery #443

Merged
merged 31 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
23f62d7
Add hologram_templates.glb
rasmusgo Jan 13, 2023
882a39c
Use hologram_templates.glb in custom rendering example
rasmusgo Jan 13, 2023
f13141a
Add cone variations
rasmusgo Jan 13, 2023
93561e8
Hardcoded rgb checkers on quadrics
rasmusgo Jan 13, 2023
0b25f68
Preserve relative pose to grabbed object
rasmusgo Jan 14, 2023
a87e4b0
Add grids on quadrics with analytical box filter
rasmusgo Jan 14, 2023
174c94e
Adjust quadrics to have the same radius at the ends
rasmusgo Jan 15, 2023
2403213
Grip closest object instead of first object
rasmusgo Jan 18, 2023
f8f6f8e
Add second entity for the back surface of quadrics
rasmusgo Jan 18, 2023
b2807f7
Only grip when button is just pressed
rasmusgo Jan 18, 2023
f28e9d4
Check if hands are holding anything instead of colliding with anything
rasmusgo Jan 18, 2023
3e16a04
Make stage navigation system work together with grabbing system
rasmusgo Jan 18, 2023
44ed996
Don't use unlit material for hands
rasmusgo Jan 18, 2023
0504abb
Quadric surface solver with control points that can be moved by hand
rasmusgo Jan 19, 2023
2e8b7c9
Tidy up surface_solver.rs
rasmusgo Jan 29, 2023
574592b
Use alternative quadratic formula
rasmusgo Feb 4, 2023
250548e
Use top-down UV-mapping for manipulable quadric
rasmusgo Feb 4, 2023
0e24234
Quadric surfaces with varying number of control points
rasmusgo Feb 5, 2023
942712c
Handle clippy warnings in tests
rasmusgo Jan 15, 2023
78a2329
ci.yaml: Run clippy with --tests
rasmusgo Jan 15, 2023
c37fc8c
Replace gridTextureGradBox with filteredGrid
rasmusgo Feb 6, 2023
d64c758
Reduce flying pixels in quadrics shader and add long description/deri…
rasmusgo Feb 12, 2023
98c3cef
quadrics: Use camera as ray origin to allow for some minor optimizations
rasmusgo Feb 12, 2023
cf17f74
quadrics: Reuse boundsQTimesHitPoint
rasmusgo Feb 12, 2023
7942995
quadrics: Normalize rayDir for computation of hitpoint derivatives
rasmusgo Feb 12, 2023
d4c090a
Simple and effective clamping of hitpoint derivatives
rasmusgo Feb 12, 2023
a333fca
Reorder computations to discard earlier
rasmusgo Feb 13, 2023
ee83884
Add hyperbolic paraboloid (saddle/pringles)
rasmusgo Feb 14, 2023
b7da1de
Comments with names and equations of quadrics
rasmusgo Feb 14, 2023
85509a2
Merge branch 'main' into rasmusgo/quadrics-gallery
rasmusgo Aug 25, 2023
43de0f8
Appease clippy
rasmusgo Aug 25, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: clippy
args: -- -D warnings
args: --tests -- -D warnings
- name: Run cargo clippy (android)
uses: actions-rs/cargo@v1
with:
Expand Down
201 changes: 156 additions & 45 deletions examples/custom-rendering/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod custom_render_context;
mod custom_rendering;
mod hologram;
mod surface_solver;

use custom_render_context::{create_quadrics_pipeline, CustomRenderContext};
use custom_rendering::custom_rendering_system;
Expand All @@ -10,8 +11,8 @@ use hotham::{
components::{
hand::Handedness, physics::SharedShape, Collider, Grabbable, LocalTransform, Mesh,
},
glam::{Mat4, Quat, Vec3},
hecs::World,
glam::{Mat4, Quat},
hecs::{Entity, World},
systems::{
animation_system, debug::debug_system, grabbing_system, hands::add_hand, hands_system,
physics_system, skinning::skinning_system, update_global_transform_system,
Expand All @@ -20,6 +21,7 @@ use hotham::{
xr, Engine, HothamResult, TickData,
};
use hotham_examples::navigation::{navigation_system, State};
use surface_solver::{surface_solver_system, ControlPoints, HologramBackside};

#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
pub fn main() {
Expand Down Expand Up @@ -62,6 +64,7 @@ fn tick(
physics_system(engine);
animation_system(engine);
navigation_system(engine, state);
surface_solver_system(engine);
update_global_transform_system(engine);
skinning_system(engine);
debug_system(engine);
Expand Down Expand Up @@ -123,87 +126,179 @@ fn init(engine: &mut Engine) -> Result<(), hotham::HothamError> {
let vulkan_context = &mut engine.vulkan_context;
let world = &mut engine.world;

let mut glb_buffers: Vec<&[u8]> = vec![
let glb_buffers: Vec<&[u8]> = vec![
include_bytes!("../../../test_assets/left_hand.glb"),
include_bytes!("../../../test_assets/right_hand.glb"),
include_bytes!("../../../test_assets/sphere.glb"),
include_bytes!("../../../test_assets/hologram_templates.glb"),
];

#[cfg(target_os = "android")]
glb_buffers.push(include_bytes!(
"../../../test_assets/damaged_helmet_squished.glb"
));

#[cfg(not(target_os = "android"))]
glb_buffers.push(include_bytes!("../../../test_assets/damaged_helmet.glb"));

let models =
asset_importer::load_models_from_glb(&glb_buffers, vulkan_context, render_context)?;
add_helmet(&models, world, [-1., 1.4, -1.].into());
add_helmet(&models, world, [1., 1.4, -1.].into());
add_hand(&models, Handedness::Left, world);
add_hand(&models, Handedness::Right, world);
let uv1_from_local = Mat4::from_diagonal([1.0, 1.0, 1.0, 0.1].into());
let uv2_from_local = Mat4::from_cols_array(&[
1.0, 0.0, 0.0, 0.0, //
0.0, 0.0, 1.0, 0.0, //
0.0, 1.0, 0.0, 0.0, //
0.0, 0.0, 0.0, 0.1, //
]);
let uv3_from_local = Mat4::from_diagonal([0.0, 1.0, 0.0, 0.1].into());
add_quadric(
&models,
"Sphere",
world,
&LocalTransform {
translation: [1.0, 1.4, -1.5].into(),
rotation: Quat::IDENTITY,
scale: [0.5, 0.5, 0.5].into(),
},
&make_transform(-1.0, 1.4, -1.5, 0.5),
0.5,
HologramData {
// Sphere, x² + y² + z² = 1
surface_q_in_local: Mat4::from_diagonal([1.0, 1.0, 1.0, -1.0].into()),
bounds_q_in_local: Mat4::from_diagonal([0.0, 0.0, 0.0, 0.0].into()),
uv_from_local: Mat4::IDENTITY,
uv_from_local: uv1_from_local,
},
);
add_quadric(
&models,
"Cylinder",
world,
&LocalTransform {
translation: [-1.0, 1.4, -1.5].into(),
rotation: Quat::IDENTITY,
scale: [0.5, 0.5, 0.5].into(),
&make_transform(0.0, 1.4, -1.5, 0.5),
0.5_f32.sqrt(),
HologramData {
// Cylinder, x² + z² = 1
surface_q_in_local: Mat4::from_diagonal([1.0, 0.0, 1.0, -1.0].into()),
bounds_q_in_local: Mat4::from_diagonal([0.0, 1.0, 0.0, -1.0].into()),
uv_from_local: uv1_from_local,
},
0.5,
);
add_quadric(
&models,
"Cylinder",
world,
&make_transform(1.0, 1.4, -1.5, 0.5),
0.5_f32.sqrt(),
HologramData {
// Hyperboloid of one sheet, x² - y² + z² = c
surface_q_in_local: Mat4::from_diagonal([1.0, -1.0 + 0.1, 1.0, -0.1].into()),
bounds_q_in_local: Mat4::from_diagonal([0.0, 1.0, 0.0, -1.0].into()),
uv_from_local: uv2_from_local,
},
);
add_quadric(
&models,
"Cylinder",
world,
&make_transform(2.0, 1.4, -1.5, 0.5),
0.5_f32.sqrt(),
HologramData {
// Double cones, x² - y² + z² = 0
surface_q_in_local: Mat4::from_diagonal([1.0, -1.0, 1.0, 0.0].into()),
bounds_q_in_local: Mat4::from_diagonal([0.0, 1.0, 0.0, -1.0].into()),
uv_from_local: uv2_from_local,
},
);
add_quadric(
&models,
"Cylinder",
world,
&make_transform(3.0, 1.4, -1.5, 0.5),
0.5_f32.sqrt(),
HologramData {
// Hyperboloid of two sheets, x² - y² + z² = -c
surface_q_in_local: Mat4::from_diagonal([1.0, -1.0 - 0.1, 1.0, 0.1].into()),
bounds_q_in_local: Mat4::from_diagonal([0.0, 1.0, 0.0, -1.0].into()),
uv_from_local: uv2_from_local,
},
);
add_quadric(
&models,
"Cylinder",
world,
&make_transform(4.0, 1.4, -1.5, 0.5),
0.5_f32.sqrt(),
HologramData {
surface_q_in_local: Mat4::from_diagonal([1.0, 1.0, 0.0, -1.0].into()),
bounds_q_in_local: Mat4::from_diagonal([0.0, 0.0, 1.0, -1.0].into()),
uv_from_local: Mat4::IDENTITY,
// Hyperbolic paraboloid - "saddle", cy = x² + z²
surface_q_in_local: Mat4::from_cols(
[1.0, 0.0, 0.0, 0.0].into(),
[0.0, 0.0, 0.0, 1.0].into(),
[0.0, 0.0, -1.0, 0.0].into(),
[0.0, 1.0, 0.0, 0.0].into(),
),
bounds_q_in_local: Mat4::from_diagonal([1.0, 0.0, 1.0, -1.0].into()),
uv_from_local: uv2_from_local,
},
);

Ok(())
}
// Quadric surfaces with varying number of control points
let target_initial_hologram_data = HologramData {
surface_q_in_local: Mat4::from_diagonal([1.0, 1.0, 1.0, -1.0].into()),
bounds_q_in_local: Mat4::from_diagonal([1.0, 1.0, 1.0, -1.0].into()),
uv_from_local: uv2_from_local,
};
let t_from_local = Mat4::from_translation([0.0, -1.0, 0.0].into());
let t2_from_local = Mat4::from_translation([0.0, -0.5, 0.0].into());
let control_point_hologram_data = HologramData {
surface_q_in_local: t_from_local.transpose()
* Mat4::from_diagonal([1.0, -1.0, 1.0, 0.0].into())
* t_from_local,
bounds_q_in_local: t2_from_local.transpose()
* Mat4::from_diagonal([0.0, 1.0, 0.0, -0.25].into())
* t2_from_local,
uv_from_local: uv3_from_local,
};
for n in 1..=9 {
let target = add_quadric(
&models,
"Sphere",
world,
&make_transform(-2.0 + n as f32, 1.4, 1.5, 0.5),
0.5,
target_initial_hologram_data,
);

fn add_helmet(
models: &std::collections::HashMap<String, World>,
world: &mut World,
translation: Vec3,
) {
let helmet = add_model_to_world("Damaged Helmet", models, world, None)
.expect("Could not find Damaged Helmet");
let entities = (0..n)
.map(|i| {
add_quadric(
&models,
"Cylinder",
world,
&make_transform(
-2.0 + n as f32 + 0.1 * (i & 1) as f32,
1.4,
1.5 + 0.1 * (i >> 1) as f32,
0.05,
),
0.05,
control_point_hologram_data,
)
})
.collect();

{
let mut local_transform = world.get::<&mut LocalTransform>(helmet).unwrap();
local_transform.translation = translation;
local_transform.scale = [0.5, 0.5, 0.5].into();
let control_points = ControlPoints { entities };
world.insert_one(target, control_points).unwrap();
world.remove_one::<Grabbable>(target).unwrap();
}

let collider = Collider::new(SharedShape::ball(0.35));
Ok(())
}

world.insert(helmet, (collider, Grabbable {})).unwrap();
fn make_transform(x: f32, y: f32, z: f32, scale: f32) -> LocalTransform {
LocalTransform {
translation: [x, y, z].into(),
rotation: Quat::IDENTITY,
scale: [scale, scale, scale].into(),
}
}

fn add_quadric(
models: &std::collections::HashMap<String, World>,
model_name: &str,
world: &mut World,
local_transform: &LocalTransform,
ball_radius: f32,
hologram_data: HologramData,
) {
let entity = add_model_to_world("Sphere", models, world, None).expect("Could not find Sphere");
) -> Entity {
let entity = add_model_to_world(model_name, models, world, None)
.unwrap_or_else(|| panic!("Could not find {}", model_name));
*world.get::<&mut LocalTransform>(entity).unwrap() = *local_transform;
let collider = Collider::new(SharedShape::ball(ball_radius));
let hologram_component = Hologram {
Expand All @@ -214,4 +309,20 @@ fn add_quadric(
.insert(entity, (collider, Grabbable {}, hologram_component))
.unwrap();
world.remove_one::<Mesh>(entity).unwrap();

// Add second entity for the back surface
let second_entity = add_model_to_world(model_name, models, world, Some(entity))
.unwrap_or_else(|| panic!("Could not find {}", model_name));
// Negate Q to flip the surface normal
let mut hologram_component = hologram_component;
hologram_component.hologram_data.surface_q_in_local *= -1.0;
world
.insert(
second_entity,
(hologram_component, HologramBackside { entity }),
)
.unwrap();
world.remove_one::<Mesh>(second_entity).unwrap();

entity
}
Loading
Loading