Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
NiccoloGranieri committed Dec 4, 2018
2 parents 62b4574 + 0654c33 commit 6bb8648
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 149 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Reach - Leap Motion OSC Sender

Reach is a free and open source application, written using [JUCE](https://juce.com), to map [Leap Motion](https://leapmotion.com) data to OSC messages. Using the latest Leap Motion SDK [Orion](https://developer.leapmotion.com/orion/) this app
enables easy mapping of leap motion parameters in any other environment without having to code a single line.

### [**Web Page**](http://niccologranieri.com/reach/) - [**DOWNLOAD**](https://github.com/NiccoloGranieri/Reach/releases)

## Key Features
- Tracking and OSC parsing of hand nodes' spatial position (x, y, z), and grab hand gesture.
- Detection and OSC parsing of grab gesture

## Acknowledgements

Reach is a software supported by [Integra Lab](http://integra.io).

### Team:
- [Niccolò Granieri](http://niccologranieri.com), creator
- [Jefferson Bledsoe](https://twitter.com/Jeff_Bledsoe), developer
214 changes: 107 additions & 107 deletions Source/LeapLogger.cpp
Original file line number Diff line number Diff line change
@@ -1,107 +1,107 @@
#include "JuceHeader.h"
#include "LeapLogger.h"

//==============================================================================
LeapLogger::LeapLogger ()
{
createNewLogFile ();

startTimer (5);
}

LeapLogger::~LeapLogger()
{
stopTimer();
}

//==============================================================================
void LeapLogger::createNewLogFile()
{
DBG("CREATING FILE");
const auto logFilename = String(String(ProjectInfo::projectName)
+ "_Session" + String (currentSessionNumber) + "_Log_"
+ Time::getCurrentTime().formatted("%d-%m-%Y_%H-%M-%S"));

const auto logExtension = String(".csv");

auto logFile = File::getSpecialLocation(File::SpecialLocationType::userDesktopDirectory)
.getChildFile(logFilename + logExtension);

Logger::setCurrentLogger(nullptr);
logger.reset(new FileLogger(logFile, {}));
Logger::setCurrentLogger(logger.get());

logger->logMessage(ProjectInfo::projectName + String(" Data Log"));
logger->logMessage({});
logger->logMessage(dataNames);
logger->logMessage({});

logFrameData.ensureStorageAllocated(200);

++currentSessionNumber;
DBG(currentSessionNumber);
DBG(logFilename);
}

//==============================================================================
void LeapLogger::hiResTimerCallback()
{
if (! controller.isConnected())
{
DBG("DISCONNECT");
shouldStartNewSession = true;
return;
}

if (shouldStartNewSession && controller.isConnected())
{
DBG("NEW FILE INSIDE CALLBACK");
createNewLogFile();
shouldStartNewSession = false;
return;
}

const auto& frame = controller.frame();

if (frame.id() == lastFrameId)
return;

const auto& hands = frame.hands();

if (hands.isEmpty())
return;

logFrameData.clearQuick();

for (auto& hand : hands)
{
if (hand.isLeft())
logFrameData.add("Left");
else
logFrameData.add("Right");

logFrameData.add(static_cast<String> (hand.stabilizedPalmPosition().x));
logFrameData.add(static_cast<String> (hand.stabilizedPalmPosition().y));
logFrameData.add(static_cast<String> (hand.stabilizedPalmPosition().z));

logFrameData.add(static_cast<String> (hand.wristPosition().x));
logFrameData.add(static_cast<String> (hand.wristPosition().y));
logFrameData.add(static_cast<String> (hand.wristPosition().z));

for (auto& finger : hand.fingers())
{
for (auto i = 0; ++i < 4;)
{
const auto& boneType = static_cast<Leap::Bone::Type> (i);
const auto& bone = finger.bone (boneType);
logFrameData.add(static_cast<String> (bone.nextJoint().x));
logFrameData.add(static_cast<String> (bone.nextJoint().y));
logFrameData.add(static_cast<String> (bone.nextJoint().z));
}
}
}

logger->logMessage (logFrameData.joinIntoString (","));

lastFrameId = frame.id();
}
#include "JuceHeader.h"
#include "LeapLogger.h"

//==============================================================================
LeapLogger::LeapLogger ()
{
createNewLogFile ();

startTimer (5);
}

LeapLogger::~LeapLogger()
{
stopTimer();
}

//==============================================================================
void LeapLogger::createNewLogFile()
{
DBG("CREATING FILE");
const auto logFilename = String(String(ProjectInfo::projectName)
+ "_Session" + String (currentSessionNumber) + "_Log_"
+ Time::getCurrentTime().formatted("%d-%m-%Y_%H-%M-%S"));

const auto logExtension = String(".csv");

auto logFile = File::getSpecialLocation(File::SpecialLocationType::userDesktopDirectory)
.getChildFile(logFilename + logExtension);

Logger::setCurrentLogger(nullptr);
logger.reset(new FileLogger(logFile, {}));
Logger::setCurrentLogger(logger.get());

logger->logMessage(ProjectInfo::projectName + String(" Data Log"));
logger->logMessage({});
logger->logMessage(dataNames);
logger->logMessage({});

logFrameData.ensureStorageAllocated(200);

++currentSessionNumber;
DBG(currentSessionNumber);
DBG(logFilename);
}

//==============================================================================
void LeapLogger::hiResTimerCallback()
{
if (! controller.isConnected())
{
DBG("DISCONNECT");
shouldStartNewSession = true;
return;
}

if (shouldStartNewSession && controller.isConnected())
{
DBG("NEW FILE INSIDE CALLBACK");
createNewLogFile();
shouldStartNewSession = false;
return;
}

const auto& frame = controller.frame();

if (frame.id() == lastFrameId)
return;

const auto& hands = frame.hands();

if (hands.isEmpty())
return;

logFrameData.clearQuick();

for (auto& hand : hands)
{
if (hand.isLeft())
logFrameData.add("Left");
else
logFrameData.add("Right");

logFrameData.add(static_cast<String> (hand.stabilizedPalmPosition().x));
logFrameData.add(static_cast<String> (hand.stabilizedPalmPosition().y));
logFrameData.add(static_cast<String> (hand.stabilizedPalmPosition().z));

logFrameData.add(static_cast<String> (hand.wristPosition().x));
logFrameData.add(static_cast<String> (hand.wristPosition().y));
logFrameData.add(static_cast<String> (hand.wristPosition().z));

for (auto& finger : hand.fingers())
{
for (auto i = 0; ++i < 4;)
{
const auto& boneType = static_cast<Leap::Bone::Type> (i);
const auto& bone = finger.bone (boneType);
logFrameData.add(static_cast<String> (bone.nextJoint().x));
logFrameData.add(static_cast<String> (bone.nextJoint().y));
logFrameData.add(static_cast<String> (bone.nextJoint().z));
}
}
}

logger->logMessage (logFrameData.joinIntoString (","));

lastFrameId = frame.id();
}
82 changes: 41 additions & 41 deletions Source/LeapLogger.h
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
#pragma once

#include "JuceHeader.h"
#include "Leap.h"

//==============================================================================
class LeapLogger : public HighResolutionTimer
{
public:
//==========================================================================
LeapLogger ();
~LeapLogger();

//==========================================================================
void setLogFile (File logFolder);

private:
//==========================================================================
std::unique_ptr<FileLogger> logger;
StringArray logFrameData;
bool shouldStartNewSession = false;

int currentSessionNumber = 0;

//==========================================================================
Leap::Controller controller;
int lastFrameId = -1;

//==========================================================================
const StringArray jointTypes = { "/TYPE_THUMB", "/TYPE_INDEX", "/TYPE_MIDDLE", "/TYPE_RING", "/TYPE_PINKY" };
const StringArray joints = { "/knuckle", "/joint1", "/joint2", "/joint3" };
String dataNames{ "Hand,PalmX,PalmY,PalmZ,WristX,WristY,WristZ,Finger1Bone1X,Finger1Bone1Y,Finger1Bone1Z,Finger1Bone2X,Finger1Bone2Y,Finger1Bone2Z,Finger1Bone3X,Finger1Bone3Y,Finger1Bone3Z,Finger1Bone4X,Finger1Bone4Y,Finger1Bone4Z,Finger2Bone1X,Finger2Bone1Y,Finger2Bone1Z,Finger2Bone2X,Finger2Bone2Y,Finger2Bone2Z,Finger2Bone3X,Finger2Bone3Y,Finger2Bone3Z,Finger2Bone4X,Finger2Bone4Y,Finger2Bone4Z,Finger3Bone1X,Finger3Bone1Y,Finger3Bone1Z,Finger3Bone2X,Finger3Bone2Y,Finger3Bone2Z,Finger3Bone3X,Finger3Bone3Y,Finger3Bone3Z,Finger3Bone4X,Finger3Bone4Y,Finger3Bone4Z,Finger4Bone1X,Finger4Bone1Y,Finger4Bone1Z,Finger4Bone2X,Finger4Bone2Y,Finger4Bone2Z,Finger4Bone3X,Finger4Bone3Y,Finger4Bone3Z,Finger4Bone4X,Finger4Bone4Y,Finger4Bone4Z" };

//==========================================================================
void createNewLogFile();

//==========================================================================
void hiResTimerCallback() override;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LeapLogger)
};
#pragma once

#include "JuceHeader.h"
#include "Leap.h"

//==============================================================================
class LeapLogger : public HighResolutionTimer
{
public:
//==========================================================================
LeapLogger ();
~LeapLogger();

//==========================================================================
void setLogFile (File logFolder);

private:
//==========================================================================
std::unique_ptr<FileLogger> logger;
StringArray logFrameData;
bool shouldStartNewSession = false;

int currentSessionNumber = 0;

//==========================================================================
Leap::Controller controller;
int lastFrameId = -1;

//==========================================================================
const StringArray jointTypes = { "/TYPE_THUMB", "/TYPE_INDEX", "/TYPE_MIDDLE", "/TYPE_RING", "/TYPE_PINKY" };
const StringArray joints = { "/knuckle", "/joint1", "/joint2", "/joint3" };
String dataNames{ "Hand,PalmX,PalmY,PalmZ,WristX,WristY,WristZ,Finger1Bone1X,Finger1Bone1Y,Finger1Bone1Z,Finger1Bone2X,Finger1Bone2Y,Finger1Bone2Z,Finger1Bone3X,Finger1Bone3Y,Finger1Bone3Z,Finger1Bone4X,Finger1Bone4Y,Finger1Bone4Z,Finger2Bone1X,Finger2Bone1Y,Finger2Bone1Z,Finger2Bone2X,Finger2Bone2Y,Finger2Bone2Z,Finger2Bone3X,Finger2Bone3Y,Finger2Bone3Z,Finger2Bone4X,Finger2Bone4Y,Finger2Bone4Z,Finger3Bone1X,Finger3Bone1Y,Finger3Bone1Z,Finger3Bone2X,Finger3Bone2Y,Finger3Bone2Z,Finger3Bone3X,Finger3Bone3Y,Finger3Bone3Z,Finger3Bone4X,Finger3Bone4Y,Finger3Bone4Z,Finger4Bone1X,Finger4Bone1Y,Finger4Bone1Z,Finger4Bone2X,Finger4Bone2Y,Finger4Bone2Z,Finger4Bone3X,Finger4Bone3Y,Finger4Bone3Z,Finger4Bone4X,Finger4Bone4Y,Finger4Bone4Z" };

//==========================================================================
void createNewLogFile();

//==========================================================================
void hiResTimerCallback() override;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LeapLogger)
};
2 changes: 1 addition & 1 deletion Source/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class ReachApplication : public JUCEApplication
private:

std::unique_ptr<MainWindow> mainWindow;

// Commented out logger
// LeapLogger logger;

Expand Down

0 comments on commit 6bb8648

Please sign in to comment.