Merge pull request #201 from Ventrella/master

gravity fixes
This commit is contained in:
Jeffrey Ventrella 2013-05-06 12:42:18 -07:00
commit 69734f41fc
3 changed files with 115 additions and 100 deletions

View file

@ -21,7 +21,9 @@
using namespace std; using namespace std;
const bool BALLS_ON = false; const bool BALLS_ON = false;
const bool AVATAR_GRAVITY = true; const bool USING_AVATAR_GRAVITY = true;
const float GRAVITY_SCALE = 6.0f;
const float BOUNCE = 0.3f;
const float DECAY = 0.1; const float DECAY = 0.1;
const float THRUST_MAG = 1200.0; const float THRUST_MAG = 1200.0;
const float YAW_MAG = 500.0; const float YAW_MAG = 500.0;
@ -145,6 +147,7 @@ Avatar::Avatar(bool isMine) {
_interactingOther = 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
initializeSkeleton(); initializeSkeleton();
@ -336,13 +339,13 @@ void Avatar::simulate(float deltaTime) {
updateHandMovementAndTouching(deltaTime); updateHandMovementAndTouching(deltaTime);
// apply gravity and collision wiht the ground/floor // apply gravity and collision with the ground/floor
if (AVATAR_GRAVITY) { if (USING_AVATAR_GRAVITY) {
if ( _position.y > _pelvisStandingHeight + 0.01f) { if (_position.y > _pelvisStandingHeight + 0.01f) {
_velocity += glm::dvec3(getGravity(getPosition())) * (6.0 * deltaTime ); _velocity += _gravity * (GRAVITY_SCALE * deltaTime);
} else if (_position.y < _pelvisStandingHeight) { } else if (_position.y < _pelvisStandingHeight) {
_position.y = _pelvisStandingHeight; _position.y = _pelvisStandingHeight;
_velocity.y = 0.0; _velocity.y = -_velocity.y * BOUNCE;
} }
} }
@ -387,16 +390,16 @@ void Avatar::simulate(float deltaTime) {
_velocity += _thrust * deltaTime; _velocity += _thrust * deltaTime;
// calculate speed // calculate speed
_speed = glm::length( _velocity ); _speed = glm::length(_velocity);
//pitch and roll the body as a function of forward speed and turning delta //pitch and roll the body as a function of forward speed and turning delta
float forwardComponentOfVelocity = glm::dot( _orientation.getFront(), _velocity ); float forwardComponentOfVelocity = glm::dot(_orientation.getFront(), _velocity);
_bodyPitch += BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity; _bodyPitch += BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity;
_bodyRoll += BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta; _bodyRoll += BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta;
// these forces keep the body upright... // these forces keep the body upright...
float tiltDecay = 1.0 - BODY_UPRIGHT_FORCE * deltaTime; float tiltDecay = 1.0 - BODY_UPRIGHT_FORCE * deltaTime;
if ( tiltDecay < 0.0f ) { tiltDecay = 0.0f; } if (tiltDecay < 0.0f) {tiltDecay = 0.0f;}
_bodyPitch *= tiltDecay; _bodyPitch *= tiltDecay;
_bodyRoll *= tiltDecay; _bodyRoll *= tiltDecay;
@ -404,7 +407,7 @@ void Avatar::simulate(float deltaTime) {
_position += _velocity * deltaTime; _position += _velocity * deltaTime;
// decay velocity // decay velocity
_velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); _velocity *= (1.0 - LIN_VEL_DECAY * deltaTime);
// If someone is near, damp velocity as a function of closeness // If someone is near, damp velocity as a function of closeness
const float AVATAR_BRAKING_RANGE = 1.2f; const float AVATAR_BRAKING_RANGE = 1.2f;
@ -419,7 +422,7 @@ void Avatar::simulate(float deltaTime) {
updateHead(deltaTime); updateHead(deltaTime);
// use speed and angular velocity to determine walking vs. standing // use speed and angular velocity to determine walking vs. standing
if ( _speed + fabs( _bodyYawDelta ) > 0.2 ) { if (_speed + fabs(_bodyYawDelta) > 0.2) {
_mode = AVATAR_MODE_WALKING; _mode = AVATAR_MODE_WALKING;
} else { } else {
_mode = AVATAR_MODE_INTERACTING; _mode = AVATAR_MODE_INTERACTING;
@ -449,7 +452,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
// if the avatar being simulated is mine, then loop through // if the avatar being simulated is mine, then loop through
// all the other avatars for potential interactions... // all the other avatars for potential interactions...
if ( _isMine ) if (_isMine)
{ {
// Reset detector for nearest avatar // Reset detector for nearest avatar
_distanceToNearestAvatar = std::numeric_limits<float>::max(); _distanceToNearestAvatar = std::numeric_limits<float>::max();
@ -463,24 +466,24 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
updateCollisionWithOtherAvatar(otherAvatar, deltaTime ); updateCollisionWithOtherAvatar(otherAvatar, deltaTime );
// test other avatar hand position for proximity // test other avatar hand position for proximity
glm::vec3 v( _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position ); glm::vec3 v(_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position);
v -= otherAvatar->getJointPosition( AVATAR_JOINT_RIGHT_SHOULDER ); v -= otherAvatar->getJointPosition(AVATAR_JOINT_RIGHT_SHOULDER);
float distance = glm::length( v ); float distance = glm::length(v);
if (distance < _distanceToNearestAvatar) { _distanceToNearestAvatar = distance; } if (distance < _distanceToNearestAvatar) {_distanceToNearestAvatar = distance;}
if (distance < _maxArmLength + _maxArmLength) { if (distance < _maxArmLength + _maxArmLength) {
_interactingOther = otherAvatar; _interactingOther = otherAvatar;
if ( ! _avatarTouch.getAbleToReachOtherAvatar() ) { if (! _avatarTouch.getAbleToReachOtherAvatar()) {
//initialize _handHolding //initialize _handHolding
_handHoldingPosition = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position; _handHoldingPosition = _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position;
_avatarTouch.setAbleToReachOtherAvatar(true); _avatarTouch.setAbleToReachOtherAvatar(true);
} }
glm::vec3 vectorBetweenHands( _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position ); glm::vec3 vectorBetweenHands(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
vectorBetweenHands -= otherAvatar->getJointPosition( AVATAR_JOINT_RIGHT_FINGERTIPS ); vectorBetweenHands -= otherAvatar->getJointPosition(AVATAR_JOINT_RIGHT_FINGERTIPS);
float distanceBetweenHands = glm::length(vectorBetweenHands); float distanceBetweenHands = glm::length(vectorBetweenHands);
if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP) { if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP) {
@ -488,7 +491,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
} }
// if I am holding hands with another avatar, a force is applied // if I am holding hands with another avatar, a force is applied
if (( _handState == 1 ) || ( _interactingOther->_handState == 1 )) { if ((_handState == 1) || (_interactingOther->_handState == 1)) {
// if the hands are close enough to grasp... // if the hands are close enough to grasp...
if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP) if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP)
@ -502,7 +505,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handHoldingPosition; _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handHoldingPosition;
// apply a force to the avatar body // apply a force to the avatar body
if ( glm::length(vectorToOtherHand) > _maxArmLength * 0.9 ) { if (glm::length(vectorToOtherHand) > _maxArmLength * 0.9) {
_velocity += vectorToOtherHand; _velocity += vectorToOtherHand;
} }
} }
@ -514,18 +517,18 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
// Set the vector we send for hand position to other people to be our right hand // Set the vector we send for hand position to other people to be our right hand
setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
}//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
updateArmIKAndConstraints( deltaTime ); updateArmIKAndConstraints(deltaTime);
// set hand positions for _avatarTouch.setMyHandPosition AFTER calling updateArmIKAndConstraints // set hand positions for _avatarTouch.setMyHandPosition AFTER calling updateArmIKAndConstraints
if ( _interactingOther ) { if (_interactingOther) {
if (_isMine) { if (_isMine) {
_avatarTouch.setMyHandPosition ( _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position ); _avatarTouch.setMyHandPosition (_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
_avatarTouch.setYourHandPosition( _interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position ); _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position);
_avatarTouch.setMyHandState ( _handState ); _avatarTouch.setMyHandState (_handState);
_avatarTouch.setYourHandState ( _interactingOther->_handState ); _avatarTouch.setYourHandState (_interactingOther->_handState);
_avatarTouch.simulate(deltaTime); _avatarTouch.simulate(deltaTime);
} }
} }
@ -539,7 +542,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
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...
if ( fabs( _head.leanSideways + _head.leanForward ) > 0.0f ) { if (fabs( _head.leanSideways + _head.leanForward ) > 0.0f) {
glm::vec3 headLean = glm::vec3 headLean =
_orientation.getRight() * _head.leanSideways + _orientation.getRight() * _head.leanSideways +
_orientation.getFront() * _head.leanForward; _orientation.getFront() * _head.leanForward;
@ -650,19 +653,19 @@ float Avatar::getHeight() {
} }
void Avatar::updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime ) { void Avatar::updateCollisionWithSphere(glm::vec3 position, float radius, float deltaTime) {
float myBodyApproximateBoundingRadius = 1.0f; float myBodyApproximateBoundingRadius = 1.0f;
glm::vec3 vectorFromMyBodyToBigSphere(_position - position); glm::vec3 vectorFromMyBodyToBigSphere(_position - position);
bool jointCollision = false; bool jointCollision = false;
float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere); float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere);
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + radius ) { if (distanceToBigSphere < myBodyApproximateBoundingRadius + radius) {
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
glm::vec3 vectorFromJointToBigSphereCenter(_joint[b].springyPosition - position); glm::vec3 vectorFromJointToBigSphereCenter(_joint[b].springyPosition - position);
float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter); float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter);
float combinedRadius = _joint[b].radius + radius; float combinedRadius = _joint[b].radius + radius;
if ( distanceToBigSphereCenter < combinedRadius ) { if (distanceToBigSphereCenter < combinedRadius) {
jointCollision = true; jointCollision = true;
if (distanceToBigSphereCenter > 0.0) { if (distanceToBigSphereCenter > 0.0) {
glm::vec3 directionVector = vectorFromJointToBigSphereCenter / distanceToBigSphereCenter; glm::vec3 directionVector = vectorFromJointToBigSphereCenter / distanceToBigSphereCenter;
@ -677,7 +680,7 @@ void Avatar::updateCollisionWithSphere( glm::vec3 position, float radius, float
} }
} }
if ( jointCollision ) { if (jointCollision) {
if (!_usingBodySprings) { if (!_usingBodySprings) {
_usingBodySprings = true; _usingBodySprings = true;
initializeBodySprings(); initializeBodySprings();
@ -688,37 +691,37 @@ void Avatar::updateCollisionWithSphere( glm::vec3 position, float radius, float
//detect collisions with other avatars and respond //detect collisions with other avatars and respond
void Avatar::updateCollisionWithOtherAvatar( Avatar * otherAvatar, float deltaTime ) { void Avatar::updateCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) {
// check if the bounding spheres of the two avatars are colliding // check if the bounding spheres of the two avatars are colliding
glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position); glm::vec3 vectorBetweenBoundingSpheres(_position - otherAvatar->_position);
if ( glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF ) { if (glm::length(vectorBetweenBoundingSpheres) < _height * ONE_HALF + otherAvatar->_height * ONE_HALF) {
float bodyMomentum = 1.0f; float bodyMomentum = 1.0f;
glm::vec3 bodyPushForce = glm::vec3( 0.0, 0.0, 0.0 ); 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); glm::vec3 vectorBetweenJoints(_joint[b].springyPosition - otherAvatar->_joint[o].springyPosition);
float distanceBetweenJoints = glm::length(vectorBetweenJoints); float distanceBetweenJoints = glm::length(vectorBetweenJoints);
if ( distanceBetweenJoints > 0.0 ) { // to avoid divide by zero if (distanceBetweenJoints > 0.0 ) { // to avoid divide by zero
float combinedRadius = _joint[b].radius + otherAvatar->_joint[o].radius; 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 // push balls away from each other and apply friction
glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * deltaTime; glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * deltaTime;
float ballMomentum = 1.0 - COLLISION_BALL_FRICTION * deltaTime; float ballMomentum = 1.0 - COLLISION_BALL_FRICTION * deltaTime;
if ( ballMomentum < 0.0 ) { ballMomentum = 0.0;} if (ballMomentum < 0.0 ) { ballMomentum = 0.0;}
_joint[b].springyVelocity += ballPushForce; _joint[b].springyVelocity += ballPushForce;
otherAvatar->_joint[o].springyVelocity -= ballPushForce; otherAvatar->_joint[o].springyVelocity -= ballPushForce;
@ -729,7 +732,7 @@ void Avatar::updateCollisionWithOtherAvatar( Avatar * otherAvatar, float deltaTi
// accumulate forces and frictions to apply to the velocities of avatar bodies // accumulate forces and frictions to apply to the velocities of avatar bodies
bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime; bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime;
bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime; bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime;
if ( bodyMomentum < 0.0 ) { bodyMomentum = 0.0;} if (bodyMomentum < 0.0 ) { bodyMomentum = 0.0;}
}// check for collision }// check for collision
} // to avoid divide by zero } // to avoid divide by zero
@ -749,7 +752,7 @@ void Avatar::updateCollisionWithOtherAvatar( Avatar * otherAvatar, float deltaTi
} //method } //method
void Avatar::setDisplayingHead( bool displayingHead ) { void Avatar::setDisplayingHead(bool displayingHead ) {
_displayingHead = displayingHead; _displayingHead = displayingHead;
} }
@ -760,28 +763,33 @@ static TextRenderer* textRenderer() {
} }
void Avatar::setGravity(glm::vec3 gravity) {
_gravity = gravity;
}
void Avatar::render(bool lookingInMirror) { void Avatar::render(bool lookingInMirror) {
// 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 );
/* /*
// show avatar position // show avatar position
glColor4f( 0.5f, 0.5f, 0.5f, 0.6 ); glColor4f(0.5f, 0.5f, 0.5f, 0.6 );
glPushMatrix(); glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z); glTranslatef(_position.x, _position.y, _position.z);
glScalef( 0.03, 0.03, 0.03 ); glScalef(0.03, 0.03, 0.03 );
glutSolidSphere( 1, 10, 10 ); glutSolidSphere(1, 10, 10 );
glPopMatrix(); glPopMatrix();
*/ */
if ( usingBigSphereCollisionTest ) { if (usingBigSphereCollisionTest ) {
// show TEST big sphere // show TEST big sphere
glColor4f( 0.5f, 0.6f, 0.8f, 0.7 ); glColor4f(0.5f, 0.6f, 0.8f, 0.7 );
glPushMatrix(); glPushMatrix();
glTranslatef(_TEST_bigSpherePosition.x, _TEST_bigSpherePosition.y, _TEST_bigSpherePosition.z); glTranslatef(_TEST_bigSpherePosition.x, _TEST_bigSpherePosition.y, _TEST_bigSpherePosition.z);
glScalef( _TEST_bigSphereRadius, _TEST_bigSphereRadius, _TEST_bigSphereRadius ); glScalef(_TEST_bigSphereRadius, _TEST_bigSphereRadius, _TEST_bigSphereRadius );
glutSolidSphere( 1, 20, 20 ); glutSolidSphere(1, 20, 20 );
glPopMatrix(); glPopMatrix();
} }
@ -794,7 +802,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();
} }
@ -855,7 +863,7 @@ void Avatar::renderHead(bool lookingInMirror) {
glEnable(GL_RESCALE_NORMAL); glEnable(GL_RESCALE_NORMAL);
// show head orientation // show head orientation
//renderOrientationDirections( _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition, _joint[ AVATAR_JOINT_HEAD_BASE ].orientation, 0.2f ); //renderOrientationDirections(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition, _joint[ AVATAR_JOINT_HEAD_BASE ].orientation, 0.2f );
glPushMatrix(); glPushMatrix();
@ -871,7 +879,7 @@ void Avatar::renderHead(bool lookingInMirror) {
} }
glScalef glScalef
( (
_joint[ AVATAR_JOINT_HEAD_BASE ].radius, _joint[ AVATAR_JOINT_HEAD_BASE ].radius,
_joint[ AVATAR_JOINT_HEAD_BASE ].radius, _joint[ AVATAR_JOINT_HEAD_BASE ].radius,
_joint[ AVATAR_JOINT_HEAD_BASE ].radius _joint[ AVATAR_JOINT_HEAD_BASE ].radius
@ -883,15 +891,15 @@ void Avatar::renderHead(bool lookingInMirror) {
//glRotatef(_bodyPitch + _headPitch, 1, 0, 0); //glRotatef(_bodyPitch + _headPitch, 1, 0, 0);
//glRotatef(_bodyRoll - _headRoll, 0, 0, 1); //glRotatef(_bodyRoll - _headRoll, 0, 0, 1);
// don't let body pitch and roll affect the head.. // don't let body pitch and roll affect the head..
glRotatef( _headPitch, 1, 0, 0); glRotatef( _headPitch, 1, 0, 0);
glRotatef( -_headRoll, 0, 0, 1); glRotatef(-_headRoll, 0, 0, 1);
} else { } else {
glRotatef(_bodyYaw + _headYaw, 0, 1, 0); glRotatef(_bodyYaw + _headYaw, 0, 1, 0);
//glRotatef(_bodyPitch + _headPitch, 1, 0, 0); //glRotatef(_bodyPitch + _headPitch, 1, 0, 0);
//glRotatef(_bodyRoll + _headRoll, 0, 0, 1); //glRotatef(_bodyRoll + _headRoll, 0, 0, 1);
// don't let body pitch and roll affect the head.. // don't let body pitch and roll affect the head..
glRotatef( _headPitch, 1, 0, 0); glRotatef(_headPitch, 1, 0, 0);
glRotatef( _headRoll, 0, 0, 1); glRotatef(_headRoll, 0, 0, 1);
} }
//glScalef(2.0, 2.0, 2.0); //glScalef(2.0, 2.0, 2.0);
@ -1020,7 +1028,7 @@ void Avatar::renderHead(bool lookingInMirror) {
glPopMatrix(); glPopMatrix();
} }
void Avatar::setHandMovementValues( glm::vec3 handOffset ) { void Avatar::setHandMovementValues(glm::vec3 handOffset ) {
_movedHandOffset = handOffset; _movedHandOffset = handOffset;
} }
@ -1033,11 +1041,11 @@ void Avatar::initializeSkeleton() {
for (int b=0; b<NUM_AVATAR_JOINTS; b++) { for (int b=0; b<NUM_AVATAR_JOINTS; b++) {
_joint[b].isCollidable = true; _joint[b].isCollidable = true;
_joint[b].parent = AVATAR_JOINT_NULL; _joint[b].parent = AVATAR_JOINT_NULL;
_joint[b].position = glm::vec3( 0.0, 0.0, 0.0 ); _joint[b].position = glm::vec3(0.0, 0.0, 0.0 );
_joint[b].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 ); _joint[b].defaultPosePosition = glm::vec3(0.0, 0.0, 0.0 );
_joint[b].springyPosition = glm::vec3( 0.0, 0.0, 0.0 ); _joint[b].springyPosition = glm::vec3(0.0, 0.0, 0.0 );
_joint[b].springyVelocity = glm::vec3( 0.0, 0.0, 0.0 ); _joint[b].springyVelocity = glm::vec3(0.0, 0.0, 0.0 );
_joint[b].rotation = glm::quat( 0.0f, 0.0f, 0.0f, 0.0f ); _joint[b].rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f );
_joint[b].yaw = 0.0; _joint[b].yaw = 0.0;
_joint[b].pitch = 0.0; _joint[b].pitch = 0.0;
_joint[b].roll = 0.0; _joint[b].roll = 0.0;
@ -1074,19 +1082,19 @@ void Avatar::initializeSkeleton() {
_joint[ AVATAR_JOINT_RIGHT_TOES ].parent = AVATAR_JOINT_RIGHT_HEEL; _joint[ AVATAR_JOINT_RIGHT_TOES ].parent = AVATAR_JOINT_RIGHT_HEEL;
// specify the default pose position // specify the default pose position
_joint[ AVATAR_JOINT_PELVIS ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 ); _joint[ AVATAR_JOINT_PELVIS ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 );
_joint[ AVATAR_JOINT_TORSO ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.01 ); _joint[ AVATAR_JOINT_TORSO ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.01 );
_joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, 0.0 ); _joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, 0.0 );
_joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.1, -0.01 ); _joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.1, -0.01 );
_joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.01 ); _joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.01 );
_joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3( -0.06, 0.04, -0.01 ); _joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3(-0.06, 0.04, -0.01 );
_joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.03, 0.0, -0.01 ); _joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3(-0.03, 0.0, -0.01 );
_joint[ AVATAR_JOINT_LEFT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.13, 0.0 ); _joint[ AVATAR_JOINT_LEFT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.13, 0.0 );
_joint[ AVATAR_JOINT_LEFT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.11, 0.0 ); _joint[ AVATAR_JOINT_LEFT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.11, 0.0 );
_joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.07, 0.0 ); _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.07, 0.0 );
_joint[ AVATAR_JOINT_RIGHT_COLLAR ].defaultPosePosition = glm::vec3( 0.06, 0.04, -0.01 ); _joint[ AVATAR_JOINT_RIGHT_COLLAR ].defaultPosePosition = glm::vec3( 0.06, 0.04, -0.01 );
_joint[ AVATAR_JOINT_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.03, 0.0, -0.01 ); _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.03, 0.0, -0.01 );
_joint[ AVATAR_JOINT_RIGHT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.13, 0.0 ); _joint[ AVATAR_JOINT_RIGHT_ELBOW ].defaultPosePosition = glm::vec3( 0.0, -0.13, 0.0 );
_joint[ AVATAR_JOINT_RIGHT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.11, 0.0 ); _joint[ AVATAR_JOINT_RIGHT_WRIST ].defaultPosePosition = glm::vec3( 0.0, -0.11, 0.0 );
_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.07, 0.0 ); _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.07, 0.0 );
_joint[ AVATAR_JOINT_LEFT_HIP ].defaultPosePosition = glm::vec3( -0.04, 0.0, -0.02 ); _joint[ AVATAR_JOINT_LEFT_HIP ].defaultPosePosition = glm::vec3( -0.04, 0.0, -0.02 );
@ -1523,25 +1531,6 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity
} }
} }
// Find and return the gravity vector at my location
glm::vec3 Avatar::getGravity(glm::vec3 pos) {
//
// For now, we'll test this with a simple global lookup, but soon we will add getting this
// from the domain/voxelserver (or something similar)
//
if ((pos.x > 0.f) &&
(pos.x < 10.f) &&
(pos.z > 0.f) &&
(pos.z < 10.f) &&
(pos.y > 0.f) &&
(pos.y < 3.f)) {
// If above ground plane, turn gravity on
return glm::vec3(0.f, -1.f, 0.f);
} else {
// If flying in space, turn gravity OFF
return glm::vec3(0.f, 0.f, 0.f);
}
}
const char AVATAR_DATA_FILENAME[] = "avatar.ifd"; const char AVATAR_DATA_FILENAME[] = "avatar.ifd";

