Skip to main content

oxihuman_viewer/
object_motion_path_view.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5//! Object motion path overlay view.
6
7/// Motion path display settings.
8#[derive(Debug, Clone)]
9pub struct ObjectMotionPathView {
10    pub enabled: bool,
11    pub frame_start: i32,
12    pub frame_end: i32,
13    pub show_frame_numbers: bool,
14    pub line_width: f32,
15}
16
17impl Default for ObjectMotionPathView {
18    fn default() -> Self {
19        Self {
20            enabled: false,
21            frame_start: 0,
22            frame_end: 100,
23            show_frame_numbers: false,
24            line_width: 1.0,
25        }
26    }
27}
28
29/// Create a new ObjectMotionPathView.
30pub fn new_object_motion_path_view() -> ObjectMotionPathView {
31    ObjectMotionPathView::default()
32}
33
34/// Set the frame range for the path display.
35pub fn motion_path_set_range(view: &mut ObjectMotionPathView, start: i32, end: i32) {
36    view.frame_start = start;
37    view.frame_end = end.max(start);
38}
39
40/// Enable or disable path overlay.
41pub fn motion_path_set_enabled(view: &mut ObjectMotionPathView, enabled: bool) {
42    view.enabled = enabled;
43}
44
45/// Toggle frame number labels.
46pub fn motion_path_show_frames(view: &mut ObjectMotionPathView, show: bool) {
47    view.show_frame_numbers = show;
48}
49
50/// Set line width for path rendering.
51pub fn motion_path_set_line_width(view: &mut ObjectMotionPathView, w: f32) {
52    view.line_width = w.clamp(0.5, 10.0);
53}
54
55/// Compute frame count in range.
56pub fn motion_path_frame_count(view: &ObjectMotionPathView) -> u32 {
57    (view.frame_end - view.frame_start).max(0) as u32
58}
59
60/// Serialize to JSON.
61pub fn object_motion_path_to_json(view: &ObjectMotionPathView) -> String {
62    format!(
63        r#"{{"enabled":{},"start":{},"end":{},"show_frames":{},"line_width":{}}}"#,
64        view.enabled, view.frame_start, view.frame_end, view.show_frame_numbers, view.line_width,
65    )
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn test_new() {
74        let v = new_object_motion_path_view();
75        assert!(!v.enabled /* disabled by default */);
76    }
77
78    #[test]
79    fn test_set_range() {
80        let mut v = new_object_motion_path_view();
81        motion_path_set_range(&mut v, 10, 50);
82        assert_eq!(v.frame_start, 10 /* stored */);
83        assert_eq!(v.frame_end, 50 /* stored */);
84    }
85
86    #[test]
87    fn test_range_end_min() {
88        let mut v = new_object_motion_path_view();
89        motion_path_set_range(&mut v, 50, 10);
90        assert_eq!(v.frame_end, 50 /* end >= start */);
91    }
92
93    #[test]
94    fn test_enable() {
95        let mut v = new_object_motion_path_view();
96        motion_path_set_enabled(&mut v, true);
97        assert!(v.enabled /* enabled */);
98    }
99
100    #[test]
101    fn test_show_frames() {
102        let mut v = new_object_motion_path_view();
103        motion_path_show_frames(&mut v, true);
104        assert!(v.show_frame_numbers /* enabled */);
105    }
106
107    #[test]
108    fn test_line_width_clamp() {
109        let mut v = new_object_motion_path_view();
110        motion_path_set_line_width(&mut v, 20.0);
111        assert!((v.line_width - 10.0).abs() < 1e-6 /* clamped */);
112    }
113
114    #[test]
115    fn test_frame_count() {
116        let mut v = new_object_motion_path_view();
117        motion_path_set_range(&mut v, 0, 100);
118        assert_eq!(motion_path_frame_count(&v), 100 /* 100 frames */);
119    }
120
121    #[test]
122    fn test_frame_count_inverted() {
123        let mut v = new_object_motion_path_view();
124        v.frame_start = 100;
125        v.frame_end = 50;
126        assert_eq!(motion_path_frame_count(&v), 0 /* inverted = 0 */);
127    }
128
129    #[test]
130    fn test_json_keys() {
131        let v = new_object_motion_path_view();
132        let j = object_motion_path_to_json(&v);
133        assert!(j.contains("enabled") /* key */);
134    }
135}