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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
pub mod archetype;
pub mod skeleton;

// Reexports
pub use self::{
    archetype::{house::House, keep::Keep, Archetype},
    skeleton::*,
};

use crate::IndexRef;
use common::{calendar::Calendar, terrain::Block};
use rand::prelude::*;
use serde::Deserialize;
use vek::*;

#[derive(Deserialize)]
pub struct Colors {
    pub archetype: archetype::Colors,
}

pub struct Building<A: Archetype> {
    skel: Skeleton<A::Attr>,
    archetype: A,
    origin: Vec3<i32>,
}

impl<A: Archetype> Building<A> {
    pub fn generate(rng: &mut impl Rng, origin: Vec3<i32>, calendar: Option<&Calendar>) -> Self
    where
        A: Sized,
    {
        let (archetype, skel) = A::generate(rng, calendar);
        Self {
            skel,
            archetype,
            origin,
        }
    }

    pub fn bounds_2d(&self) -> Aabr<i32> {
        let b = self.skel.bounds();
        Aabr {
            min: Vec2::from(self.origin) + b.min,
            max: Vec2::from(self.origin) + b.max,
        }
    }

    pub fn bounds(&self) -> Aabb<i32> {
        let aabr = self.bounds_2d();
        Aabb {
            min: Vec3::from(aabr.min) + Vec3::unit_z() * (self.origin.z - 8),
            max: Vec3::from(aabr.max) + Vec3::unit_z() * (self.origin.z + 48),
        }
    }

    pub fn sample(&self, index: IndexRef, pos: Vec3<i32>) -> Option<Block> {
        let rpos = pos - self.origin;
        self.skel
            .sample_closest(
                rpos,
                |pos, dist, bound_offset, center_offset, ori, branch| {
                    self.archetype.draw(
                        index,
                        pos,
                        dist,
                        bound_offset,
                        center_offset,
                        rpos.z,
                        ori,
                        branch.locus,
                        branch.len,
                        &branch.attr,
                    )
                },
            )
            .finish()
    }
}