feat: complete stable OpenSim live interactions
This commit is contained in:
@@ -168,6 +168,7 @@ impl LibremetaverseClientOwner {
|
||||
.map_err(|_| BackendError::Configuration {
|
||||
component: "libremetaverse client defaults",
|
||||
})?;
|
||||
let _grid = client.grid();
|
||||
let agent = Arc::new(
|
||||
libremetaverse::AgentManager::new(Some(Arc::new(client.clone()))).map_err(|_| {
|
||||
BackendError::Configuration {
|
||||
@@ -568,13 +569,26 @@ impl crate::behavior::EmbodimentSink for LibremetaverseEmbodimentSink {
|
||||
.network()
|
||||
.native_current_sim()
|
||||
.ok_or(crate::behavior::BehaviorError::NotReady)?;
|
||||
simulator
|
||||
let object_position = simulator
|
||||
.objects_avatars
|
||||
.read()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
||||
.values()
|
||||
.find(|avatar| avatar.id == avatar_id)
|
||||
.map(|avatar| native_position(avatar.position))
|
||||
.map(|avatar| native_position(avatar.position));
|
||||
let coarse_position = self
|
||||
.client
|
||||
.grid()
|
||||
.native_coarse_position(simulator.handle, avatar_id);
|
||||
object_position
|
||||
.or_else(|| {
|
||||
let origin = self.agent.sim_position();
|
||||
coarse_position.map(|position| crate::perception::WorldPosition {
|
||||
x: unwrap_coarse_axis(position.x, origin.x),
|
||||
y: unwrap_coarse_axis(position.y, origin.y),
|
||||
z: f64::from(position.z),
|
||||
})
|
||||
})
|
||||
.ok_or(crate::behavior::BehaviorError::TargetUnavailable)
|
||||
})
|
||||
}
|
||||
@@ -642,21 +656,41 @@ impl crate::behavior::EmbodimentSink for LibremetaverseEmbodimentSink {
|
||||
.network()
|
||||
.native_current_sim()
|
||||
.ok_or(crate::behavior::BehaviorError::NotReady)?;
|
||||
let parcels = self.client.parcels();
|
||||
let current = parcels
|
||||
.get_parcel_local_id(simulator.clone(), self.agent.sim_position())
|
||||
.map_err(|_| crate::behavior::BehaviorError::NativeOperation)?;
|
||||
let target = parcels
|
||||
.get_parcel_local_id(
|
||||
simulator,
|
||||
libremetaverse_types::Vector3 {
|
||||
x: point.x as f32,
|
||||
y: point.y as f32,
|
||||
z: point.z as f32,
|
||||
},
|
||||
)
|
||||
.map_err(|_| crate::behavior::BehaviorError::NativeOperation)?;
|
||||
if current == 0 || current != target {
|
||||
let current_position = self.agent.sim_position();
|
||||
let reported_bounds_contain_agent = f64::from(current_position.x)
|
||||
<= f64::from(simulator.size_x)
|
||||
&& f64::from(current_position.y) <= f64::from(simulator.size_y);
|
||||
if point.x < 0.0
|
||||
|| point.y < 0.0
|
||||
|| (reported_bounds_contain_agent
|
||||
&& (point.x > f64::from(simulator.size_x)
|
||||
|| point.y > f64::from(simulator.size_y)))
|
||||
{
|
||||
return Err(crate::behavior::BehaviorError::RegionBoundary);
|
||||
}
|
||||
let parcels = simulator
|
||||
.parcels
|
||||
.read()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||
let parcel_at = |x: f32, y: f32| {
|
||||
parcels
|
||||
.values()
|
||||
.filter(|parcel| {
|
||||
x >= parcel.aabb_min.x
|
||||
&& x <= parcel.aabb_max.x
|
||||
&& y >= parcel.aabb_min.y
|
||||
&& y <= parcel.aabb_max.y
|
||||
})
|
||||
.map(|parcel| parcel.local_id)
|
||||
.min()
|
||||
};
|
||||
let current = parcel_at(current_position.x, current_position.y);
|
||||
let target = parcel_at(point.x as f32, point.y as f32);
|
||||
if current
|
||||
.zip(target)
|
||||
.is_some_and(|(current, target)| current != target)
|
||||
|| (reported_bounds_contain_agent && (current.is_none() || target.is_none()))
|
||||
{
|
||||
return Err(crate::behavior::BehaviorError::RegionBoundary);
|
||||
}
|
||||
Ok(())
|
||||
@@ -714,6 +748,20 @@ impl crate::behavior::EmbodimentSink for LibremetaverseEmbodimentSink {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
fn unwrap_coarse_axis(encoded: f32, origin: f32) -> f64 {
|
||||
f64::from(encoded + ((origin - encoded) / 256.0).round() * 256.0)
|
||||
}
|
||||
|
||||
#[cfg(all(test, feature = "live-grid"))]
|
||||
mod live_grid_tests {
|
||||
#[test]
|
||||
fn coarse_avatar_axis_unwraps_to_nearest_varregion_tile() {
|
||||
assert!((super::unwrap_coarse_axis(164.0, 678.0) - 676.0).abs() < f64::EPSILON);
|
||||
assert!((super::unwrap_coarse_axis(26.0, 539.0) - 538.0).abs() < f64::EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
fn native_position(value: libremetaverse_types::Vector3) -> crate::perception::WorldPosition {
|
||||
crate::perception::WorldPosition {
|
||||
|
||||
Reference in New Issue
Block a user