Leap Motion for T3D
by Entr0py · 01/18/2013 (8:42 am) · 5 comments
This will get your leap motion data into T3d. It doesn't do much but spam the console right now, but this should get you started in the right direction. You will have to alter LeapListener::onFrame to pass the data to wherever it is you need it.
LeapListener::onFrame is called every time the Leap device creates a new frame. You may want to change this to only call a leap data frame when your frames are rendered in which case you will have to poll the controller object (controller.frame()) rather than use the LeapListener::onFrame function.
First you need to add the leap SDK libs and includes to your project. You can get them at leapmotion.com in the developer's section.
Here is my header file:
And my cpp file:
In script somewhere:
This code needs proper destruction of the listener/controller because it hangs the client when it is closed.
LeapListener::onFrame is called every time the Leap device creates a new frame. You may want to change this to only call a leap data frame when your frames are rendered in which case you will have to poll the controller object (controller.frame()) rather than use the LeapListener::onFrame function.
First you need to add the leap SDK libs and includes to your project. You can get them at leapmotion.com in the developer's section.
Here is my header file:
#include <iostream>
#ifndef _WINLEAPINPUT_H_
#define _WINLEAPINPUT_H_
#ifndef _LEAP_H_
#include "leap.h"
#endif
#ifndef _SIMBASE_H_
#include "console/simBase.h"
#endif
#ifndef _PLATFORMTHREAD_H_
#include "platform/threads/thread.h"
#endif
class LeapListener : public Leap::Listener {
public:
public:
LeapListener();
~LeapListener();
virtual void onInit(const Leap::Controller&);
virtual void onConnect(const Leap::Controller&);
virtual void onDisconnect(const Leap::Controller&);
virtual void onExit(const Leap::Controller&);
virtual void onFrame(const Leap::Controller&);
};
class LeapThread : public SimObject
{
typedef SimObject Parent;
public:
LeapThread();
~LeapThread();
Thread* mThread;
static void launchThread(void* data);
Leap::Frame getframe(int history);
LeapListener listener;
Leap::Controller controller;
void processThread();
DECLARE_CONOBJECT(LeapThread);
};
#endifAnd my cpp file:
#include "platformWin32/winLeapInput.h"
#include "console/console.h"
#include "console/engineAPI.h"
#include "console/consoleTypes.h"
#include "console/simBase.h"
LeapListener::LeapListener()
{
}
void LeapListener::onInit(const Leap::Controller& controller) {
Con::printf("Leap Motion Listener Initialized");
}
void LeapListener::onConnect(const Leap::Controller& controller) {
Con::printf("Leap Motion Connected");
}
void LeapListener::onDisconnect(const Leap::Controller& controller) {
Con::printf("Leap Motion Disconnected");
}
void LeapListener::onExit(const Leap::Controller& controller) {
Con::printf("Leap Motion Exited");
}
void LeapListener::onFrame(const Leap::Controller& controller) {
// Get the most recent frame and report some basic information
const Leap::Frame frame = controller.frame();
if(controller.isConnected())
Con::executef("onLeapFrame");
Con::printf("Leap Motion Frame Id: %d, time: %d", frame.id()), frame.timestamp();
Con::printf("Tools: %d", frame.tools().count());
if (!frame.hands().empty()) {
// Get the first hand
const Leap::Hand hand = frame.hands()[0];
// Check if the hand has any fingers
const Leap::FingerList fingers = hand.fingers();
if (!fingers.empty()) {
// Calculate the hand's average finger tip position
Leap::Vector avgPos;
for (int i = 0; i < fingers.count(); ++i) {
avgPos += fingers[i].tipPosition();
}
avgPos /= (float)fingers.count();
Con::printf("Fingers %d , Average Finger Pos: %s ", fingers.count(), avgPos.toString().c_str());
}
Con::printf("Hands: %d", frame.hands().count());
// Get the hand's sphere radius and palm position
Con::printf("Hand sphere radius: %f",hand.sphereRadius());
Con::printf("Hand palm position: %f",hand.palmPosition().toString().c_str());
// Get the hand's normal vector and direction
const Leap::Vector normal = hand.palmNormal();
const Leap::Vector direction = hand.direction();
// Calculate the hand's pitch, roll, and yaw angles
Con::printf("Hand Pitch: %f ", direction.pitch() * Leap::RAD_TO_DEG);
Con::printf("Hand Rolls: %f ", normal.roll() * Leap::RAD_TO_DEG);
Con::printf("Hand Yaw: %f ", direction.yaw() * Leap::RAD_TO_DEG);
}
}
LeapListener::~LeapListener()
{
}
IMPLEMENT_CONOBJECT(LeapThread);
LeapThread::LeapThread()
{
mThread = new Thread((ThreadRunFunction)launchThread, this);
mThread->start();
}
LeapThread::~LeapThread()
{
// needs a proper destruction
if(mThread)
delete mThread;
mThread = NULL;
}
void LeapThread::launchThread(void* data)
{
LeapThread* pThis = (LeapThread*)data;
pThis->processThread();
}
void LeapThread::processThread()
{
controller.addListener(listener);
}In script somewhere:
function onLeapFrame()
{
// do stuff here if you want
}
$leap = new leapthread();Bugs:This code needs proper destruction of the listener/controller because it hangs the client when it is closed.
About the author
#2
01/18/2013 (11:07 am)
The next version of T3D will support the Leap Motion (among other devices) with it's new input manager.
#3
01/18/2013 (11:12 am)
Great! I would like to see a demo of a pair of hands that can work with Physx objects.
#4
- Dave
01/24/2013 (1:23 pm)
Blog talking about Leap Motion controller support in Torque 3D, and a demo game you can try out: www.garagegames.com/community/blogs/view/22128- Dave
#5
01/24/2013 (3:10 pm)
Awesome thanks! 
Torque Owner Christian S
Oak-Entertainment
-applied for their devkit for a project idea I have, and eagerly await feedback atm!