Skip to main content

pfx_scene/types/
mod.rs

1mod either;
2mod finish;
3mod material;
4mod scene;
5mod sky;
6mod tunable;
7
8use std::collections::BTreeMap;
9
10use serde::{Deserialize, Serialize};
11
12pub use either::Color;
13pub use finish::{
14    Bloom, BloomKind, BloomTable, Dither, DitherKind, Finish, FinishKeys, Grain, GrainTable, Ink,
15    Lut, Outline, OutlineTable, STYLES, Scratches, ScratchesTable, Style, Tape, TapeDirection,
16    TapeTable, Tone, ToneKind, ToneTable, Vignette, VignetteKind, VignetteTable, Warmth,
17    WarmthKind, WarmthTable,
18};
19pub use material::{
20    Ageing, Blend, Content as ContentKind, ContentLayer, Family, LAYER_CAP, Maps, Material,
21    NoiseKind, NoiseLayer, Normal, NormalSource, PARAMS,
22};
23pub use scene::{
24    Animation, BlendClip, Body, BodyKind, BodyShape, Bounds, Camera, Casters, CellSize, Character,
25    CharacterKind, ClipEvent, Content, Cue, Depth, Emitter, Haze, Hush, Light, Look, Mesh, Motion,
26    Mover, MoverKind, Node, Nudge, Object, Orbit, Physics, Plane, Plates, Preset, Projection,
27    Proxy, ProxyKind, Repeat, Rig, RigKind, Scale, Shadow, Sound, SpriteClip, Sun, SunModel, Text,
28    TileCell, TilePlane, Tiles, Trace, Trigger, Wander, Zoom,
29};
30pub use sky::{Prepare, Room, RoomLamp, Sky, SkyKind};
31pub use tunable::{Tunable, TunableKind, TunableValue};
32
33pub const FORMAT: u32 = 1;
34
35pub const LAYER_COUNT: usize = 32;
36
37pub(crate) fn is_false(value: &bool) -> bool {
38    !*value
39}
40
41pub(crate) fn is_zero3(value: &[f32; 3]) -> bool {
42    *value == [0.0; 3]
43}
44
45#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
46#[serde(deny_unknown_fields)]
47pub struct ProjectFile {
48    #[serde(default, skip_serializing_if = "Option::is_none")]
49    pub format: Option<u32>,
50    pub project: ProjectTable,
51    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
52    pub tunables: BTreeMap<String, Tunable>,
53    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
54    pub layers: BTreeMap<String, Vec<String>>,
55    #[serde(default, skip_serializing_if = "Option::is_none")]
56    pub authoring: Option<toml::Table>,
57}
58
59#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
60#[serde(deny_unknown_fields)]
61pub struct ProjectTable {
62    pub name: String,
63    #[serde(default, skip_serializing_if = "Option::is_none")]
64    pub scene: Option<String>,
65    #[serde(default, skip_serializing_if = "Vec::is_empty")]
66    pub ignore: Vec<String>,
67}
68
69#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
70#[serde(deny_unknown_fields)]
71pub struct SceneFile {
72    #[serde(default, skip_serializing_if = "Option::is_none")]
73    pub format: Option<u32>,
74    #[serde(default, skip_serializing_if = "Vec::is_empty")]
75    pub include: Vec<String>,
76    #[serde(default, skip_serializing_if = "Vec::is_empty")]
77    pub materials: Vec<String>,
78    #[serde(default, skip_serializing_if = "Option::is_none")]
79    pub fallback: Option<String>,
80    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
81    pub mesh: BTreeMap<String, Mesh>,
82    #[serde(default, skip_serializing_if = "Vec::is_empty")]
83    pub object: Vec<Object>,
84    #[serde(default, skip_serializing_if = "Vec::is_empty")]
85    pub light: Vec<Light>,
86    #[serde(default, skip_serializing_if = "Vec::is_empty")]
87    pub emitter: Vec<Emitter>,
88    #[serde(default, skip_serializing_if = "Vec::is_empty")]
89    pub mover: Vec<Mover>,
90    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
91    pub content: BTreeMap<String, Content>,
92    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
93    pub text: BTreeMap<String, Text>,
94    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
95    pub sound: BTreeMap<String, Sound>,
96    #[serde(default, skip_serializing_if = "Vec::is_empty")]
97    pub rig: Vec<Rig>,
98    #[serde(default, skip_serializing_if = "Vec::is_empty")]
99    pub tiles: Vec<Tiles>,
100    #[serde(default, skip_serializing_if = "Option::is_none")]
101    pub sun: Option<Sun>,
102    #[serde(default, skip_serializing_if = "Option::is_none")]
103    pub sky: Option<Sky>,
104    #[serde(default, skip_serializing_if = "Option::is_none")]
105    pub haze: Option<Haze>,
106    #[serde(default, skip_serializing_if = "Option::is_none")]
107    pub camera: Option<Camera>,
108    #[serde(default, skip_serializing_if = "Option::is_none")]
109    pub finish: Option<Finish>,
110    #[serde(default, skip_serializing_if = "Option::is_none")]
111    pub trace: Option<Trace>,
112    #[serde(default, skip_serializing_if = "Option::is_none")]
113    pub plates: Option<Plates>,
114    #[serde(default, skip_serializing_if = "Option::is_none")]
115    pub physics: Option<Physics>,
116    #[serde(default, skip_serializing_if = "Option::is_none")]
117    pub authoring: Option<toml::Table>,
118}
119
120#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
121#[serde(deny_unknown_fields)]
122pub struct PrefabFile {
123    #[serde(default, skip_serializing_if = "Option::is_none")]
124    pub format: Option<u32>,
125    #[serde(default, skip_serializing_if = "Vec::is_empty")]
126    pub include: Vec<String>,
127    #[serde(default, skip_serializing_if = "Vec::is_empty")]
128    pub materials: Vec<String>,
129    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
130    pub mesh: BTreeMap<String, Mesh>,
131    #[serde(default, skip_serializing_if = "Vec::is_empty")]
132    pub object: Vec<Object>,
133    #[serde(default, skip_serializing_if = "Vec::is_empty")]
134    pub light: Vec<Light>,
135    #[serde(default, skip_serializing_if = "Vec::is_empty")]
136    pub emitter: Vec<Emitter>,
137    #[serde(default, skip_serializing_if = "Vec::is_empty")]
138    pub mover: Vec<Mover>,
139    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
140    pub content: BTreeMap<String, Content>,
141    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
142    pub text: BTreeMap<String, Text>,
143    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
144    pub sound: BTreeMap<String, Sound>,
145    #[serde(default, skip_serializing_if = "Vec::is_empty")]
146    pub rig: Vec<Rig>,
147    #[serde(default, skip_serializing_if = "Option::is_none")]
148    pub authoring: Option<toml::Table>,
149}
150
151#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
152#[serde(deny_unknown_fields)]
153pub struct MaterialsFile {
154    #[serde(default, skip_serializing_if = "Option::is_none")]
155    pub format: Option<u32>,
156    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
157    pub materials: BTreeMap<String, Material>,
158    #[serde(default, skip_serializing_if = "Option::is_none")]
159    pub authoring: Option<toml::Table>,
160}
161
162#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
163#[serde(deny_unknown_fields)]
164pub struct ProxiesFile {
165    #[serde(default, skip_serializing_if = "Option::is_none")]
166    pub format: Option<u32>,
167    #[serde(default, skip_serializing_if = "Vec::is_empty")]
168    pub proxy: Vec<Proxy>,
169    #[serde(default, skip_serializing_if = "Option::is_none")]
170    pub authoring: Option<toml::Table>,
171}
172
173#[allow(clippy::large_enum_variant)]
174#[derive(Clone, Debug, PartialEq)]
175pub enum File {
176    Project(ProjectFile),
177    Scene(SceneFile),
178    Prefab(PrefabFile),
179    Materials(MaterialsFile),
180    Proxies(ProxiesFile),
181    Finish(FinishKeys),
182}
183
184#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
185pub enum FileKind {
186    Project,
187    Scene,
188    Prefab,
189    Materials,
190    Proxies,
191    Finish,
192}
193
194impl FileKind {
195    pub fn of(path: &std::path::Path) -> Option<Self> {
196        let name = path.file_name()?.to_str()?;
197        if name == "project.toml" {
198            Some(Self::Project)
199        } else if name.ends_with(".scene.toml") || name == "scene.toml" {
200            Some(Self::Scene)
201        } else if name.ends_with(".prefab.toml") {
202            Some(Self::Prefab)
203        } else if name.ends_with(".materials.toml") {
204            Some(Self::Materials)
205        } else if name.ends_with(".proxies.toml") {
206            Some(Self::Proxies)
207        } else {
208            None
209        }
210    }
211
212    pub fn name(self) -> &'static str {
213        match self {
214            Self::Project => "project file",
215            Self::Scene => "scene",
216            Self::Prefab => "prefab",
217            Self::Materials => "material library",
218            Self::Proxies => "proxies file",
219            Self::Finish => "finish file",
220        }
221    }
222}