11use cgmath:: * ;
2- #[ cfg( target_arch = "wasm32" ) ]
3- use web_time:: Duration ;
42use num_traits:: Float ;
53use std:: f32:: consts:: PI ;
64#[ cfg( not( target_arch = "wasm32" ) ) ]
75use std:: time:: Duration ;
6+ #[ cfg( target_arch = "wasm32" ) ]
7+ use web_time:: Duration ;
88
99use winit:: keyboard:: KeyCode ;
1010
1111use crate :: camera:: PerspectiveCamera ;
1212
13+ #[ derive( Debug , Clone ) ]
14+ pub struct TouchState {
15+ pub touches : Vec < Touch > ,
16+ pub last_touch_count : usize ,
17+ pub last_pinch_distance : Option < f32 > ,
18+ pub last_touch_center : Option < ( f32 , f32 ) > ,
19+ }
20+
21+ #[ derive( Debug , Clone ) ]
22+ pub struct Touch {
23+ pub id : u64 ,
24+ pub position : ( f32 , f32 ) ,
25+ pub phase : TouchPhase ,
26+ }
27+
28+ #[ derive( Debug , Clone , Copy , PartialEq ) ]
29+ pub enum TouchPhase {
30+ Started ,
31+ Moved ,
32+ Ended ,
33+ Cancelled ,
34+ }
35+
36+ impl TouchState {
37+ pub fn new ( ) -> Self {
38+ Self {
39+ touches : Vec :: new ( ) ,
40+ last_touch_count : 0 ,
41+ last_pinch_distance : None ,
42+ last_touch_center : None ,
43+ }
44+ }
45+ }
46+
1347#[ derive( Debug ) ]
1448pub struct CameraController {
1549 pub center : Point3 < f32 > ,
@@ -25,6 +59,9 @@ pub struct CameraController {
2559 pub right_mouse_pressed : bool ,
2660 pub alt_pressed : bool ,
2761 pub user_inptut : bool ,
62+
63+ // Touch support
64+ pub touch_state : TouchState ,
2865}
2966
3067impl CameraController {
@@ -42,6 +79,7 @@ impl CameraController {
4279 right_mouse_pressed : false ,
4380 alt_pressed : false ,
4481 user_inptut : false ,
82+ touch_state : TouchState :: new ( ) ,
4583 }
4684 }
4785
@@ -104,6 +142,98 @@ impl CameraController {
104142 self . user_inptut = true ;
105143 }
106144
145+ pub fn process_touch ( & mut self , touch : Touch ) {
146+ // Update touch state
147+ match touch. phase {
148+ TouchPhase :: Started => {
149+ self . touch_state . touches . push ( touch) ;
150+ }
151+ TouchPhase :: Moved => {
152+ if let Some ( existing_touch) = self
153+ . touch_state
154+ . touches
155+ . iter_mut ( )
156+ . find ( |t| t. id == touch. id )
157+ {
158+ existing_touch. position = touch. position ;
159+ }
160+ }
161+ TouchPhase :: Ended | TouchPhase :: Cancelled => {
162+ self . touch_state . touches . retain ( |t| t. id != touch. id ) ;
163+ }
164+ }
165+
166+ self . handle_touch_gestures ( ) ;
167+ self . user_inptut = true ;
168+ }
169+
170+ fn handle_touch_gestures ( & mut self ) {
171+ let touch_count = self . touch_state . touches . len ( ) ;
172+
173+ match touch_count {
174+ 1 => {
175+ // Single touch - camera rotation
176+ let touch = & self . touch_state . touches [ 0 ] ;
177+ if let Some ( last_center) = self . touch_state . last_touch_center {
178+ let dx = touch. position . 0 - last_center. 0 ;
179+ let dy = touch. position . 1 - last_center. 1 ;
180+
181+ // Scale the touch movement similar to mouse movement but with better mobile sensitivity
182+ self . rotation . x += dx * 0.3 ; // Reduced sensitivity for more precise control
183+ self . rotation . y += dy * 0.3 ;
184+ }
185+ self . touch_state . last_touch_center = Some ( touch. position ) ;
186+ }
187+ 2 => {
188+ // Two touches - pinch to zoom and pan
189+ let touch1 = & self . touch_state . touches [ 0 ] ;
190+ let touch2 = & self . touch_state . touches [ 1 ] ;
191+
192+ let center_x = ( touch1. position . 0 + touch2. position . 0 ) / 2.0 ;
193+ let center_y = ( touch1. position . 1 + touch2. position . 1 ) / 2.0 ;
194+ let current_center = ( center_x, center_y) ;
195+
196+ // Calculate distance for pinch gesture
197+ let dx = touch2. position . 0 - touch1. position . 0 ;
198+ let dy = touch2. position . 1 - touch1. position . 1 ;
199+ let current_distance = ( dx * dx + dy * dy) . sqrt ( ) ;
200+
201+ if let Some ( last_distance) = self . touch_state . last_pinch_distance {
202+ // Pinch to zoom with improved sensitivity
203+ let distance_change = current_distance - last_distance;
204+ let zoom_factor = distance_change * 0.005 ; // Adjusted for better mobile zoom control
205+ self . scroll += zoom_factor;
206+ }
207+
208+ if let Some ( last_center) = self . touch_state . last_touch_center {
209+ // Pan with two fingers - improved sensitivity for mobile
210+ let center_dx = current_center. 0 - last_center. 0 ;
211+ let center_dy = current_center. 1 - last_center. 1 ;
212+
213+ self . shift . y += -center_dx * 0.3 ; // Reduced sensitivity for more precise panning
214+ self . shift . x += center_dy * 0.3 ;
215+ }
216+
217+ self . touch_state . last_pinch_distance = Some ( current_distance) ;
218+ self . touch_state . last_touch_center = Some ( current_center) ;
219+ }
220+ _ => {
221+ // No touches or more than 2 touches - reset state
222+ self . touch_state . last_pinch_distance = None ;
223+ self . touch_state . last_touch_center = None ;
224+ }
225+ }
226+
227+ self . touch_state . last_touch_count = touch_count;
228+ }
229+
230+ pub fn clear_touch_state ( & mut self ) {
231+ self . touch_state . touches . clear ( ) ;
232+ self . touch_state . last_touch_count = 0 ;
233+ self . touch_state . last_pinch_distance = None ;
234+ self . touch_state . last_touch_center = None ;
235+ }
236+
107237 /// moves the controller center to the closest point on a line defined by the camera position and rotation
108238 /// ajusts the controller up vector by projecting the current up vector onto the plane defined by the camera right vector
109239 pub fn reset_to_camera ( & mut self , camera : PerspectiveCamera ) {
0 commit comments