mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
webxr: Update hand input to match latest spec (#32958)
* Update IDLs Signed-off-by: Daniel Adams <msub2official@gmail.com> * Update XRHand and XRJointSpace methods/bindings Signed-off-by: Daniel Adams <msub2official@gmail.com> * Implement fillJointRadii Signed-off-by: Daniel Adams <msub2official@gmail.com> * Implement fillPoses Signed-off-by: Daniel Adams <msub2official@gmail.com> * Formatting Signed-off-by: Daniel Adams <msub2official@gmail.com> * Update test expectations Signed-off-by: Daniel Adams <msub2official@gmail.com> * Tidy, missing spec link Signed-off-by: Daniel Adams <msub2official@gmail.com> * Remove idlharness expectation files, update hands pref Signed-off-by: Daniel Adams <msub2official@gmail.com> * Update interfaces Signed-off-by: Daniel Adams <msub2official@gmail.com> * XRJointPose interface Signed-off-by: Daniel Adams <msub2official@gmail.com> * XRHand interface Signed-off-by: Daniel Adams <msub2official@gmail.com> --------- Signed-off-by: Daniel Adams <msub2official@gmail.com>
This commit is contained in:
parent
057873c94a
commit
825d6f10e9
12 changed files with 314 additions and 553 deletions
|
@ -5,6 +5,8 @@
|
|||
use std::cell::Cell;
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use js::gc::CustomAutoRooterGuard;
|
||||
use js::typedarray::Float32Array;
|
||||
use webxr_api::{Frame, LayerId, SubImages};
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::XRFrameBinding::XRFrameMethods;
|
||||
|
@ -175,4 +177,107 @@ impl XRFrameMethods for XRFrame {
|
|||
.map(|r| XRHitTestResult::new(&self.global(), *r, self))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
/// <https://www.w3.org/TR/webxr-hand-input-1/#dom-xrframe-filljointradii>
|
||||
fn FillJointRadii(
|
||||
&self,
|
||||
joint_spaces: Vec<DomRoot<XRJointSpace>>,
|
||||
mut radii: CustomAutoRooterGuard<Float32Array>,
|
||||
) -> Result<bool, Error> {
|
||||
if !self.active.get() {
|
||||
return Err(Error::InvalidState);
|
||||
}
|
||||
|
||||
for joint_space in &joint_spaces {
|
||||
if self.session != joint_space.upcast::<XRSpace>().session() {
|
||||
return Err(Error::InvalidState);
|
||||
}
|
||||
}
|
||||
|
||||
if joint_spaces.len() > radii.len() {
|
||||
return Err(Error::Type(
|
||||
"Length of radii does not match length of joint spaces".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let mut radii_vec = radii.to_vec();
|
||||
let mut all_valid = true;
|
||||
radii_vec.iter_mut().enumerate().for_each(|(i, radius)| {
|
||||
if let Some(joint_frame) = joint_spaces
|
||||
.get(i)
|
||||
.and_then(|joint_space| joint_space.frame(&self.data))
|
||||
{
|
||||
*radius = joint_frame.radius;
|
||||
} else {
|
||||
all_valid = false;
|
||||
}
|
||||
});
|
||||
|
||||
if !all_valid {
|
||||
radii_vec.fill(f32::NAN);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
radii.update(&radii_vec);
|
||||
}
|
||||
|
||||
Ok(all_valid)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
/// <https://www.w3.org/TR/webxr-hand-input-1/#dom-xrframe-fillposes>
|
||||
fn FillPoses(
|
||||
&self,
|
||||
spaces: Vec<DomRoot<XRSpace>>,
|
||||
base_space: &XRSpace,
|
||||
mut transforms: CustomAutoRooterGuard<Float32Array>,
|
||||
) -> Result<bool, Error> {
|
||||
if !self.active.get() {
|
||||
return Err(Error::InvalidState);
|
||||
}
|
||||
|
||||
for space in &spaces {
|
||||
if self.session != space.session() {
|
||||
return Err(Error::InvalidState);
|
||||
}
|
||||
}
|
||||
|
||||
if self.session != base_space.session() {
|
||||
return Err(Error::InvalidState);
|
||||
}
|
||||
|
||||
if spaces.len() * 16 > transforms.len() {
|
||||
return Err(Error::Type(
|
||||
"Transforms array length does not match 16 * spaces length".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let mut transforms_vec = transforms.to_vec();
|
||||
let mut all_valid = true;
|
||||
spaces.iter().enumerate().for_each(|(i, space)| {
|
||||
let Some(joint_pose) = self.get_pose(space) else {
|
||||
all_valid = false;
|
||||
return;
|
||||
};
|
||||
let Some(base_pose) = self.get_pose(base_space) else {
|
||||
all_valid = false;
|
||||
return;
|
||||
};
|
||||
let pose = joint_pose.then(&base_pose.inverse());
|
||||
let elements = pose.to_transform();
|
||||
let elements_arr = elements.to_array();
|
||||
transforms_vec[i * 16..(i + 1) * 16].copy_from_slice(&elements_arr);
|
||||
});
|
||||
|
||||
if !all_valid {
|
||||
transforms_vec.fill(f32::NAN);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
transforms.update(&transforms_vec);
|
||||
}
|
||||
|
||||
Ok(all_valid)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue