@@ -4,72 +4,95 @@ pub mod sk_controller;
|
||||
pub mod sk_hand;
|
||||
|
||||
use crate::nodes::{
|
||||
fields::{Field, FieldTrait, Ray}, input::{InputDataTrait, InputDataType, InputHandler, InputMethod, INPUT_HANDLER_REGISTRY}, spatial::Spatial
|
||||
fields::{Field, FieldTrait, Ray},
|
||||
input::{InputDataTrait, InputDataType, InputHandler, InputMethod, INPUT_HANDLER_REGISTRY},
|
||||
spatial::Spatial,
|
||||
};
|
||||
use glam::vec3;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CaptureManager {
|
||||
pub capture: Option<Arc<InputHandler>>,
|
||||
pub capture: Option<Arc<InputHandler>>,
|
||||
}
|
||||
impl CaptureManager {
|
||||
pub fn update_capture(&mut self, pointer: &InputMethod) {
|
||||
if let Some(capture) = &self.capture {
|
||||
if !pointer.internal_capture_requests.get_valid_contents().contains(capture) {
|
||||
self.capture.take();
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn set_new_capture(&mut self, pointer: &InputMethod, distance_calculator: DistanceCalculator) {
|
||||
if self.capture.is_none() {
|
||||
self.capture = find_closest_capture(pointer, distance_calculator);
|
||||
}
|
||||
}
|
||||
pub fn apply_capture(&self, method: &InputMethod) {
|
||||
method.captures.clear();
|
||||
if let Some(capture) = &self.capture {
|
||||
method.set_handler_order([capture].into_iter());
|
||||
method.captures.add_raw(capture);
|
||||
}
|
||||
}
|
||||
pub fn update_capture(&mut self, pointer: &InputMethod) {
|
||||
if let Some(capture) = &self.capture {
|
||||
if !pointer
|
||||
.internal_capture_requests
|
||||
.get_valid_contents()
|
||||
.contains(capture)
|
||||
{
|
||||
self.capture.take();
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn set_new_capture(
|
||||
&mut self,
|
||||
pointer: &InputMethod,
|
||||
distance_calculator: DistanceCalculator,
|
||||
) {
|
||||
if self.capture.is_none() {
|
||||
self.capture = find_closest_capture(pointer, distance_calculator);
|
||||
}
|
||||
}
|
||||
pub fn apply_capture(&self, method: &InputMethod) {
|
||||
method.captures.clear();
|
||||
if let Some(capture) = &self.capture {
|
||||
method.set_handler_order([capture].into_iter());
|
||||
method.captures.add_raw(capture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
type DistanceCalculator = fn(&Arc<Spatial>, &InputDataType, &Field) -> Option<f32>;
|
||||
|
||||
pub fn find_closest_capture(method: &InputMethod, distance_calculator: DistanceCalculator) -> Option<Arc<InputHandler>> {
|
||||
method
|
||||
.internal_capture_requests
|
||||
.get_valid_contents()
|
||||
.into_iter()
|
||||
.filter_map(|h| distance_calculator(&method.spatial, &method.data.lock(), &h.field).map(|dist| (h.clone(), dist)))
|
||||
.min_by(|(_, dist_a), (_, dist_b)| dist_a.partial_cmp(dist_b).unwrap())
|
||||
.map(|(handler, _)| handler)
|
||||
pub fn find_closest_capture(
|
||||
method: &InputMethod,
|
||||
distance_calculator: DistanceCalculator,
|
||||
) -> Option<Arc<InputHandler>> {
|
||||
method
|
||||
.internal_capture_requests
|
||||
.get_valid_contents()
|
||||
.into_iter()
|
||||
.filter_map(|h| {
|
||||
distance_calculator(&method.spatial, &method.data.lock(), &h.field)
|
||||
.map(|dist| (h.clone(), dist))
|
||||
})
|
||||
.min_by(|(_, dist_a), (_, dist_b)| dist_a.partial_cmp(dist_b).unwrap())
|
||||
.map(|(handler, _)| handler)
|
||||
}
|
||||
|
||||
pub fn get_sorted_handlers(method: &InputMethod, distance_calculator: DistanceCalculator) -> Vec<Arc<InputHandler>> {
|
||||
INPUT_HANDLER_REGISTRY
|
||||
.get_valid_contents()
|
||||
.into_iter()
|
||||
.filter(|handler| handler.spatial.node().map_or(false, |node| node.enabled()))
|
||||
.filter(|handler| handler.field.spatial.node().map_or(false, |node| node.enabled()))
|
||||
.filter_map(|handler| {
|
||||
distance_calculator(&method.spatial, &method.data.lock(), &handler.field)
|
||||
.map(|distance| (vec![handler], distance))
|
||||
})
|
||||
.filter(|(_, distance)| *distance > 0.0)
|
||||
.reduce(|(mut handlers_a, distance_a), (handlers_b, distance_b)| {
|
||||
if (distance_a - distance_b).abs() < 0.001 {
|
||||
handlers_a.extend(handlers_b);
|
||||
(handlers_a, distance_a)
|
||||
} else if distance_a < distance_b {
|
||||
(handlers_a, distance_a)
|
||||
} else {
|
||||
(handlers_b, distance_b)
|
||||
}
|
||||
})
|
||||
.map(|(handlers, _)| handlers)
|
||||
.unwrap_or_default()
|
||||
pub fn get_sorted_handlers(
|
||||
method: &InputMethod,
|
||||
distance_calculator: DistanceCalculator,
|
||||
) -> Vec<Arc<InputHandler>> {
|
||||
INPUT_HANDLER_REGISTRY
|
||||
.get_valid_contents()
|
||||
.into_iter()
|
||||
.filter(|handler| handler.spatial.node().map_or(false, |node| node.enabled()))
|
||||
.filter(|handler| {
|
||||
handler
|
||||
.field
|
||||
.spatial
|
||||
.node()
|
||||
.map_or(false, |node| node.enabled())
|
||||
})
|
||||
.filter_map(|handler| {
|
||||
distance_calculator(&method.spatial, &method.data.lock(), &handler.field)
|
||||
.map(|distance| (vec![handler], distance))
|
||||
})
|
||||
.filter(|(_, distance)| *distance > 0.0)
|
||||
.reduce(|(mut handlers_a, distance_a), (handlers_b, distance_b)| {
|
||||
if (distance_a - distance_b).abs() < 0.001 {
|
||||
handlers_a.extend(handlers_b);
|
||||
(handlers_a, distance_a)
|
||||
} else if distance_a < distance_b {
|
||||
(handlers_a, distance_a)
|
||||
} else {
|
||||
(handlers_b, distance_b)
|
||||
}
|
||||
})
|
||||
.map(|(handlers, _)| handlers)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user