LeapMotion #001 Starling from Takepepe on Vimeo.
1ヶ月ぶりの投稿です。GW最終日、皆様いかがお過ごしですか?
今回の投稿は、個人的に今年最も気になるガジェット「LeapMotion」についてです。
・Leap Motion
LeapMotionは端末の上1m四方空間内で、1ミリ単位で指やツール(ペン等)を検知するセンサーです。
また、SDKレベルで数種類のジェスチャーを認識します。
つい先日、プレオーダーした人への発送延期がアナウンスされたばかりですが、
自分は3月末にプレオーダー、デベロッパー登録したところ、2週間ほどで手元に届きました。
発送延期の理由としては、完璧な状態として世に送り出したい、というような内容でした。
7月22日が発送予定日とされていますが、実際どうなるかはまだわかりませんね。
まだ日本語のリソースが少ない状態ですので、コード解説にはいる前に
DeveloperPortalの概要を写したものを交えて、簡単に解説したいと思います。
Frame
LeapMotionで値を取得するために使用するFrameオブジェクトの中には以下のものが含まれます。
・Lists of tracking data
Pointables — Pointableオブジェクトとして、すべての指とツール
Fingers — すべての指
Tools — すべてのツール
Gestures — 開始、更新、終了のハンドラーを含むすべてのジェスチャー
・Frame motion
Rotation Angle — 回転軸(右手の法則を使用して)のまわりで右回りの回転角。
Rotation Matrix — 回転を表現するtransformマトリックス。
Scale Factor — 拡大縮小を表現するファクター。
Translation — 直線運動を表現するベクトル。
Hand model
手について様々な情報を提供します。2本の手を認識しますが、右手左手の識別はしていません。
・Hand attributes
Palm Velocity — 秒速ミリメートル単位の、手のひらの移動速度
Palm Normal — 手のひらの中心から、下方へ指す垂直方向のベクトル
Direction — 手のひらの中心から、指へ向かうベクトル。
Sphere Center — 手の屈曲に適当な球体の中心。(手でボールを持っているような感じ)
Sphere Radius — 手の屈曲に適当な球体の半径。半径は手の形とともに変化します。
・Hand motion
Rotation Angle — 回転軸(右手の法則を使用して)のまわりで右回りの回転角。
Rotation Matrix —回転を表現するtransformマトリックス。
Scale Factor — 拡大縮小を表現するファクター。
Translation — 直線運動を表現するベクトル。
・Finger and Tool lists
検知した手に属する、指やツールの情報を取得できます。
Fingers — すべての指
Tools — すべてのツール
Finger and Tool models
Leapはその視界内の指およびツールの両方を検知するおよび追跡します。
Width — オブジェクトの可視部の平均幅。
Direction — オブジェクト(つまり基礎から先端まで)と同じ方角に指すユニット方向ベクトル。
Tip Position — Leapの起点から計測した指先の座標
Tip Velocity — 秒速ミリメートル単位の、指先の移動速度
Gestures
Leapは特定の移動パターンをGesturesとして認識します。
Swipe — 手の直線運動。
Key Tap — キーボード・キーを軽く打つかのような指の動作。
Screen Tap — コンピューター・スクリーンを軽く打つかのような指の動作。
開発環境について
現在サポートされている言語は、C++、C#、Objective-C、Java、Python、JavaScriptになります。
DevelperPortalでは前述の概要の他に、各フレームワークに対応したライブラリの配布、
ガイドライン、コミュニティ、アプリストア概要などが掲載されています。
Leapに興味があるかたは是非覗いてみてください。
・Leap Motion Developer Portal
LeapMotion × Adobe AIR Starling
今回作成したデモについての解説です。
AdobeAIRでStarlingのParticleSystemを使用して作成しています。
・Starling Framework
・Starling-Extension-Particle-System
StarlingはStage3Dを使用しているのでapp.xmlに以下の設定を忘れずにしましょう。
<depthAndStencil>false</depthAndStencil>
LeapをActionScriptで使用するために、以下のライブラリと付属のC++SDKをラップしているANEを使用します。
導入方法については、下記ページの下部に書いてあるので、それぞれ開発環境にあったものを選んでください。
自分はFlashBuilder4.7でした。
・LeapMotionAS3
Starlingを使用したパーティクルのデモはClockmakerさんやにゃあプロジェクトさんが充実していますので、
そちらを参考にさせていただきました。
FL001.as
package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageDisplayState; import flash.display.StageScaleMode; import flash.events.KeyboardEvent; import starling.core.Starling; [SWF(backgroundColor="#00164a", width="1440", height="900", frameRate="60")] public class FL001 extends Sprite { private var starling:Starling; public function FL001() { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown); starling = new Starling(MainView, stage); starling.start(); } private function onKeyDown(e:KeyboardEvent):void { if(stage.displayState == StageDisplayState.NORMAL){ stage.displayState = StageDisplayState.FULL_SCREEN; } else { stage.displayState = StageDisplayState.NORMAL } } } }
MainView.as
package { import flash.geom.Rectangle; import starling.core.Starling; import starling.display.Sprite; import starling.events.Event; import starling.events.ResizeEvent; import starling.extensions.ParticleDesignerPS; import starling.textures.Texture; import com.leapmotion.leap.LeapMotion; import com.leapmotion.leap.Pointable; import com.leapmotion.leap.events.LeapEvent; internal class MainView extends Sprite { // 事前に「online particle editor」で.pexファイルとtexture.pngを用意しておきます // http://onebyonedesign.com/flash/particleeditor/ [Embed(source = "assets/particle.pex", mimeType = "application/octet-stream")] private static var ParticleData:Class; [Embed(source = "assets/texture.png")] private static var ParticleImage:Class; private var particles:Vector.<ParticleDesignerPS>; private var count:int = 10; private var leap:LeapMotion; public function MainView() { addEventListener(Event.ADDED_TO_STAGE, onAddStage); } private function onAddStage(e:Event):void { setParticles(); leap = new LeapMotion(); leap.controller.addEventListener( LeapEvent.LEAPMOTION_FRAME, onLeapFrame ); stage.addEventListener(ResizeEvent.RESIZE, onResizeStage); } private function setParticles():void{ particles = new Vector.<ParticleDesignerPS>(10); for(var i:int = 0; i<count ; i++){ particles[i] = new ParticleDesignerPS( XML(new ParticleData()), Texture.fromBitmap(new ParticleImage())); particles[i].startSize = 100; particles[i].endSize = 100; particles[i].speed = 0; particles[i].start(); Starling.juggler.add(particles[i]); addChild(particles[i]); } } private function onResizeStage(e:ResizeEvent):void { Starling.current.viewPort = new Rectangle(0, 0, e.width, e.height); stage.stageWidth = e.width; stage.stageHeight = e.height; } private function onLeapFrame(e:LeapEvent):void { var max:int = e.frame.pointables.length; for(var i:int = 0; i<count ; i++){ if( i < max ){ var pointable:Pointable = e.frame.pointables[i]; particles[i].emitterX = (pointable.tipPosition.x)*3+stage.stageWidth/2; particles[i].emitterY = (pointable.tipPosition.y)*-3+stage.stageHeight; particles[i].gravityX = pointable.tipVelocity.x*-5; particles[i].gravityY = pointable.tipVelocity.y*5; particles[i].maxNumParticles = 50; }else{ particles[i].maxNumParticles = 1; } } } } }
1ヶ月いじった上で得た感想(というかぶちあたっている壁)です。
- 指がLeapに向かって垂直に重なると検知できない。
- 細かなUI操作に向いていない
- ジェスチャーはそのままでは利用しづらい
あくまで、現状公開されているSDKとライブラリを使用した上での感想です。
概要を読む限りではワクワクするばかりですが、ちゃんとアプリケーションに落とし込むためには
上記の問題をカバーしたフレームワークが必要だなと思いました。
今回の投稿はさらっと紹介しただけになってしまったので、
次回はちょっとしたフレームワークと何か面白いネタで投稿できればいいなー。