Thanks Driven Life

日々是感謝

Muscle based slideshow system "Musclide"

This article is the 10th of JavaFX Advent Calendar 2012.

here has been written in Japanese.

What's "Musclide" ?

Musclide (Muscle + Slide) is slideshow tool. source code gongo/Musclide · GitHub

demo movie.

Musclide demo from gongo on Vimeo.

  1. [00:01] The detection of the speaker begins when press the "Entering" button.
  2. [00:05] After the speaker has been detected, stick person appears.
    • stick person connected with movement of speaker
  3. [00:14] Operate the slide by posing the following four.

    Posing

  4. [00:53] Demonstrates using the actual slide.

  5. The rest of the time, enjoy the muscle presentation.

Steps

0. requirement

1. Install OpenNI/Sensor/NITE

2. IDE

Take your pick. I use IntellijIDEA.

Challenged

Previously , I made tool to operate the slide using muscle.


Tython Lightning Talk

(Speaker of this video is me. I'm talking in Japanese.)

This tool can be to simulate the keyboard events by the movement of the body.

  • "left jab" → "right arrow"
  • "right straight" → "left arrow" , etc...

This time, I did not divert this tool. Because It's a good chance to use the specific features of JavaFX (Property, Bind, Event).

Property & Binding

I was used Property and Binding to monitor the movement of the speaker in Musclide. You can see from the following code. (I wrote comment in Japanese. sorry.)

  1. Musclide/src/musclide/sensor/Speaker.java at master · gongo/Musclide · GitHub
    • Set the coordinates of body (head, left hand, etc..) to DoubleProperty.
  2. Musclide/src/musclide/sensor/MuscleRadar.java at master · gongo/Musclide · GitHub
    • Binding to javafx.scene.shape.Line property from coordinates properties.
  3. Stick person that connected with movement of speaker is now complete!

Custom Event

I made "MuscleEvent" similar to KeyEvent and MouseEvent. This event is generated when posing specific detected.

First, it is a code that defines the MuscleEvent class.

package musclide.event;

import javafx.event.Event;
import javafx.event.EventType;


public class MuscleEvent extends Event {
    public static final EventType<MuscleEvent> ANY
            = new EventType<MuscleEvent>(Event.ANY, "Detect Muscle Posing");

    public enum Pose {
        NEXT,
        PREV,
        FIRST,
        LAST,
        STANDBY
    };

    public Pose pose = Pose.STANDBY;

    public MuscleEvent() {
        super(ANY);
    }
}

code Musclide/src/musclide/event/MuscleEvent.java at master · gongo/Musclide · GitHub

Second, it is a code that generates (fire) MuscleEvent.

TimelineBuilder.create()
        .cycleCount(Timeline.INDEFINITE)
        .keyFrames(
                new KeyFrame(
                        new Duration(1000), // Check the pose every second
                        new EventHandler<ActionEvent>() {
                            @Override
                            public void handle(ActionEvent event) {
                                if (speaker == null || !speaker.isTracking()) {
                                    return;
                                }
 
                                if (speaker.owataPoseDetected()) {
                                    firePosingDetected(MuscleEvent.Pose.NEXT);
                                } else if (speaker.hangerPoseDetected()) {
                                    firePosingDetected(MuscleEvent.Pose.PREV);
                                } else if (speaker.showtimePoseDetected()) {
                                    firePosingDetected(MuscleEvent.Pose.FIRST);
                                } else if (speaker.kakashiPoseDetected()) {
                                    firePosingDetected(MuscleEvent.Pose.LAST);
                                } else {
                                    firePosingDetected(MuscleEvent.Pose.STANDBY);
                                }
                            }
                        }
                )
        ).build().play();

private void firePosingDetected(MuscleEvent.Pose pose) {
        MuscleEvent event = new MuscleEvent();
        event.pose = pose;
        Event.fireEvent(this, event);
}

public final void setOnPosingDetected(EventHandler<MuscleEvent> eventHandler) {
        this.addEventHandler(MuscleEvent.ANY, eventHandler);
}

code Musclide/src/musclide/Ring.java at master · gongo/Musclide · GitHub

Final, it is the code to catch MuscleEvent.

ring.setOnPosingDetected(new EventHandler<MuscleEvent>() {
    @Override
    public void handle(MuscleEvent muscleEvent) {
        switch (muscleEvent.pose) {
            case NEXT:
                next();
                break;
            case PREV:
                prev();
                break;
            case FIRST:
                first();
                break;
            case LAST:
                last();
                break;
            case STANDBY:
            default:
                standby();
        }
    }
});

code Musclide/src/musclide/slide/Slide.java at master · gongo/Musclide · GitHub

Supplementation : OpenNI and Java

Conclusion

Let's muscle presentation!!

Supplementation : Motivation for English Translation