aboutsummaryrefslogtreecommitdiff
path: root/src/world/room.rs
blob: fed889087ce4d8771ee71fb20755f2ca08242c25 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//! Polygon rooms are the standard rooms in graf karto. They can take the form of anything that a
//! [Polygon](crate::math::Polygon) can have.

use super::Component;
use crate::math::{Polygon, Rect};
use crate::transformable::NonRigidTransformable;
use nalgebra::{Matrix3, Point2};
use serde::{Deserialize, Serialize};

/// A polygon shaped room, which can be placed and modified in the world.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Room {
    shape: Polygon<f64>,
}

impl Room {
    /// Create a new room with the given shape.
    pub fn new(shape: Polygon<f64>) -> Self {
        Self { shape }
    }

    /// Get the polygon this room is based on.
    pub fn shape(&self) -> &Polygon<f64> {
        &self.shape
    }
}

impl Component for Room {
    fn bounding_rect(&self) -> Rect<f64> {
        Rect::bounding_rect_n(&self.shape.corners())
    }

    fn as_non_rigid(&self) -> Option<&dyn NonRigidTransformable> {
        Some(self as &dyn NonRigidTransformable)
    }

    fn as_non_rigid_mut(&mut self) -> Option<&mut dyn NonRigidTransformable> {
        Some(self as &mut dyn NonRigidTransformable)
    }
}

impl NonRigidTransformable for Room {
    // XXX: This produces undefined behaviour when using a mirroring matrix, since
    // the polygon corners must be sorted in counterclockwise direction.
    fn apply_matrix(&mut self, matrix: &Matrix3<f64>) {
        for corner in self.shape.corners_mut() {
            *corner = matrix
                .transform_point(&Point2::new(corner.x, corner.y))
                .into();
        }
    }
}