gamnit :: camera_control_android $ EulerCamera
Simple camera with perspective oriented with Euler angles (pitch, yaw, roll
)
gamnit :: camera_control_android $ EulerCamera
Simple camera with perspective oriented with Euler angles (pitch, yaw, roll
)
Serializable::inspect
to show more useful information
more_collections :: more_collections
Highly specific, but useful, collections-related classes.serialization :: serialization_core
Abstract services to serialize Nit objects to different formatscore :: union_find
union–find algorithm using an efficient disjoint-set data structureaccept_scroll_and_zoom
# Two fingers camera manipulation, pinch to zoom and slide to scroll
module camera_control_android
import android
import camera_control
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
redef fun accept_scroll_and_zoom(event)
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
lib/gamnit/camera_control_android.nit:15,1--92,3