Skip to main content

semantic_scene/scene/
object.rs

1//! Semantic object model.
2
3use std::fmt;
4
5use crate::{Aabb, Obb, SemanticScene};
6
7/// Represents a distinct semantically annotated object.
8///
9/// The source index is also the object's semantic id, matching Habitat-Sim's
10/// `SemanticObject::semanticID()`.
11#[derive(Debug, Clone, PartialEq)]
12pub struct SemanticObject {
13    index: i32,
14    region_index: Option<usize>,
15    category_index: Option<usize>,
16    obb: Obb,
17}
18
19impl SemanticObject {
20    #[must_use]
21    pub(crate) const fn new(
22        index: i32,
23        region_index: Option<usize>,
24        category_index: Option<usize>,
25        obb: Obb,
26    ) -> Self {
27        Self {
28            index,
29            region_index,
30            category_index,
31            obb,
32        }
33    }
34
35    /// Returns the Habitat-Sim-style object id.
36    ///
37    /// If the object has a parent region, the form is
38    /// `<level_id>_<region_id>_<object_id>`. Otherwise, the form is
39    /// `_<object_id>`.
40    #[must_use]
41    pub fn id(&self, scene: &SemanticScene) -> String {
42        self.region_index.map_or_else(
43            || format!("_{}", self.index),
44            |region_index| format!("{}_{}", scene.regions()[region_index].id(scene), self.index),
45        )
46    }
47
48    /// Returns the source descriptor index.
49    #[must_use]
50    pub const fn index(&self) -> i32 {
51        self.index
52    }
53
54    /// Returns the unique semantic id corresponding to this object.
55    #[must_use]
56    pub const fn semantic_id(&self) -> i32 {
57        self.index
58    }
59
60    /// Returns the index of this object's parent region in `SemanticScene::regions`.
61    #[must_use]
62    pub const fn region_index(&self) -> Option<usize> {
63        self.region_index
64    }
65
66    /// Returns the index of this object's category in `SemanticScene::categories`.
67    #[must_use]
68    pub const fn category_index(&self) -> Option<usize> {
69        self.category_index
70    }
71
72    /// Returns the axis-aligned bounding box enclosing this object.
73    #[must_use]
74    pub fn aabb(&self) -> Aabb {
75        self.obb.to_aabb()
76    }
77
78    /// Returns the object's oriented bounding box.
79    #[must_use]
80    pub const fn obb(&self) -> &Obb {
81        &self.obb
82    }
83}
84
85impl fmt::Display for SemanticObject {
86    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
87        let region = self
88            .region_index
89            .map_or_else(|| "none".to_string(), |index| index.to_string());
90        let category = self
91            .category_index
92            .map_or_else(|| "none".to_string(), |index| index.to_string());
93        write!(
94            formatter,
95            "object {}: region={}, category={}, {}",
96            self.index, region, category, self.obb
97        )
98    }
99}