semantic-scene 0.1.0

Rust parser for Habitat-Sim `SemanticScene` descriptors.
Documentation
//! Semantic level model.

use std::fmt;

use crate::{Aabb, Vec3};

/// Represents a level of a semantic scene.
///
/// This follows Habitat-Sim's `SemanticLevel`: a level owns lists of regions
/// and objects and exposes its id and axis-aligned bounding box.
#[derive(Debug, Clone, PartialEq)]
pub struct SemanticLevel {
    index: i32,
    label: String,
    position: Vec3,
    aabb: Aabb,
    region_indices: Vec<usize>,
    object_indices: Vec<usize>,
}

impl SemanticLevel {
    #[must_use]
    pub(crate) const fn new(index: i32, label: String, position: Vec3, aabb: Aabb) -> Self {
        Self {
            index,
            label,
            position,
            aabb,
            region_indices: Vec::new(),
            object_indices: Vec::new(),
        }
    }

    /// Returns this level's id.
    ///
    /// Habitat-Sim represents level ids as the source index converted to a
    /// string.
    #[must_use]
    pub fn id(&self) -> String {
        self.index.to_string()
    }

    /// Returns the source descriptor index.
    #[must_use]
    pub const fn index(&self) -> i32 {
        self.index
    }

    /// Returns the source descriptor label code.
    #[must_use]
    pub fn label(&self) -> &str {
        &self.label
    }

    /// Returns the level position from the source descriptor.
    #[must_use]
    pub const fn position(&self) -> Vec3 {
        self.position
    }

    /// Returns the level axis-aligned bounding box.
    #[must_use]
    pub const fn aabb(&self) -> &Aabb {
        &self.aabb
    }

    /// Returns indices of regions contained by this level.
    #[must_use]
    pub fn region_indices(&self) -> &[usize] {
        &self.region_indices
    }

    /// Returns indices of objects contained by this level.
    #[must_use]
    pub fn object_indices(&self) -> &[usize] {
        &self.object_indices
    }

    pub(crate) fn add_region(&mut self, region_index: usize) {
        self.region_indices.push(region_index);
    }

    pub(crate) fn add_object(&mut self, object_index: usize) {
        self.object_indices.push(object_index);
    }
}

impl fmt::Display for SemanticLevel {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            formatter,
            "level {}: regions={}, objects={}, bounds=[{}]",
            self.index,
            self.region_indices.len(),
            self.object_indices.len(),
            self.aabb
        )
    }
}