use serde::{Deserialize, Serialize};
use crate::avatar::PointOfView;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "snake_case")]
pub enum TourMode {
#[default]
Walk,
Fly,
Teleport,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct TourWaypoint {
pub position: [f32; 3],
pub look_at: [f32; 3],
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(default)]
pub pause_duration: f32,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct TourDef {
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub waypoints: Vec<TourWaypoint>,
#[serde(default = "default_tour_speed")]
pub speed: f32,
#[serde(default)]
pub mode: TourMode,
#[serde(default)]
pub autostart: bool,
#[serde(default)]
pub loop_tour: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub pov: Option<PointOfView>,
}
fn default_tour_speed() -> f32 {
3.0
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tour_roundtrip() {
let tour = TourDef {
name: "grand_tour".to_string(),
description: Some("A scenic tour".to_string()),
waypoints: vec![
TourWaypoint {
position: [0.0, 1.0, 5.0],
look_at: [0.0, 1.5, 0.0],
description: Some("Start".to_string()),
pause_duration: 3.0,
},
TourWaypoint {
position: [10.0, 1.0, 0.0],
look_at: [5.0, 2.0, -5.0],
description: None,
pause_duration: 0.0,
},
],
speed: 2.0,
mode: TourMode::Walk,
autostart: false,
loop_tour: true,
pov: Some(PointOfView::ThirdPerson),
};
let json = serde_json::to_string_pretty(&tour).unwrap();
let back: TourDef = serde_json::from_str(&json).unwrap();
assert_eq!(tour, back);
}
#[test]
fn tour_modes() {
for mode in [TourMode::Walk, TourMode::Fly, TourMode::Teleport] {
let json = serde_json::to_string(&mode).unwrap();
let back: TourMode = serde_json::from_str(&json).unwrap();
assert_eq!(mode, back);
}
}
}