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.
- [00:01] The detection of the speaker begins when press the "Entering" button.
- [00:05] After the speaker has been detected, stick person appears.
- stick person connected with movement of speaker
[00:14] Operate the slide by posing the following four.
[00:53] Demonstrates using the actual slide.
- 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.
(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.)
- Musclide/src/musclide/sensor/Speaker.java at master · gongo/Musclide · GitHub
- Set the coordinates of body (head, left hand, etc..) to DoubleProperty.
- Musclide/src/musclide/sensor/MuscleRadar.java at master · gongo/Musclide · GitHub
- Binding to javafx.scene.shape.Line property from coordinates properties.
- 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
Sample code for OpenNI in Java
- When use homebrew,
$(brew --cellar openni)/$VERSION/sample/*.java/
- When use homebrew,
In Musclide, Musclide/src/musclide/sensor/MuscleSensor.java.
Conclusion
Let's muscle presentation!!
Supplementation : Motivation for English Translation
@skrb @gongoZ Musclide looks fascinating but I don't fully understand because of language barrier. Possible to blog about it in English?
2012-12-11 02:11:39 via Echofon to @skrb
@javafxpert @gongoz I'll talk to gongoZ about translation of his blog entry!
2012-12-11 07:13:23 via HootSuite to @JavaFXpert
@skrb @JavaFXpert I'll try to challenge translation
2012-12-11 07:56:24 via TweetIrcGateway to @skrb
@gongoz @JavaFXpert Great!!
2012-12-11 07:58:49 via HootSuite to @gongoZ
@gongoZ @skrb Thanks! I look forward to it. Also, I'll be happy to help smooth any rough edges in the translation, so please let me know.
2012-12-11 08:04:27 via Echofon to @gongoZ