gamnit: intro `camera_control` an abstraction of `accept_two_fingers_motion`
[nit.git] / lib / gamnit / android_two_fingers_motion.nit
diff --git a/lib/gamnit/android_two_fingers_motion.nit b/lib/gamnit/android_two_fingers_motion.nit
deleted file mode 100644 (file)
index b8329ef..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Two fingers camera manipulation, scroll and pinch to zoom
-#
-# Provides the main service `EulerCamera::accept_two_fingers_motion`.
-module android_two_fingers_motion
-
-# TODO add an abstraction when another platform supports it
-
-import gamnit
-import cameras
-import android
-
-redef class EulerCamera
-       # Smoothened history of pointers in the current motion event
-       private var last_motion_pointers = new HashMap[Int, Point[Float]] is lazy
-
-       # Start time of the current motion event
-       private var last_motion_start: Int = -1
-
-       # Move and zoom (set `position`) from a two finger pinch and slide option
-       #
-       # Returns `true` if the event is intercepted.
-       #
-       # Should be called from `App::accept_event` before accepting pointer events:
-       #
-       # ~~~nitish
-       # redef class App
-       #     redef fun accept_event(event)
-       #     do
-       #         if world_camera.accept_two_fingers_motion(event) then return true
-       #
-       #         # Handle other events...
-       #     end
-       # end
-       # ~~~
-       fun accept_two_fingers_motion(event: InputEvent): Bool
-       do
-               if not event isa AndroidMotionEvent then return false
-
-               if event.pointers.length < 2 then
-                       # Intercept leftovers of the last motion
-                       return event.down_time == last_motion_start
-               end
-
-               # Collect active pointer and their world position
-               var new_motion_pointers = new HashMap[Int, Point[Float]]
-               var ids = new Array[Int]
-               for pointer in event.pointers do
-                       var id = pointer.pointer_id
-                       ids.add id
-                       new_motion_pointers[id] = camera_to_world(pointer.x, pointer.y)
-               end
-
-               var last_motion_pointers = last_motion_pointers
-               if last_motion_start == event.down_time and
-                  last_motion_pointers.keys.has(ids[0]) and last_motion_pointers.keys.has(ids[1]) then
-                       # Continued motion event
-
-                       # Get new and old position for 2 fingers
-                       var new_motion_a = new_motion_pointers[ids[0]]
-                       var new_motion_b = new_motion_pointers[ids[1]]
-                       var prev_pos_a = last_motion_pointers[ids[0]]
-                       var prev_pos_b = last_motion_pointers[ids[1]]
-
-                       # Move camera
-                       var prev_middle_pos = prev_pos_a.lerp(prev_pos_b, 0.5)
-                       var new_middle_pos = new_motion_a.lerp(new_motion_b, 0.5)
-                       position.x -= new_middle_pos.x - prev_middle_pos.x
-                       position.y -= new_middle_pos.y - prev_middle_pos.y
-
-                       # Zoom camera
-                       var prev_dist = prev_pos_a.dist(prev_pos_b)
-                       var new_dist = new_motion_a.dist(new_motion_b)
-
-                       position.z = prev_dist * position.z / new_dist
-               else
-                       # Prepare for a new motion event
-                       last_motion_pointers.clear
-                       last_motion_start = event.down_time
-               end
-
-               # Keep a smooth history
-               for i in [0..1] do
-                       if last_motion_pointers.keys.has(ids[i]) then
-                               last_motion_pointers[ids[i]] = last_motion_pointers[ids[i]]*0.5 +
-                                                               new_motion_pointers[ids[i]]*0.5
-                       else last_motion_pointers[ids[i]] = new_motion_pointers[ids[i]]
-               end
-
-               return true
-       end
-end
-
-redef class Point[N]
-       private fun *(scalar: Numeric): Point[N]
-       do return new Point[N](x.mul(scalar), y.mul(scalar))
-
-       private fun +(other: Point[N]): Point[N]
-       do return new Point[N](x.add(other.x), y.add(other.y))
-end