define_api_id!(0x3c5a_8c47_30ab_ec47, "world-v4");
pub use crate::world_v0::EntityHandle;
pub use crate::world_v0::MeshHandle;
pub use crate::world_v0::Ray;
pub use crate::world_v0::Value;
pub use crate::world_v0::ENTITY_HANDLE_INVALID;
pub use crate::world_v2::DataHandle;
pub use crate::world_v2::ResourceHandleRepr;
pub use crate::world_v3::RaycastHit;
use crate::FFIResult;
use bytemuck::Pod;
use bytemuck::Zeroable;
#[ark_api_macros::ark_bindgen(imports = "ark-world-v4")]
mod world {
use super::*;
bitflags! {
#[repr(C)]
#[derive(Pod, Zeroable)]
pub struct RaycastQueryOptions : u32 {
/// For raycasts, skips hits where t = min_t or in other words
/// direct hits inside a solid primitive.
const IGNORE_INTERIOR_HITS = 0b0010_0000;
}
}
impl Default for RaycastQueryOptions {
fn default() -> Self {
Self::empty()
}
}
#[derive(Copy, Clone, Default, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct RaycastQueryWithOptions {
pub ray: Ray,
pub layer_mask: u64,
pub ignore_entity: EntityHandle,
pub max_distance: f32,
pub options: RaycastQueryOptions,
}
#[derive(Copy, Clone, Default, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct SpherecastQuery {
pub ray: Ray,
pub layer_mask: u64,
pub ignore_entity: EntityHandle,
pub max_distance: f32,
pub options: RaycastQueryOptions,
/// When zero, this is just a raycast.
pub spherecast_radius: f32,
pub _pad: u32,
}
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct SpatialQueryHit {
pub entity: EntityHandle,
pub point: [f32; 3],
/// The distance along the ray.
///
/// The hits are sorted by this distance when returned from raycast and spherecast queries.
/// In a raycast this is equal to `ray.origin.distance(hit.position)`,
/// but in a spherecast it can be different.
pub distance: f32,
pub normal: [f32; 3],
pub _pad: u32,
}
impl SpatialQueryHit {
pub fn invalid() -> Self {
Self {
entity: ENTITY_HANDLE_INVALID,
point: [f32::NAN; 3],
distance: f32::NAN,
normal: [f32::NAN; 3],
_pad: 0,
}
}
}
#[deprecated(note = "Use EntityLocalTransformConformal3 instead")] // 2022-09-13
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct EntityTransform {
/// Vec3
pub translation: [f32; 3],
/// Quaternion, normalized
pub rotation: [f32; 4],
/// Vec3
pub scale: [f32; 3],
}
#[deprecated(note = "Use EntityLocalTransformConformal3 instead")] // 2022-09-13
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct EntityTransformAffine3 {
/// Mat3 (rotation, scale)
pub rotation_scale: [f32; 9],
/// Vec3 (translation)
pub translation: [f32; 3],
}
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct EntityTransformConformal3 {
/// Vec4 (translation, scale)
pub translation_and_scale: [f32; 4],
/// Quat (rotation)
pub rotation: [f32; 4],
}
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct EntityMeshStyleTint {
/// Vec4 (rgba)
pub tint: [f32; 4],
}
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct EntityRenderEnable {
/// 0 = off, 1 = on,
pub enable: u32,
}
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct EntityBounds {
// Vec3
pub bounding_box_min: [f32; 3],
// Vec3
pub bounding_box_max: [f32; 3],
// Radius from bounding box center
pub bounding_sphere_radius: f32,
}
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct EntityVelocity {
// Vec3, linear velocity
pub positional: [f32; 3],
// Vec3, angular velocity, axis-angle. length == velocity
pub rotational: [f32; 3],
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[repr(u32)]
#[non_exhaustive]
pub enum EntityValueType {
/// Expects data with the same layout and size as the struct `EntityTransform`
#[deprecated(note = "Use EntityLocalTransformConformal3 instead")] // 2022-09-13
EntityLocalTransform = 0,
/// Expects data with the same layout and size as the struct `EntityMeshStyleTint`
/// Will set the tint on all mesh styles that are used by this entity. This assumes
/// each entity uses its own `MeshStyle`.
EntityRenderTint = 1,
/// Expects data with the same layout and size as the struct `EntityRenderEnable`
EntityRenderEnable = 2,
/// Expects data with the same layout and size as the struct `EntityTransform`
#[deprecated(note = "Use EntityWorldTransformConformal3 instead")] // 2022-09-13
EntityWorldTransform = 3,
/// Expects data with the same layout and size as the struct `EntityBounds`
EntityLocalBounds = 4,
/// Expects data with the same layout and size as the struct `EntityVelocity`
EntityPhysicsVelocity = 5,
/// Expects data with the same layout and size as the struct `EntityStateFlags`
EntityStateFlags = 6,
/// Expects data with the same layout and size as the struct `EntityTransformAffine3`
#[deprecated(note = "Use EntityWorldTransformConformal3 instead")] // 2022-09-13
EntityWorldTransformAffine3 = 7,
/// Expects data with the same layout and size as the struct `EntityTransformConformal3`
EntityLocalTransformConformal3 = 8,
/// Expects data with the same layout and size as the struct `EntityTransformConformal3`
EntityWorldTransformConformal3 = 9,
}
impl EntityValueType {
pub fn size_of_element(&self) -> u32 {
let size = match self {
Self::EntityLocalTransform | Self::EntityWorldTransform => {
std::mem::size_of::<EntityTransform>()
}
Self::EntityRenderTint => std::mem::size_of::<EntityMeshStyleTint>(),
Self::EntityRenderEnable => std::mem::size_of::<EntityRenderEnable>(),
Self::EntityLocalBounds => std::mem::size_of::<EntityBounds>(),
Self::EntityPhysicsVelocity => std::mem::size_of::<EntityVelocity>(),
Self::EntityStateFlags => std::mem::size_of::<EntityStateFlags>(),
Self::EntityWorldTransformAffine3 => std::mem::size_of::<EntityTransformAffine3>(),
Self::EntityLocalTransformConformal3 | Self::EntityWorldTransformConformal3 => {
std::mem::size_of::<EntityTransformConformal3>()
}
};
size as u32
}
}
bitflags! {
/// The state of a requested entity value
#[repr(C)]
#[derive(Default, Pod, Zeroable)]
pub struct EntityStateFlags : u32 {
const VALID = 0b0000_0001;
const TRANSFORM_CHANGED = 0b0000_0010;
const PHYSICS_VELOCITY_CHANGED = 0b0000_0100;
const BOUNDS_CHANGED = 0b0000_1000;
}
}
bitflags! {
#[repr(C)]
#[derive(Pod, Zeroable)]
pub struct EntityDebugOptions : u32 {
const PHYSICS_SHAPE_DEBUG_RENDERING_ENABLE = 0b0000_0001;
}
}
/// `min_x`/`min_y`/`width`/`height` are in World units, same as the size the text will appear in the world if you apply no scaling
#[derive(Debug, Copy, Clone, Pod, Zeroable)]
#[repr(C)]
pub struct MeasuredTextSize {
pub min_x: f32,
pub min_y: f32,
pub width: f32,
pub height: f32,
}
#[derive(Debug, Copy, Clone, Pod, Zeroable)]
#[repr(C)]
pub struct AudioClipResource {
pub handle: ResourceHandleRepr,
}
#[derive(Default, Copy, Clone, Debug, PartialEq, Pod, Zeroable)]
#[repr(C)]
pub struct DominantColorWithArea {
pub color: [u8; 4], // sRGBA vertex color
pub area: f32,
}
/// Error value that is returned from get/set entity value functions.
#[derive(Default, Copy, Clone, Debug, PartialEq)]
#[non_exhaustive]
#[repr(u32)]
pub enum EntityValueError {
/// No error occurred.
#[default]
Undefined = 0,
/// The component parameter value is a NaN value.
NanValue = 1,
/// The component parameter value is an infinite value.
InfiniteParamValue = 2,
/// The supplied component type is invalid.
InvalidComponentType = 3,
/// The supplied component parameter id is invalid.
InvalidComponentParameterId = 4,
/// The component did not exist.
InvalidComponent = 5,
/// Invalid supplied entity key
InvalidEntityKey = 6,
/// Invalid parent of parent (a parent was pointing to an invalid entity)
InvalidParentOfParent = 7,
/// Trying to set an entity value that is incompatible with the component parameter value.
IncompatibleValueType = 8,
/// Trying to set an entity value that is incompatible with the component parameter value.
IncompatibleValue = 9,
/// Could not set the entity component parameter value.
Unsettable = 10,
/// Could not get the entity component parameter value.
Ungettable = 11,
/// The component was not available.
NotAvailable = 12,
/// Trying to set an unnormalized rotation on an entity
UnnormalizedRotation = 13,
}
extern "C" {
#[deprecated(note = "use `spherecast` instead")] // since 2021-09-23
#[deprecated_infallible]
pub fn raycast(raycast: &RaycastQueryWithOptions) -> RaycastHit;
#[deprecated(note = "use `spherecast_batched` instead")] // since 2021-09-23
#[deprecated_infallible]
pub fn raycast_batched(raycasts: &[RaycastQueryWithOptions], hits: &mut [RaycastHit]);
pub fn spherecast(raycast: &SpherecastQuery) -> RaycastHit;
pub fn spherecast_batched(raycasts: &[SpherecastQuery], hits: &mut [RaycastHit]);
/// Sets the debug name of a data object (useful for debugging data memory usage and leaks etc.)
#[deprecated_infallible]
pub fn set_data_debug_name(data: DataHandle, name: &str);
pub fn get_data_debug_name(data: DataHandle) -> String;
// An empty slice will mean to apply the options to all entities in the world.
pub fn set_entity_debug_options(
entities: &[EntityHandle],
debug_options: &EntityDebugOptions,
);
pub fn set_entity_values(
entities: &[EntityHandle],
value_type: EntityValueType,
data: &[u8],
);
pub fn get_entity_values(
entities: &[EntityHandle],
value_type: EntityValueType,
out_data: &mut [u8],
);
/// Try setting an entity component parameter value.
///
/// - `entity`: The entity handle that has the component on which the value will be set.
/// - `component_type`: ([ComponentType][crate::world_v2::ComponentType]): the component that is to be updated.
/// - `component_param_id`: The component parameter id that specifies which parameter is to be updated.
/// - `new_component_value`: The new value for the component parameter. This should not contain NaN values.
/// - `out_error_info`: Error values are written to this enum field. Make sure to allocate enough memory.
///
/// This can fail if an invalid entity handle, component type, parameter id, or value was supplied.
/// Make sure the entity and component actually exist and use the right value for it.
pub fn try_set_entity_value(
entity: EntityHandle,
component_type: u64,
component_param_id: u32,
new_component_value: &Value,
out_error_info: &mut EntityValueError,
) -> FFIResult<()>;
/// Try fetching an entity component parameter value.
///
/// - `entity`: The entity handle that has the component from which the value will be fetched.
/// - `component_type` ([`crate::world_v2::ComponentType`]): the component with the field that is to be fetched.
/// - `component_param_id`: The component parameter id that specifies which parameter is to be fetched.
/// - `out_component_value`: The returned component parameter value. Make sure to allocate enough memory.
/// - `out_error_info`: Error values are written to this enum field. Make sure to allocate enough memory.
///
/// This can fail if an invalid entity handle, component type, or parameter id was supplied.
/// Make sure the entity and component actually exist.
pub fn try_get_entity_value(
entity: EntityHandle,
component_type: u64,
component_param_id: u32,
out_component_value: &mut Value,
out_error_info: &mut EntityValueError,
) -> FFIResult<()>;
/// Measure how large text will be when mesh-generated and rendered. Needed for some layout tasks in sandbox.
/// Formatting information is embedded in the text with the same encoding as is used for display, so just pass
/// the string in here.
pub fn measure_formatted_text(text: DataHandle, size: &mut MeasuredTextSize);
pub fn get_mesh_section_count(handle: MeshHandle) -> u64;
pub fn get_mesh_section_dominant_color(
handle: MeshHandle,
idx: u64,
) -> DominantColorWithArea;
pub fn get_mesh_section_material_index(handle: MeshHandle, idx: u64) -> u64;
}
}
pub use world::*;