Fixes in merge.

This commit is contained in:
Philip Rosedale 2013-05-07 08:40:11 -07:00
commit c7635604a9
8 changed files with 312 additions and 270 deletions

View file

@ -34,10 +34,6 @@ const float BODY_ROLL_WHILE_TURNING = 0.1;
const float LIN_VEL_DECAY = 5.0; const float LIN_VEL_DECAY = 5.0;
const float MY_HAND_HOLDING_PULL = 0.2; const float MY_HAND_HOLDING_PULL = 0.2;
const float YOUR_HAND_HOLDING_PULL = 1.0; const float YOUR_HAND_HOLDING_PULL = 1.0;
//const float BODY_SPRING_DEFAULT_TIGHTNESS = 20.0f;
//const float BODY_SPRING_FORCE = 6.0f;
const float BODY_SPRING_DEFAULT_TIGHTNESS = 1500.0f; const float BODY_SPRING_DEFAULT_TIGHTNESS = 1500.0f;
const float BODY_SPRING_FORCE = 300.0f; const float BODY_SPRING_FORCE = 300.0f;
@ -144,13 +140,14 @@ Avatar::Avatar(bool isMine) {
_renderYaw = 0.0; _renderYaw = 0.0;
_renderPitch = 0.0; _renderPitch = 0.0;
_sphere = NULL; _sphere = NULL;
_interactingOther = NULL;
_handHoldingPosition = glm::vec3(0.0f, 0.0f, 0.0f); _handHoldingPosition = glm::vec3(0.0f, 0.0f, 0.0f);
_distanceToNearestAvatar = std::numeric_limits<float>::max(); _distanceToNearestAvatar = std::numeric_limits<float>::max();
_gravity = glm::vec3(0.0f, -1.0f, 0.0f); // default _gravity = glm::vec3(0.0f, -1.0f, 0.0f); // default
initializeSkeleton(); initializeSkeleton();
_avatarTouch.setReachableRadius(0.6);
if (iris_texture.size() == 0) { if (iris_texture.size() == 0) {
switchToResourcesParentIfRequired(); switchToResourcesParentIfRequired();
unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file); unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file);
@ -295,7 +292,6 @@ void Avatar::UpdateGyros(float frametime, SerialInterface* serialInterface, glm:
if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) { if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) {
addHeadYaw(_head.yawRate * HEAD_ROTATION_SCALE * frametime); addHeadYaw(_head.yawRate * HEAD_ROTATION_SCALE * frametime);
} }
} }
float Avatar::getAbsoluteHeadYaw() const { float Avatar::getAbsoluteHeadYaw() const {
@ -316,16 +312,14 @@ void Avatar::setLeanSideways(float dist){
_head.leanSideways = dist; _head.leanSideways = dist;
} }
void Avatar::setMousePressed(bool d) { void Avatar::setMousePressed(bool mousePressed) {
_mousePressed = d; _mousePressed = mousePressed;
} }
bool Avatar::getIsNearInteractingOther() { bool Avatar::getIsNearInteractingOther() {
return _avatarTouch.getAbleToReachOtherAvatar(); return _avatarTouch.getAbleToReachOtherAvatar();
} }
void Avatar::simulate(float deltaTime) { void Avatar::simulate(float deltaTime) {
@ -335,9 +329,15 @@ void Avatar::simulate(float deltaTime) {
// update avatar skeleton // update avatar skeleton
updateSkeleton(); updateSkeleton();
//detect and respond to collisions with other avatars...
if (_isMine) {
updateAvatarCollisions(deltaTime);
}
//update the movement of the hand and process handshaking with other avatars... //update the movement of the hand and process handshaking with other avatars...
updateHandMovementAndTouching(deltaTime); updateHandMovementAndTouching(deltaTime);
_avatarTouch.simulate(deltaTime);
// apply gravity and collision with the ground/floor // apply gravity and collision with the ground/floor
if (USING_AVATAR_GRAVITY) { if (USING_AVATAR_GRAVITY) {
@ -381,7 +381,7 @@ void Avatar::simulate(float deltaTime) {
// decay body rotation momentum // decay body rotation momentum
float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime; float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime;
if ( bodySpinMomentum < 0.0f ) { bodySpinMomentum = 0.0f; } if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; }
_bodyPitchDelta *= bodySpinMomentum; _bodyPitchDelta *= bodySpinMomentum;
_bodyYawDelta *= bodySpinMomentum; _bodyYawDelta *= bodySpinMomentum;
_bodyRollDelta *= bodySpinMomentum; _bodyRollDelta *= bodySpinMomentum;
@ -430,8 +430,6 @@ void Avatar::simulate(float deltaTime) {
} }
//update the movement of the hand and process handshaking with other avatars...
void Avatar::updateHandMovementAndTouching(float deltaTime) { void Avatar::updateHandMovementAndTouching(float deltaTime) {
// reset hand and arm positions according to hand movement // reset hand and arm positions according to hand movement
@ -441,34 +439,20 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
+ _orientation.getFront() * -_movedHandOffset.y * 1.0f; + _orientation.getFront() * -_movedHandOffset.y * 1.0f;
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement;
if (_isMine) {
_handState = _mousePressed;
}
//reset these for the next go-round
_avatarTouch.setAbleToReachOtherAvatar (false);
_avatarTouch.setHandsCloseEnoughToGrasp(false);
// if the avatar being simulated is mine, then loop through
// all the other avatars for potential interactions...
if (_isMine) if (_isMine)
{ {
// Reset detector for nearest avatar _avatarTouch.setMyBodyPosition(_position);
_distanceToNearestAvatar = std::numeric_limits<float>::max();
Avatar * _interactingOther = NULL;
float closestDistance = std::numeric_limits<float>::max();
//loop through all the other avatars for potential interactions...
AgentList* agentList = AgentList::getInstance(); AgentList* agentList = AgentList::getInstance();
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
Avatar *otherAvatar = (Avatar *)agent->getLinkedData(); Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
// check for collisions with other avatars and respond
updateCollisionWithOtherAvatar(otherAvatar, deltaTime );
// test other avatar hand position for proximity
glm::vec3 v(_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position);
v -= otherAvatar->getJointPosition(AVATAR_JOINT_RIGHT_SHOULDER);
/* /*
// Test: Show angle between your fwd vector and nearest avatar // Test: Show angle between your fwd vector and nearest avatar
glm::vec3 vectorBetweenUs = otherAvatar->getJointPosition(AVATAR_JOINT_PELVIS) - glm::vec3 vectorBetweenUs = otherAvatar->getJointPosition(AVATAR_JOINT_PELVIS) -
@ -477,76 +461,46 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
printLog("Angle between: %f\n", angleBetween(&vectorBetweenUs, &myForwardVector)); printLog("Angle between: %f\n", angleBetween(&vectorBetweenUs, &myForwardVector));
*/ */
// test whether shoulders are close enough to allow for reaching to touch hands
glm::vec3 v(_position - otherAvatar->_position);
float distance = glm::length(v); float distance = glm::length(v);
if (distance < _distanceToNearestAvatar) {_distanceToNearestAvatar = distance;} if (distance < closestDistance) {
closestDistance = distance;
if (distance < _maxArmLength + _maxArmLength) {
_interactingOther = otherAvatar; _interactingOther = otherAvatar;
if (! _avatarTouch.getAbleToReachOtherAvatar()) {
//initialize _handHolding
_handHoldingPosition = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position;
_avatarTouch.setAbleToReachOtherAvatar(true);
}
glm::vec3 vectorBetweenHands(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
vectorBetweenHands -= otherAvatar->getJointPosition(AVATAR_JOINT_RIGHT_FINGERTIPS);
float distanceBetweenHands = glm::length(vectorBetweenHands);
if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP) {
_avatarTouch.setHandsCloseEnoughToGrasp(true);
}
// if I am holding hands with another avatar, a force is applied
if ((_handState == 1) || (_interactingOther->_handState == 1)) {
// if the hands are close enough to grasp...
if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP)
{
// apply the forces...
glm::vec3 vectorToOtherHand = _interactingOther->_handPosition - _handHoldingPosition;
glm::vec3 vectorToMyHand = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - _handHoldingPosition;
_handHoldingPosition += vectorToOtherHand * YOUR_HAND_HOLDING_PULL;
_handHoldingPosition += vectorToMyHand * MY_HAND_HOLDING_PULL;
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handHoldingPosition;
// apply a force to the avatar body
if (glm::length(vectorToOtherHand) > _maxArmLength * 0.9) {
_velocity += vectorToOtherHand;
}
}
}
} }
} }
} }
// Set the vector we send for hand position to other people to be our right hand if (_interactingOther) {
setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); _avatarTouch.setYourBodyPosition(_interactingOther->_position);
_avatarTouch.setYourHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition);
_avatarTouch.setYourHandState (_interactingOther->_handState);
}
}//if (_isMine) }//if (_isMine)
//constrain right arm length and re-adjust elbow position as it bends //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); updateArmIKAndConstraints(deltaTime);
// set hand positions for _avatarTouch.setMyHandPosition AFTER calling updateArmIKAndConstraints
if (_interactingOther) {
if (_isMine) {
_avatarTouch.setMyHandPosition (_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
_avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
_avatarTouch.setMyHandState (_handState);
_avatarTouch.setYourHandState (_interactingOther->_handState);
_avatarTouch.simulate(deltaTime);
}
}
if (!_avatarTouch.getAbleToReachOtherAvatar() ) { if (_isMine) {
_interactingOther = NULL; //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;
} else {
_handState = 0;
}
_avatarTouch.setMyHandState(_handState);
if (_handState == 1) {
_avatarTouch.setMyHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition);
}
} }
} }
void Avatar::updateHead(float deltaTime) { void Avatar::updateHead(float deltaTime) {
//apply the head lean values to the springy position... //apply the head lean values to the springy position...
@ -698,66 +652,96 @@ void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float d
} }
//detect collisions with other avatars and respond
void Avatar::updateCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) {
// check if the bounding spheres of the two avatars are colliding
glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position); void Avatar::updateAvatarCollisions(float deltaTime) {
if (glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF) {
// Reset detector for nearest avatar
_distanceToNearestAvatar = std::numeric_limits<float>::max();
//loop through all the other avatars for potential interactions...
AgentList* agentList = AgentList::getInstance();
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
// check if the bounding spheres of the two avatars are colliding
glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position);
if (glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF) {
//apply forces from collision
applyCollisionWithOtherAvatar(otherAvatar, deltaTime );
}
// test other avatar hand position for proximity
glm::vec3 v(_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position);
v -= otherAvatar->getPosition();
float distance = glm::length(v);
if (distance < _distanceToNearestAvatar) {
_distanceToNearestAvatar = distance;
}
}
}
}
//detect collisions with other avatars and respond
void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) {
float bodyMomentum = 1.0f; float bodyMomentum = 1.0f;
glm::vec3 bodyPushForce = glm::vec3(0.0f, 0.0f, 0.0f); glm::vec3 bodyPushForce = glm::vec3(0.0f, 0.0f, 0.0f);
// loop through the joints of each avatar to check for every possible collision // loop through the joints of each avatar to check for every possible collision
for (int b=1; b<NUM_AVATAR_JOINTS; b++) { for (int b=1; b<NUM_AVATAR_JOINTS; b++) {
if (_joint[b].isCollidable) { if (_joint[b].isCollidable) {
for (int o=b+1; o<NUM_AVATAR_JOINTS; o++) { for (int o=b+1; o<NUM_AVATAR_JOINTS; o++) {
if (otherAvatar->_joint[o].isCollidable) { if (otherAvatar->_joint[o].isCollidable) {
glm::vec3 vectorBetweenJoints(_joint[b].springyPosition - otherAvatar->_joint[o].springyPosition);
float distanceBetweenJoints = glm::length(vectorBetweenJoints);
glm::vec3 vectorBetweenJoints(_joint[b].springyPosition - otherAvatar->_joint[o].springyPosition); if (distanceBetweenJoints > 0.0 ) { // to avoid divide by zero
float distanceBetweenJoints = glm::length(vectorBetweenJoints); float combinedRadius = _joint[b].radius + otherAvatar->_joint[o].radius;
if (distanceBetweenJoints > 0.0 ) { // to avoid divide by zero
float combinedRadius = _joint[b].radius + otherAvatar->_joint[o].radius;
// check for collision // check for collision
if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) { if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) {
glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints; glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints;
// push balls away from each other and apply friction
glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * deltaTime;
float ballMomentum = 1.0 - COLLISION_BALL_FRICTION * deltaTime;
if (ballMomentum < 0.0 ) { ballMomentum = 0.0;}
_joint[b].springyVelocity += ballPushForce;
otherAvatar->_joint[o].springyVelocity -= ballPushForce;
_joint[b].springyVelocity *= ballMomentum;
otherAvatar->_joint[o].springyVelocity *= ballMomentum;
// accumulate forces and frictions to apply to the velocities of avatar bodies
bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime;
bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime;
if (bodyMomentum < 0.0 ) { bodyMomentum = 0.0;}
}// check for collision
} // to avoid divide by zero
} // o loop
} // collidable
} // b loop
} // collidable
//apply forces and frictions on the bodies of both avatars
_velocity += bodyPushForce;
otherAvatar->_velocity -= bodyPushForce;
_velocity *= bodyMomentum;
otherAvatar->_velocity *= bodyMomentum;
}
// push balls away from each other and apply friction
glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * deltaTime;
float ballMomentum = 1.0 - COLLISION_BALL_FRICTION * deltaTime;
if (ballMomentum < 0.0 ) { ballMomentum = 0.0;}
_joint[b].springyVelocity += ballPushForce;
otherAvatar->_joint[o].springyVelocity -= ballPushForce;
_joint[b].springyVelocity *= ballMomentum;
otherAvatar->_joint[o].springyVelocity *= ballMomentum;
// accumulate forces and frictions to apply to the velocities of avatar bodies
bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime;
bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime;
if (bodyMomentum < 0.0 ) { bodyMomentum = 0.0;}
}// check for collision
} // to avoid divide by zero
} // o loop
} // collidable
} // b loop
} // collidable
//apply forces and frictions on the bodies of both avatars
_velocity += bodyPushForce;
otherAvatar->_velocity -= bodyPushForce;
_velocity *= bodyMomentum;
otherAvatar->_velocity *= bodyMomentum;
} // bounding sphere collision
} //method
void Avatar::setDisplayingHead(bool displayingHead ) { void Avatar::setDisplayingHead(bool displayingHead ) {
@ -776,7 +760,7 @@ void Avatar::setGravity(glm::vec3 gravity) {
} }
void Avatar::render(bool lookingInMirror) { void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) {
// render a simple round on the ground projected down from the avatar's position // render a simple round on the ground projected down from the avatar's position
renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f ), 0.1f, 0.2f ); renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f ), 0.1f, 0.2f );
@ -811,7 +795,7 @@ void Avatar::render(bool lookingInMirror) {
// if this is my avatar, then render my interactions with the other avatar // if this is my avatar, then render my interactions with the other avatar
if (_isMine ) { if (_isMine ) {
_avatarTouch.render(); _avatarTouch.render(cameraPosition);
} }
// Render the balls // Render the balls
@ -1201,6 +1185,9 @@ void Avatar::initializeSkeleton() {
// generate world positions // generate world positions
updateSkeleton(); updateSkeleton();
//set spring positions to be in the skeleton bone positions
initializeBodySprings();
} }
void Avatar::calculateBoneLengths() { void Avatar::calculateBoneLengths() {

View file

@ -101,13 +101,6 @@ public:
void setLeanForward(float dist); void setLeanForward(float dist);
void setLeanSideways(float dist); void setLeanSideways(float dist);
void addLean(float x, float z); void addLean(float x, float z);
/*
const glm::vec3& getHeadRightDirection() const { return _orientation.getRight(); };
const glm::vec3& getHeadUpDirection () const { return _orientation.getUp (); };
const glm::vec3& getHeadFrontDirection() const { return _orientation.getFront(); };
*/
const glm::vec3& getHeadPosition() const ; const glm::vec3& getHeadPosition() const ;
const glm::vec3& getJointPosition(AvatarJointID j) const { return _joint[j].position; }; const glm::vec3& getJointPosition(AvatarJointID j) const { return _joint[j].position; };
const glm::vec3& getBodyUpDirection() const { return _orientation.getUp(); }; const glm::vec3& getBodyUpDirection() const { return _orientation.getUp(); };
@ -117,8 +110,8 @@ public:
AvatarMode getMode(); AvatarMode getMode();
void setMousePressed( bool pressed ); void setMousePressed(bool pressed);
void render(bool lookingInMirror); void render(bool lookingInMirrorm, glm::vec3 cameraPosition);
void renderBody(); void renderBody();
void renderHead(bool lookingInMirror); void renderHead(bool lookingInMirror);
void simulate(float); void simulate(float);
@ -241,7 +234,6 @@ private:
float _transmitterHz; float _transmitterHz;
int _transmitterPackets; int _transmitterPackets;
glm::vec3 _transmitterInitialReading; glm::vec3 _transmitterInitialReading;
Avatar* _interactingOther;
float _pelvisStandingHeight; float _pelvisStandingHeight;
float _height; float _height;
Balls* _balls; Balls* _balls;
@ -260,8 +252,9 @@ private:
void readSensors(); void readSensors();
void updateHead( float deltaTime ); void updateHead( float deltaTime );
void updateHandMovementAndTouching(float deltaTime); void updateHandMovementAndTouching(float deltaTime);
void updateAvatarCollisions(float deltaTime);
void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime ); void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime );
void updateCollisionWithOtherAvatar( Avatar * other, float deltaTime ); void applyCollisionWithOtherAvatar( Avatar * other, float deltaTime );
void setHeadFromGyros(glm::vec3 * eulerAngles, glm::vec3 * angularVelocity, float deltaTime, float smoothingTime); void setHeadFromGyros(glm::vec3 * eulerAngles, glm::vec3 * angularVelocity, float deltaTime, float smoothingTime);
void setHeadSpringScale(float s) { _head.returnSpringScale = s; } void setHeadSpringScale(float s) { _head.returnSpringScale = s; }
}; };

