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}