concinnity_core/components/
camera3d.rs1use concinnity_asset::cook;
7
8use crate::components::CameraController;
9use crate::ecs::Component;
10
11#[derive(Debug, serde::Serialize, serde::Deserialize)]
13pub struct Camera3D {
14 pub fov_y_degrees: f32,
16 pub near: f32,
18 pub far: f32,
20 pub view_matrix: [[f32; 4]; 4],
23 pub position: [f32; 3],
25 pub yaw: f32,
27 pub pitch: f32,
29 pub desired_move: [f32; 3],
32 pub jump_requested: bool,
34 pub interact_requested: bool,
36 pub controller: Option<CameraController>,
39}
40
41impl Camera3D {
42 pub fn bake(args: cook::Camera3D) -> Self {
46 Self {
47 fov_y_degrees: args.fov_y_degrees,
48 near: args.near,
49 far: args.far,
50 view_matrix: crate::gfx::camera::view_matrix(args.position, args.yaw, args.pitch),
51 position: args.position,
52 yaw: args.yaw,
53 pitch: args.pitch,
54 desired_move: [0.0; 3],
55 jump_requested: false,
56 interact_requested: false,
57 controller: args.controller,
58 }
59 }
60}
61
62impl Component for Camera3D {
63 const NAME: &'static str = "Camera3D";
64
65 fn from_baked(bytes: &[u8]) -> Result<Self, crate::result::CnResult> {
66 Ok(crate::blob::decode_exact(bytes)?)
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use crate::components::FollowDrive;
74 use crate::ecs::SkinnedMeshHandle;
75
76 #[test]
77 fn follow_block_deserializes_names_and_defaults() {
78 crate::test_support::reset_interner();
79 crate::test_support::intern_all(&["hero"]);
80 let args: cook::Camera3D = serde_json::from_value(serde_json::json!({
81 "controller": {"follow": {"target": "hero", "drive": "direct"}}
82 }))
83 .unwrap();
84 let follow = args.controller.unwrap().follow.unwrap();
85 assert_eq!(follow.target, Some(SkinnedMeshHandle(0)));
88 assert_eq!(follow.drive, FollowDrive::Direct);
89 assert_eq!(follow.speed_parameter, "speed");
91 assert!((follow.distance - 4.0).abs() < 1e-6);
92 assert!((follow.height - 1.5).abs() < 1e-6);
93 assert_eq!(follow.jump_height, 0.0);
94
95 let bare: cook::Camera3D =
97 serde_json::from_value(serde_json::json!({"controller": {}})).unwrap();
98 assert!(bare.controller.unwrap().follow.is_none());
99 }
100}