Commits

Sebastien Mondet committed 9710c2c

webpdb: implement drag-based-rotation interaction

Comments (0)

Files changed (1)

     let last_draw = ref (get_time ()) in
     let draw_times = Queue.create () in
     let renderer = { gl; render = (fun () -> ()); prog} in
-    let interaction_mode = ref (`turning 0.) in
+
+    let interaction_mat = ref mat in
+    let interaction_mode = ref (`turning 0.1) in
     canvas##ondblclick <- Dom_html.handler (fun click_ev ->
         begin match !interaction_mode with
-        | `turning f ->
-          interaction_mode := `stopped f;
-        | `stopped f ->
-          interaction_mode := `turning f;
+        | `turning _ | `dragging _ ->
+          (* we use the double-click to stop everything (panic button) *)
+          interaction_mode := `stopped;
+        | `stopped ->
+          interaction_mode := `turning 0.1;
         end;
         Js._true
       );
+    (* Disable drag-and-drop on the canvas: *)
+    canvas##ondragstart <- Dom_html.handler (fun _ -> Js._false);
+    canvas##ondrop <- Dom_html.handler (fun _ -> Js._false);
+
+    canvas##onmousedown <- Dom_html.handler (fun click_ev ->
+        interaction_mode := `dragging (!interaction_mode,
+                                       click_ev##clientX,
+                                       click_ev##clientY,
+                                       click_ev##clientX,
+                                       click_ev##clientY);
+        Js._true
+      );
+    canvas##onmouseup <- Dom_html.handler (fun click_ev ->
+        begin match !interaction_mode with
+        | `dragging (previous, _, _, _, _) ->
+          interaction_mode := previous
+        | _ -> ()
+        end;
+        Js._true);
+    canvas##onmousemove <- Dom_html.handler (fun click_ev ->
+        begin match !interaction_mode with
+        | `dragging (previous, px, py, nx, ny) ->
+          interaction_mode := `dragging (previous,
+                                         px, py,
+                                         click_ev##clientX,
+                                         click_ev##clientY);
+        | _ -> ()
+        end;
+        Js._true);
 
     let rec f () =
       begin match !interaction_mode with
       | `turning f ->
-        let mat' = Proj3D.mult mat (Proj3D.rotate_y (f)) in
-        gl##uniformMatrix4fv_typed(proj_loc, _false, Proj3D.array mat');
-        interaction_mode := `turning (f +. 0.1)
-      | `stopped _ -> ()
+        interaction_mat := Proj3D.mult !interaction_mat (Proj3D.rotate_y (f));
+      | `dragging (previous, px, py, nx, ny) ->
+        let rot = Proj3D.(
+            mult
+              (rotate_x (float_of_int (py - ny) *. 0.01))
+              (rotate_y (float_of_int (px - nx) *. 0.01))
+          ) in
+        debug "rot y : %f" (float_of_int (ny - py) *. 0.01);
+        debug "rot x : %f" (float_of_int (nx - px) *. 0.01);
+        interaction_mat := Proj3D.mult !interaction_mat rot;
+        interaction_mode := `dragging (previous,
+                                       nx, ny,
+                                       nx, ny);
+      | _ -> ()
       end;
+      gl##uniformMatrix4fv_typed(proj_loc, _false,
+                                 Proj3D.array !interaction_mat);
 
       gl##clear(gl##_DEPTH_BUFFER_BIT_ lor gl##_COLOR_BUFFER_BIT_);
       renderer.render ();