View file

@ -16,13 +16,4 @@ AvatarRenderer::AvatarRenderer() {
// this method renders the avatar // this method renders the avatar
void AvatarRenderer::render(Avatar *avatar, bool lookingInMirror) { void AvatarRenderer::render(Avatar *avatar, bool lookingInMirror) {
/*
// show avatar position
glColor4f( 0.5f, 0.5f, 0.5f, 0.6 );
glPushMatrix();
glTranslatef(avatar->_position.x, avatar->_position.y, avatar->_position.z);
glScalef( 0.03, 0.03, 0.03 );
glutSolidSphere( 1, 10, 10 );
glPopMatrix();
*/
} }

View file

@ -10,6 +10,7 @@
#include <SharedUtil.h> #include <SharedUtil.h>
#include "AvatarTouch.h" #include "AvatarTouch.h"
#include "InterfaceConfig.h" #include "InterfaceConfig.h"
#include "Util.h"
const float THREAD_RADIUS = 0.012; const float THREAD_RADIUS = 0.012;
@ -17,8 +18,11 @@ AvatarTouch::AvatarTouch() {
_myHandPosition = glm::vec3( 0.0f, 0.0f, 0.0f ); _myHandPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
_yourHandPosition = glm::vec3( 0.0f, 0.0f, 0.0f ); _yourHandPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
_myBodyPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
_yourBodyPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
_myHandState = 0; _myHandState = 0;
_yourHandState = 0; _yourHandState = 0;
_reachableRadius = 0.0f;
_canReachToOtherAvatar = false; _canReachToOtherAvatar = false;
_handsCloseEnoughToGrasp = false; _handsCloseEnoughToGrasp = false;
@ -28,40 +32,46 @@ AvatarTouch::AvatarTouch() {
} }
} }
void AvatarTouch::setMyHandPosition( glm::vec3 position ) { void AvatarTouch::setMyHandPosition(glm::vec3 position) {
_myHandPosition = position; _myHandPosition = position;
} }
void AvatarTouch::setYourHandPosition( glm::vec3 position ) { void AvatarTouch::setYourHandPosition(glm::vec3 position) {
_yourHandPosition = position; _yourHandPosition = position;
} }
void AvatarTouch::setMyHandState( int state ) { void AvatarTouch::setMyBodyPosition(glm::vec3 position) {
_myBodyPosition = position;
}
void AvatarTouch::setYourBodyPosition(glm::vec3 position) {
_yourBodyPosition = position;
}
void AvatarTouch::setMyHandState(int state) {
_myHandState = state; _myHandState = state;
} }
void AvatarTouch::setYourHandState( int state ) { void AvatarTouch::setYourHandState(int state) {
_yourHandState = state; _yourHandState = state;
} }
void AvatarTouch::render() { void AvatarTouch::setReachableRadius(float r) {
_reachableRadius = r;
}
glm::vec3 v1( _myHandPosition );
glm::vec3 v2( _yourHandPosition ); void AvatarTouch::render(glm::vec3 cameraPosition) {
if (_canReachToOtherAvatar) { if (_canReachToOtherAvatar) {
// if my hand is grasping, show it...
if ( _myHandState == 1 ) { glColor4f( 0.3, 0.4, 0.5, 0.5 );
glPushMatrix(); glm::vec3 p(_yourBodyPosition);
glTranslatef(_myHandPosition.x, _myHandPosition.y, _myHandPosition.z); p.y = 0.0005f;
glColor4f( 1.0, 1.0, 0.8, 0.3 ); glutSolidSphere( 0.020f, 10.0f, 10.0f ); renderCircle(p, _reachableRadius, glm::vec3(0.0f, 1.0f, 0.0f), 30);
glColor4f( 1.0, 1.0, 0.4, 0.2 ); glutSolidSphere( 0.025f, 10.0f, 10.0f );
glColor4f( 1.0, 1.0, 0.2, 0.1 ); glutSolidSphere( 0.030f, 10.0f, 10.0f );
glPopMatrix();
}
// if your hand is grasping, show it... // if your hand is grasping, show it...
if ( _yourHandState == 1 ) { if (_yourHandState == 1) {
glPushMatrix(); glPushMatrix();
glTranslatef(_yourHandPosition.x, _yourHandPosition.y, _yourHandPosition.z); glTranslatef(_yourHandPosition.x, _yourHandPosition.y, _yourHandPosition.z);
glColor4f( 1.0, 1.0, 0.8, 0.3 ); glutSolidSphere( 0.020f, 10.0f, 10.0f ); glColor4f( 1.0, 1.0, 0.8, 0.3 ); glutSolidSphere( 0.020f, 10.0f, 10.0f );
@ -69,35 +79,61 @@ void AvatarTouch::render() {
glColor4f( 1.0, 1.0, 0.2, 0.1 ); glutSolidSphere( 0.030f, 10.0f, 10.0f ); glColor4f( 1.0, 1.0, 0.2, 0.1 ); glutSolidSphere( 0.030f, 10.0f, 10.0f );
glPopMatrix(); glPopMatrix();
} }
//show beam
glm::vec3 v1(_myHandPosition);
glm::vec3 v2(_yourHandPosition);
if (_handsCloseEnoughToGrasp) {
glLineWidth(2.0);
glColor4f( 0.7f, 0.4f, 0.1f, 0.3 );
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 );
for (int p=0; p<NUM_POINTS; p++) {
glBegin(GL_POINTS);
glVertex3f(_point[p].x, _point[p].y, _point[p].z);
glEnd();
}
}
} }
//show beam // if my hand is grasping, show it...
if (_handsCloseEnoughToGrasp) { if (_myHandState == 1) {
glLineWidth( 2.0 ); glPushMatrix();
glColor4f( 0.7f, 0.4f, 0.1f, 0.3 ); glTranslatef(_myHandPosition.x, _myHandPosition.y, _myHandPosition.z);
glBegin( GL_LINE_STRIP ); glColor4f( 1.0, 1.0, 0.8, 0.3 ); glutSolidSphere( 0.020f, 10.0f, 10.0f );
glVertex3f( v1.x, v1.y, v1.z ); glColor4f( 1.0, 1.0, 0.4, 0.2 ); glutSolidSphere( 0.025f, 10.0f, 10.0f );
glVertex3f( v2.x, v2.y, v2.z ); glColor4f( 1.0, 1.0, 0.2, 0.1 ); glutSolidSphere( 0.030f, 10.0f, 10.0f );
glEnd(); glPopMatrix();
glColor4f( 1.0f, 1.0f, 0.0f, 0.8 );
for (int p=0; p<NUM_POINTS; p++) {
glBegin(GL_POINTS);
glVertex3f(_point[p].x, _point[p].y, _point[p].z);
glEnd();
}
} }
} }
void AvatarTouch::simulate (float deltaTime) { void AvatarTouch::simulate (float deltaTime) {
glm::vec3 v = _yourHandPosition - _myHandPosition; glm::vec3 v = _yourBodyPosition - _myBodyPosition;
float distance = glm::length(v);
if (distance < _reachableRadius ) {
_canReachToOtherAvatar = true;
} else {
_canReachToOtherAvatar = false;
}
/*
for (int p=0; p<NUM_POINTS; p++) { for (int p=0; p<NUM_POINTS; p++) {
_point[p] = _myHandPosition + v * ( (float)p / (float)NUM_POINTS ); _point[p] = _myHandPosition + v * ( (float)p / (float)NUM_POINTS );
_point[p].x += randFloatInRange( -THREAD_RADIUS, THREAD_RADIUS ); _point[p].x += randFloatInRange( -THREAD_RADIUS, THREAD_RADIUS );
_point[p].y += randFloatInRange( -THREAD_RADIUS, THREAD_RADIUS ); _point[p].y += randFloatInRange( -THREAD_RADIUS, THREAD_RADIUS );
_point[p].z += randFloatInRange( -THREAD_RADIUS, THREAD_RADIUS ); _point[p].z += randFloatInRange( -THREAD_RADIUS, THREAD_RADIUS );
} }
*/
} }

