This commit is contained in:
Philip Rosedale 2013-05-09 22:06:57 -07:00
commit eefd0c36f1
4 changed files with 120 additions and 54 deletions

View file

@ -483,12 +483,10 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
/*
// Test: Show angle between your fwd vector and nearest avatar
glm::vec3 vectorBetweenUs = otherAvatar->getJointPosition(AVATAR_JOINT_PELVIS) -
getJointPosition(AVATAR_JOINT_PELVIS);
printLog("Angle between: %f\n", angleBetween(vectorBetweenUs, _orientation.getFront()));
*/
//Test: Show angle between your fwd vector and nearest avatar
//glm::vec3 vectorBetweenUs = otherAvatar->getJointPosition(AVATAR_JOINT_PELVIS) -
// getJointPosition(AVATAR_JOINT_PELVIS);
//printLog("Angle between: %f\n", angleBetween(vectorBetweenUs, _orientation.getFront()));
// test whether shoulders are close enough to allow for reaching to touch hands
glm::vec3 v(_position - otherAvatar->_position);
@ -505,26 +503,60 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
_avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition);
_avatarTouch.setYourHandState (_interactingOther->_handState);
if ( _avatarTouch.getAbleToReachOtherAvatar()) {
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position =
_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition;
//if hand-holding is initiated by either avatar, turn on hand-holding...
if (_avatarTouch.getHandsCloseEnoughToGrasp()) {
if ((_handState == HAND_STATE_GRASPING ) || (_interactingOther->_handState == HAND_STATE_GRASPING)) {
if (!_avatarTouch.getHoldingHands())
{
_avatarTouch.setHoldingHands(true);
}
}
}
if (!_avatarTouch.getAbleToReachOtherAvatar()) {
_avatarTouch.setHoldingHands(false);
}
if ((_handState != HAND_STATE_GRASPING ) && (_interactingOther->_handState != HAND_STATE_GRASPING)) {
_avatarTouch.setHoldingHands(false);
}
}
//if holding hands, apply the appropriate forces
if (_avatarTouch.getHoldingHands()) {
glm::vec3 vectorToOtherHand = _interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition - _handHoldingPosition;
glm::vec3 vectorToMyHand = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - _handHoldingPosition;
float myInfluence = 30.0f;
float yourInfluence = 30.0f;
glm::vec3 myForce = vectorToMyHand * myInfluence * deltaTime;
glm::vec3 yourForce = vectorToOtherHand * yourInfluence * deltaTime;
if (_handState == HAND_STATE_GRASPING) {myForce *= 2.0f; }
if (_interactingOther->_handState == HAND_STATE_GRASPING) {yourForce *= 2.0f; }
_handHoldingPosition += myForce + yourForce;
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handHoldingPosition;
} else {
_handHoldingPosition = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position;
}
}//if (_isMine)
//constrain right arm length and re-adjust elbow position as it bends
// NOTE - the following must be called on all avatars - not just _isMine
updateArmIKAndConstraints(deltaTime);
//Set right hand position and state to be transmitted, and also tell AvatarTouch about it
if (_isMine) {
//Set the vector we send for hand position to other people to be our right hand
setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
if (_mousePressed) {
_handState = 1;
_handState = HAND_STATE_GRASPING;
} else {
_handState = 0;
_handState = HAND_STATE_NULL;
}
_avatarTouch.setMyHandState(_handState);
@ -546,7 +578,7 @@ void Avatar::updateHead(float deltaTime) {
_orientation.getRight() * _head.leanSideways +
_orientation.getFront() * _head.leanForward;
// this is not a long-term solution, but it works ok for initial purposes...
// this is not a long-term solution, but it works ok for initial purposes of making the avatar lean
_joint[ AVATAR_JOINT_TORSO ].springyPosition += headLean * 0.1f;
_joint[ AVATAR_JOINT_CHEST ].springyPosition += headLean * 0.4f;
_joint[ AVATAR_JOINT_NECK_BASE ].springyPosition += headLean * 0.7f;

View file

@ -13,6 +13,7 @@
#include "Util.h"
const float THREAD_RADIUS = 0.012;
const float HANDS_CLOSE_ENOUGH_TO_GRASP = 0.1;
AvatarTouch::AvatarTouch() {
@ -21,9 +22,10 @@ AvatarTouch::AvatarTouch() {
_myBodyPosition = glm::vec3(0.0f, 0.0f, 0.0f);
_yourBodyPosition = glm::vec3(0.0f, 0.0f, 0.0f);
_vectorBetweenHands = glm::vec3(0.0f, 0.0f, 0.0f);
_myHandState = 0;
_yourHandState = 0;
_myHandState = HAND_STATE_NULL;
_yourHandState = HAND_STATE_NULL;
_reachableRadius = 0.0f;
_weAreHoldingHands = false;
_canReachToOtherAvatar = false;
_handsCloseEnoughToGrasp = false;
@ -61,19 +63,63 @@ void AvatarTouch::setReachableRadius(float r) {
_reachableRadius = r;
}
void AvatarTouch::simulate (float deltaTime) {
glm::vec3 vectorBetweenBodies = _yourBodyPosition - _myBodyPosition;
float distanceBetweenBodies = glm::length(vectorBetweenBodies);
if (distanceBetweenBodies < _reachableRadius) {
_vectorBetweenHands = _yourHandPosition - _myHandPosition;
float distanceBetweenHands = glm::length(_vectorBetweenHands);
if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP) {
_handsCloseEnoughToGrasp = true;
} else {
_handsCloseEnoughToGrasp = false;
}
_canReachToOtherAvatar = true;
} else {
_canReachToOtherAvatar = false;
}
}
void AvatarTouch::render(glm::vec3 cameraPosition) {
if (_canReachToOtherAvatar) {
if (_canReachToOtherAvatar) {
//show circle indicating that we can reach out to each other...
glColor4f(0.3, 0.4, 0.5, 0.5);
glm::vec3 p(_yourBodyPosition);
p.y = 0.0005f;
renderCircle(p, _reachableRadius, glm::vec3(0.0f, 1.0f, 0.0f), 30);
// show is we are golding hands...
if (_weAreHoldingHands) {
glColor4f(0.9, 0.3, 0.3, 0.5);
renderSphereOutline(_myHandPosition, HANDS_CLOSE_ENOUGH_TO_GRASP * 0.3f, 20, cameraPosition);
renderSphereOutline(_myHandPosition, HANDS_CLOSE_ENOUGH_TO_GRASP * 0.2f, 20, cameraPosition);
renderSphereOutline(_myHandPosition, HANDS_CLOSE_ENOUGH_TO_GRASP * 0.1f, 20, cameraPosition);
renderSphereOutline(_yourHandPosition, HANDS_CLOSE_ENOUGH_TO_GRASP * 0.3f, 20, cameraPosition);
renderSphereOutline(_yourHandPosition, HANDS_CLOSE_ENOUGH_TO_GRASP * 0.2f, 20, cameraPosition);
renderSphereOutline(_yourHandPosition, HANDS_CLOSE_ENOUGH_TO_GRASP * 0.1f, 20, cameraPosition);
}
//render the beam between our hands indicting that we can reach out and grasp hands...
renderBeamBetweenHands();
//show that our hands are close enough to grasp..
if (_handsCloseEnoughToGrasp) {
glColor4f(0.9, 0.3, 0.3, 0.5);
renderSphereOutline(_myHandPosition, HANDS_CLOSE_ENOUGH_TO_GRASP / 3.0f, 20, cameraPosition);
}
// if your hand is grasping, show it...
if (_yourHandState == 1) {
if (_yourHandState == HAND_STATE_GRASPING) {
glPushMatrix();
glTranslatef(_yourHandPosition.x, _yourHandPosition.y, _yourHandPosition.z);
glColor4f(1.0, 1.0, 0.8, 0.3); glutSolidSphere(0.020f, 10.0f, 10.0f);
@ -84,7 +130,7 @@ if (_canReachToOtherAvatar) {
}
// if my hand is grasping, show it...
if (_myHandState == 1) {
if (_myHandState == HAND_STATE_GRASPING) {
glPushMatrix();
glTranslatef(_myHandPosition.x, _myHandPosition.y, _myHandPosition.z);
glColor4f(1.0, 1.0, 0.8, 0.3); glutSolidSphere(0.020f, 10.0f, 10.0f);
@ -94,34 +140,6 @@ if (_canReachToOtherAvatar) {
}
}
void AvatarTouch::simulate (float deltaTime) {
_vectorBetweenHands = _yourBodyPosition - _myBodyPosition;
float distance = glm::length(_vectorBetweenHands);
if (distance < _reachableRadius) {
_canReachToOtherAvatar = true;
generateBeamBetweenHands();
} else {
_canReachToOtherAvatar = false;
}
}
void AvatarTouch::generateBeamBetweenHands() {
for (int p=0; p<NUM_POINTS; p++) {
_point[p] = _myHandPosition + _vectorBetweenHands * ((float)p / (float)NUM_POINTS);
_point[p].x += randFloatInRange(-THREAD_RADIUS, THREAD_RADIUS);
_point[p].y += randFloatInRange(-THREAD_RADIUS, THREAD_RADIUS);
_point[p].z += randFloatInRange(-THREAD_RADIUS, THREAD_RADIUS);
}
}
void AvatarTouch::renderBeamBetweenHands() {
@ -130,15 +148,20 @@ void AvatarTouch::renderBeamBetweenHands() {
glm::vec3 v2(_yourHandPosition);
glLineWidth(2.0);
glColor4f(0.7f, 0.4f, 0.1f, 0.3);
glColor4f(0.9f, 0.9f, 0.1f, 0.7);
glBegin(GL_LINE_STRIP);
glVertex3f(v1.x, v1.y, v1.z);
glVertex3f(v2.x, v2.y, v2.z);
glEnd();
glColor4f(1.0f, 1.0f, 0.0f, 0.8);
glColor3f(1.0f, 1.0f, 1.0f);
for (int p=0; p<NUM_POINTS; p++) {
_point[p] = _myHandPosition + _vectorBetweenHands * ((float)p / (float)NUM_POINTS);
_point[p].x += randFloatInRange(-THREAD_RADIUS, THREAD_RADIUS);
_point[p].y += randFloatInRange(-THREAD_RADIUS, THREAD_RADIUS);
_point[p].z += randFloatInRange(-THREAD_RADIUS, THREAD_RADIUS);
glBegin(GL_POINTS);
glVertex3f(_point[p].x, _point[p].y, _point[p].z);
glEnd();

View file

@ -11,7 +11,14 @@
#include <glm/glm.hpp>
const float HANDS_CLOSE_ENOUGH_TO_GRASP = 0.1;
enum AvatarHandState
{
HAND_STATE_NULL = -1,
HAND_STATE_OPEN,
HAND_STATE_GRASPING,
HAND_STATE_POINTING,
NUM_HAND_STATES
};
class AvatarTouch {
public:
@ -28,16 +35,20 @@ public:
void setMyHandState (int state);
void setYourHandState (int state);
void setReachableRadius (float r);
void setAbleToReachOtherAvatar (bool a) {_canReachToOtherAvatar = a;}
void setHandsCloseEnoughToGrasp(bool h) {_handsCloseEnoughToGrasp = h;}
void setHoldingHands (bool h) {_weAreHoldingHands = h;}
bool getAbleToReachOtherAvatar () const {return _canReachToOtherAvatar;}
bool getAbleToReachOtherAvatar () const {return _canReachToOtherAvatar; }
bool getHandsCloseEnoughToGrasp() const {return _handsCloseEnoughToGrasp;}
bool getHoldingHands () const {return _weAreHoldingHands; }
private:
static const int NUM_POINTS = 100;
bool _weAreHoldingHands;
glm::vec3 _point [NUM_POINTS];
glm::vec3 _myBodyPosition;
glm::vec3 _yourBodyPosition;
@ -50,7 +61,6 @@ private:
bool _handsCloseEnoughToGrasp;
float _reachableRadius;
void generateBeamBetweenHands();
void renderBeamBetweenHands();
};

View file

@ -1892,10 +1892,11 @@ glm::vec3 getGravity(glm::vec3 pos) {
return glm::vec3(0.f, 0.f, 0.f);
}
}
void mouseFunc(int button, int state, int x, int y) {
//catch mouse actiond on the menu
//catch mouse actions on the menu
bool menuClickedOrUnclicked = menu.mouseClick(x, y);
if (!menuClickedOrUnclicked) {