Bamboo touchでのマルチタッチ
prev : http://d.hatena.ne.jp/mjt/20091004/p1
というわけで、mosh canvasを使って取得した座標を表示してみる。手持ちで撮影しているので手ぶれがひどい。
http://storage.osdev.info/pub/idmjt/diaryimage/0910/neta091005l1.flv
- 黄色い点 : 最初のタッチポイント
- 小さい点 : おそらく中間点
- 青い点 : 次のタッチポイント
青い点だけ という状況があることに注意。一度離すと点は黄色くなる。2つの点は独立してコントロールできる。
動画では解りづらいが、10秒おき程度に一瞬固まる。これはGCによる。
canvasの使用
実際の描画は、canvas-draw!に描画命令のリストを渡すことで行う。描画命令はmove-toのようなよく知られたものを受け付け、描画命令のセットはOpenVGに由来する。
Window上のcanvasはmake-simple-canvas-windowで作ることができる。これはバックグラウンドで(mosh concurrentによる)スレッドを作り、イベントを処理する。今回は、リアルタイムのビジュアライズを行いたいため明示的にWindowを作っているが、通常のシチュエーションではファイルと同様の感覚で画面に表示できる。
ただし、画面に表示できるのはWindowsのみ。他のOSではファイル(cairoによるPDF/PNG)への出力のみ利用できる。
実際の描画部は以下のようになる :
(define (draw-rect x y s r g b) (let ((sx (- x s)) (sy (- y s)) (d (* 2 s))) `((pen-width 0) (paint-color-rgb ,r ,g ,b) (move-to ,sx ,sy) (line-to* ,d 0) (line-to* 0 ,d) (line-to* ,(- d) 0) (close-path) (fill)))) ... (canvas-draw! ca (append pro (draw-rect x0 y0 (/ p0 3.0) 255 255 0) (draw-rect x1 y1 5 255 0 0) (draw-rect x2 y2 (/ p2 3.0) 0 255 255)))))
今の実装には描画クロージャが含まれていないので、明示的にリストを作成して連結する必要がある。描画クロージャを導入すると、描画命令をユーザサイドで拡張することが出来るようになる。
draw!はリストを深さ優先で辿って実行するので、描画部のappendはlistでも動作する。ただ、この仕様が将来的に残るかは検討中。
(import (rnrs) (ext win32 usb) (ext canvas win32 window) ;→(ext canvas simple)になる予定 ; STUB。将来的にはこれらは不要になる。 (ext win32 mainthread) (ext win32 window-master)) ; STUB (init-window-master) (usb_init) (define dh (usb_open0 #x56a #xd1)) (usb_set_configuration dh 1) (usb_claim_interface dh 0) (usb_claim_interface dh 1) (define pktlen #x14) (define buf (make-bytevector pktlen)) (define init-data #vu8(2 2)) (usb_control_msg dh 33 9 #x0302 0 init-data 2) (define ca (make-simple-canvas-window 480 320)) (define pro '((paint-color-rgb 255 255 255) (clear))) (define (draw-rect x y s r g b) (let ((sx (- x s)) (sy (- y s)) (d (* 2 s))) `((pen-width 0) (paint-color-rgb ,r ,g ,b) (move-to ,sx ,sy) (line-to* ,d 0) (line-to* 0 ,d) (line-to* ,(- d) 0) (close-path) (fill)))) (define (tab-display buf) (define (b x) (bytevector-u8-ref buf x)) (define (w x) (bitwise-and #x7fff (bytevector-u16-ref buf x (endianness big)))) (let ((p0 (b 2)) (x0 (w 3)) (y0 (w 5)) (x1 (w 7)) (y1 (w 9)) (p2 (b 11)) (x2 (w 12)) (y2 (w 14))) (canvas-draw! ca (append pro (draw-rect x0 y0 (/ p0 3.0) 255 255 0) (draw-rect x1 y1 5 255 0 0) (draw-rect x2 y2 (/ p2 3.0) 0 255 255))))) (define (loop) (let ((r (usb_interrupt_read dh #x82 buf pktlen))) (if (< r 0) (loop) (begin (tab-display buf) (loop))))) (loop)