use super::{
Actor, ActorBase, ActorBlueprint, ActorBuilder, ActorList, ActorVec, BlueprintLibrary,
BoundingBoxList, DebugHelper, EnvironmentObjectList, LabelledPointList, Landmark, LightManager,
Map, Waypoint, WorldSnapshot,
};
#[cfg(carla_0100)]
use crate::rpc::{MaterialParameter, TextureColor, TextureFloatColor};
use crate::{
error::{OperationError, Result, ffi::with_ffi_error},
geom::{Location, Transform, Vector3D},
road::JuncId,
rpc::{
ActorId, AttachmentType, EpisodeSettings, LabelledPoint, MapLayer, VehicleLightStateList,
WeatherParameters,
},
utils::CxxVectorExt,
};
use autocxx::prelude::*;
use carla_sys::carla_rust::{
client::{FfiActor, FfiWorld, FfiWorldSnapshot},
geom::FfiVector3D,
};
use cxx::{CxxVector, UniquePtr, let_cxx_string};
use derivative::Derivative;
use static_assertions::assert_impl_all;
use std::{mem, ptr, time::Duration};
use autocxx::c_void;
const DEFAULT_TICK_TIMEOUT: Duration = Duration::from_secs(60);
#[cfg_attr(carla_version_0916, doc = "")]
#[cfg_attr(
carla_version_0916,
doc = " [`carla.World`]: https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World"
)]
#[cfg_attr(carla_version_0915, doc = "")]
#[cfg_attr(
carla_version_0915,
doc = " [`carla.World`]: https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World"
)]
#[cfg_attr(carla_version_0914, doc = "")]
#[cfg_attr(
carla_version_0914,
doc = " [`carla.World`]: https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World"
)]
#[derive(Derivative)]
#[derivative(Debug)]
#[repr(transparent)]
pub struct World {
#[derivative(Debug = "ignore")]
pub(crate) inner: UniquePtr<FfiWorld>,
}
impl World {
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.id](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.id)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.id](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.id)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.id](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.id)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn id(&self) -> Result<u64> {
with_ffi_error("World::id", |e| self.inner.GetId(e))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_map](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_map)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_map](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_map)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_map](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_map)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn map(&self) -> crate::Result<Map> {
let ptr = with_ffi_error("map", |e| self.inner.GetMap(e))?;
Ok(unsafe { Map::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_lightmanager](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_lightmanager)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_lightmanager](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_lightmanager)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_lightmanager](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_lightmanager)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn light_manager(&self) -> crate::Result<LightManager> {
let ptr = with_ffi_error("light_manager", |e| self.inner.GetLightManager(e))?;
Ok(unsafe { LightManager::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.load_map_layer](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.load_map_layer)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.load_map_layer](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.load_map_layer)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.load_map_layer](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.load_map_layer)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn load_level_layer(&self, map_layers: MapLayer) -> crate::Result<()> {
with_ffi_error("load_level_layer", |e| {
self.inner.LoadLevelLayer(map_layers as u16, e)
})
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.unload_map_layer](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.unload_map_layer)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.unload_map_layer](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.unload_map_layer)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.unload_map_layer](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.unload_map_layer)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn unload_level_layer(&self, map_layers: MapLayer) -> crate::Result<()> {
with_ffi_error("unload_level_layer", |e| {
self.inner.UnloadLevelLayer(map_layers as u16, e)
})
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_blueprint_library](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_blueprint_library)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_blueprint_library](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_blueprint_library)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_blueprint_library](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_blueprint_library)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn blueprint_library(&self) -> crate::Result<BlueprintLibrary> {
let ptr = with_ffi_error("blueprint_library", |e| self.inner.GetBlueprintLibrary(e))?;
Ok(unsafe { BlueprintLibrary::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_vehicles_light_states](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_vehicles_light_states)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_vehicles_light_states](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_vehicles_light_states)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_vehicles_light_states](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_vehicles_light_states)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn vehicle_light_states(&self) -> crate::Result<VehicleLightStateList> {
let ptr = with_ffi_error("vehicle_light_states", |e| {
self.inner.GetVehiclesLightStates(e)
})?;
Ok(unsafe { VehicleLightStateList::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_random_location_from_navigation](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_random_location_from_navigation)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_random_location_from_navigation](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_random_location_from_navigation)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_random_location_from_navigation](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_random_location_from_navigation)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn random_location_from_navigation(&self) -> crate::Result<Location> {
let ptr = with_ffi_error("random_location_from_navigation", |e| {
self.inner.GetRandomLocationFromNavigation(e)
})?;
Ok(Location::from_ffi(ptr.as_ref().unwrap().clone()))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_spectator](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_spectator)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_spectator](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_spectator)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_spectator](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_spectator)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn spectator(&self) -> crate::Result<Actor> {
let ptr = with_ffi_error("spectator", |e| self.inner.GetSpectator(e))?;
Ok(unsafe { Actor::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_settings](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_settings)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_settings](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_settings)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_settings](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_settings)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn settings(&self) -> crate::Result<EpisodeSettings> {
let ptr = with_ffi_error("settings", |e| self.inner.GetSettings(e))?;
Ok(EpisodeSettings::from_cxx(&ptr))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_snapshot](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_snapshot)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_snapshot](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_snapshot)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_snapshot](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_snapshot)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn snapshot(&self) -> crate::Result<WorldSnapshot> {
let ptr = with_ffi_error("snapshot", |e| self.inner.GetSnapshot(e))?;
Ok(unsafe { WorldSnapshot::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_names_of_all_objects](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_names_of_all_objects)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_names_of_all_objects](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_names_of_all_objects)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_names_of_all_objects](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_names_of_all_objects)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn names_of_all_objects(&self) -> crate::Result<Vec<String>> {
let names = with_ffi_error("names_of_all_objects", |e| {
self.inner.GetNamesOfAllObjects(e)
})?;
Ok(names.iter().map(|s| s.to_string()).collect())
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_actor](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_actor)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_actor](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_actor)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_actor](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_actor)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn actor(&self, actor_id: ActorId) -> crate::Result<Option<Actor>> {
let ptr = with_ffi_error("actor", |e| self.inner.GetActor(actor_id, e))?;
Ok(Actor::from_cxx(ptr))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_actors](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_actors)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_actors](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_actors)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_actors](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_actors)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn actors(&self) -> crate::Result<ActorList> {
let ptr = with_ffi_error("actors", |e| self.inner.GetActors(e))?;
Ok(unsafe { ActorList::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_actors](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_actors)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_actors](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_actors)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_actors](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_actors)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn actors_by_ids(&self, ids: &[ActorId]) -> crate::Result<ActorList> {
let mut vec = CxxVector::new_typed();
ids.iter().cloned().for_each(|id| {
vec.pin_mut().push(id);
});
let ptr = with_ffi_error("actors_by_ids", |e| self.inner.GetActorsByIds(&vec, e))?;
Ok(unsafe { ActorList::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_traffic_lights_from_waypoint](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_traffic_lights_from_waypoint)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_traffic_lights_from_waypoint](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_traffic_lights_from_waypoint)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_traffic_lights_from_waypoint](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_traffic_lights_from_waypoint)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn traffic_lights_from_waypoint(
&self,
waypoint: &Waypoint,
distance: f64,
) -> crate::Result<ActorVec> {
let ptr = with_ffi_error("traffic_lights_from_waypoint", |e| {
self.inner
.GetTrafficLightsFromWaypoint(&waypoint.inner, distance, e)
})?;
Ok(unsafe { ActorVec::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_traffic_lights_in_junction](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_traffic_lights_in_junction)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_traffic_lights_in_junction](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_traffic_lights_in_junction)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_traffic_lights_in_junction](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_traffic_lights_in_junction)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn traffic_lights_in_junction(&self, junc_id: JuncId) -> crate::Result<ActorVec> {
let ptr = with_ffi_error("traffic_lights_in_junction", |e| {
self.inner.GetTrafficLightsInJunction(junc_id.into(), e)
})?;
Ok(unsafe { ActorVec::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.apply_settings](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.apply_settings)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.apply_settings](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.apply_settings)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.apply_settings](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.apply_settings)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn apply_settings(
&mut self,
settings: &EpisodeSettings,
timeout: Duration,
) -> crate::Result<u64> {
let ffi_settings = settings.to_cxx();
let millis = timeout.as_millis() as usize;
with_ffi_error("apply_settings", |e| {
self.inner.pin_mut().ApplySettings(&ffi_settings, millis, e)
})
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.spawn_actor](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.spawn_actor)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.spawn_actor](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.spawn_actor)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.spawn_actor](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.spawn_actor)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn spawn_actor(
&mut self,
blueprint: &ActorBlueprint,
transform: &Transform,
) -> Result<Actor> {
self.spawn_actor_opt::<Actor, _>(blueprint, transform, None, None)
}
pub fn spawn_actor_opt<A, T>(
&mut self,
blueprint: &ActorBlueprint,
transform: &Transform,
parent: Option<&A>,
attachment_type: T,
) -> Result<Actor>
where
A: ActorBase,
T: Into<Option<AttachmentType>>,
{
let parent = parent.map(|parent| parent.cxx_actor());
let attachment_type = attachment_type.into().unwrap_or(AttachmentType::Rigid);
unsafe {
let parent_ptr: *mut FfiActor = parent
.as_ref()
.and_then(|parent| parent.as_ref())
.map(|ref_| ref_ as *const _ as *mut _)
.unwrap_or(ptr::null_mut());
let ffi_transform = transform.clone();
#[cfg(carla_version_0916)]
let actor = {
use cxx::let_cxx_string;
let_cxx_string!(socket_name = "");
with_ffi_error("World::try_spawn_actor", |e| {
self.inner.pin_mut().TrySpawnActor(
&blueprint.inner,
ffi_transform.as_ffi(),
parent_ptr,
attachment_type,
&socket_name,
e,
)
})?
};
#[cfg(not(carla_version_0916))]
let actor = with_ffi_error("World::try_spawn_actor", |e| {
self.inner.pin_mut().TrySpawnActor(
&blueprint.inner,
ffi_transform.as_ffi(),
parent_ptr,
attachment_type,
e,
)
})?;
Actor::from_cxx(actor).ok_or_else(|| {
OperationError::SpawnFailed {
blueprint: blueprint.id().to_string(),
transform: format!("{:?}", transform),
reason: "Spawn returned null (likely collision or invalid location)"
.to_string(),
source: None,
}
.into()
})
}
}
pub fn spawn_actor_attached<A, T>(
&mut self,
blueprint: &ActorBlueprint,
transform: &Transform,
parent: &A,
attachment_type: T,
) -> Result<Actor>
where
A: ActorBase,
T: Into<Option<AttachmentType>>,
{
self.spawn_actor_opt(blueprint, transform, Some(parent), attachment_type)
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.wait_for_tick](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.wait_for_tick)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.wait_for_tick](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.wait_for_tick)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.wait_for_tick](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.wait_for_tick)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn wait_for_tick(&self) -> Result<WorldSnapshot> {
self.wait_for_tick_or_timeout(DEFAULT_TICK_TIMEOUT)?
.ok_or_else(|| {
crate::error::ConnectionError::Timeout {
operation: "wait_for_tick".to_string(),
duration: DEFAULT_TICK_TIMEOUT,
source: None,
}
.into()
})
}
pub fn actor_builder(&mut self, key: &str) -> Result<ActorBuilder<'_>> {
ActorBuilder::new(self, key)
}
pub fn wait_for_tick_or_timeout(&self, timeout: Duration) -> Result<Option<WorldSnapshot>> {
with_ffi_error("wait_for_tick", |error| {
let ptr = self.inner.WaitForTick(timeout.as_millis() as usize, error);
WorldSnapshot::from_cxx(ptr)
})
}
pub fn tick_or_timeout(&mut self, timeout: Duration) -> crate::Result<u64> {
let millis = timeout.as_millis() as usize;
with_ffi_error("tick", |e| self.inner.pin_mut().Tick(millis, e))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.tick](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.tick)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.tick](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.tick)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.tick](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.tick)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn tick(&mut self) -> crate::Result<u64> {
self.tick_or_timeout(DEFAULT_TICK_TIMEOUT)
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.set_pedestrians_cross_factor](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.set_pedestrians_cross_factor)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.set_pedestrians_cross_factor](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.set_pedestrians_cross_factor)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.set_pedestrians_cross_factor](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.set_pedestrians_cross_factor)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn set_pedestrians_cross_factor(&mut self, percentage: f32) -> crate::Result<()> {
with_ffi_error("set_pedestrians_cross_factor", |e| {
self.inner
.pin_mut()
.SetPedestriansCrossFactor(percentage, e)
})
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.set_pedestrians_seed](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.set_pedestrians_seed)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.set_pedestrians_seed](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.set_pedestrians_seed)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.set_pedestrians_seed](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.set_pedestrians_seed)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn set_pedestrians_seed(&mut self, seed: usize) -> crate::Result<()> {
let seed = c_uint(seed as std::os::raw::c_uint);
with_ffi_error("set_pedestrians_seed", |e| {
self.inner.pin_mut().SetPedestriansSeed(seed, e)
})
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_traffic_sign](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_traffic_sign)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_traffic_sign](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_traffic_sign)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_traffic_sign](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_traffic_sign)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn traffic_sign_at(&self, landmark: &Landmark) -> crate::Result<Option<Actor>> {
let ptr = with_ffi_error("traffic_sign_at", |e| {
self.inner
.GetTrafficSign(unsafe { landmark.inner.as_ref().unwrap_unchecked() }, e)
})?;
Ok(Actor::from_cxx(ptr))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_traffic_light](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_traffic_light)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_traffic_light](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_traffic_light)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_traffic_light](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_traffic_light)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn traffic_light_at(&self, landmark: &Landmark) -> crate::Result<Option<Actor>> {
let ptr = with_ffi_error("traffic_light_at", |e| {
self.inner
.GetTrafficLight(unsafe { landmark.inner.as_ref().unwrap_unchecked() }, e)
})?;
Ok(Actor::from_cxx(ptr))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_traffic_light_from_opendrive](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_traffic_light_from_opendrive)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_traffic_light_from_opendrive](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_traffic_light_from_opendrive)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_traffic_light_from_opendrive](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_traffic_light_from_opendrive)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn traffic_light_from_open_drive(&self, sign_id: &str) -> crate::Result<Option<Actor>> {
let_cxx_string!(sign_id = sign_id);
let ptr = with_ffi_error("traffic_light_from_open_drive", |e| {
self.inner.GetTrafficLightFromOpenDRIVE(&sign_id, e)
})?;
Ok(Actor::from_cxx(ptr))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.freeze_all_traffic_lights](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.freeze_all_traffic_lights)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.freeze_all_traffic_lights](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.freeze_all_traffic_lights)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.freeze_all_traffic_lights](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.freeze_all_traffic_lights)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn freeze_all_traffic_lights(&mut self, frozen: bool) -> crate::Result<()> {
with_ffi_error("freeze_all_traffic_lights", |e| {
self.inner.pin_mut().FreezeAllTrafficLights(frozen, e)
})
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.reset_all_traffic_lights](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.reset_all_traffic_lights)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.reset_all_traffic_lights](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.reset_all_traffic_lights)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.reset_all_traffic_lights](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.reset_all_traffic_lights)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn reset_all_traffic_lights(&mut self) -> crate::Result<()> {
with_ffi_error("reset_all_traffic_lights", |e| {
self.inner.pin_mut().ResetAllTrafficLights(e)
})
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_level_bbs](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_level_bbs)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_level_bbs](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_level_bbs)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_level_bbs](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_level_bbs)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn level_bounding_boxes(&self, queried_tag: u8) -> crate::Result<BoundingBoxList> {
let ptr = with_ffi_error("level_bounding_boxes", |e| {
self.inner.GetLevelBBs(queried_tag, e)
})?;
Ok(unsafe { BoundingBoxList::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_weather](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_weather)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_weather](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_weather)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_weather](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_weather)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn weather(&self) -> crate::Result<WeatherParameters> {
with_ffi_error("weather", |e| self.inner.GetWeather(e))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.set_weather](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.set_weather)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.set_weather](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.set_weather)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.set_weather](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.set_weather)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn set_weather(&mut self, weather: &WeatherParameters) -> crate::Result<()> {
with_ffi_error("set_weather", |e| {
self.inner.pin_mut().SetWeather(weather, e)
})
}
#[cfg(carla_0100)]
pub fn is_weather_enabled(&self) -> crate::Result<bool> {
with_ffi_error("is_weather_enabled", |e| self.inner.IsWeatherEnabled(e))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.get_environment_objects](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.get_environment_objects)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.get_environment_objects](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.get_environment_objects)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.get_environment_objects](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.get_environment_objects)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn environment_objects(&self, queried_tag: u8) -> crate::Result<EnvironmentObjectList> {
let ptr = with_ffi_error("environment_objects", |e| {
self.inner.GetEnvironmentObjects(queried_tag, e)
})?;
Ok(unsafe { EnvironmentObjectList::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.World.enable_environment_objects](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.World.enable_environment_objects)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.World.enable_environment_objects](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.World.enable_environment_objects)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.World.enable_environment_objects](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.World.enable_environment_objects)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn enable_environment_objects(&self, ids: &[u64], enable: bool) -> crate::Result<()> {
let ptr = ids.as_ptr();
let len = ids.len();
with_ffi_error("enable_environment_objects", |e| unsafe {
self.inner.EnableEnvironmentObjects(ptr, len, enable, e)
})
}
pub fn project_point(
&self,
location: &Location,
direction: &Vector3D,
search_distance: f32,
) -> crate::Result<Option<LabelledPoint>> {
let cpp_dir = unsafe {
std::mem::transmute::<FfiVector3D, carla_sys::carla::geom::Vector3D>(
direction.into_ffi(),
)
};
let ptr = with_ffi_error("project_point", |e| {
self.inner
.ProjectPoint(location.into_ffi(), cpp_dir, search_distance, e)
})?;
if ptr.is_null() {
Ok(None)
} else {
Ok(Some((*ptr).clone()))
}
}
pub fn ground_projection(
&self,
location: &Location,
search_distance: f32,
) -> crate::Result<Option<LabelledPoint>> {
let ptr = with_ffi_error("ground_projection", |e| {
self.inner
.GroundProjection(location.into_ffi(), search_distance, e)
})?;
if ptr.is_null() {
Ok(None)
} else {
Ok(Some((*ptr).clone()))
}
}
pub fn cast_ray(&self, start: &Location, end: &Location) -> crate::Result<LabelledPointList> {
let ptr = with_ffi_error("cast_ray", |e| {
self.inner.CastRay(start.into_ffi(), end.into_ffi(), e)
})?;
Ok(unsafe { LabelledPointList::from_cxx(ptr).unwrap_unchecked() })
}
pub fn debug(&mut self) -> crate::Result<DebugHelper> {
let ptr = with_ffi_error("debug", |e| self.inner.pin_mut().MakeDebugHelper(e))?;
Ok(DebugHelper { inner: ptr })
}
#[cfg(carla_0100)]
pub fn apply_color_texture_to_object(
&mut self,
object_name: &str,
parameter: MaterialParameter,
texture: &TextureColor,
) -> crate::Result<()> {
let_cxx_string!(name = object_name);
with_ffi_error("apply_color_texture_to_object", |e| {
self.inner.pin_mut().ApplyColorTextureToObject(
&name,
parameter.as_u8(),
&texture.inner,
e,
)
})
}
#[cfg(carla_0100)]
pub fn apply_float_color_texture_to_object(
&mut self,
object_name: &str,
parameter: MaterialParameter,
texture: &TextureFloatColor,
) -> crate::Result<()> {
let_cxx_string!(name = object_name);
with_ffi_error("apply_float_color_texture_to_object", |e| {
self.inner.pin_mut().ApplyFloatColorTextureToObject(
&name,
parameter.as_u8(),
&texture.inner,
e,
)
})
}
#[cfg(carla_0100)]
pub fn apply_textures_to_object(
&mut self,
object_name: &str,
diffuse: &TextureColor,
emissive: &TextureFloatColor,
normal: &TextureFloatColor,
ao_roughness_metallic_emissive: &TextureFloatColor,
) -> crate::Result<()> {
let_cxx_string!(name = object_name);
with_ffi_error("apply_textures_to_object", |e| {
self.inner.pin_mut().ApplyTexturesToObject(
&name,
&diffuse.inner,
&emissive.inner,
&normal.inner,
&ao_roughness_metallic_emissive.inner,
e,
)
})
}
pub fn on_tick<F>(&mut self, mut callback: F) -> crate::Result<OnTickId>
where
F: FnMut(WorldSnapshot) + Send + 'static,
{
with_ffi_error("on_tick", |e| unsafe {
let fn_ptr = {
let fn_ = move |ptr: UniquePtr<FfiWorldSnapshot>| {
if let Some(snapshot) = WorldSnapshot::from_cxx(ptr) {
(callback)(snapshot);
}
};
let fn_: Box<OnTickCb> = Box::new(fn_);
let fn_ = Box::new(fn_);
let fn_: *mut Box<OnTickCb> = Box::into_raw(fn_);
fn_ as *mut c_void
};
let caller_ptr = on_tick_caller as *mut c_void;
let deleter_ptr = on_tick_deleter as *mut c_void;
OnTickId(
self.inner
.pin_mut()
.OnTick(caller_ptr, fn_ptr, deleter_ptr, e),
)
})
}
pub fn remove_on_tick(&mut self, id: OnTickId) -> crate::Result<()> {
with_ffi_error("remove_on_tick", |e| {
self.inner.pin_mut().RemoveOnTick(id.0, e);
})
}
pub(crate) fn from_cxx(ptr: UniquePtr<FfiWorld>) -> Option<World> {
if ptr.is_null() {
None
} else {
Some(Self { inner: ptr })
}
}
}
impl Clone for World {
fn clone(&self) -> Self {
let ptr =
with_ffi_error("World::clone", |e| self.inner.clone(e)).expect("World::clone failed");
unsafe { Self::from_cxx(ptr).unwrap_unchecked() }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct OnTickId(usize);
type OnTickCb = dyn FnMut(UniquePtr<FfiWorldSnapshot>) + Send + 'static;
unsafe extern "C" fn on_tick_caller(fn_: *mut c_void, arg: *mut FfiWorldSnapshot) {
if fn_.is_null() || arg.is_null() {
eprintln!(
"ERROR: Null pointer in on_tick callback - fn_: {:p}, arg: {:p}",
fn_, arg
);
return;
}
let fn_ = fn_ as *mut Box<OnTickCb>;
unsafe {
let snapshot = UniquePtr::from_raw(arg);
(*fn_)(snapshot);
}
}
unsafe extern "C" fn on_tick_deleter(fn_: *mut c_void) {
if fn_.is_null() {
eprintln!("ERROR: Null pointer in on_tick deleter");
return;
}
let fn_ = fn_ as *mut Box<OnTickCb>;
let fn_: Box<Box<OnTickCb>> = unsafe { Box::from_raw(fn_) };
mem::drop(fn_);
}
assert_impl_all!(World: Sync, Send);