Skip to main content

rakata_generics/git/
camera.rs

1//! Static camera entries in a GIT.
2
3use rakata_formats::{
4    gff_schema::{AbsentDefault, FieldLife, FieldSchema, GffType},
5    GffStruct, GffValue,
6};
7
8use crate::gff_helpers::{get_f32, get_i32, upsert_field};
9
10/// A static camera entry in the area.
11///
12/// `Position` is a GFF Vector3 and `Orientation` is a GFF Quaternion (Vector4).
13#[derive(Debug, Clone, PartialEq, Default)]
14pub struct GitCamera {
15    /// Camera ID (`CameraID`).
16    pub camera_id: i32,
17    /// Position as GFF Vector3 (`Position`).
18    pub position: [f32; 3],
19    /// Orientation as GFF Quaternion (`Orientation`).
20    pub orientation: [f32; 4],
21    /// Pitch angle (`Pitch`).
22    pub pitch: f32,
23    /// Height offset (`Height`).
24    pub height: f32,
25    /// Field of view (`FieldOfView`, engine default 55.0).
26    pub field_of_view: f32,
27    /// Microphone range (`MicRange`).
28    pub mic_range: f32,
29}
30
31impl GitCamera {
32    pub(crate) fn from_gff_struct(s: &GffStruct) -> Self {
33        let position = match s.field("Position") {
34            Some(GffValue::Vector3(v)) => *v,
35            _ => [0.0, 0.0, 0.0],
36        };
37        let orientation = match s.field("Orientation") {
38            Some(GffValue::Vector4(v)) => *v,
39            _ => [0.0, 0.0, 0.0, 1.0],
40        };
41
42        Self {
43            camera_id: get_i32(s, "CameraID").unwrap_or(-1),
44            position,
45            orientation,
46            pitch: get_f32(s, "Pitch").unwrap_or(0.0),
47            height: get_f32(s, "Height").unwrap_or(0.0),
48            field_of_view: get_f32(s, "FieldOfView").unwrap_or(55.0),
49            mic_range: get_f32(s, "MicRange").unwrap_or(0.0),
50        }
51    }
52
53    pub(crate) fn to_gff_struct(&self) -> GffStruct {
54        let mut s = GffStruct::new(0);
55        upsert_field(&mut s, "CameraID", GffValue::Int32(self.camera_id));
56        upsert_field(&mut s, "Position", GffValue::Vector3(self.position));
57        upsert_field(&mut s, "Orientation", GffValue::Vector4(self.orientation));
58        upsert_field(&mut s, "Pitch", GffValue::Single(self.pitch));
59        upsert_field(&mut s, "Height", GffValue::Single(self.height));
60        upsert_field(&mut s, "FieldOfView", GffValue::Single(self.field_of_view));
61        upsert_field(&mut s, "MicRange", GffValue::Single(self.mic_range));
62        s
63    }
64}
65
66/// GIT `CameraList` entry child schema. Client-side only. Max 50 entries.
67pub(crate) static CAMERA_LIST_CHILDREN: &[FieldSchema] = &[
68    FieldSchema {
69        label: "CameraID",
70        expected_type: GffType::Int32,
71        life: FieldLife::Live,
72        required: false,
73        absent: AbsentDefault::Unverified,
74        children: None,
75        constraint: None,
76    },
77    FieldSchema {
78        label: "Position",
79        expected_type: GffType::Vector3,
80        life: FieldLife::Live,
81        required: false,
82        absent: AbsentDefault::Unverified,
83        children: None,
84        constraint: None,
85    },
86    FieldSchema {
87        label: "Orientation",
88        expected_type: GffType::Vector4,
89        life: FieldLife::Live,
90        required: false,
91        absent: AbsentDefault::Unverified,
92        children: None,
93        constraint: None,
94    },
95    FieldSchema {
96        label: "Pitch",
97        expected_type: GffType::Single,
98        life: FieldLife::Live,
99        required: false,
100        absent: AbsentDefault::Unverified,
101        children: None,
102        constraint: None,
103    },
104    FieldSchema {
105        label: "Height",
106        expected_type: GffType::Single,
107        life: FieldLife::Live,
108        required: false,
109        absent: AbsentDefault::Unverified,
110        children: None,
111        constraint: None,
112    },
113    FieldSchema {
114        label: "FieldOfView",
115        expected_type: GffType::Single,
116        life: FieldLife::Live,
117        required: false,
118        absent: AbsentDefault::Unverified,
119        children: None,
120        constraint: None,
121    },
122    FieldSchema {
123        label: "MicRange",
124        expected_type: GffType::Single,
125        life: FieldLife::Live,
126        required: false,
127        absent: AbsentDefault::Unverified,
128        children: None,
129        constraint: None,
130    },
131];