View file

@ -84,7 +84,7 @@ public:
void reset(); void reset();
void UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); void UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity);
void setNoise (float mag) { _head.noise = mag; } void setNoise (float mag) {_head.noise = mag;}
void setScale(float s) {_head.scale = s; }; void setScale(float s) {_head.scale = s; };
void setRenderYaw(float y) {_renderYaw = y;} void setRenderYaw(float y) {_renderYaw = y;}
void setRenderPitch(float p) {_renderPitch = p;} void setRenderPitch(float p) {_renderPitch = p;}
@ -93,6 +93,7 @@ public:
float getLastMeasuredHeadYaw() const {return _head.yawRate;} float getLastMeasuredHeadYaw() const {return _head.yawRate;}
float getBodyYaw() {return _bodyYaw;}; float getBodyYaw() {return _bodyYaw;};
void addBodyYaw(float y) {_bodyYaw += y;}; void addBodyYaw(float y) {_bodyYaw += y;};
void setGravity(glm::vec3 gravity);
bool getIsNearInteractingOther(); bool getIsNearInteractingOther();
@ -143,9 +144,6 @@ public:
void processTransmitterData(unsigned char * packetData, int numBytes); void processTransmitterData(unsigned char * packetData, int numBytes);
float getTransmitterHz() { return _transmitterHz; }; float getTransmitterHz() { return _transmitterHz; };
// Find out what the local gravity vector is at this location
glm::vec3 getGravity(glm::vec3 pos);
void writeAvatarDataToFile(); void writeAvatarDataToFile();
void readAvatarDataFromFile(); void readAvatarDataFromFile();
@ -251,6 +249,7 @@ private:
bool _displayingHead; // should be false if in first-person view bool _displayingHead; // should be false if in first-person view
bool _returnHeadToCenter; bool _returnHeadToCenter;
float _distanceToNearestAvatar; // How close is the nearest avatar? float _distanceToNearestAvatar; // How close is the nearest avatar?
glm::vec3 _gravity;
// private methods... // private methods...
void initializeSkeleton(); void initializeSkeleton();

