DHJJ [Hatsune's Journal Japan] blog

Hatsune's Journal Japan blog

目次

Blog 利用状況

ニュース

最新ツイート

運営サイト

Hatsune's Journal Japan
DHJJ

著作など

資格など

OCP
MCP

書庫

日記カテゴリ

わんくま同盟

[Leap]Understanding the C# Sample Applicationの日本語訳

Leap Motionの日本語情報は非常に限られているので公式ドキュメントをざっくり日本語訳にしました。誤訳などあったらお知らせください。

本エントリはhttps://developer.leapmotion.com/documentation/Languages/CSharpandUnity/Guides/Sample_CSharp_Tutorial.htmlの日本語訳となります。

Understanding the C# Sample Application

Topics:

Overview
Creating a Controller object
Subclassing the Listener class
Getting a Frame of data
Getting Gestures
Running the sample

Leap SDKフォルダ配下に、この資料で使う次のファイルがあります。

  • LeapSDK/samples/Sample.cs ? C# sample application
  • Windows:
    • LeapSDK/lib/LeapCSharp.NET3.5.dll ? Leap C# library for .NET 3.5
    • LeapSDK/lib/LeapCSharp.NET4.0.dll ? Leap C# library for .NET 4.0
    • LeapSDK/lib/x86/LeapCSharp.dll ? 32-bit Leap C# library for Windows
    • LeapSDK/lib/x64/LeapCSharp.dll ? 64-bit Leap C# library for Windows
    • LeapSDK/lib/x86/Leap.dll ? 32-bit Leap library for Windows
    • LeapSDK/lib/x64/Leap.dll ? 64-bit Leap library for Windows
  • Mac (Mono):
    • LeapSDK/lib/LeapCSharp.NET3.5.dll ? Leap C# library for .NET 3.5
    • LeapSDK/lib/LeapCSharp.NET4.0.dll ? Leap C# library for .NET 4.0
    • LeapSDK/lib/libLeapCSharp.dylib ? Leap C# library for Mac
    • LeapSDK/lib/libLeap.dylib ? Leap library for Mac

Leap APIリファレンスは、LeapSDK/docs/API_Reference/annotated.html にインストールされます。

Overview

一言で言えば、Leap Motionトラッキングデバイスが検出され、手とその検出範囲内にある指を追跡します。Leapは、1度に1フレームのデータをキャプチャします。アプリケーションからこのデータにアクセスするにはLeap APIを使います。

サンプル アプリケーションはLeap API を使用して、Leapからのフレームイベントを取得する方法と、各フレームの手や指のデータにアクセスする手段を提供します。Sample.csはコマンドラインアプリケーションとなっており、検出された手や指を標準出力に出力します。

サンプルアプリケーションでは、Leap APIの主要なクラスの大部分を使用しています。

  • Controller ? Leapとアプリケーション間のインターフェース
  • Listener ? Leapによって送出されたイベントを処理するために使用
  • Frame ? 手と指のトラッキングデータのセットが含まれています
  • Hand ? 検出された手のトラッキングデータが含まれています
  • Finger ? 検出された指のトラッキングデータが含まれています
  • Vector ? 3Dの位置または方向ベクトルを表します
  • Gesture ? 認識できたジェスチャーを表します

これらのクラスの詳細についてはLeap APIのリファレンスを参照してください。

Creating a Controller object

Controllerクラスは、Leapとアプリケーションの間の主要なインターフェイスを提供します。Controllerオブジェクトを作成すると実行中のLeapソフトウェアに接続して、Frameオブジェクトを通じて手のトラッキングデータが利用可能になります。Frameオブジェクトは、Controllerオブジェクトをインスタンス化して、Controller.Frame メソッドを呼び出すことによってアクセスできます。

アプリケーションからはループ処理によりController.Frameを呼び出して使います。ループ処理により定期的にポーリングする以外に、Controllerオブジェクトにリスナーを追加する方法もあります。Controllerオブジェクトはトラッキングデータの新たしいフレームが利用できるとき(もしくは他のLeapイベント発生時に)はListenerサブクラスで定義されているコールバックメソッドを呼び出します。

サンプルアプリケーションでは、MainメソッドでControllerオブジェクトを作成し、Controller.AddListenerメソッドでListenerのサブクラスインスタンスを追加します。

VB.NET
Class Sample
    Public Sub Main()
        ' Create a sample listener and controller
        Dim listener As new SampleListener
        Dim _controller As new Controller

        ' Have the sample listener receive events from the controller
        _controller.AddListener(listener);

        ' Keep this process running until Enter is pressed
        Console.WriteLine("Press Enter to quit...");
        Console.ReadLine();

        ' Remove the sample listener when done
        _controller.RemoveListener(listener)
        _controller.Dispose()
    End Sub
End Class
C#
class Sample
{
    public static void Main()
    {
        // Create a sample listener and controller
        SampleListener listener = new SampleListener();
        Controller controller = new Controller();

        // Have the sample listener receive events from the controller
        controller.AddListener(listener);

        // Keep this process running until Enter is pressed
        Console.WriteLine("Press Enter to quit...");
        Console.ReadLine();

        // Remove the sample listener when done
        controller.RemoveListener(listener);
        controller.Dispose();
    }
}

[ENTER]キーを押すまでサンプルアプリケーションは十恋し続けます。実行している間、Leapイベントが発生したときはControllerが適切なリスナーコールバックを呼び出します。上記のサンプルコードではSampleListenerクラスがリスナークラスの独自サブクラスになります。次はそのサブクラスの実装をみてみましょう。

Subclassing the Listener class

サンプル アプリケーションでは、リスナーのサブクラスであるSampleListenerでLeapからのイベントを処理するコールバックメソッドを実装しています。

イベントは次のとおりです。

  • OnInit ? Listenerが登録されているControllerオブジェクトの初期化時のイベント。一度だけ発生します。
  • OnConnect ? Leapに接続し、モーショントラッキングデータのフレームの送信開始の準備ができたときのイベント
  • OnDisconnect ? Leapデバイスを外したりLeapソフトウェアを落としたときなど、ControllerオブジェクトがLeapから切り離されたときのイベント
  • OnExit ? ControllerオブジェクトからListenerが切り離された時のイベント
  • OnFrame ? モーショントラッ キングデータの新しいフレームが使用できるときのイベント

サンプルアプリケーションでは、 3つのライフサイクルイベントコールバック(OnInit OnDisconnect、OnExit)が発生すると標準出力にメッセージを出力します。OnConnect とOnFrameのイベント発生時にはメッセージ出力以外の処理もしています。 OnConnectコールバックで呼び出された関数の中では、認識したいジェスチャを使用可能にしています。OnFrameコールバックで呼び出された関数の中では、モーショントラッ キングデータの最新のフレームの内容を標準出力にメッセージ出力します。

Getting a Frame of data

Leapは、モーショントラッキングデータの新しいフレームを生成するときに、OnFrameコールバックメソッドを呼び出します。Controller.Frame()メソッドを呼び出すことによって、新たなデータにアクセスすることができます (Controllerオブジェクトへの参照がパラメータとしてコールバックに渡されます)。Frameオブジェクトには、ID、タイムスタンプおよび検出された手に対するHandオブジェクトを含むリストから構成されています。

サンプルアプリケーションのOnFrame実装の次の部分は、Controllerオブジェクトから最新のFrameオブジェクトを取得し、フレームID、タイムスタンプ、検出した手の数、検出した指の数、検出したツールの数を出力しています。

VB.NET
' Get the most recent frame and report some basic information
Dim _frame As Frame = _controller.Frame()
SafeWriteLine("Frame id: " + _frame.Id
            & ", timestamp: " & _frame.Timestamp
            & ", hands: " & _frame.Hands.Count
            & ", fingers: " & _frame.Fingers.Count
            & ", tools: " & _frame.Tools.Count)
C#
// Get the most recent frame and report some basic information
Frame frame = controller.Frame();
SafeWriteLine("Frame id: " + frame.Id
            + ", timestamp: " + frame.Timestamp
            + ", hands: " + frame.Hands.Count
            + ", fingers: " + frame.Fingers.Count
            + ", tools: " + frame.Tools.Count);

 

次のコードは、手が検出できたかをチェックし、検出できた場合はリストの最初の手を取得しています。

VB.NET
If (Not _frame.Hands.Empty) Then
    ' Get the first hand
    Dim _hand As Hand = _frame.Hands(0)
C#
if (!frame.Hands.Empty)
{
    // Get the first hand
    Hand hand = frame.Hands[0];

 

Handオブジェクトは、ID、手の物理的特性を表すプロパティおよびFingerオブジェクトリストが含まれています。各Fingerオブジェクトは、IDと指の特性を表すプロパティが含まれています。

次のコードはHandオブジェクトからFingerオブジェクトリストを取り出して、指の先端の平均的な位置を標準出力に出力します。

VB.NET
' Check if the hand has any fingers
Dim fingers As FingerList = _hand.Fingers
If (Not fingers.Empty) Then
    ' Calculate the hand's average finger tip position
    Dim avgPos As Vector = Vector.Zero
    For Each _finger In fingers
        avgPos += _finger.TipPosition
    Next
    avgPos /= fingers.Count
    SafeWriteLine("Hand has " & fingers.Count
                & " fingers, average finger tip position: " & avgPos)
End If
C#
// Check if the hand has any fingers
FingerList fingers = hand.Fingers;
if (!fingers.Empty)
{
    // Calculate the hand's average finger tip position
    Vector avgPos = Vector.Zero;
    foreach (Finger finger in fingers)
    {
        avgPos += finger.TipPosition;
    }
    avgPos /= fingers.Count;
    SafeWriteLine("Hand has " + fingers.Count
                + " fingers, average finger tip position: " + avgPos);
}

 

次に、手の平が形作っている球体の半径と手の平の位置を出力します。

VB.NET
' Get the hand's sphere radius and palm position
SafeWriteLine("Hand sphere radius: " & _hand.SphereRadius.ToString("n2") _
            & " mm, palm position: " & hand.PalmPosition)
C#
// Get the hand's sphere radius and palm position
SafeWriteLine("Hand sphere radius: " + hand.SphereRadius.ToString("n2")
            + " mm, palm position: " + hand.PalmPosition);

 

最後に、OnFrameメソッドは、手の法線ベクトルと方向ベクトルから手のピッチ、ロール、ヨー角を算出するベクトルを使用します。角度はラジアンから度に変換されます。

VB.NET
' Get the hand's normal vector and direction
Dim normal As Vector = _hand.PalmNormal
Dim direction As Vector = _hand.Direction

' Calculate the hand's pitch, roll, and yaw angles
SafeWriteLine("Hand pitch: " & direction.Pitch * 180.0F / CType(Math.PI, Single) & " degrees, " _
            & "roll: " & normal.Roll * 180.0F / CType(Math.PI, Single) & " degrees, " _
            & "yaw: " & direction.Yaw * 180.0F / CType(Math.PI, Single) & " degrees\n")
C#
// Get the hand's normal vector and direction
Vector normal = hand.PalmNormal;
Vector direction = hand.Direction;

// Calculate the hand's pitch, roll, and yaw angles
SafeWriteLine("Hand pitch: " + direction.Pitch * 180.0f / (float)Math.PI  + " degrees, "
            + "roll: " + normal.Roll * 180.0f / (float)Math.PI + " degrees, "
            + "yaw: " + direction.Yaw * 180.0f / (float)Math.PI + " degrees\n");

Getting Gestures


Leapからジェスチャーを受け取るには、最初に認識するジェスチャーを有効にする必要があります。Leapと接続したControllerオブジェクト(IsConnectedがTrue)は、いつでもジェスチャー認識を有効にできます。サンプルプログラムでは、OnConnect()コールバック関数の中でEnableGesture()Controllerクラスで定義されたメソッドを使用して認識したいすべてジェスチャを有効にしています。

VB.NET
Public Overrides Sub OnConnect(_controller As Controller)
    SafeWriteLine("Connected")
    _controller.EnableGesture(Gesture.GestureType.TYPECIRCLE)
    _controller.EnableGesture(Gesture.GestureType.TYPEKEYTAP)
    _controller.EnableGesture(Gesture.GestureType.TYPESCREENTAP)
    _controller.EnableGesture(Gesture.GestureType.TYPESWIPE)
End Sub
C#
public override void OnConnect (Controller controller)
{
        SafeWriteLine ("Connected");
        controller.EnableGesture (Gesture.GestureType.TYPECIRCLE);
        controller.EnableGesture (Gesture.GestureType.TYPEKEYTAP);
        controller.EnableGesture (Gesture.GestureType.TYPESCREENTAP);
        controller.EnableGesture (Gesture.GestureType.TYPESWIPE);
}

Leapは、Frameオブジェクトにおけるジェスチャーリストにジェスチャーの動きを定義したGestureオブジェクトを追加します。 サンプル・アプリケーションのOnFrame()イベントでは、検出されたジェスチャーに合わせた情報を標準出力に出力しています。

Gesture APIは、Gestureクラスをベースにして個々のジェスチャーを表すクラスに拡張されています。ジェスチャーリスト内のオブジェクトは、ジェスチャーインスタンスですので、あなたは正しいサブクラスのインスタンスにジェスチャーインスタンスを変換する必要があります。キャストはサポートされない代わりに各サブクラスは変換を実行するコンストラクターを提供します。例えば、例えば、円のジェスチャーは、以下のコードでCircleGestureインスタンスに変換できます。

VB.NET
CircleGesture circle = new CircleGesture (gesture)
C#
CircleGesture circle = new CircleGesture (gesture)

 

間違えているサブクラスにジェスチャインスタンスを変換する場合、コンストラクター関数は無効なジェスチャオブジェクトを返します。

ジェスチャーでは以前のフレームと現在のフレームでジェスチャーの特性を比較すると便利な場合があります。例えば、円のジェスチャーには円を何回描いたかをカウントするProgressプロパティがあります。今回のフレームの円のジェスチャーのProgressから前回のフレームの円のジェスチャーを引くことで1フレームの回数が取得できます。

VB.NET
' Calculate angle swept since last frame
Dim sweptAngle As Single = 0
If (circle.State <> Gesture.GestureState.STATESTART) Then
    Dim previousUpdate As New CircleGesture(_controller.Frame(1).Gesture(circle.Id))
    sweptAngle = (circle.Progress - previousUpdate.Progress) * 360
End If
C#
// Calculate angle swept since last frame
float sweptAngle = 0;
if (circle.State != Gesture.GestureState.STATESTART) {
    CircleGesture previousUpdate = new CircleGesture (controller.Frame (1).Gesture (circle.Id));
    sweptAngle = (circle.Progress - previousUpdate.Progress) * 360;
}

 

ジェスチャーループの完全なコードは次の通りです。

VB.NET
' Get gestures
Dim gestures As GestureList = _frame.Gestures()
For i As Integer = 0 To gestures.Count - 1
    Dim _gesture As Gesture = gestures(i)

    Select Case _gesture.Type
        Case Gesture.GestureType.TYPECIRCLE
            Dim circle As New CircleGesture(_gesture)

            ' Calculate clock direction using the angle between circle normal and pointable
            Dim clockwiseness As String
            If (circle.Pointable.Direction.AngleTo(circle.Normal) <= Math.PI / 4) Then
                'Clockwise if angle is less than 90 degrees
                clockwiseness = "clockwise"
            Else
                clockwiseness = "counterclockwise"
            End If

            Dim sweptAngle As Single = 0

            ' Calculate angle swept since last frame
            If (circle.State <> Gesture.GestureState.STATESTART) Then
                Dim previousUpdate As New CircleGesture(_controller.Frame(1).Gesture(circle.Id))
                sweptAngle = (circle.Progress - previousUpdate.Progress) * 360
            End If

            SafeWriteLine("Circle id: " & circle.Id _
                        & ", " & circle.State _
                        & ", progress: " & circle.Progress _
                        & ", radius: " & circle.Radius _
                        & ", angle: " & sweptAngle _
                        & ", " & clockwiseness)
        Case Gesture.GestureType.TYPESWIPE
            Dim swipe As New SwipeGesture(_gesture)
            SafeWriteLine("Swipe id: " & swipe.Id _
                        & ", " & swipe.State _
                        & ", position: " & swipe.Position.ToString _
                        & ", direction: " & swipe.Direction.ToString _
                        & ", speed: " & swipe.Speed)
        Case Gesture.GestureType.TYPEKEYTAP
            Dim keytap As New KeyTapGesture(_gesture)
            SafeWriteLine("Tap id: " & keytap.Id _
                        & ", " & keytap.State _
                        & ", position: " & keytap.Position.ToString _
                        & ", direction: " & keytap.Direction.ToString)
        Case Gesture.GestureType.TYPESCREENTAP
            Dim screentap As New ScreenTapGesture(_gesture)
            SafeWriteLine("Tap id: " & screentap.Id _
                        & ", " & screentap.State _
                        & ", position: " & screentap.Position.ToString _
                        & ", direction: " & screentap.Direction.ToString)
        Case Else
            SafeWriteLine("Unknown gesture type.")
    End Select
Next
C#
// Get gestures
GestureList gestures = frame.Gestures ();
for (int i = 0; i < gestures.Count; i++) {
        Gesture gesture = gestures [i];

        switch (gesture.Type) {
        case Gesture.GestureType.TYPECIRCLE:
                CircleGesture circle = new CircleGesture (gesture);

    // Calculate clock direction using the angle between circle normal and pointable
                String clockwiseness;
                if (circle.Pointable.Direction.AngleTo (circle.Normal) <= Math.PI / 4) {
                        //Clockwise if angle is less than 90 degrees
                        clockwiseness = "clockwise";
                } else {
                        clockwiseness = "counterclockwise";
                }

                float sweptAngle = 0;

    // Calculate angle swept since last frame
                if (circle.State != Gesture.GestureState.STATESTART) {
                        CircleGesture previousUpdate = new CircleGesture (controller.Frame (1).Gesture (circle.Id));
                        sweptAngle = (circle.Progress - previousUpdate.Progress) * 360;
                }

                SafeWriteLine ("Circle id: " + circle.Id
               + ", " + circle.State
               + ", progress: " + circle.Progress
               + ", radius: " + circle.Radius
               + ", angle: " + sweptAngle
               + ", " + clockwiseness);
                break;
        case Gesture.GestureType.TYPESWIPE:
                SwipeGesture swipe = new SwipeGesture (gesture);
                SafeWriteLine ("Swipe id: " + swipe.Id
               + ", " + swipe.State
               + ", position: " + swipe.Position
               + ", direction: " + swipe.Direction
               + ", speed: " + swipe.Speed);
                break;
        case Gesture.GestureType.TYPEKEYTAP:
                KeyTapGesture keytap = new KeyTapGesture (gesture);
                SafeWriteLine ("Tap id: " + keytap.Id
               + ", " + keytap.State
               + ", position: " + keytap.Position
               + ", direction: " + keytap.Direction);
                break;
        case Gesture.GestureType.TYPESCREENTAP:
                ScreenTapGesture screentap = new ScreenTapGesture (gesture);
                SafeWriteLine ("Tap id: " + screentap.Id
               + ", " + screentap.State
               + ", position: " + screentap.Position
               + ", direction: " + screentap.Direction);
                break;
        default:
                SafeWriteLine ("Unknown gesture type.");
                break;
        }
}

Running the sample

To run the sample application:

  1. サンプルのコンパイル
    • dows では、現在のディレクトリにある Sample.cs と LeapCSharp.NET3.5.dll または LeapCSharp.NET4.0.dll を確認します。(を使用している .NET framework の適切なライブラリ参照を使用して) コマンド ライン プロンプトで次のコマンドを実行します。

      csc /reference:LeapCSharp.NET4.0.dll /platform:x86 /target:exe Sample.cs

      注: .NET framework の適切なバージョンから「csc」コンパイラを使用します。

    • Mac では、c# プログラムをコンパイルする、Mono プロジェクトを使用してできます。現在のディレクトリにある Sample.cs と LeapCSharp.NET3.5.dll または LeapCSharp.NET4.0.dll を確認します。
      • .NET 3.5 framework

        gmcs /reference:LeapCSharp.NET3.5.dll /platform:x86 /target:exe Sample.cs

      • .NET 4.0 framework

        dmcs /reference:LeapCSharp.NET4.0.dll /platform:x86 /target:exe Sample.cs

  2. LeapデバイスをUSBに繋ぎ、自分の前に設置
  3. Leapソフトウェアをインストールしていなかったらインストール
  4. Leapソフトウェアをスタート。プロンプトが表示されたら登録したメールアドレスとパスワードを入力します。準備ができたらタスクバーの通知領域に表示されたアイコンが緑色になります。
  5. サンプルアプリの実行
    • Windowsでは、Sample.exe、LeapCSharp.dll、Leap.dll、LeapCSharp.NET3.5.dllまたはLeapCSharp.NET4.0.dllを同じディレクトリに配置します。32ビットのプロジェクトはlib\x86ディレクトリのライブラリを使用し、64ビットプロジェクトはlib\x64ディレクトリのライブラリを使用します。コマンドラインプロンプトで次のコマンドを実行します。

      Sample.exe

      Visual Studioでコンパイルする場合は、プロジェクトでlib\LeapCSharp.NET4.0.dllを参照設定し、ビルドターゲットをx86にした場合はlib\x86\LeapCSharp.dllとlib\x86\Leap.dllを取り込み、コンパイルアクション「なし」、コピーアクション「常にコピーする」と各ファイルのプロパティで設定しておくと便利です。なお、ターゲットフレームワークを4.5としても動作します。
      image

      なお、ビルドターゲットをx64にした場合はlib\x64\LeapCSharp.dllとlib\x64\Leap.dllを取り込みます。

    • MacではSample.exe、 libLeapCSharp.dylib、 libLeap.dylib、LeapCSharp.NET3.5.dllまたはLeapCSharp.NET4.0.dllを同じディレクトリに配置し、ターミナルウィンドウで次のコマンドを実行して確認してください。

      mono Sample.exe

サンプルアプリケーションを実行すると、初期化時とLeap接続時に「Initialized」と「Connected」が標準出力に出力されます。OnFrameのイベントが検出されると標準出力にフレーム情報が出力されます。Leapの上に手をかざすと指と手の平の位置情報が出力されます。

このサンプルでLeapからのモーショントラックングデータの取得方法が理解できたら、Leapを使ったC#アプリケーションの開発を始めることができます。

投稿日時 : 2013年8月3日 17:15

Feedback

# What's up friends, how is everything, and what you wish for to say concerning this post, in my view its truly amazing in favor of me. 2019/05/29 6:43 What's up friends, how is everything, and what yo

What's up friends, how is everything, and what you wish for to say concerning this
post, in my view its truly amazing in favor of me.

# Informative article, totally what I was looking for. 2019/06/16 19:32 Informative article, totally what I was looking fo

Informative article, totally what I was looking for.

# Paragraph writing is also a fun, if you be familiar with after that you can write otherwise it is complicated to write. 2019/07/22 14:09 Paragraph writing is also a fun, if you be familia

Paragraph writing is also a fun, if you be familiar with
after that you can write otherwise it is complicated to write.

# Excellent article! We will be linking to this great article on our website. Keep up the good writing. 2019/09/04 21:23 Excellent article! We will be linking to this grea

Excellent article! We will be linking to this great article on our website.

Keep up the good writing.

# DhhqWydCHQaw 2021/07/03 3:16 https://amzn.to/365xyVY

I will right away clutch your rss feed as I can not in finding your e-mail subscription hyperlink or newsletter service. Do you have any? Please allow me recognise so that I may subscribe. Thanks.

# yRTRMBbcIJDPlrJ 2021/07/03 4:45 https://www.blogger.com/profile/060647091882378654

I will bookmark your weblog and take a look at again right here regularly.

# Seriously lots of excellent info! edu essay thesis help 2021/08/12 16:59 Seriously lots of excellent info! edu essay thesis

Seriously lots of excellent info!
edu essay
thesis help

# Бизнесмен и меценат Максим Евгеньевич Каганский родился в Москве 19 ноября 1980 года в многодетной семье сотрудника МВД. В 1998 году поступил в Московский Юридический Институт МВД России (сейчас – Академия МВД России), специальность – юрист-правовед. м 2021/08/12 19:35 Бизнесмен и меценат Максим Евгеньевич Каганский ро

Бизнесмен и меценат Максим Евгеньевич
Каганский родился в Москве 19 ноября 1980 года в многодетной семье сотрудника МВД.
В 1998 году поступил в Московский Юридический Институт МВД России (сейчас ? Академия
МВД России), специальность ? юрист-правовед.


максим каганский сейчас
максим каганский сейчас

# Really tons of superb facts! thesis writing service writing service 2021/08/14 15:06 Really tons of superb facts! thesis writing servic

Really tons of superb facts!
thesis writing service
writing service

# You made your position extremely clearly.! paper writing service paper writing 2021/08/26 0:24 You made your position extremely clearly.! paper w

You made your position extremely clearly.!

paper writing service
paper writing

# Terrific knowledge, Thanks a lot! Leanne https://americandental.ru/ (Latosha) 2021/08/26 21:00 Terrific knowledge, Thanks a lot! Leanne https://a

Terrific knowledge, Thanks a lot!
Leanne
https://americandental.ru/ (Latosha)

# Regards, Useful information! porno femme enceinte porno picture 2021/09/22 22:38 Regards, Useful information! porno femme enceinte

Regards, Useful information!
porno femme enceinte
porno picture

# Hi, I want to subscribe for this webpage to take hottest updates, so where can i do it please assist. https://blip.fm/gardenbee2 Tina (Tina) 2021/11/02 3:05 Hi, I want to subscribe for this webpage to take h

Hi, I want to subscribe for this webpage to take
hottest updates, so where can i do it please assist.
https://blip.fm/gardenbee2
Tina (Tina)

# 偽物時計 2021/12/29 6:05 bbyhnrvspd@aol.jp

絶品が大集合●激安販売中!
2022【新色】最新アイテムを海外通販!
限定SALE超激得!
日本正規専門店、激安販売中!
通販最大80%OFF、送料無料!
激安全国送料無料!100%正規品!
【新商品!】☆安心の全品国内発送!
激安通販!☆安心の全品国内発送!
【超人気新品】即日発送,品質100%保証!
激安販売中!
【楽天市場】激安販売中、全国送料無料!
【新色】最新アイテムを海外通販!
販売出售,正規品保証!
【専門店】即日発送!80%以上割引
野球 激安 大ヒットSALE!
【新商品!】安い卸売,即日発送!
偽物時計 https://www.kopi66.com/product/detail.aspx?id=16560

タイトル
名前
Url
コメント