View file

@ -19,30 +19,35 @@ public:
AvatarTouch(); AvatarTouch();
void simulate(float deltaTime); void simulate(float deltaTime);
void render(); void render(glm::vec3 cameraPosition);
void setMyHandPosition ( glm::vec3 position ); void setMyHandPosition (glm::vec3 position);
void setYourHandPosition( glm::vec3 position ); void setYourHandPosition(glm::vec3 position);
void setMyHandState ( int state ); void setMyBodyPosition (glm::vec3 position);
void setYourHandState ( int state ); void setYourBodyPosition(glm::vec3 position);
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 setAbleToReachOtherAvatar ( bool a ) { _canReachToOtherAvatar = a; } bool getAbleToReachOtherAvatar () const {return _canReachToOtherAvatar;}
void setHandsCloseEnoughToGrasp( bool h ) { _handsCloseEnoughToGrasp = h; } bool getHandsCloseEnoughToGrasp() const {return _handsCloseEnoughToGrasp;}
bool getAbleToReachOtherAvatar () { return _canReachToOtherAvatar; }
bool getHandsCloseEnoughToGrasp() { return _handsCloseEnoughToGrasp; }
private: private:
static const int NUM_POINTS = 100; static const int NUM_POINTS = 100;
glm::vec3 _point [NUM_POINTS]; glm::vec3 _point [NUM_POINTS];
glm::vec3 _myBodyPosition;
glm::vec3 _yourBodyPosition;
glm::vec3 _myHandPosition; glm::vec3 _myHandPosition;
glm::vec3 _yourHandPosition; glm::vec3 _yourHandPosition;
int _myHandState; int _myHandState;
int _yourHandState; int _yourHandState;
bool _canReachToOtherAvatar; bool _canReachToOtherAvatar;
bool _handsCloseEnoughToGrasp; bool _handsCloseEnoughToGrasp;
float _reachableRadius;
}; };
#endif #endif

