Ejemplo n.º 1
0
static VALUE each(VALUE self)
{
  Leap::PointableList * list;
  int i;

  Data_Get_Struct(self, Leap::PointableList, list);

  for (i = 0; i < list->count(); i++) {
    rb_yield(MakePointable((*list)[i]));
  }

  return self;
}
void LeapSample03App::draw()
{
    gl::clear( Color( .97, .93, .79 ) );
    Leap::PointableList pointables = leap.frame().pointables();
    Leap::InteractionBox iBox = leap.frame().interactionBox();

    for ( int p = 0; p < pointables.count(); p++ ) {
        Leap::Pointable pointable = pointables[p];
#if 1
        // ここから追加
        // 伸びている指、ツール以外は無視する
        if ( !pointable.isExtended() ) {
            continue;
        }
        // ここまで追加
#endif

        Leap::Vector normalizedPosition =
            iBox.normalizePoint( pointable.stabilizedTipPosition() );
        float x = normalizedPosition.x * windowWidth;
        float y = windowHeight - normalizedPosition.y * windowHeight;

        // ホバー状態
        if ( (pointable.touchDistance() > 0) &&
            (pointable.touchZone() != Leap::Pointable::Zone::ZONE_NONE) ) {
            gl::color(0, 1, 0, 1 - pointable.touchDistance());
        }
        // タッチ状態
        else if ( pointable.touchDistance() <= 0 ) {
            gl::color(1, 0, 0, -pointable.touchDistance());
        }
        // タッチ対象外
        else {
            gl::color(0, 0, 1, .05);
        }

        gl::drawSolidCircle( Vec2f( x, y ), 40 );
    }
}
Ejemplo n.º 3
0
bool LeapHandler::findBestMatchOnCurrentFrame(Point2i & inputWorld, float radius, LeapMapping & leap2world, Point3i &match)
{


    Leap::PointableList list;
    list = frame.pointables();
    //cout<<(list[0].tipPosition()[2]<-2)<<endl;

    match.x=-1;
    match.y=-1;
    match.z=-1;


    if( !list.isEmpty() ){
        cout<<"Leap found Pointables: "<<list.count()<<endl;

        //Vector<float> distances;
        float minDist=1e9;
        int minIdx=-1;
        //cout<<"Found "<<list.count()<<" tip(s)."<<endl;
        Leap::Vector leapTipMatch;
        //get (closest) tips' positions from Leap
        for(int i=0;i<list.count();i++)
        {
            Leap::Pointable element=list[i];
            Leap::Vector position =  element.tipPosition();
            Point2i positionLeap;
            positionLeap.x=position[0];
            positionLeap.y=position[1];
            leap2world.mapPoints( positionLeap, positionLeap );
            //leapTouchPts.push_back(Point(position[0],position[1]));

            //converting leap to world

            float distx=inputWorld.x-positionLeap.x;
            float disty=inputWorld.y-positionLeap.y;
            float dist=std::sqrt(distx*distx+disty*disty);

            if(dist<radius && dist<minDist)
            {
                minDist=dist;
                minIdx=i;
                leapTipMatch.x=positionLeap.x;
                leapTipMatch.y=positionLeap.y;
                leapTipMatch.z=position[2];

            }
        }

        bool leapMatchFound=(minIdx!=-1);
        if(leapMatchFound){//point found
            cout<<"Leap best match found "<<match<<endl;
            //cout<<minIdx<<endl;
            //cout<<"Updated touch location: "<<leapTipMatch<<endl;
            //filteredPt=leapTouchPts[minIdx];
            match.x=leapTipMatch[0];
            match.y=leapTipMatch[1];
            match.z=leapTipMatch[2];
            return true;
        }
        else{
            //use Kinect's touch determination
            //return kinectTouchPt;
            return false;
        }
    }else{
        cout<<"Leap list empty"<<endl;
    }

    return false;
}
Ejemplo n.º 4
0
void ZirkLeap::onFrame(const Leap::Controller& controller) {
    if(controller.hasFocus()) {
        Leap::Frame frame = controller.frame();
        if (mPointableId >= 0) {
            ourProcessor->setSelectedSource(mEditor->getCBSelectedSource()-1);
            Leap::Pointable p = frame.pointable(mPointableId);
            if (!p.isValid() || !p.isExtended()) {
                mPointableId = -1;
                mLastPositionValid = false;
            } else {
                Leap::Vector pos = p.tipPosition();
                const float zPlane1 = 50;	// 5 cm
                const float zPlane2 = 100;	// 10 cm
                
                if (pos.z < zPlane2) {
                    if (mLastPositionValid) {
                        //Leap Motion mouvement are calculated from the last position in order to have something dynamic and ergonomic
                        Leap::Vector delta = pos- mLastPosition;
                        
                        float scale = 3;
                        if (pos.z > zPlane1) {
                            float s = 1 - (pos.z - zPlane1) / (zPlane2 - zPlane1);
                            scale *= s;
                            
                        }
                        
                        int src = ourProcessor->getSelectedSource();
                        float fX, fY;
                        ourProcessor->getSources()[src].getXY(fX, fY);
                        fX += delta.x * scale;
                        fY -= delta.y * scale;
                        
                        //clamp coordinates to circle
                        float fCurR = hypotf(fX, fY);
                        if ( fCurR > ZirkOscAudioProcessor::s_iDomeRadius){
                            float fExtraRatio = ZirkOscAudioProcessor::s_iDomeRadius / fCurR;
                            fX *= fExtraRatio;
                            fY *= fExtraRatio;
                        }
                        
                        mEditor->move(src, fX, fY);
                    } else {
                        //std::cout << "pointable last pos not valid" << std::endl;
                    }
                    mLastPosition = pos;
                    mLastPositionValid = true;
                } else {
                    //std::cout << "pointable not touching plane" << std::endl;
                    mLastPositionValid = false;
                }
            }
        }
        if (mPointableId < 0) {
            Leap::PointableList pl = frame.pointables().extended();
            if (pl.count() > 0) {
                mPointableId = pl[0].id();
                //std::cout << "got new pointable: " << mPointableId << std::endl;
            }
        }
    }
}
Ejemplo n.º 5
0
//function to get a frame and return it in the format acceptable to MATLAB
//ie mxArray
void loadFrame(mxArray *plhs[])
{
    //get current frame
	Leap::Frame frame = controller->frame();
	//DEBUG: check if frame is valid
	if(!frame.isValid()) mexErrMsgTxt("Frame returned was not valid");
    //wait for frame to be valid
	//while(!frame.isValid()) controller->frame();
    
    Leap::HandList hands = frame.hands();
    
    //import variables and create struct
	
	//number of hands
	int numHands = hands.count();
	
	//if there are no hands return a null pointer
	if(!numHands){
		plhs[0] = mxCreateDoubleScalar(0);
		return;
	}
	
	//fields returned to matlab in the struct:
	int numHandFields = 4;    //change number of fields here****
	const char *hand_field_names[] = 
	{
		"position",
		"velocity",
		"direction",
		"pointables"
		//add new hand fields here****
	};
	
	//pointable temp values for a given hand
	int numPointables;
	Leap::PointableList pointList;
	int numPointFields = 3;  	//change number of pointable fields here****
	const char *point_field_names[] = 
	{
		"position",
		"velocity",
		"direction"
		//add new pointable fields here****
	};
	mxArray *p;	
		
	//allocate the structure array to export to matlab
	mxArray *h = mxCreateStructMatrix(1, numHands, numHandFields, hand_field_names);
	
	//put vectors into structure array fields
	int i,j; //iterators
	for(i=0;i<numHands;i++){
		//fill in hand information
		mxSetFieldByNumber(h,i,0,makeVector(hands[i].palmPosition()));
		mxSetFieldByNumber(h,i,1,makeVector(hands[i].palmVelocity()));
		mxSetFieldByNumber(h,i,2,makeVector(hands[i].direction()));
		// add new field information here****
		//create pointable struct for this hand
		pointList = hands[i].pointables();		//get list of pointables for this hand
		numPointables = pointList.count();	    //get number of pointables for this hand
		//build list of pointables
		p = mxCreateStructMatrix(1,numPointables,numPointFields,point_field_names);
		for(j=0;j<numPointables;j++){
			mxSetFieldByNumber(p,j,0,makeVector(pointList[j].tipPosition()));
			mxSetFieldByNumber(p,j,1,makeVector(pointList[j].tipVelocity()));
			mxSetFieldByNumber(p,j,2,makeVector(pointList[j].direction()));
			//add new pointable fields here****
		}
		//put pointable list into hand struct
		mxSetFieldByNumber(h,i,3,p);
	}
    plhs[0] = h;  //set output
    return;
}
Ejemplo n.º 6
0
void MouseListener::onFrame(const Leap::Controller &controller) {
    // get list of detected screens
    const Leap::ScreenList screens = controller.calibratedScreens();
    
    // make sure we have a detected screen
    if (screens.empty()) return;
    const Leap::Screen screen = screens[0];

    // get hands
    const Leap::Frame frame = controller.frame();
    const Leap::HandList hands = frame.hands();
    if (hands.empty()) return;
    
    // which is the pointer hand and which is the clicker hand?
    // if there's only one hand it's the pointer hand. if there's two
    // then we'll use the user's primary hand. if ambidextrous, bail.
    Leap::Hand pointerHand, clickerHand;
    
    if (pointerHandID) {
        pointerHand = frame.hand(pointerHandID);
        if (! pointerHand.isValid())
            pointerHand = hands[0];
    }
    
    if (clickerHandID)
        clickerHand = frame.hand(clickerHandID);

    if (! clickerHand.isValid() && hands.count() == 2) {
        // figure out clicker and pointer hand
                
        // which hand is on the left and which is on the right?
        Leap::Hand leftHand, rightHand;
        if (hands[0].palmPosition()[0] <= hands[1].palmPosition()[0]) {
            leftHand = hands[0];
            rightHand = hands[1];
        } else {
            leftHand = hands[1];
            rightHand = hands[0];
        }
        
        // now that we know the left and right hands, determine
        // which is the clicker and which is the pointer
        if (leftHanded) {
            pointerHand = leftHand;
            clickerHand = rightHand;
        } else {
            pointerHand = rightHand;
            clickerHand = leftHand;
        }
        
        // keep track of which hands we decided on
        clickerHandID = clickerHand.id();
        pointerHandID = pointerHand.id();
    }
    
    // find the first finger or tool
    const Leap::PointableList pointables = pointerHand.pointables();
    if (pointables.empty()) return;
    const Leap::Pointable firstPointable = pointables[0];
    
    // get x, y coordinates on the first screen
    const Leap::Vector intersection = screen.intersect(
                                                       firstPointable,
                                                       true,  // normalize
                                                       1.0f   // clampRatio
                                                       );
    
    // if the user is not pointing at the screen all components of
    // the returned vector will be Not A Number (NaN)
    // isValid() returns true only if all components are finite
    if (! intersection.isValid()) return;
    
    unsigned int x = screen.widthPixels() * intersection.x;
    // flip y coordinate to standard top-left origin
    unsigned int y = screen.heightPixels() * (1.0f - intersection.y);
    
    // move cursor to location pointed at
    CGPoint destPoint = CGPointMake(x, y);
    CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, destPoint);
    
    // check for click gesture
    if (! clickerHand.isValid()) return;
    
    // click = two fingers on the clicker hand touching together

    const Leap::PointableList clickerFingers = clickerHand.pointables();
    if (clickerFingers.count() != 2) return;
    
    // get finger distance
    float clickFingerDistance = clickerFingers[0].tipPosition().distanceTo(
                                                                           clickerFingers[1].tipPosition()
                                                                           );
    cout << "distance: " << clickFingerDistance << endl;
    if (! clickActive && clickFingerDistance < clickActivationDistance) {
        clickActive = true;
        cout << "mouseDown\n";
        postMouseDown(x, y);
    } else if (clickActive && clickFingerDistance > clickActivationDistance) {
        cout << "mouseUp\n";
        clickActive = false;
        postMouseUp(x, y);
    }
}
Ejemplo n.º 7
0
void oleap_bang(t_oleap *x)
{

	const Leap::Frame frame = x->leap->frame();
    const int64_t frame_id = frame.id();
    Leap::Controller controller;
    
	// ignore the same frame
	if (frame_id == x->frame_id_save) return;
	x->frame_id_save = frame_id;
	
	//outlet_anything(x->outlet, gensym("frame_start"), 0, nil);
    
    char buff[128];
    
    const Leap::HandList hands = frame.hands();
	const size_t numHands = hands.count();
    const Leap::Hand leftmost = hands.leftmost();
    const Leap::Hand rightmost = hands.rightmost();
    
    t_osc_bundle_u *bundle = osc_bundle_u_alloc();//alloc creates memory for and initializes the bundle

    controller.enableGesture(Leap::Gesture::TYPE_CIRCLE);
    controller.enableGesture(Leap::Gesture::TYPE_KEY_TAP);
    controller.enableGesture(Leap::Gesture::TYPE_SCREEN_TAP);
    controller.enableGesture(Leap::Gesture::TYPE_SWIPE);
    
    
    // Get gestures
    const Leap::GestureList gestures = frame.gestures();
    
    for (int g = 0; g < gestures.count(); ++g) {
        Leap::Gesture gesture = gestures[g];
        
        switch (gesture.type()) {
            case Leap::Gesture::TYPE_CIRCLE:
            {
                
                Leap::CircleGesture circle = gesture;
                std::string clockwiseness;
                
                sprintf(buff,"/gesture/circle/center/x");
                oleap_bundleMessage(bundle,buff,circle.center().x);
                
                sprintf(buff,"/gesture/circle/center/y");
                oleap_bundleMessage(bundle,buff,circle.center().y);
                
                sprintf(buff,"/gesture/circle/center/z");
                oleap_bundleMessage(bundle,buff,circle.center().z);
                
                sprintf(buff,"/gesture/circle/pitch");
                oleap_bundleMessage(bundle,buff,circle.center().pitch());
                
                sprintf(buff,"/gesture/circle/yaw");
                oleap_bundleMessage(bundle,buff,circle.center().yaw());
                
                sprintf(buff,"/gesture/circle/roll");
                oleap_bundleMessage(bundle,buff,circle.center().roll());
                
                sprintf(buff,"/gesture/circle/radius");
                oleap_bundleMessage(bundle,buff,circle.radius());
                
                sprintf(buff,"/gesture/circle/duration");
                oleap_bundleMessage(bundle,buff,circle.duration());
                
                
                if (circle.pointable().direction().angleTo(circle.normal()) <= Leap::PI/4) {
                    clockwiseness = "clockwise";
                    
                    sprintf(buff,"/gesture/circle/clockwiseness/");
                    oleap_bundleMessage(bundle,buff,1);
                    
                } else {
                    clockwiseness = "counterclockwise";
                    
                    sprintf(buff,"/gesture/circle/clockwiseness/");
                    oleap_bundleMessage(bundle,buff,-1);
                }
                
                
                // Calculate angle swept since last frame
                float sweptAngle = 0;
                if (circle.state() != Leap::Gesture::STATE_START) {
                    Leap::CircleGesture previousUpdate = Leap::CircleGesture(controller.frame(1).gesture(circle.id()));
                    sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * Leap::PI;
                    
                    sprintf(buff,"/gesture/circle/angle/sweep");
                    oleap_bundleMessage(bundle,buff,sweptAngle);
                }
            }
                
            case Leap::Gesture::TYPE_SWIPE:
            {
                Leap::SwipeGesture swipe = gesture;
                int swipe_id = gesture.id();
                int gesture_state = gesture.state();
                Leap::Vector swipe_direction = swipe.direction();
                float swipe_speed = swipe.speed();
                
                ////////////////////////////////Swipe data
                
                sprintf(buff,"/gesture/swipe/direction/x");
                oleap_bundleMessage(bundle,buff,swipe_direction.x);
                
                sprintf(buff,"/gesture/swipe/direction/x");
                oleap_bundleMessage(bundle,buff,swipe_direction.y);
                
                sprintf(buff,"/gesture/swipe/direction/x");
                oleap_bundleMessage(bundle,buff,swipe_direction.z);
                
                sprintf(buff,"/gesture/swipe/position/x");
                oleap_bundleMessage(bundle,buff,swipe.position().x);
                
                sprintf(buff,"/gesture/swipe/position/y");
                oleap_bundleMessage(bundle,buff,swipe.position().y);
                
                sprintf(buff,"/gesture/swipe/position/z");
                oleap_bundleMessage(bundle,buff,swipe.position().z);
                
                sprintf(buff,"/gesture/swipe/pitch");
                oleap_bundleMessage(bundle,buff,swipe.position().pitch());
                
                sprintf(buff,"/gesture/swipe/yaw");
                oleap_bundleMessage(bundle,buff,swipe.position().yaw());
                
                sprintf(buff,"/gesture/swipe/roll");
                oleap_bundleMessage(bundle,buff,swipe.position().roll());
                
                sprintf(buff,"/gesture/swipe/position/start/x");
                oleap_bundleMessage(bundle,buff,swipe.startPosition().x);
                
                sprintf(buff,"/gesture/swipe/position/start/y");
                oleap_bundleMessage(bundle,buff,swipe.startPosition().y);
                
                sprintf(buff,"/gesture/swipe/position/start/z");
                oleap_bundleMessage(bundle,buff,swipe.startPosition().z);
                
                sprintf(buff,"/gesture/swipe/speed");
                oleap_bundleMessage(bundle,buff,swipe_speed);
                
                sprintf(buff,"/gesture/swipe/duration");
                oleap_bundleMessage(bundle,buff,swipe.duration());
            
                
            }
                
            case Leap::Gesture::TYPE_KEY_TAP:
            {
                Leap::KeyTapGesture tap = gesture;
                int tap_id = gesture.id();
                int tap_state = gesture.state();
                Leap::Vector tap_position = tap.position();
                Leap::Vector tap_direction = tap.direction();
                
                ////////////////////////////////Key tap data
                
                sprintf(buff,"/gesture/tap/down/position/x");
                oleap_bundleMessage(bundle,buff,tap_position.x);
                
                sprintf(buff,"/gesture/tap/down/position/y");
                oleap_bundleMessage(bundle,buff,tap_position.y);
                
                sprintf(buff,"/gesture/tap/down/position/z");
                oleap_bundleMessage(bundle,buff,tap_position.z);
                
                sprintf(buff,"/gesture/tap/down/direction/x");
                oleap_bundleMessage(bundle,buff,tap_direction.x);
                
                sprintf(buff,"/gesture/tap/down/direction/y");
                oleap_bundleMessage(bundle,buff,tap_direction.y);
                
                sprintf(buff,"/gesture/tap/down/direction/z");
                oleap_bundleMessage(bundle,buff,tap_direction.z);
                
                sprintf(buff,"/gesture/tap/down/duration");
                oleap_bundleMessage(bundle,buff,tap.duration());
          
            }
                
            case Leap::Gesture::TYPE_SCREEN_TAP:
            {
                Leap::ScreenTapGesture screentap = gesture;
                int screen_tap_id = gesture.id();
                int screen_tap_state = gesture.state();
                Leap::Vector screentap_position = screentap.position();
                Leap::Vector screentap_direction = screentap.direction();
                
                ////////////////////////////////Screen tap data
                
                sprintf(buff,"/gesture/tap/forward/position/x");
                oleap_bundleMessage(bundle,buff,screentap_position.x);
                
                sprintf(buff,"/gesture/tap/forward/position/y");
                oleap_bundleMessage(bundle,buff,screentap_position.y);
                
                sprintf(buff,"/gesture/tap/forward/position/z");
                oleap_bundleMessage(bundle,buff,screentap_position.z);
                
                sprintf(buff,"/gesture/tap/forward/direction/x");
                oleap_bundleMessage(bundle,buff,screentap_direction.x);
                
                sprintf(buff,"/gesture/tap/forward/direction/y");
                oleap_bundleMessage(bundle,buff,screentap_direction.y);
                
                sprintf(buff,"/gesture/tap/forward/direction/z");
                oleap_bundleMessage(bundle,buff,screentap_direction.z);
                
                sprintf(buff,"/gesture/tap/forward/duration");
                oleap_bundleMessage(bundle,buff,screentap.duration());

              
            }
            default:
                
                break;
        }
    }
    
    

    sprintf(buff,"/timeStamp");
    oleap_bundleMessage(bundle,buff,frame.timestamp());
    
    sprintf(buff,"/Hands");
    oleap_bundleMessage(bundle,buff,numHands);
    
    sprintf(buff,"/hand/leftmost/id");
    oleap_bundleMessage(bundle,buff,leftmost.id());
    
    sprintf(buff,"/hand/leftmost/palm/positiony/x");
    oleap_bundleMessage(bundle,buff,leftmost.palmPosition().x);
    
    sprintf(buff,"/hand/leftmost/palm/positiony/y");
    oleap_bundleMessage(bundle,buff,leftmost.palmPosition().y);
    
    sprintf(buff,"/hand/leftmost/palm/positiony/z");
    oleap_bundleMessage(bundle,buff,leftmost.palmPosition().z);

    sprintf(buff,"/hand/leftmost/direction/x");
    oleap_bundleMessage(bundle,buff,leftmost.direction().x);
    
    sprintf(buff,"/hand/leftmost/direction/y");
    oleap_bundleMessage(bundle,buff,leftmost.direction().y);
    
    sprintf(buff,"/hand/leftmost/direction/z");
    oleap_bundleMessage(bundle,buff,leftmost.direction().z);
    
    sprintf(buff,"/hand/leftmost/pitch");
    oleap_bundleMessage(bundle,buff,leftmost.palmPosition().pitch());
    
    sprintf(buff,"/hand/leftmost/yaw");
    oleap_bundleMessage(bundle,buff,leftmost.palmPosition().yaw());
    
    sprintf(buff,"/hand/leftmost/roll");
    oleap_bundleMessage(bundle,buff,leftmost.palmPosition().roll());
    
    sprintf(buff,"/hand/leftmost/palm/velocity/x");
    oleap_bundleMessage(bundle,buff,leftmost.palmVelocity().x);
    
    sprintf(buff,"/hand/leftmost/palm/velocity/y");
    oleap_bundleMessage(bundle,buff,leftmost.palmVelocity().y);
    
    sprintf(buff,"/hand/leftmost/palm/velocity/z");
    oleap_bundleMessage(bundle,buff,leftmost.palmVelocity().z);
    
    sprintf(buff,"/hand/leftmost/palm/sphere/center/x");
    oleap_bundleMessage(bundle,buff,leftmost.sphereCenter().x);
    
    sprintf(buff,"/hand/leftmost/palm/sphere/center/y");
    oleap_bundleMessage(bundle,buff,leftmost.sphereCenter().y);
    
    sprintf(buff,"/hand/leftmost/palm/sphere/center/z");
    oleap_bundleMessage(bundle,buff,leftmost.sphereCenter().z);

    sprintf(buff,"/hand/leftmost/palm/sphere/radius");
    oleap_bundleMessage(bundle,buff,leftmost.sphereRadius());
    
    sprintf(buff,"/hand/leftmost/palm/normal/x");
    oleap_bundleMessage(bundle,buff,leftmost.palmNormal().x);
    
    sprintf(buff,"/hand/leftmost/palm/normal/y");
    oleap_bundleMessage(bundle,buff,leftmost.palmNormal().y);
    
    sprintf(buff,"/hand/leftmost/palm/normal/z");
    oleap_bundleMessage(bundle,buff,leftmost.palmNormal().z);
    
    sprintf(buff,"/hand/leftmost/distance/from/rightmost");
    oleap_bundleMessage(bundle,buff,leftmost.palmPosition().angleTo(rightmost.palmPosition()));
    
    const Leap::FingerList &fingers = leftmost.fingers();
    const size_t numFingers = fingers.count();
    
    for(size_t j = 0; j < numFingers; j++)
    {
        const Leap::Finger &finger = fingers[j];
        const int32_t finger_id = finger.id();
        //const Leap::Ray& tip = finger.tip();
        const Leap::Vector direction = finger.direction();
        const Leap::Vector position = finger.tipPosition();
        const Leap::Vector velocity = finger.tipVelocity();
        const double width = finger.width();
        const double length = finger.length();
        const bool isTool = finger.isTool();
        
        sprintf(buff,"/hand/leftmost/finger/%d/hand_id",j+1);
        oleap_bundleMessage(bundle,buff,leftmost.id());
        
        sprintf(buff,"/hand/leftmost/finger/%d/finger_id",j+1);
        oleap_bundleMessage(bundle,buff,finger.id());
        
        sprintf(buff,"/hand/leftmost/finger/%d/position/x",j+1);
        oleap_bundleMessage(bundle,buff,position.x);
        
        sprintf(buff,"/hand/leftmost/finger/%d/position/y",j+1);
        oleap_bundleMessage(bundle,buff,position.y);
        
        sprintf(buff,"/hand/leftmost/finger/%d/position/z",j+1);
        oleap_bundleMessage(bundle,buff,position.z);
        
        sprintf(buff,"/hand/leftmost/finger/%d/direction/x",j+1);
        oleap_bundleMessage(bundle,buff,direction.x);
        
        sprintf(buff,"/hand/leftmost/finger/%d/direction/y",j+1);
        oleap_bundleMessage(bundle,buff,direction.y);
        
        sprintf(buff,"/hand/leftmost/finger/%d/direction/z",j+1);
        oleap_bundleMessage(bundle,buff,direction.z);
        
        sprintf(buff,"/hand/leftmost/finger/%d/velocity/x",j+1);
        oleap_bundleMessage(bundle,buff,velocity.x);
        
        sprintf(buff,"/hand/leftmost/finger/%d/velocity/y",j+1);
        oleap_bundleMessage(bundle,buff,velocity.y);
        
        sprintf(buff,"/hand/leftmost/finger/%d/velocity/z",j+1);
        oleap_bundleMessage(bundle,buff,velocity.z);
    
        sprintf(buff,"/hand/leftmost/finger/%d/direction/normalized/x",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().x);
        
        sprintf(buff,"/hand/leftmost/finger/%d/direction/normalized/y",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().y);
        
        sprintf(buff,"/hand/leftmost/finger/%d/direction/normalized/z",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().z);
        
        sprintf(buff,"/hand/leftmost/finger/%d/pitch/normalized/",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().pitch());
        
        sprintf(buff,"/hand/leftmost/finger/%d/yaw/normalized/",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().yaw());
        
        sprintf(buff,"/hand/leftmost/finger/%d/roll/normalized/",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().roll());
        
        sprintf(buff,"/hand/leftmost/finger/%d/width",j+1);
        oleap_bundleMessage(bundle,buff,width);
        
        sprintf(buff,"/hand/leftmost/finger/%d/length",j+1);
        oleap_bundleMessage(bundle,buff,length);
        
        sprintf(buff,"/hand/leftmost/isTool",j+1);
        oleap_bundleMessage(bundle,buff,isTool);
        
        for(size_t i = j+1; i < numFingers; i++)
        {
            sprintf(buff,"/hand/leftmost/finger/%d/distance/to/finger/%d",j+1,i+1);
            oleap_bundleMessage(bundle,buff,fingers[j].direction().distanceTo(fingers[i].direction()));
            
            sprintf(buff,"/hand/leftmost/finger/%d/angle/to/finger/%d",j+1,i+1);
            oleap_bundleMessage(bundle,buff,fingers[j].direction().angleTo((fingers[i].direction())));
            
        }
        
    }
    
    sprintf(buff,"/hand/rightmost/id");
    oleap_bundleMessage(bundle,buff,rightmost.id());
    
    sprintf(buff,"/hand/rightmost/palm/positiony/x");
    oleap_bundleMessage(bundle,buff,rightmost.palmPosition().x);
    
    sprintf(buff,"/hand/rightmost/palm/positiony/y");
    oleap_bundleMessage(bundle,buff,rightmost.palmPosition().y);
    
    sprintf(buff,"/hand/rightmost/palm/positiony/z");
    oleap_bundleMessage(bundle,buff,rightmost.palmPosition().z);
    
    sprintf(buff,"/hand/rightmost/direction/x");
    oleap_bundleMessage(bundle,buff,rightmost.direction().x);
    
    sprintf(buff,"/hand/rightmost/direction/y");
    oleap_bundleMessage(bundle,buff,rightmost.direction().y);
    
    sprintf(buff,"/hand/rightmost/direction/z");
    oleap_bundleMessage(bundle,buff,rightmost.direction().z);
    
    sprintf(buff,"/hand/rightmost/pitch");
    oleap_bundleMessage(bundle,buff,rightmost.palmPosition().pitch());
    
    sprintf(buff,"/hand/rightmost/yaw");
    oleap_bundleMessage(bundle,buff,rightmost.palmPosition().yaw());
    
    sprintf(buff,"/hand/rightmost/roll");
    oleap_bundleMessage(bundle,buff,rightmost.palmPosition().roll());
    
    sprintf(buff,"/hand/rightmost/palm/velocity/x");
    oleap_bundleMessage(bundle,buff,rightmost.palmVelocity().x);
    
    sprintf(buff,"/hand/rightmost/palm/velocity/y");
    oleap_bundleMessage(bundle,buff,rightmost.palmVelocity().y);
    
    sprintf(buff,"/hand/rightmost/palm/velocity/z");
    oleap_bundleMessage(bundle,buff,rightmost.palmVelocity().z);
    
    sprintf(buff,"/hand/rightmost/palm/sphere/center/x");
    oleap_bundleMessage(bundle,buff,rightmost.sphereCenter().x);
    
    sprintf(buff,"/hand/rightmost/palm/sphere/center/y");
    oleap_bundleMessage(bundle,buff,rightmost.sphereCenter().y);
    
    sprintf(buff,"/hand/rightmost/palm/sphere/center/z");
    oleap_bundleMessage(bundle,buff,rightmost.sphereCenter().z);
    
    sprintf(buff,"/hand/rightmost/palm/sphere/radius");
    oleap_bundleMessage(bundle,buff,rightmost.sphereRadius());
    
    sprintf(buff,"/hand/rightmost/palm/normal/x");
    oleap_bundleMessage(bundle,buff,rightmost.palmNormal().x);
    
    sprintf(buff,"/hand/rightmost/palm/normal/y");
    oleap_bundleMessage(bundle,buff,rightmost.palmNormal().y);
    
    sprintf(buff,"/hand/rightmost/palm/normal/z");
    oleap_bundleMessage(bundle,buff,rightmost.palmNormal().z);
    
    sprintf(buff,"/hand/rightmost/distance/from/leftmost");
    oleap_bundleMessage(bundle,buff,rightmost.palmPosition().angleTo(leftmost.palmPosition()));
    
    const Leap::FingerList &rightMostfingers = rightmost.fingers();
    const size_t rightMostnNumFingers = fingers.count();
    
    for(size_t j = 0; j < rightMostnNumFingers; j++)
    {
        const Leap::Finger &finger = rightMostfingers[j];
        const int32_t finger_id = finger.id();
        //const Leap::Ray& tip = finger.tip();
        const Leap::Vector direction = finger.direction();
        const Leap::Vector position = finger.tipPosition();
        const Leap::Vector velocity = finger.tipVelocity();
        const double width = finger.width();
        const double length = finger.length();
        const bool isTool = finger.isTool();
        
        sprintf(buff,"/hand/rightmost/finger/%d/hand_id",j+1);
        oleap_bundleMessage(bundle,buff,rightmost.id());
        
        sprintf(buff,"/hand/rightmost/finger/%d/finger_id",j+1);
        oleap_bundleMessage(bundle,buff,finger.id());
        
        sprintf(buff,"/hand/rightmost/finger/%d/position/x",j+1);
        oleap_bundleMessage(bundle,buff,position.x);
        
        sprintf(buff,"/hand/rightmost/finger/%d/position/y",j+1);
        oleap_bundleMessage(bundle,buff,position.y);
        
        sprintf(buff,"/hand/rightmost/finger/%d/position/z",j+1);
        oleap_bundleMessage(bundle,buff,position.z);
        
        sprintf(buff,"/hand/rightmost/finger/%d/direction/x",j+1);
        oleap_bundleMessage(bundle,buff,direction.x);
        
        sprintf(buff,"/hand/rightmost/finger/%d/direction/y",j+1);
        oleap_bundleMessage(bundle,buff,direction.y);
        
        sprintf(buff,"/hand/rightmost/finger/%d/direction/z",j+1);
        oleap_bundleMessage(bundle,buff,direction.z);
        
        sprintf(buff,"/hand/rightmost/finger/%d/velocity/x",j+1);
        oleap_bundleMessage(bundle,buff,velocity.x);
        
        sprintf(buff,"/hand/rightmost/finger/%d/velocity/y",j+1);
        oleap_bundleMessage(bundle,buff,velocity.y);
        
        sprintf(buff,"/hand/rightmost/finger/%d/velocity/z",j+1);
        oleap_bundleMessage(bundle,buff,velocity.z);
        
        sprintf(buff,"/hand/rightmost/finger/%d/direction/normalized/x",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().x);
        
        sprintf(buff,"/hand/rightmost/finger/%d/direction/normalized/y",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().y);
        
        sprintf(buff,"/hand/rightmost/finger/%d/direction/normalized/z",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().z);
        
        sprintf(buff,"/hand/rightmost/finger/%d/pitch/normalized/",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().pitch());
        
        sprintf(buff,"/hand/rightmost/finger/%d/yaw/normalized/",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().yaw());
        
        sprintf(buff,"/hand/rightmost/finger/%d/roll/normalized/",j+1);
        oleap_bundleMessage(bundle,buff,direction.normalized().roll());
        
        sprintf(buff,"/hand/rightmost/finger/%d/width",j+1);
        oleap_bundleMessage(bundle,buff,width);
        
        sprintf(buff,"/hand/rightmost/finger/%d/length",j+1);
        oleap_bundleMessage(bundle,buff,length);
        
        sprintf(buff,"/hand/rightmost/isTool",j+1);
        oleap_bundleMessage(bundle,buff,isTool);
        
        for(size_t i = j+1; i < numFingers; i++)
        {
            sprintf(buff,"/hand/rightmost/finger/%d/distance/to/finger/%d",j+1,i+1);
            oleap_bundleMessage(bundle,buff,fingers[j].direction().distanceTo(fingers[i].direction()));
            
            sprintf(buff,"/hand/rightmost/finger/%d/angle/to/finger/%d",j+1,i+1);
            oleap_bundleMessage(bundle,buff,fingers[j].direction().angleTo((fingers[i].direction())));
            
        }
        
    }
    
    
    //////////////////////////
    for(size_t i = 0; i < numHands; i++)
	{
		// Hand
        
        
		const Leap::Hand &hand = hands[i];
		const int32_t hand_id = hand.id();
                
		const Leap::FingerList &fingers = hand.fingers();
		const size_t numFingers = fingers.count();
        
        float pitch = hand.direction().pitch();
        float yaw = hand.direction().yaw();
        float roll = hand.palmNormal().roll();
        
        //Leap::Hand leftmost = ;
        
        

        //t_osc_bundle_u *bundle, string address, float datum

        sprintf(buff,"/hand/%d/id",i+1);
        oleap_bundleMessage(bundle,buff,hand_id);
        
        sprintf(buff,"/hand/%d/fingers",i+1);
        oleap_bundleMessage(bundle,buff,numFingers);
        
        sprintf(buff,"/hand/%d/pitch",i+1);
        oleap_bundleMessage(bundle,buff,pitch);
        
        sprintf(buff,"/hand/%d/yaw",i+1);
        oleap_bundleMessage(bundle,buff,yaw);
        
        sprintf(buff,"/hand/%d/roll",i+1);
        oleap_bundleMessage(bundle,buff,roll);
        

        
		for(size_t j = 0; j < numFingers; j++)
		{
			// Finger
			const Leap::Finger &finger = fingers[j];
			const int32_t finger_id = finger.id();
			//const Leap::Ray& tip = finger.tip();
			const Leap::Vector direction = finger.direction();
			const Leap::Vector position = finger.tipPosition();
			const Leap::Vector velocity = finger.tipVelocity();
			const double width = finger.width();
			const double length = finger.length();
			const bool isTool = finger.isTool();
            
            
            /*
            string names [14]= {“xpos”,”ypos”,”zpos”,”xdir”,”ydir”,”zdir”,”xvel”,”yvel”,”zvel,finger_length”,”istool_mes”};
            
            for(LOOP OVER FINGERS “J”)
            {
                t_osc_message_u *handdata[14];
                for(int i=0;i<14;i++)
                {
                    handdata[i]=osc_message_u_alloc();
                    osc_message_u_setAddress(handdata[i], “/”+j.toString()+ ”/” +names[i]);
                }	
                
            }
            */
            
            sprintf(buff,"/hand/%d/finger/%d/hand_id",i+1,j+1);
            oleap_bundleMessage(bundle,buff,hand_id);
            
            sprintf(buff,"/hand/%d/finger/%d/finger_id",i+1,j+1);
            oleap_bundleMessage(bundle,buff,finger_id);

            sprintf(buff,"/hand/%d/finger/%d/position/x",i+1,j+1);
            oleap_bundleMessage(bundle,buff,position.x);
            
            sprintf(buff,"/hand/%d/finger/%d/position/y",i+1,j+1);
            oleap_bundleMessage(bundle,buff,position.y);
            
            sprintf(buff,"/hand/%d/finger/%d/position/z",i+1,j+1);
            oleap_bundleMessage(bundle,buff,position.z);

            sprintf(buff,"/hand/%d/finger/%d/direction/x",i+1,j+1);
            oleap_bundleMessage(bundle,buff,direction.x);
            
            sprintf(buff,"/hand/%d/finger/%d/direction/y",i+1,j+1);
            oleap_bundleMessage(bundle,buff,direction.y);

            sprintf(buff,"/hand/%d/finger/%d/direction/z",i+1,j+1);
            oleap_bundleMessage(bundle,buff,direction.z);

            sprintf(buff,"/hand/%d/finger/%d/velocity/x",i+1,j+1);
            oleap_bundleMessage(bundle,buff,velocity.x);

            sprintf(buff,"/hand/%d/finger/%d/velocity/y",i+1,j+1);
            oleap_bundleMessage(bundle,buff,velocity.y);

            sprintf(buff,"/hand/%d/finger/%d/velocity/z",i+1,j+1);
            oleap_bundleMessage(bundle,buff,velocity.z);

            sprintf(buff,"/hand/%d/finger/%d/width",i+1,j+1);
            oleap_bundleMessage(bundle,buff,width);

            sprintf(buff,"/hand/%d/finger/%d/length",i+1,j+1);
            oleap_bundleMessage(bundle,buff,length);

            sprintf(buff,"/hand/%d/tool",i+1,j+1);
            oleap_bundleMessage(bundle,buff,isTool);

		}
        
        
        const Leap::Vector position = hand.palmPosition();
        const Leap::Vector direction = hand.direction();
        const Leap::Vector velocity = hand.palmVelocity();
        const Leap::Vector normal = hand.palmNormal();
        const Leap::Vector sphereCenter = hand.sphereCenter();
        const double sphereRadius = hand.sphereRadius();
        
        
        ///////////////////////////Palm Data!!!
        
        
        sprintf(buff,"/hand/%d/palm/hand_id",i+1);
        oleap_bundleMessage(bundle,buff,hand_id);
        
        sprintf(buff,"/hand/%d/palm/frame_id",i+1);
        oleap_bundleMessage(bundle,buff,frame_id);
        
        sprintf(buff,"/hand/%d/palm/position/x",i+1);
        oleap_bundleMessage(bundle,buff,position.x);
        
        sprintf(buff,"/hand/%d/palm/position/y",i+1);
        oleap_bundleMessage(bundle,buff,position.y);
        
        sprintf(buff,"/hand/%d/palm/position/z",i+1);
        oleap_bundleMessage(bundle,buff,position.z);
        
        sprintf(buff,"/hand/%d/palm/direction/x",i+1);
        oleap_bundleMessage(bundle,buff,direction.x);
        
        sprintf(buff,"/hand/%d/palm/direction/y",i+1);
        oleap_bundleMessage(bundle,buff,direction.y);
        
        sprintf(buff,"/hand/%d/palm/direction/z",i+1);
        oleap_bundleMessage(bundle,buff,direction.z);
        
        sprintf(buff,"/hand/%d/palm/velocity/x",i+1);
        oleap_bundleMessage(bundle,buff,velocity.x);
        
        sprintf(buff,"/hand/%d/palm/velocity/x",i+1);
        oleap_bundleMessage(bundle,buff,velocity.y);
        
        sprintf(buff,"/hand/%d/palm/velocity/z",i+1);
        oleap_bundleMessage(bundle,buff,velocity.z);
        
        sprintf(buff,"/hand/%d/palm/normal/x",i+1);
        oleap_bundleMessage(bundle,buff,normal.x);
        
        sprintf(buff,"/hand/%d/palm/normal/y",i+1);
        oleap_bundleMessage(bundle,buff,normal.y);
        
        sprintf(buff,"/hand/%d/palm/normal/z",i+1);
        oleap_bundleMessage(bundle,buff,normal.z);
        
        
        sprintf(buff,"/hand/%d/sphere/id",i);
        oleap_bundleMessage(bundle,buff,hand_id);
        
        sprintf(buff,"/hand/%d/sphere/frame_id",i);
        oleap_bundleMessage(bundle,buff,frame_id);
        
        sprintf(buff,"/hand/%d/sphere/center/x",i+1);
        oleap_bundleMessage(bundle,buff,sphereCenter.x);
        
        sprintf(buff,"/hand/%d/sphere/center/y",i+1);
        oleap_bundleMessage(bundle,buff,sphereCenter.y);
        
        sprintf(buff,"/hand/%d/sphere/center/z",i+1);
        oleap_bundleMessage(bundle,buff,sphereCenter.z);
        
        sprintf(buff,"/hand/%d/sphere/radius",i+1);
        oleap_bundleMessage(bundle,buff,sphereRadius);
    
        
        
        const Leap::PointableList pointables = frame.pointables();
        const int count = pointables.count();

        for(size_t j = 0; j < count; j++){

            sprintf(buff,"/hand/%d/pointable/%d/id",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).id());
            
            sprintf(buff,"/hand/%d/pointable/%d/length",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).length());
            
            sprintf(buff,"/hand/%d/pointable/%d/width",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).width());
        
            sprintf(buff,"/hand/%d/pointable/%d/direction/x",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).direction().x);
        
            sprintf(buff,"/hand/%d/pointable/%d/direction/y",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).direction().y);
        
            sprintf(buff,"/hand/%d/pointable/%d/direction/z",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).direction().z);
        
            sprintf(buff,"/hand/%d/pointable/%d/isFinger",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).isFinger());
            
            sprintf(buff,"/hand/%d/pointable/%d/isTool",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).isTool());
        
            sprintf(buff,"/hand/%d/pointable/%d/position/tip/x",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).tipPosition().x);
            
            sprintf(buff,"/hand/%d/pointable/%d/position/tip/y",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).tipPosition().y);
        
            sprintf(buff,"/hand/%d/pointable/%d/position/tip/z",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).tipPosition().z);
            
            sprintf(buff,"/hand/%d/pointable/%d/velocity/tip/x",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).tipVelocity().x);
            
            sprintf(buff,"/hand/%d/pointable/%d/velocity/tip/y",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).tipVelocity().y);
            
            sprintf(buff,"/hand/%d/pointable/%d/velocity/tip/z",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).tipVelocity().z);
     
            sprintf(buff,"/hand/%d/pointable/%d/position/stabilized/x",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).stabilizedTipPosition().x);
            
            sprintf(buff,"/hand/%d/pointable/%d/position/stabilized/y",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).stabilizedTipPosition().y);
            
            sprintf(buff,"/hand/%d/pointable/%d/position/stabilized/z",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).stabilizedTipPosition().z);
            
            sprintf(buff,"/hand/%d/pointable/%d/touchZone/distance",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).touchDistance());
            
            sprintf(buff,"/hand/%d/pointable/%d/touchZone",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).touchZone());
            
            sprintf(buff,"/hand/%d/pointable/%d/touchZone/touching",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).ZONE_TOUCHING);
            
            sprintf(buff,"/hand/%d/pointable/%d/touchZone/hovering",i+1,j+1);
            oleap_bundleMessage(bundle,buff,pointables.operator[](j).ZONE_HOVERING);
            
        }
        
        const Leap::InteractionBox box = frame.interactionBox();
        const Leap::Vector center = box.center();
        const Leap::Vector normalizedPosition = box.normalizePoint(position);
    
        sprintf(buff,"/hand/%d/interactionBox/depth",i+1);
        oleap_bundleMessage(bundle,buff,box.depth());
        
        sprintf(buff,"/hand/%d/interactionBox/center/x",i+1);
        oleap_bundleMessage(bundle,buff,center.x);
        
        sprintf(buff,"/hand/%d/interactionBox/center/y",i+1);
        oleap_bundleMessage(bundle,buff,center.y);
        
        sprintf(buff,"/hand/%d/interactionBox/center/z",i+1);
        oleap_bundleMessage(bundle,buff,center.z);
        
        sprintf(buff,"/hand/%d/interactionBox/position/normalized/x",i+1);
        oleap_bundleMessage(bundle,buff,normalizedPosition.x);
        
        sprintf(buff,"/hand/%d/interactionBox/position/normalized/y",i+1);
        oleap_bundleMessage(bundle,buff,normalizedPosition.y);
        
        sprintf(buff,"/hand/%d/interactionBox/position/normalized/z",i+1);
        oleap_bundleMessage(bundle,buff,normalizedPosition.z);
        
        sprintf(buff,"/hand/%d/interactionBox/width",i+1);
        oleap_bundleMessage(bundle,buff,box.width());
        
        sprintf(buff,"/hand/%d/interactionBox/height",i+1);
        oleap_bundleMessage(bundle,buff,box.height());
        
    }

    
    long bytes = 0;//length of byte array
    char* pointer = NULL;
    
    osc_bundle_u_serialize(bundle, &bytes, &pointer);//& is address of the variable
    //post("%ld %p", bytes,pointer);
    
    t_atom out[2];
    atom_setlong(out, bytes);
    atom_setlong(out+1, (long)pointer);
    outlet_anything(x->outlet, gensym("FullPacket"), 2, out);
    
    osc_bundle_u_free(bundle);//get rid of stuff in osc message
    osc_mem_free(pointer);//marks pointer address as being free (clear if you want to keep using same)
    

}