From d0f2cf32345e45b1276fe8a2c444b77a03a98919 Mon Sep 17 00:00:00 2001 From: Nicky Date: Sun, 13 Apr 2014 23:14:38 +0200 Subject: [PATCH] Demo tool to select objects via Leap controller. --- indra/newview/CMakeLists.txt | 4 +- indra/newview/fsleapexampletool.cpp | 10 +- indra/newview/fsleapexampletool.h | 3 +- indra/newview/fsleapmaniptool.cpp | 576 +++++++++++++++++++++++ indra/newview/fsleapmaniptool.h | 85 ++++ indra/newview/fsleaptool.cpp | 3 + indra/newview/fsleaptool.h | 4 +- indra/newview/llleapmotioncontroller.cpp | 12 +- indra/newview/llselectmgr.cpp | 28 +- indra/newview/llselectmgr.h | 10 +- 10 files changed, 720 insertions(+), 15 deletions(-) create mode 100644 indra/newview/fsleapmaniptool.cpp create mode 100644 indra/newview/fsleapmaniptool.h diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 91048a6e77..f69a129542 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -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) diff --git a/indra/newview/fsleapexampletool.cpp b/indra/newview/fsleapexampletool.cpp index 8ab64ffa3b..f8cfffe515 100644 --- a/indra/newview/fsleapexampletool.cpp +++ b/indra/newview/fsleapexampletool.cpp @@ -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() diff --git a/indra/newview/fsleapexampletool.h b/indra/newview/fsleapexampletool.h index 2c504df7e3..2459f4eb1c 100644 --- a/indra/newview/fsleapexampletool.h +++ b/indra/newview/fsleapexampletool.h @@ -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(); diff --git a/indra/newview/fsleapmaniptool.cpp b/indra/newview/fsleapmaniptool.cpp new file mode 100644 index 0000000000..6b7f278a4a --- /dev/null +++ b/indra/newview/fsleapmaniptool.cpp @@ -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 + +#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; + } + } +} \ No newline at end of file diff --git a/indra/newview/fsleapmaniptool.h b/indra/newview/fsleapmaniptool.h new file mode 100644 index 0000000000..3988fe21b2 --- /dev/null +++ b/indra/newview/fsleapmaniptool.h @@ -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 + +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 diff --git a/indra/newview/fsleaptool.cpp b/indra/newview/fsleaptool.cpp index 0784abf8b5..6714a46370 100644 --- a/indra/newview/fsleaptool.cpp +++ b/indra/newview/fsleaptool.cpp @@ -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; } \ No newline at end of file diff --git a/indra/newview/fsleaptool.h b/indra/newview/fsleaptool.h index d3fba120a0..8cab0161ee 100644 --- a/indra/newview/fsleaptool.h +++ b/indra/newview/fsleaptool.h @@ -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; diff --git a/indra/newview/llleapmotioncontroller.cpp b/indra/newview/llleapmotioncontroller.cpp index ad50a739ac..447476c909 100644 --- a/indra/newview/llleapmotioncontroller.cpp +++ b/indra/newview/llleapmotioncontroller.cpp @@ -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 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) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index e44ca54049..44943759cb 100755 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1000,7 +1000,10 @@ LLSelectNode *LLSelectMgr::getPrimaryHoverNode() return mHoverObjects->mSelectNodeMap[mHoverObjects->mPrimaryObject]; } -void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) +// Color per highlighted object +//void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) +void LLSelectMgr::highlightObjectOnly(LLViewerObject *objectp, LLColor4 const &aColor ) +// { if (!objectp) { @@ -1027,6 +1030,8 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) // mRectSelectedObjects.insert(objectp); + + mHighlightColor[ objectp ] = aColor; // Color per highlighted object } void LLSelectMgr::highlightObjectAndFamily(LLViewerObject* objectp) @@ -1088,6 +1093,7 @@ void LLSelectMgr::unhighlightObjectOnly(LLViewerObject* objectp) } mRectSelectedObjects.erase(objectp); + mHighlightColor.erase( objectp ); // Color per highlighted object } void LLSelectMgr::unhighlightObjectAndFamily(LLViewerObject* objectp) @@ -1115,6 +1121,8 @@ void LLSelectMgr::unhighlightAll() { mRectSelectedObjects.clear(); mHighlightedObjects->deleteAllNodes(); + + mHighlightColor.clear(); // 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); + // Color per highlighted object + if( mHighlightColor.find( objectp ) != mHighlightColor.end() ) + rect_select_root_node->mHighlightColor = mHighlightColor[ objectp ]; + // + 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) +// Color per highlighted object +//void LLSelectNode::renderOneSilhouette(const LLColor4 &color) +void LLSelectNode::renderOneSilhouette(const LLColor4 &aColor) +// { + // Color per highlighted object + LLColor4 color( aColor ); + if( this->mHighlightColor.lengthSquared() > 0 ) + color = this->mHighlightColor; + // + LLViewerObject* objectp = getObject(); if (!objectp) { diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 364bd91a25..2514095809 100755 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -194,6 +194,8 @@ public: std::vector mSilhouetteNormals; // array of normals to render silhouette of object BOOL mSilhouetteExists; // need to generate silhouette? + LLColor4 mHighlightColor; // Color per highlighted object + protected: LLPointer mObject; S32 mTESelectMask; @@ -440,7 +442,11 @@ public: LLSelectNode *getHoverNode(); LLSelectNode *getPrimaryHoverNode(); - void highlightObjectOnly(LLViewerObject *objectp); + // Color per highlighted object + // void highlightObjectOnly(LLViewerObject *objectp); + void highlightObjectOnly(LLViewerObject *objectp, LLColor4 const &aColor = LLColor4() ); + // + void highlightObjectAndFamily(LLViewerObject *objectp); void highlightObjectAndFamily(const std::vector& list); @@ -782,6 +788,8 @@ private: LLObjectSelectionHandle mHighlightedObjects; std::set > mRectSelectedObjects; + std::map< LLPointer< LLViewerObject >, LLColor4 > mHighlightColor; // Color per highlighted object + LLObjectSelection mGridObjects; LLQuaternion mGridRotation; LLVector3 mGridOrigin;