View file

@ -90,6 +90,8 @@ using namespace std;
void reshape(int width, int height); // will be defined below void reshape(int width, int height); // will be defined below
void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below
glm::vec3 getGravity(glm::vec3 pos); //get the local gravity vector at this location in the universe
QApplication* app; QApplication* app;
bool enableNetworkThread = true; bool enableNetworkThread = true;
@ -1703,6 +1705,7 @@ void idle(void) {
} }
agentList->unlock(); agentList->unlock();
myAvatar.setGravity(getGravity(myAvatar.getPosition()));
myAvatar.simulate(deltaTime); myAvatar.simulate(deltaTime);
glutPostRedisplay(); glutPostRedisplay();
@ -1765,6 +1768,30 @@ void reshape(int width, int height) {
glLoadIdentity(); glLoadIdentity();
} }
//Find and return the gravity vector at this location
glm::vec3 getGravity(glm::vec3 pos) {
//
// For now, we'll test this with a simple global lookup, but soon we will add getting this
// from the domain/voxelserver (or something similar)
//
if ((pos.x > 0.f) &&
(pos.x < 10.f) &&
(pos.z > 0.f) &&
(pos.z < 10.f) &&
(pos.y > 0.f) &&
(pos.y < 3.f)) {
// If above ground plane, turn gravity on
return glm::vec3(0.f, -1.f, 0.f);
} else {
// If flying in space, turn gravity OFF
return glm::vec3(0.f, 0.f, 0.f);
}
}
void mouseFunc(int button, int state, int x, int y) { void mouseFunc(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) {
if (state == GLUT_DOWN && !menu.mouseClick(x, y)) { if (state == GLUT_DOWN && !menu.mouseClick(x, y)) {