Exemple #1
0
//--------------------------------------------------------------
void testApp::recordHandXML (Hand & hand, int handIndex){
	
	if (bRecordingThisFrame){
		if (hand.isValid()){
			
			int handTagNum = XML.addTag("H");
			if( XML.pushTag("H", handTagNum) ){
				XML.setValue("INDEX", handIndex, handTagNum);
				XML.setValue("ID", hand.id(), handTagNum);
				XML.setValue("TYPE", (hand.isLeft() ? "LEFT" : "RIGHT"), handTagNum);
				XML.setValue("CONF", hand.confidence(), handTagNum);
				
				FingerList fingers = hand.fingers();
				for (int f=0; f<fingers.count(); f++){
					const Finger & finger = fingers[f];
					
					if (finger.isValid()){
						recordFingerXML (finger);
					}
				}
				
				recordArmXML (hand);
				XML.popTag(); // pop H(AND)
			}
		}
	}
}
ofPoint LeapVisualizer::getIndexFingertip(ofxLeapMotion & leap){
    
    vector <Hand> hands = leap.getLeapHands();
    Hand hand;
    
	if (hands.size() > 0){
		for (int h=0; h<hands.size(); h++){
			hand = hands[h];
			if (hand.isValid()) break;
		}
	}
	
	// For each finger in the Hand,
	FingerList fingers = hand.fingers();
	for (int f=0; f<fingers.count(); f++)
    {
		// Get the current finger, and it's type (index, thumb, etc.);
		const Finger & finger = fingers[f];
		Finger::Type fingerType = finger.type();
		if (finger.isValid() && fingerType == Finger::TYPE_INDEX)
        {
            return ofPoint(finger.tipPosition().x, finger.tipPosition().y, finger.tipPosition().z);
		}
	}
    cout << "FINGER NOT FOUND" << endl;
    return ofPoint(-1.0f,-1.0f,-1.0f);
}
//callback function
void glListener::onFrame(const Controller& controller){
	
	/*memset(pitches, 0,sizeof(pitches));
	memset(rolls, 0,sizeof(rolls));
	memset(yaws, 0,sizeof(yaws));*/
	//Get the most recent frame and report some basic information
	const Frame frame = controller.frame();
	if(!frame.hands().empty()) 
	{
		//get the first hand
		const Hand hand = frame.hands()[0];
		//wrist
		pitches[0] = hand.palmNormal().pitch();
		rolls[0] = hand.palmNormal().roll();
		yaws[0] = hand.palmNormal().yaw();

		/*pitches[0] = hand.direction().pitch();
		rolls[0] = hand.direction().roll();
		yaws[0] = hand.direction().yaw();*/

		//check if the hand has any fingers
		const FingerList fingers = hand.fingers();
		//如果检测到手指且手指的数目等于5
		if (!fingers.empty() && fingers.count() == 5) {
			
			/*for(int i = 0; i < fingers.count(); i++) {
				
			}*/
			//Thumb
			yaws[2] = -fingers.leftmost().direction().pitch();
			//Index
			yaws[5] = -fingers[2].direction().pitch();
			//Middle
			yaws[8]= -fingers[0].direction().pitch();
			//Ring
			yaws[11]= -fingers[1].direction().pitch();
			//Little
			yaws[14]= -fingers.rightmost().direction().pitch();
			float temp = 0;
			//if index is at the right of ring
			if(fingers[2].tipPosition().x > fingers[1].tipPosition().x) {
				//swap the pitch angle of index and ring
				temp = yaws[5];
				yaws[5] = yaws[11];
				yaws[11] = temp;
			}
		}
	}
	pModel->animation(pitches,rolls,yaws);
}
//--------------------------------------------------------------
void LeapVisualizer::drawFingers (Hand & hand,ofxLeapMotion & leap){
	
	// For each finger in the Hand,
	FingerList fingers = hand.fingers();
	for (int f=0; f<fingers.count(); f++){
		
		// Get the current finger, and it's type (index, thumb, etc.);
		const Finger & finger = fingers[f];
		if (finger.isValid()){
			
			drawFinger(finger,leap);
			
		} //end if finger isValid()
	} // end for each finger
}
void LeapBrowser::updateCursorLocation()
{
	bool is_index_found = false;

	Frame frame = leap_controller.frame();	
	HandList hands = frame.hands();
	for( int h=0; h < hands.count(); h++ )
	{
		Hand hand = hands[h];
		FingerList fingers = hand.fingers();
		for( int f=0; f < fingers.count(); f++ )
		{
			Finger finger = fingers[f];
			if( finger.type() == Finger::Type::TYPE_INDEX )
			{
				is_index_found = true;

				Vector position = finger.tipPosition();
				cursor_location = math::position(position.x, position.y, position.z) * leap_transform;

				break;
			}
		}
		if( is_index_found )
		{
			break;
		}
	}

	if( !is_index_found )
	{
		cursor_location = math::position(0,0,0);
		is_cursor_located = false;
	}
	else
	{
		is_cursor_located = true;
	}
}
void LeapController::onFrame(const Controller& controller) {
	//console() << "Leap: onFrame" << std::endl;
	// Get the most recent frame and report some basic information
	const Frame frame = controller.frame();
  
	/*
	console() << "Frame id: " << frame.id()
			<< ", timestamp: " << frame.timestamp()
			<< ", hands: " << frame.hands().count()
			<< ", fingers: " << frame.fingers().count()
			<< ", tools: " << frame.tools().count()
			<< ", gestures: " << frame.gestures().count() << std::endl;
	*/

	if (!frame.hands().empty()) {
		const FingerList fingers = frame.fingers();
		for(int k = 0; k < fingers.count(); k++){
			if (!fingers.empty()){
				// Calculate the hand's average finger tip position
				for (int i = 0; i < fingers.count(); ++i) {
					ci::Vec2f currentFingerPos(fingers[i].tipPosition().x, fingers[i].tipPosition().z*-1.0);
					fingerPositions[i] = currentFingerPos;

					ci::Vec2f currentFingerVel(fingers[i].tipVelocity().x, (fingers[i].tipVelocity().z));
					fingerVelocities[i] = currentFingerVel;
				}
				avgPos = fingers[0].tipPosition(); 
				numActiveFingers = fingers.count();
				hasFingers = true;
			}
			else{
				hasFingers = false;
			}
		}

		/*
		// Get the first hand
		const Hand hand = frame.hands()[0];

		// Check if the hand has any fingers
		const FingerList fingers = hand.fingers();
		if (!fingers.empty()){
			// Calculate the hand's average finger tip position
			
			for (int i = 0; i < fingers.count(); ++i) {
				ci::Vec2f currentFingerPos(fingers[i].tipPosition().x, fingers[i].tipPosition().y);
				fingerPositions[i] = currentFingerPos;

				ci::Vec2f currentFingerVel(fingers[i].tipVelocity().x, (fingers[i].tipVelocity().y*-1.0));
				fingerVelocities[i] = currentFingerVel;
			}
			avgPos = fingers[0].tipPosition(); 
			numActiveFingers = fingers.count();
			//console() << "Hand has " << fingers.count() << " fingers, average finger tip position" << avgPos << std::endl;

			hasFingers = true;
		}
		else{
			hasFingers = false;
		}
		*/

		/*
		// Get the hand's sphere radius and palm position
		console() << "Hand sphere radius: " << hand.sphereRadius()
				  << " mm, palm position: " << hand.palmPosition() << std::endl;

		// Get the hand's normal vector and direction
		const Vector normal = hand.palmNormal();
		const Vector direction = hand.direction();

		// Calculate the hand's pitch, roll, and yaw angles
		console() << "Hand pitch: " << direction.pitch() * RAD_TO_DEG << " degrees, "
				  << "roll: " << normal.roll() * RAD_TO_DEG << " degrees, "
				  << "yaw: " << direction.yaw() * RAD_TO_DEG << " degrees" << std::endl;
		*/
	}
	else{
		hasFingers = false;
	}

	/*
	// Get gestures
	const GestureList gestures = frame.gestures();
	for (int g = 0; g < gestures.count(); ++g) {
		Gesture gesture = gestures[g];

	switch (gesture.type()) {
		case Gesture::TYPE_CIRCLE:
		{
			CircleGesture circle = gesture;
			std::string clockwiseness;

			if (circle.pointable().direction().angleTo(circle.normal()) <= PI/4) {
				clockwiseness = "clockwise";
			} else {
				clockwiseness = "counterclockwise";
			}
			// Calculate angle swept since last frame
			float sweptAngle = 0;
			if (circle.state() != Gesture::STATE_START) {
				CircleGesture previousUpdate = CircleGesture(controller.frame(1).gesture(circle.id()));
				sweptAngle = (circle.progress() - previousUpdate.progress()) * 2 * PI;
			}
			console() << "Circle id: " << gesture.id()
				<< ", state: " << gesture.state()
				<< ", progress: " << circle.progress()
				<< ", radius: " << circle.radius()
				<< ", angle " << sweptAngle * RAD_TO_DEG
				<<  ", " << clockwiseness << std::endl;
			break;
		}
		case Gesture::TYPE_SWIPE:
		{
			SwipeGesture swipe = gesture;
			console() << "Swipe id: " << gesture.id()
			<< ", state: " << gesture.state()
			<< ", direction: " << swipe.direction()
			<< ", speed: " << swipe.speed() << std::endl;
			break;
		}
		case Gesture::TYPE_KEY_TAP:
		{
			KeyTapGesture tap = gesture;
			console() << "Key Tap id: " << gesture.id()
			<< ", state: " << gesture.state()
			<< ", position: " << tap.position()
			<< ", direction: " << tap.direction()<< std::endl;
			break;
		}
		case Gesture::TYPE_SCREEN_TAP:
		{
			ScreenTapGesture screentap = gesture;
			console() << "Screen Tap id: " << gesture.id()
			<< ", state: " << gesture.state()
			<< ", position: " << screentap.position()
			<< ", direction: " << screentap.direction()<< std::endl;
			break;
		}
		default:
			console() << "Unknown gesture type." << std::endl;
			break;
		}
	}

	if (!frame.hands().empty() || !gestures.empty()) {
		console() << std::endl;
	}*/
}
//--------------------------------------------------------------
void LeapVisualizer::drawPalm (Hand & hand,ofxLeapMotion & leap){
	// This draws the palm as a gray region.
	
	// Collect the palm vertices into an ofMesh.
	ofMesh palmMesh;
	int nVertices = 0;
	float averageBoneWidth = 0;
	
	// For each finger,
	FingerList fingers = hand.fingers();
	for (int f=0; f<fingers.count(); f++){
		
		// Get the current finger, and it's type (index, thumb, etc.);
		const Finger & finger = fingers[f];
		if (finger.isValid()){
			
			Finger::Type fingerType = finger.type();
			Bone bone;
			if (fingerType == Finger::TYPE_THUMB){
				bone = finger.bone(Bone::TYPE_PROXIMAL);
			} else {
				bone = finger.bone(Bone::TYPE_METACARPAL);
			}
			
			// If we've found the bones we want, add their vertices to the mesh.
			if (bone.isValid()){
				float boneLength = bone.length();
				if (boneLength > 0){
					
					ofPoint pt0 = leap.getofPoint ( bone.prevJoint());
					ofPoint pt1 = leap.getofPoint ( bone.nextJoint());
					
					palmMesh.addVertex(pt0);
					palmMesh.addVertex(pt1);
					
					averageBoneWidth += bone.width();
					nVertices += 2;
				}
			}
		}
	}
	averageBoneWidth /= (nVertices/2);
	
	// Render the palm as a triangle strip surface,
	// (optionally) bordered by cylinders.
	if (nVertices > 3){
		ofSetColor(ofColor::gray);
		
		// Draw the palm as a mesh of triangles.
		int nPalmMeshVertices = palmMesh.getNumVertices();
		for (int i=0; i<(nPalmMeshVertices-2); i++){
			palmMesh.addTriangle(i, i+1, i+2);
		}
		palmMesh.drawFaces();
		
		// Add optional cylinders.
		if (!bDrawSimple){
			float rad = averageBoneWidth / 2.0;
			
			if (nPalmMeshVertices == 10){
				for (int i=0; i<4; i++){
					ofVec3f p0 = palmMesh.getVertex( i   *2);
					ofVec3f p1 = palmMesh.getVertex((i+1)*2);
					drawOrientedCylinder (p0, p1, 10);
					ofDrawSphere(p0, rad);
					ofDrawSphere(p1, rad);
				}
				
				for (int i=0; i<4; i++){
					ofVec3f p0 = palmMesh.getVertex( i   *2 + 1);
					ofVec3f p1 = palmMesh.getVertex((i+1)*2 + 1);
					drawOrientedCylinder (p0, p1, 10);
					ofDrawSphere(p0, rad);
					ofDrawSphere(p1, rad);
				}
			}
		}
		
	}
}
Exemple #8
0
void LeapListener::onFrame(const Controller &controller){
	const Frame frame = controller.frame();
	HandList hands = frame.hands();

	std::vector<HandModel> myhands;
	BoneModel mybone;
	HandModel myhand;
	//printf("frame: %d\n", frame.id());
	float scale = 0.025;
	float disp = 3.5f;
	bool record = true;
	for (int i = 0; i < hands.count(); i++){
		FingerList fingers = hands[i].fingers();
		myhand.bones.clear();
		myhand.references.clear();

		Vector handPosition = hands[i].palmPosition();
		handPosition *= scale;
		handPosition.y -= disp;

		Vector wrist = hands[i].wristPosition();
		wrist *= scale;
		wrist.y -= disp;

		myhand.palmPosition = handPosition;
		myhand.palmNormal = hands[i].palmNormal();
		myhand.direction = hands[i].direction();

		for (int j = 0; j < fingers.count(); j++){
			Bone bone;
			Bone::Type boneType;

			Vector currentPosition = fingers[j].tipPosition();
			currentPosition *= scale;
			currentPosition.y -= disp;

			Vector lastPosition = m_lastFrame.finger(fingers[j].id()).tipPosition();
			lastPosition *= scale;
			lastPosition.y -= disp;

			Vector diff = currentPosition - lastPosition;

			//printf("%f, %f, %f\n", abs(diff.x), abs(diff.y), abs(diff.z));
			
			//if (abs(diff.x) > 0.2 || abs(diff.y) > 0.2 || abs(diff.z) > 0.2) record = false;
			if (abs(diff.x) < 0.0001 || abs(diff.y) < 0.0001 || abs(diff.z) < 0.0001) record = false;

			for (int k = 0; k < 4; k++){
				boneType = static_cast<Bone::Type>(k);
				bone = fingers[j].bone(boneType);

				if (fingers[j].type() == Finger::Type::TYPE_THUMB && k == 0) continue;

				Vector prevPos = bone.prevJoint();
				prevPos *= scale;
				prevPos.y -= disp;

				Vector nextPos = bone.nextJoint();
				nextPos *= scale;
				nextPos.y -= disp;

				mybone.direction = nextPos - prevPos;
				mybone.position = (prevPos + nextPos) / 2;
				mybone.prevJoint = prevPos;
				mybone.nextJoint = nextPos;
				mybone.length = bone.length() * scale;

				if (boneType == Bone::Type::TYPE_PROXIMAL){
					if (fingers[j].type() == Finger::Type::TYPE_THUMB){
						myhand.thumb = prevPos;
						//myhand.references.push_back(nextPos);
					}
					else{
						myhand.references.push_back(prevPos);
					}
				}
				
				myhand.bones.push_back(mybone);
			}
		}

		myhand.base = myhand.references[3] - myhand.references[0];
		Vector disp = myhand.base.normalized() * 0.3f;
		myhand.references[3] += disp;
		myhand.references[0] -= disp;

		//for (int i = 1; i < 5; i++){
		//	printf("%f\n", myhand.references[i - 1].distanceTo(myhand.references[i]));
		//}

		myhands.push_back(myhand);
	}

	if (record){
		m_hands.clear();
		for (int i = 0; i < myhands.size(); i++){
			m_hands.push_back(myhands[i]);
		}
	}

	m_lastFrame = frame;
}