View file

@ -190,9 +190,7 @@ void drawtext(int x, int y, float scale, float rotate, float thick, int mono,
} }
void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec, void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec, float r, float g, float b) {
float r, float g, float b)
{
// //
// Draws text on screen as stroked so it can be resized // Draws text on screen as stroked so it can be resized
// //
@ -207,18 +205,15 @@ void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, gl
glLineWidth(thick); glLineWidth(thick);
glScalef(scale, scale, 1.0); glScalef(scale, scale, 1.0);
len = (int) strlen(vectext); len = (int) strlen(vectext);
for (i = 0; i < len; i++) for (i = 0; i < len; i++) {
{
if (!mono) glutStrokeCharacter(GLUT_STROKE_ROMAN, int(vectext[i])); if (!mono) glutStrokeCharacter(GLUT_STROKE_ROMAN, int(vectext[i]));
else glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, int(vectext[i])); else glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, int(vectext[i]));
} }
glPopMatrix(); glPopMatrix();
}
}
void drawGroundPlaneGrid(float size)
{
void drawGroundPlaneGrid(float size) {
glColor3f( 0.4f, 0.5f, 0.3f ); glColor3f( 0.4f, 0.5f, 0.3f );
glLineWidth(2.0); glLineWidth(2.0);
@ -272,6 +267,51 @@ void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, f
} }
void renderSphereOutline(glm::vec3 position, float radius, int numSides, glm::vec3 cameraPosition) {
glm::vec3 vectorToPosition(glm::normalize(position - cameraPosition));
glm::vec3 right = glm::cross(vectorToPosition, glm::vec3( 0.0f, 1.0f, 0.0f));
glm::vec3 up = glm::cross(right, vectorToPosition);
glBegin(GL_LINE_STRIP);
for (int i=0; i<numSides+1; i++) {
float r = ((float)i / (float)numSides) * PI * 2.0;
float s = radius * sin(r);
float c = radius * cos(r);
glVertex3f
(
position.x + right.x * s + up.x * c,
position.y + right.y * s + up.y * c,
position.z + right.z * s + up.z * c
);
}
glEnd();
}
void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int numSides ) {
glm::vec3 perp1 = glm::vec3(surfaceNormal.y, surfaceNormal.z, surfaceNormal.x);
glm::vec3 perp2 = glm::vec3(surfaceNormal.z, surfaceNormal.x, surfaceNormal.y);
glBegin(GL_LINE_STRIP);
for (int i=0; i<numSides+1; i++) {
float r = ((float)i / (float)numSides) * PI * 2.0;
float s = radius * sin(r);
float c = radius * cos(r);
glVertex3f
(
position.x + perp1.x * s + perp2.x * c,
position.y + perp1.y * s + perp2.y * c,
position.z + perp1.z * s + perp2.z * c
);
}
glEnd();
}
void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ) { void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ) {
glm::vec3 pRight = position + orientation.getRight() * size; glm::vec3 pRight = position + orientation.getRight() * size;
glm::vec3 pUp = position + orientation.getUp() * size; glm::vec3 pUp = position + orientation.getUp() * size;

View file

@ -52,6 +52,9 @@ void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, f
void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ); void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size );
void renderSphereOutline(glm::vec3 position, float radius, int numSides, glm::vec3 cameraPosition);
void renderCircle(glm::vec3 position, float radius, glm::vec3 surfaceNormal, int numSides );
class oTestCase { class oTestCase {
public: public:

View file

@ -692,14 +692,14 @@ void displaySide(Camera& whichCamera) {
float sphereRadius = 0.25f; float sphereRadius = 0.25f;
glColor3f(1,0,0); glColor3f(1,0,0);
glPushMatrix(); glPushMatrix();
glutSolidSphere( sphereRadius, 15, 15 ); glutSolidSphere(sphereRadius, 15, 15);
glPopMatrix(); glPopMatrix();
//draw a grid ground plane.... //draw a grid ground plane....
drawGroundPlaneGrid(10.f); drawGroundPlaneGrid(10.f);
// Draw voxels // Draw voxels
if ( showingVoxels ) if (showingVoxels)
{ {
voxels.render(); voxels.render();
} }
@ -710,7 +710,7 @@ void displaySide(Camera& whichCamera) {
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
Avatar *avatar = (Avatar *)agent->getLinkedData(); Avatar *avatar = (Avatar *)agent->getLinkedData();
avatar->render(0); avatar->render(0, ::myCamera.getPosition());
} }
} }
agentList->unlock(); agentList->unlock();
@ -722,7 +722,7 @@ void displaySide(Camera& whichCamera) {
if (::frustumOn) renderViewFrustum(::viewFrustum); if (::frustumOn) renderViewFrustum(::viewFrustum);
//Render my own avatar //Render my own avatar
myAvatar.render(::lookingInMirror); myAvatar.render(::lookingInMirror, ::myCamera.getPosition());
glPopMatrix(); glPopMatrix();
} }
@ -984,15 +984,15 @@ void display(void)
glMateriali(GL_FRONT, GL_SHININESS, 96); glMateriali(GL_FRONT, GL_SHININESS, 96);
// camera settings // camera settings
if ( ::lookingInMirror ) { if (::lookingInMirror) {
// set the camera to looking at my own face // set the camera to looking at my own face
myCamera.setTargetPosition ( myAvatar.getHeadPosition() ); myCamera.setTargetPosition (myAvatar.getHeadPosition());
myCamera.setTargetYaw ( myAvatar.getBodyYaw() - 180.0f ); // 180 degrees from body yaw myCamera.setTargetYaw (myAvatar.getBodyYaw() - 180.0f); // 180 degrees from body yaw
myCamera.setPitch ( 0.0 ); myCamera.setPitch (0.0);
myCamera.setRoll ( 0.0 ); myCamera.setRoll (0.0);
myCamera.setUpShift ( 0.0 ); myCamera.setUpShift (0.0);
myCamera.setDistance ( 0.2 ); myCamera.setDistance (0.2);
myCamera.setTightness ( 100.0f ); myCamera.setTightness (100.0f);
} else { } else {
//float firstPersonPitch = 20.0f; //float firstPersonPitch = 20.0f;
@ -1010,36 +1010,24 @@ void display(void)
float thirdPersonDistance = 1.2f; float thirdPersonDistance = 1.2f;
float thirdPersonTightness = 8.0f; float thirdPersonTightness = 8.0f;
if ( USING_FIRST_PERSON_EFFECT ) { if (USING_FIRST_PERSON_EFFECT) {
float ff = 0.0; float ff = 0.0;
float min = 0.1; float min = 0.1;
float max = 0.5; float max = 0.5;
if ( myAvatar.getIsNearInteractingOther()){ if (myAvatar.getIsNearInteractingOther()){
if ( myAvatar.getSpeed() < max ) { if (myAvatar.getSpeed() < max) {
float s = (myAvatar.getSpeed()- min)/max ; float s = (myAvatar.getSpeed()- min)/max ;
ff = 1.0 - s; ff = 1.0 - s;
} }
} }
/*
if ( ff < 0.8 ) {
myAvatar.setDisplayingHead( true );
} else {
myAvatar.setDisplayingHead( false );
}
*/
//printf( "ff = %f\n", ff );
myCamera.setPitch ( thirdPersonPitch + ff * ( firstPersonPitch - thirdPersonPitch )); myCamera.setPitch (thirdPersonPitch + ff * (firstPersonPitch - thirdPersonPitch ));
myCamera.setUpShift ( thirdPersonUpShift + ff * ( firstPersonUpShift - thirdPersonUpShift )); myCamera.setUpShift (thirdPersonUpShift + ff * (firstPersonUpShift - thirdPersonUpShift ));
myCamera.setDistance ( thirdPersonDistance + ff * ( firstPersonDistance - thirdPersonDistance )); myCamera.setDistance (thirdPersonDistance + ff * (firstPersonDistance - thirdPersonDistance ));
myCamera.setTightness ( thirdPersonTightness + ff * ( firstPersonTightness - thirdPersonTightness )); myCamera.setTightness (thirdPersonTightness + ff * (firstPersonTightness - thirdPersonTightness));
// this version uses a ramp-up/ramp-down timer in the camera to determine shift between first and thirs-person view // this version uses a ramp-up/ramp-down timer in the camera to determine shift between first and thirs-person view
/* /*
if ( myAvatar.getSpeed() < 0.02 ) { if ( myAvatar.getSpeed() < 0.02 ) {
@ -1073,12 +1061,13 @@ void display(void)
myCamera.setTightness(thirdPersonTightness); myCamera.setTightness(thirdPersonTightness);
} }
myCamera.setTargetPosition( myAvatar.getHeadPosition() ); myCamera.setTargetPosition(myAvatar.getHeadPosition());
myCamera.setTargetYaw ( myAvatar.getBodyYaw() ); myCamera.setTargetYaw (myAvatar.getBodyYaw());
myCamera.setRoll ( 0.0 ); myCamera.setRoll (0.0);
} }
// important... // important...
myCamera.update( 1.f/FPS ); myCamera.update( 1.f/FPS );
// Render anything (like HUD items) that we want to be in 3D but not in worldspace // Render anything (like HUD items) that we want to be in 3D but not in worldspace
@ -1104,11 +1093,11 @@ void display(void)
if (::viewFrustumFromOffset && ::frustumOn) { if (::viewFrustumFromOffset && ::frustumOn) {
// set the camera to third-person view but offset so we can see the frustum // set the camera to third-person view but offset so we can see the frustum
viewFrustumOffsetCamera.setTargetYaw( ::viewFrustumOffsetYaw + myAvatar.getBodyYaw() ); viewFrustumOffsetCamera.setTargetYaw(::viewFrustumOffsetYaw + myAvatar.getBodyYaw() );
viewFrustumOffsetCamera.setPitch ( ::viewFrustumOffsetPitch ); viewFrustumOffsetCamera.setPitch (::viewFrustumOffsetPitch );
viewFrustumOffsetCamera.setRoll ( ::viewFrustumOffsetRoll ); viewFrustumOffsetCamera.setRoll (::viewFrustumOffsetRoll );
viewFrustumOffsetCamera.setUpShift ( ::viewFrustumOffsetUp ); viewFrustumOffsetCamera.setUpShift (::viewFrustumOffsetUp );
viewFrustumOffsetCamera.setDistance ( ::viewFrustumOffsetDistance ); viewFrustumOffsetCamera.setDistance (::viewFrustumOffsetDistance);
viewFrustumOffsetCamera.update(1.f/FPS); viewFrustumOffsetCamera.update(1.f/FPS);
whichCamera = viewFrustumOffsetCamera; whichCamera = viewFrustumOffsetCamera;
} }
@ -1118,11 +1107,11 @@ void display(void)
// or could be viewFrustumOffsetCamera if in offset mode // or could be viewFrustumOffsetCamera if in offset mode
// I changed the ordering here - roll is FIRST (JJV) // I changed the ordering here - roll is FIRST (JJV)
glRotatef ( whichCamera.getRoll(), IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z ); glRotatef ( whichCamera.getRoll(), IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z);
glRotatef ( whichCamera.getPitch(), IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z ); glRotatef ( whichCamera.getPitch(), IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z);
glRotatef ( 180.0 - whichCamera.getYaw(), IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z ); glRotatef (180.0 - whichCamera.getYaw(), IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z );
glTranslatef( -whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z ); glTranslatef(-whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z);
if (::oculusOn) { if (::oculusOn) {
displayOculus(whichCamera); displayOculus(whichCamera);
@ -1675,18 +1664,16 @@ void idle(void) {
// update behaviors for avatar hand movement: handControl takes mouse values as input, // update behaviors for avatar hand movement: handControl takes mouse values as input,
// and gives back 3D values modulated for smooth transitioning between interaction modes. // and gives back 3D values modulated for smooth transitioning between interaction modes.
handControl.update( mouseX, mouseY ); handControl.update(mouseX, mouseY);
myAvatar.setHandMovementValues( handControl.getValues() ); myAvatar.setHandMovementValues(handControl.getValues());
// tell my avatar if the mouse is being pressed... // tell my avatar if the mouse is being pressed...
if ( mousePressed == 1 ) { if (mousePressed) {
myAvatar.setMousePressed( true ); myAvatar.setMousePressed(mousePressed);
} else { }
myAvatar.setMousePressed( false );
}
// walking triggers the handControl to stop // walking triggers the handControl to stop
if ( myAvatar.getMode() == AVATAR_MODE_WALKING ) { if (myAvatar.getMode() == AVATAR_MODE_WALKING) {
handControl.stop(); handControl.stop();
} }
@ -1879,7 +1866,7 @@ int main(int argc, const char * argv[])
#ifdef _WIN32 #ifdef _WIN32
WSADATA WsaData; WSADATA WsaData;
int wsaresult = WSAStartup( MAKEWORD(2,2), &WsaData ); int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData);
#endif #endif
// start the agentList threads // start the agentList threads