Demo tool to select objects via Leap controller.
parent
8b6f844dbc
commit
d0f2cf3234
|
|
@ -1539,8 +1539,8 @@ LIST(APPEND viewer_SOURCE_FILES llleapmotioncontroller.cpp)
|
|||
LIST(APPEND viewer_HEADER_FILES llleapmotioncontroller.h)
|
||||
|
||||
if (LEAPMOTION)
|
||||
LIST(APPEND viewer_SOURCE_FILES fsleaptool.cpp fsleapexampletool.cpp )
|
||||
LIST(APPEND viewer_HEADER_FILES fsleaptool.h fsleapexampletool.h )
|
||||
LIST(APPEND viewer_SOURCE_FILES fsleaptool.cpp fsleapexampletool.cpp fsleapmaniptool.cpp )
|
||||
LIST(APPEND viewer_HEADER_FILES fsleaptool.h fsleapexampletool.h fsleapmaniptool.h )
|
||||
endif (LEAPMOTION)
|
||||
|
||||
if (DARWIN)
|
||||
|
|
|
|||
|
|
@ -48,12 +48,16 @@ namespace nd
|
|||
return 111;
|
||||
}
|
||||
|
||||
void ExampleTool::onFrame( Leap::HandList const &aHands )
|
||||
void ExampleTool::onLeapFrame( Leap::Frame const &aFrame )
|
||||
{
|
||||
mHands = aHands.count();
|
||||
mHands = aFrame.hands().count();
|
||||
mFingers = 0;
|
||||
for( int i = 0; i < mHands; ++ i )
|
||||
mFingers += aHands[ i ].fingers().count();
|
||||
mFingers += aFrame.hands()[ i ].fingers().count();
|
||||
}
|
||||
|
||||
void ExampleTool::onRenderFrame( Leap::Frame const &aFrame )
|
||||
{
|
||||
}
|
||||
|
||||
void ExampleTool::render()
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ namespace nd
|
|||
public:
|
||||
virtual ~ExampleTool(){}
|
||||
|
||||
virtual void onFrame(Leap::HandList const&);
|
||||
virtual void onLeapFrame( Leap::Frame const& );
|
||||
virtual void onRenderFrame( Leap::Frame const& );
|
||||
virtual void render();
|
||||
virtual std::string getDebugString();
|
||||
virtual std::string getName();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,576 @@
|
|||
/**
|
||||
* $LicenseInfo:firstyear=2014&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2014, Nicky Dasmijn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include <leap-motion/Leap.h>
|
||||
|
||||
#include "fsleapmaniptool.h"
|
||||
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "lldrawable.h"
|
||||
#include "pipeline.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llselectmgr.h"
|
||||
|
||||
namespace nd
|
||||
{
|
||||
namespace leap
|
||||
{
|
||||
struct Finger
|
||||
{
|
||||
Finger( )
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
memset( this, 0, sizeof( Finger ) );
|
||||
}
|
||||
|
||||
bool isValid( ) const
|
||||
{ return mTimestamp > 0; }
|
||||
|
||||
U64 mId;
|
||||
U64 mTimestamp;
|
||||
|
||||
float mTip[3];
|
||||
float mDir[3];
|
||||
float mFromLast[3];
|
||||
float mLenFromLast;
|
||||
float mWidth;
|
||||
float mLength;
|
||||
U16 mPartner;
|
||||
LLViewerObject *mSelected;
|
||||
};
|
||||
|
||||
struct Fingers
|
||||
{
|
||||
Fingers( )
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
mTimestamp = 0;
|
||||
for( int i = 0; i < eMaxFingers; ++i )
|
||||
mFingers[ i ].clear();
|
||||
mStoredFingers = 0;
|
||||
}
|
||||
|
||||
Finger* getFinger( U64 aId )
|
||||
{
|
||||
for( int i = 0; i < mStoredFingers; ++i )
|
||||
{
|
||||
if( aId == mFingers[ i ].mId )
|
||||
return mFingers + i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Finger* at( U16 aIndex )
|
||||
{
|
||||
return &mFingers[ aIndex ];
|
||||
}
|
||||
|
||||
enum MAXFIGERS { eMaxFingers = 10 };
|
||||
|
||||
U64 mTimestamp;
|
||||
U16 mStoredFingers;
|
||||
Finger mFingers[eMaxFingers];
|
||||
};
|
||||
|
||||
|
||||
/* Do the rotation:
|
||||
| 0 0 -1 | | x |
|
||||
| -1 0 0 | * | y |
|
||||
| 0 1 0 | | z |
|
||||
|
||||
in this case it's just value flipping.
|
||||
*/
|
||||
static LLVector3 toAgentCS( float aX, float aY, float aZ )
|
||||
{
|
||||
return LLVector3( -aZ, -aX, aY );
|
||||
}
|
||||
static LLVector3 toAgentCS( LLVector3 const &aIn )
|
||||
{
|
||||
return toAgentCS( aIn.mV[VX], aIn.mV[VY], aIn.mV[VZ] );
|
||||
}
|
||||
|
||||
static float scaleY( float aIn )
|
||||
{
|
||||
return aIn - 150.f;
|
||||
}
|
||||
|
||||
static LLVector3 scaleToSL( LLVector3 const &aIn )
|
||||
{
|
||||
return aIn * 1.f/25.f;
|
||||
}
|
||||
|
||||
static void copy( Leap::Vector const &aFrom, float *aTo )
|
||||
{
|
||||
aTo[0] = aFrom[0];
|
||||
aTo[1] = aFrom[1];
|
||||
aTo[2] = aFrom[2];
|
||||
}
|
||||
|
||||
static float length( float const *aVec )
|
||||
{
|
||||
return sqrt( aVec[0]*aVec[0] + aVec[1]*aVec[1] + aVec[2]*aVec[2] );
|
||||
}
|
||||
|
||||
static float normalize( float *aVec )
|
||||
{
|
||||
float len = length( aVec );
|
||||
if( fabs( len ) > 0.0001f )
|
||||
{
|
||||
aVec[0] /= len;
|
||||
aVec[1] /= len;
|
||||
aVec[2] /= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = aVec[0] = aVec[1] = aVec[2] = 0.f;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static float dot( float const *aVec1, float const *aVec2, bool aUnitVectors = true )
|
||||
{
|
||||
float alpha = aVec1[0]*aVec2[0] + aVec1[1]*aVec2[1] + aVec1[2]*aVec2[2];
|
||||
|
||||
if( !aUnitVectors )
|
||||
alpha /= ( length( aVec1 )*length(aVec2) );
|
||||
|
||||
return acos( alpha );
|
||||
}
|
||||
|
||||
static void subtract( float const *aLeft, float const *aRight, float *aOut )
|
||||
{
|
||||
aOut[0] = aLeft[0] - aRight[0];
|
||||
aOut[1] = aLeft[1] - aRight[1];
|
||||
aOut[2] = aLeft[2] - aRight[2];
|
||||
}
|
||||
|
||||
static void move( float const *aStart, float const *aDirecton, float aScale, float *aOut )
|
||||
{
|
||||
aOut[0] = aStart[0] + aDirecton[0]*aScale;
|
||||
aOut[1] = aStart[1] + aDirecton[1]*aScale;
|
||||
aOut[2] = aStart[2] + aDirecton[2]*aScale;
|
||||
|
||||
}
|
||||
|
||||
ManipTool::ManipTool()
|
||||
{
|
||||
mLastExaminedFrame = 0;
|
||||
mLastStoredFrame = 0;
|
||||
mNextRenderedFrame = 0;
|
||||
mTotalStoredFrames = 0;
|
||||
mFingersPerFrame = new Fingers[ eMaxKeptFrames ];
|
||||
}
|
||||
|
||||
ManipTool::~ManipTool()
|
||||
{
|
||||
delete []mFingersPerFrame;
|
||||
}
|
||||
|
||||
std::string ManipTool::getName()
|
||||
{
|
||||
return "Manipulation tool";
|
||||
}
|
||||
|
||||
std::string ManipTool::getDebugString()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
S32 ManipTool::getId()
|
||||
{
|
||||
return 11;
|
||||
}
|
||||
|
||||
void ManipTool::clearSelection()
|
||||
{
|
||||
//for( std::vector< LLViewerObject* >::iterator itr = mHighlighted.begin(); itr != mHighlighted.end(); ++itr )
|
||||
//{
|
||||
// LLViewerObject *pO = *itr;
|
||||
// LLSelectMgr::getInstance()->unhighlightObjectOnly( pO );
|
||||
//}
|
||||
//mHighlighted.clear();
|
||||
|
||||
LLSelectMgr::getInstance()->unhighlightAll();
|
||||
|
||||
}
|
||||
|
||||
void ManipTool::onLeapFrame( Leap::Frame const &aFrame )
|
||||
{
|
||||
if( (aFrame.timestamp() - mLastExaminedFrame ) < 16*1000 )
|
||||
return;
|
||||
|
||||
if( aFrame.hands().count() > 2 )
|
||||
return;
|
||||
|
||||
mLastExaminedFrame = aFrame.timestamp();
|
||||
U16 curFrame = getNextFrameNo( mLastStoredFrame );
|
||||
Fingers &curFingers = mFingersPerFrame[ curFrame ];
|
||||
U16 curFinger = 0;
|
||||
curFingers.clear();
|
||||
curFingers.mTimestamp = mLastExaminedFrame;
|
||||
|
||||
Leap::HandList &hands = aFrame.hands();
|
||||
for( int i = 0; i < hands.count(); ++i )
|
||||
{
|
||||
for( int j = 0; j < hands[i].fingers().count(); ++j )
|
||||
{
|
||||
Leap::Finger oFinger( hands[i].fingers()[j] );
|
||||
|
||||
Finger &oF = curFingers.mFingers[ curFinger++ ];
|
||||
|
||||
oF.mId = oFinger.id();
|
||||
oF.mTimestamp = mLastExaminedFrame;
|
||||
copy( oFinger.direction(), oF.mDir );
|
||||
copy( oFinger.tipPosition(), oF.mTip );
|
||||
oF.mWidth = oFinger.width();
|
||||
oF.mLength = oFinger.length();
|
||||
}
|
||||
}
|
||||
|
||||
curFingers.mStoredFingers = curFinger;
|
||||
|
||||
if( mTotalStoredFrames > 0 )
|
||||
{
|
||||
Fingers &prevFingers = mFingersPerFrame[ mLastStoredFrame ];
|
||||
|
||||
for( U16 i = 0; i < curFingers.mStoredFingers; ++i )
|
||||
{
|
||||
Finger &curFinger = curFingers.mFingers[i];
|
||||
Finger const *prevFinger = prevFingers.getFinger( curFinger.mId );
|
||||
if( !prevFinger )
|
||||
continue;
|
||||
|
||||
subtract( curFinger.mTip, prevFinger->mTip, curFinger.mFromLast );
|
||||
curFinger.mLenFromLast = normalize( curFinger.mFromLast );
|
||||
}
|
||||
}
|
||||
|
||||
mLastStoredFrame = curFrame;
|
||||
++mTotalStoredFrames;
|
||||
}
|
||||
|
||||
void ManipTool::onRenderFrame( Leap::Frame const &aFrame )
|
||||
{
|
||||
clearSelection();
|
||||
doSelect( );
|
||||
}
|
||||
|
||||
void ManipTool::findPartner( U16 aIndex )
|
||||
{
|
||||
Fingers &curFingers = mFingersPerFrame[ mNextRenderedFrame ];
|
||||
Finger &curFinger = curFingers.mFingers[ aIndex ];
|
||||
|
||||
if( !curFinger.mSelected )
|
||||
return;
|
||||
|
||||
for( U16 i = 0; i < curFingers.mStoredFingers; ++i )
|
||||
{
|
||||
if( curFingers.mFingers[i].mSelected == curFinger.mSelected )
|
||||
{
|
||||
if( !curFingers.mFingers[i].mPartner )
|
||||
{
|
||||
curFingers.mFingers[i].mPartner = aIndex;
|
||||
curFinger.mPartner = i;
|
||||
}
|
||||
else
|
||||
curFinger.mSelected = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ManipTool::selectWithFinger( U16 aIndex )
|
||||
{
|
||||
Finger &oFinger = mFingersPerFrame[ mNextRenderedFrame ].mFingers[ aIndex ];
|
||||
GLfloat x( oFinger.mTip[0] );
|
||||
GLfloat y( scaleY( oFinger.mTip[1] ) );
|
||||
GLfloat z( oFinger.mTip[2] );
|
||||
LLVector3 oV1( scaleToSL( toAgentCS( x, y, z) ) );
|
||||
|
||||
x += oFinger.mDir[0] * oFinger.mLength;
|
||||
y += oFinger.mDir[1] * oFinger.mLength;
|
||||
z += oFinger.mDir[2] * oFinger.mLength;
|
||||
|
||||
LLVector3 oV2( scaleToSL( toAgentCS( x, y, z ) ) );
|
||||
|
||||
oV1 *= gAgentAvatarp->getRotationRegion();
|
||||
oV2 *= gAgentAvatarp->getRotationRegion();
|
||||
|
||||
oV1 += gAgentAvatarp->getPositionAgent( );
|
||||
oV2 += gAgentAvatarp->getPositionAgent( );
|
||||
|
||||
LLVector4a oF1,oF2;
|
||||
oF1.load3( oV1.mV );
|
||||
oF2.load3( oV2.mV );
|
||||
|
||||
S32 nFace(0);
|
||||
LLViewerObject *pHit = gPipeline.lineSegmentIntersectInWorld( oF1,oF2, FALSE, TRUE, &nFace );
|
||||
|
||||
if( pHit )
|
||||
oFinger.mSelected = pHit;
|
||||
|
||||
findPartner( aIndex );
|
||||
}
|
||||
|
||||
void ManipTool::doSelect()
|
||||
{
|
||||
Fingers &curFingers = mFingersPerFrame[ mNextRenderedFrame ];
|
||||
for( U16 i = 0; i < curFingers.mStoredFingers; ++i )
|
||||
selectWithFinger( i );
|
||||
|
||||
for( U16 i = 0; i < curFingers.mStoredFingers; ++i )
|
||||
{
|
||||
Finger &curFinger = curFingers.mFingers[ i ];
|
||||
if( curFinger.mPartner < i )
|
||||
continue;
|
||||
|
||||
if( !curFinger.mSelected )
|
||||
continue;
|
||||
|
||||
LLColor4 oCol( 0.f, 0.f, 1.f );
|
||||
if( curFinger.mPartner )
|
||||
oCol.set( 0.f, 1.f, 0.f );
|
||||
|
||||
LLSelectMgr::getInstance()->highlightObjectOnly( curFinger.mSelected, oCol );
|
||||
}
|
||||
}
|
||||
|
||||
void ManipTool::renderCone( Finger const &aFinger )
|
||||
{
|
||||
GLfloat x( aFinger.mTip[0] );
|
||||
GLfloat y( scaleY( aFinger.mTip[1] ) );
|
||||
GLfloat z( aFinger.mTip[2] );
|
||||
|
||||
LLVector3 oTip( scaleToSL( toAgentCS( x, y, z ) ) );
|
||||
|
||||
float dist = aFinger.mWidth*2;
|
||||
x -= aFinger.mDir[0] *dist;
|
||||
y -= aFinger.mDir[1] *dist;
|
||||
z -= aFinger.mDir[2] *dist;
|
||||
|
||||
LLVector3 oM( scaleToSL( toAgentCS( x, y, z) ) );
|
||||
float r = 0.25;
|
||||
int slices = 16;
|
||||
float alpha = (F_PI*2)/slices;
|
||||
|
||||
for( int i = 0; i < slices; ++i )
|
||||
{
|
||||
GLfloat cx = cos( alpha*i )*r;
|
||||
GLfloat cy = sin( alpha*i )*r;
|
||||
|
||||
GLfloat cx2 = cos( alpha*(i+1) )*r;
|
||||
GLfloat cy2 = sin( alpha*(i+1) )*r;
|
||||
|
||||
LLVector3 oV1( oM );
|
||||
LLVector3 oV2( oM );
|
||||
|
||||
oV1 += LLVector3( 0, cy, -cx );
|
||||
oV2 += LLVector3( 0, cy2, -cx2 );
|
||||
|
||||
gGL.vertex3fv( oTip.mV );
|
||||
gGL.vertex3fv( oV1.mV );
|
||||
|
||||
gGL.vertex3fv( oV1.mV );
|
||||
gGL.vertex3fv( oV2.mV );
|
||||
|
||||
gGL.vertex3fv( oV2.mV );
|
||||
gGL.vertex3fv( oTip.mV );
|
||||
}
|
||||
}
|
||||
|
||||
void ManipTool::renderMovementDirection( Finger const &aFinger )
|
||||
{
|
||||
float lenDir = aFinger.mLenFromLast;
|
||||
U16 prevFrame = getPrevFrameNo( mNextRenderedFrame );
|
||||
Finger *prevFinger = mFingersPerFrame[ prevFrame ].getFinger( aFinger.mId );
|
||||
|
||||
while( prevFinger && prevFinger->mTimestamp < aFinger.mTimestamp && (aFinger.mTimestamp - prevFinger->mTimestamp ) < getMaxBacktrackMicroseconds() )
|
||||
{
|
||||
float alpha = dot( aFinger.mFromLast, prevFinger->mFromLast );
|
||||
if( alpha > F_PI/18 )
|
||||
break;
|
||||
|
||||
lenDir += prevFinger->mLenFromLast;
|
||||
|
||||
prevFrame = getPrevFrameNo( prevFrame );
|
||||
prevFinger = mFingersPerFrame[ prevFrame ].getFinger( aFinger.mId );
|
||||
}
|
||||
#if 0
|
||||
float vec[3];
|
||||
bool haveVec( false );
|
||||
while( aFinger.mTimestamp > mFingersPerFrame[ prevFrame ].mTimestamp &&
|
||||
(aFinger.mTimestamp > mFingersPerFrame[ prevFrame ].mTimestamp) < getMaxBacktrackMicroseconds() )
|
||||
{
|
||||
Finger *pFinger = mFingersPerFrame[ prevFrame ].getFinger( aFinger.mId );
|
||||
|
||||
if( pFinger )
|
||||
{
|
||||
if( !haveVec )
|
||||
{
|
||||
subtract( aFinger.mTip, pFinger->mTip, vec );
|
||||
lenDir = normalize( vec );
|
||||
haveVec = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
float vec2[3];
|
||||
|
||||
subtract( aFinger.mTip, pFinger->mTip, vec2 );
|
||||
float lenDir2 = normalize( vec );
|
||||
|
||||
float alpha = dot( vec, vec2 );
|
||||
if( alpha > F_PI/18 )
|
||||
break;
|
||||
lenDir += lenDir2;
|
||||
}
|
||||
}
|
||||
prevFrame = getPrevFrameNo( prevFrame );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( lenDir > 0 )
|
||||
{
|
||||
GLfloat x( aFinger.mTip[0] );
|
||||
GLfloat y( scaleY( aFinger.mTip[1] ) );
|
||||
GLfloat z( aFinger.mTip[2] );
|
||||
|
||||
LLVector3 oStart( scaleToSL( toAgentCS( x, y, z ) ) );
|
||||
|
||||
x -= aFinger.mFromLast[0] *lenDir;
|
||||
y -= aFinger.mFromLast[1] *lenDir;
|
||||
z -= aFinger.mFromLast[2] *lenDir;
|
||||
|
||||
LLVector3 oEnd( scaleToSL( toAgentCS( x, y, z) ) );
|
||||
gGL.vertex3fv( oStart.mV );
|
||||
gGL.vertex3fv( oEnd.mV );
|
||||
}
|
||||
}
|
||||
|
||||
void ManipTool::renderMovementAngle( Finger const &aFinger, U16 aIndex )
|
||||
{
|
||||
if( !aFinger.mPartner || aFinger.mPartner < aIndex )
|
||||
return;
|
||||
|
||||
U16 prevFrame = getPrevFrameNo( mNextRenderedFrame );
|
||||
Finger *prevFinger = mFingersPerFrame[ prevFrame ].getFinger( aFinger.mId );
|
||||
U16 startFrame(mNextRenderedFrame);
|
||||
|
||||
while( prevFinger &&
|
||||
prevFinger->mTimestamp < aFinger.mTimestamp && (aFinger.mTimestamp - prevFinger->mTimestamp ) < getMaxBacktrackMicroseconds() &&
|
||||
prevFinger->mPartner )
|
||||
{
|
||||
startFrame = prevFrame;
|
||||
prevFrame = getPrevFrameNo( prevFrame );
|
||||
prevFinger = mFingersPerFrame[ prevFrame ].getFinger( aFinger.mId );
|
||||
}
|
||||
|
||||
if( mNextRenderedFrame == startFrame )
|
||||
return;
|
||||
|
||||
Finger const *startFinger( mFingersPerFrame[ startFrame ].getFinger( aFinger.mId ) );
|
||||
Finger const *startPartner( mFingersPerFrame[ startFrame ].at( startFinger->mPartner ) );
|
||||
|
||||
Finger const *endFinger( &aFinger );
|
||||
Finger const *endPartner( mFingersPerFrame[ startFrame ].at( endFinger->mPartner ) );
|
||||
|
||||
float vecStart[3], vecEnd[3];
|
||||
subtract( startFinger->mTip, startPartner->mTip, vecStart );
|
||||
subtract( endFinger->mTip, endPartner->mTip, vecEnd );
|
||||
|
||||
float lenStart = normalize( vecStart );
|
||||
float lenEnd = normalize( vecEnd );
|
||||
|
||||
float radius = lenStart>lenEnd?lenStart:lenEnd;
|
||||
|
||||
float alpha = dot( vecStart, vecEnd );
|
||||
|
||||
float ptStart[3], ptEnd[3];
|
||||
move( startFinger->mTip, vecStart, radius/2, ptStart );
|
||||
|
||||
ptEnd[0] = ptStart[0]*cos(alpha) - ptStart[1]*sin(alpha);
|
||||
ptEnd[1] = ptStart[1]*cos(alpha) + ptStart[0]*sin(alpha);
|
||||
ptEnd[2] = ptStart[2];
|
||||
|
||||
gGL.vertex3fv( ptStart );
|
||||
gGL.vertex3fv( ptEnd );
|
||||
}
|
||||
|
||||
void ManipTool::renderFinger( Finger const &aFinger, U16 aIndex )
|
||||
{
|
||||
if( aFinger.mPartner )
|
||||
gGL.diffuseColor4f( 0.f, 1.0f, 0.0f, 1.f);
|
||||
else if( aFinger.mSelected )
|
||||
gGL.diffuseColor4f( 0.f, 0.0f, 1.0f, 1.f);
|
||||
else
|
||||
gGL.diffuseColor4f( 1.f, 1.0f, 1.0f, 1.f);
|
||||
|
||||
renderCone( aFinger );
|
||||
renderMovementDirection( aFinger );
|
||||
renderMovementAngle( aFinger, aIndex );
|
||||
}
|
||||
|
||||
void ManipTool::render()
|
||||
{
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
gGL.pushMatrix();
|
||||
gGL.begin(LLRender::LINES);
|
||||
|
||||
LLQuaternion rot = gAgentAvatarp->getRotationRegion();
|
||||
LLVector3 pos = gAgentAvatarp->getPositionAgent();
|
||||
|
||||
gGL.translatef( pos.mV[0], pos.mV[1], pos.mV[2] );
|
||||
gGL.multMatrix( (GLfloat*) gAgentAvatarp->getRotationRegion().getMatrix4().mMatrix );
|
||||
|
||||
gGL.begin(LLRender::LINES);
|
||||
|
||||
Fingers &curFingers = mFingersPerFrame[ mNextRenderedFrame ];
|
||||
for( U16 i = 0; i < curFingers.mStoredFingers; ++i )
|
||||
{
|
||||
Finger &curFinger = curFingers.mFingers[ i ];
|
||||
renderFinger( curFinger, i );
|
||||
}
|
||||
|
||||
gGL.end();
|
||||
|
||||
gGL.popMatrix();
|
||||
mNextRenderedFrame = mLastStoredFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* $LicenseInfo:firstyear=2014&license=fsviewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2014, Nicky Dasmijn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef NDLEAPMANIPTOOL_H
|
||||
#define NDLEAPMANIPTOOL_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fsleaptool.h"
|
||||
#include <string.h>
|
||||
|
||||
class LLViewerObject;
|
||||
|
||||
namespace nd
|
||||
{
|
||||
namespace leap
|
||||
{
|
||||
struct Finger;
|
||||
struct Fingers;
|
||||
class ManipTool: public Tool
|
||||
{
|
||||
enum EMAXKEPTFRAMES{ eMaxKeptFrames = 120 };
|
||||
|
||||
inline U16 getNextFrameNo( U16 aFrame ) const
|
||||
{ return aFrame==eMaxKeptFrames-1?0:aFrame+1; }
|
||||
inline U16 getPrevFrameNo( U16 aFrame ) const
|
||||
{ return aFrame==0?eMaxKeptFrames-1:aFrame-1; }
|
||||
|
||||
inline U32 getMaxBacktrackMicroseconds() const
|
||||
{ return 1500*1000; }
|
||||
|
||||
U64 mLastExaminedFrame;
|
||||
U16 mLastStoredFrame;
|
||||
U16 mNextRenderedFrame;
|
||||
U64 mTotalStoredFrames;
|
||||
|
||||
Fingers *mFingersPerFrame;
|
||||
|
||||
void clearSelection();
|
||||
void doSelect();
|
||||
|
||||
void selectWithFinger( U16 aIndex );
|
||||
void findPartner( U16 aIndex );
|
||||
|
||||
void renderCone( Finger const & );
|
||||
void renderMovementDirection( Finger const & );
|
||||
void renderMovementAngle( Finger const &, U16 aIndex );
|
||||
void renderFinger( Finger const&, U16 aIndex );
|
||||
|
||||
public:
|
||||
ManipTool();
|
||||
virtual ~ManipTool();
|
||||
|
||||
virtual void onLeapFrame( Leap::Frame const& );
|
||||
virtual void onRenderFrame( Leap::Frame const& );
|
||||
virtual void render();
|
||||
virtual std::string getDebugString();
|
||||
virtual std::string getName();
|
||||
virtual S32 getId();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -25,11 +25,14 @@
|
|||
|
||||
#include "fsleaptool.h"
|
||||
#include "fsleapexampletool.h"
|
||||
#include "fsleapmaniptool.h"
|
||||
|
||||
nd::leap::Tool* nd::leap::constructTool( S32 aTool )
|
||||
{
|
||||
if( 111 == aTool )
|
||||
return new nd::leap::ExampleTool();
|
||||
if( 11 == aTool )
|
||||
return new nd::leap::ManipTool();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
namespace Leap
|
||||
{
|
||||
class HandList;
|
||||
class Frame;
|
||||
}
|
||||
|
||||
namespace nd
|
||||
|
|
@ -41,7 +42,8 @@ namespace nd
|
|||
public:
|
||||
virtual ~Tool(){}
|
||||
|
||||
virtual void onFrame( Leap::HandList const& ) = 0;
|
||||
virtual void onLeapFrame( Leap::Frame const& ) = 0;
|
||||
virtual void onRenderFrame( Leap::Frame const& ) = 0;
|
||||
virtual void render() = 0;
|
||||
virtual std::string getDebugString() = 0;
|
||||
virtual std::string getName() = 0;
|
||||
|
|
|
|||
|
|
@ -175,6 +175,9 @@ void LLLMImpl::onFrame(const Leap::Controller& controller)
|
|||
mCurrentFrameID = frame_id;
|
||||
mFrameAvailable = true;
|
||||
}
|
||||
|
||||
if( mTool )
|
||||
mTool->onLeapFrame( frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -207,13 +210,14 @@ void LLLMImpl::stepFrame()
|
|||
|
||||
static LLCachedControl<S32> sControllerMode(gSavedSettings, "LeapMotionTestMode", 0);
|
||||
|
||||
if( mTool && mTool->getId() != sControllerMode )
|
||||
if( !mTool || mTool->getId() != sControllerMode )
|
||||
{
|
||||
delete mTool;
|
||||
|
||||
mTool = nd::leap::constructTool( sControllerMode );
|
||||
mTool = nd::leap::constructTool( sControllerMode );
|
||||
}
|
||||
|
||||
if( mTool )
|
||||
mTool->onFrame( hands );
|
||||
mTool->onRenderFrame( frame );
|
||||
else
|
||||
{
|
||||
switch (sControllerMode)
|
||||
|
|
|
|||
|
|
@ -1000,7 +1000,10 @@ LLSelectNode *LLSelectMgr::getPrimaryHoverNode()
|
|||
return mHoverObjects->mSelectNodeMap[mHoverObjects->mPrimaryObject];
|
||||
}
|
||||
|
||||
void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
|
||||
// <FS:ND> Color per highlighted object
|
||||
//void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
|
||||
void LLSelectMgr::highlightObjectOnly(LLViewerObject *objectp, LLColor4 const &aColor )
|
||||
// </FS:ND>
|
||||
{
|
||||
if (!objectp)
|
||||
{
|
||||
|
|
@ -1027,6 +1030,8 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
|
|||
// </FS:Ansariel>
|
||||
|
||||
mRectSelectedObjects.insert(objectp);
|
||||
|
||||
mHighlightColor[ objectp ] = aColor; // <FS:ND/> Color per highlighted object
|
||||
}
|
||||
|
||||
void LLSelectMgr::highlightObjectAndFamily(LLViewerObject* objectp)
|
||||
|
|
@ -1088,6 +1093,7 @@ void LLSelectMgr::unhighlightObjectOnly(LLViewerObject* objectp)
|
|||
}
|
||||
|
||||
mRectSelectedObjects.erase(objectp);
|
||||
mHighlightColor.erase( objectp ); // <FS:ND/> Color per highlighted object
|
||||
}
|
||||
|
||||
void LLSelectMgr::unhighlightObjectAndFamily(LLViewerObject* objectp)
|
||||
|
|
@ -1115,6 +1121,8 @@ void LLSelectMgr::unhighlightAll()
|
|||
{
|
||||
mRectSelectedObjects.clear();
|
||||
mHighlightedObjects->deleteAllNodes();
|
||||
|
||||
mHighlightColor.clear(); // <FS:ND/> Color per highlighted object
|
||||
}
|
||||
|
||||
LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()
|
||||
|
|
@ -5575,6 +5583,11 @@ void LLSelectMgr::updateSilhouettes()
|
|||
LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE);
|
||||
rect_select_root_node->selectAllTEs(TRUE);
|
||||
|
||||
// <FS:ND> Color per highlighted object
|
||||
if( mHighlightColor.find( objectp ) != mHighlightColor.end() )
|
||||
rect_select_root_node->mHighlightColor = mHighlightColor[ objectp ];
|
||||
// </FS:ND>
|
||||
|
||||
if (!select_linked_set)
|
||||
{
|
||||
rect_select_root_node->mIndividualSelection = TRUE;
|
||||
|
|
@ -6206,7 +6219,7 @@ void pushWireframe(LLDrawable* drawable)
|
|||
|
||||
}
|
||||
|
||||
void LLSelectNode::renderOneWireframe(const LLColor4& color)
|
||||
void LLSelectNode::renderOneWireframe(const LLColor4& color)
|
||||
{
|
||||
LLViewerObject* objectp = getObject();
|
||||
if (!objectp)
|
||||
|
|
@ -6296,8 +6309,17 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)
|
|||
//-----------------------------------------------------------------------------
|
||||
// renderOneSilhouette()
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
|
||||
// <FS:ND> Color per highlighted object
|
||||
//void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
|
||||
void LLSelectNode::renderOneSilhouette(const LLColor4 &aColor)
|
||||
// </FS:ND>
|
||||
{
|
||||
// <FS:ND> Color per highlighted object
|
||||
LLColor4 color( aColor );
|
||||
if( this->mHighlightColor.lengthSquared() > 0 )
|
||||
color = this->mHighlightColor;
|
||||
// </FS:ND>
|
||||
|
||||
LLViewerObject* objectp = getObject();
|
||||
if (!objectp)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -194,6 +194,8 @@ public:
|
|||
std::vector<LLVector3> mSilhouetteNormals; // array of normals to render silhouette of object
|
||||
BOOL mSilhouetteExists; // need to generate silhouette?
|
||||
|
||||
LLColor4 mHighlightColor; // <FS:ND/> Color per highlighted object
|
||||
|
||||
protected:
|
||||
LLPointer<LLViewerObject> mObject;
|
||||
S32 mTESelectMask;
|
||||
|
|
@ -440,7 +442,11 @@ public:
|
|||
LLSelectNode *getHoverNode();
|
||||
LLSelectNode *getPrimaryHoverNode();
|
||||
|
||||
void highlightObjectOnly(LLViewerObject *objectp);
|
||||
// <FS:ND> Color per highlighted object
|
||||
// void highlightObjectOnly(LLViewerObject *objectp);
|
||||
void highlightObjectOnly(LLViewerObject *objectp, LLColor4 const &aColor = LLColor4() );
|
||||
// </FS:ND>
|
||||
|
||||
void highlightObjectAndFamily(LLViewerObject *objectp);
|
||||
void highlightObjectAndFamily(const std::vector<LLViewerObject*>& list);
|
||||
|
||||
|
|
@ -782,6 +788,8 @@ private:
|
|||
LLObjectSelectionHandle mHighlightedObjects;
|
||||
std::set<LLPointer<LLViewerObject> > mRectSelectedObjects;
|
||||
|
||||
std::map< LLPointer< LLViewerObject >, LLColor4 > mHighlightColor; // <FS:ND/> Color per highlighted object
|
||||
|
||||
LLObjectSelection mGridObjects;
|
||||
LLQuaternion mGridRotation;
|
||||
LLVector3 mGridOrigin;
|
||||
|
|
|
|||
Loading…
Reference in New Issue