From 5a5b22db617d610b811a006bb8e15d8823addacc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 3 Jun 2013 12:00:57 -0700 Subject: [PATCH] fix use of PI constant after merge with upstream master --- interface/src/Application.cpp | 2 +- interface/src/Avatar.cpp | 396 +++++++++++++++++----------------- 2 files changed, 195 insertions(+), 203 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e61a04aaba..44a06c948b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -288,7 +288,7 @@ void Application::paintGL() { if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myCamera.setTightness (100.0f); _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + _myCamera.setTargetRotation(_myAvatar.getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f))); } else if (OculusManager::isConnected()) { _myCamera.setUpShift (0.0f); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index a678f9c6b0..0e21f15b17 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -62,41 +62,41 @@ float chatMessageScale = 0.0015; float chatMessageHeight = 0.20; Avatar::Avatar(Agent* owningAgent) : - AvatarData(owningAgent), - _head(this), - _TEST_bigSphereRadius(0.4f), - _TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f), - _mousePressed(false), - _bodyPitchDelta(0.0f), - _bodyYawDelta(0.0f), - _bodyRollDelta(0.0f), - _movedHandOffset(0.0f, 0.0f, 0.0f), - _mode(AVATAR_MODE_STANDING), - _cameraPosition(0.0f, 0.0f, 0.0f), - _handHoldingPosition(0.0f, 0.0f, 0.0f), - _velocity(0.0f, 0.0f, 0.0f), - _thrust(0.0f, 0.0f, 0.0f), - _speed(0.0f), - _maxArmLength(0.0f), - _pelvisStandingHeight(0.0f), - _pelvisFloatingHeight(0.0f), - _distanceToNearestAvatar(std::numeric_limits::max()), - _gravity(0.0f, -1.0f, 0.0f), - _worldUpDirection(DEFAULT_UP_DIRECTION), - _mouseRayOrigin(0.0f, 0.0f, 0.0f), - _mouseRayDirection(0.0f, 0.0f, 0.0f), - _interactingOther(NULL), - _cumulativeMouseYaw(0.0f), - _isMouseTurningRight(false) +AvatarData(owningAgent), +_head(this), +_TEST_bigSphereRadius(0.4f), +_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f), +_mousePressed(false), +_bodyPitchDelta(0.0f), +_bodyYawDelta(0.0f), +_bodyRollDelta(0.0f), +_movedHandOffset(0.0f, 0.0f, 0.0f), +_mode(AVATAR_MODE_STANDING), +_cameraPosition(0.0f, 0.0f, 0.0f), +_handHoldingPosition(0.0f, 0.0f, 0.0f), +_velocity(0.0f, 0.0f, 0.0f), +_thrust(0.0f, 0.0f, 0.0f), +_speed(0.0f), +_maxArmLength(0.0f), +_pelvisStandingHeight(0.0f), +_pelvisFloatingHeight(0.0f), +_distanceToNearestAvatar(std::numeric_limits::max()), +_gravity(0.0f, -1.0f, 0.0f), +_worldUpDirection(DEFAULT_UP_DIRECTION), +_mouseRayOrigin(0.0f, 0.0f, 0.0f), +_mouseRayDirection(0.0f, 0.0f, 0.0f), +_interactingOther(NULL), +_cumulativeMouseYaw(0.0f), +_isMouseTurningRight(false) { // give the pointer to our head to inherited _headData variable from AvatarData _headData = &_head; - + for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = false; } - + _skeleton.initialize(); initializeBodyBalls(); @@ -105,9 +105,9 @@ Avatar::Avatar(Agent* owningAgent) : _maxArmLength = _skeleton.getArmLength(); _pelvisStandingHeight = _skeleton.getPelvisStandingHeight() + _bodyBall[ AVATAR_JOINT_LEFT_HEEL ].radius; _pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight() + _bodyBall[ AVATAR_JOINT_LEFT_HEEL ].radius; - + _avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS); - + if (BALLS_ON) { _balls = new Balls(100); } else { @@ -154,14 +154,14 @@ void Avatar::initializeBodyBalls() { _bodyBall[ AVATAR_JOINT_RIGHT_HIP ].radius = 0.04; _bodyBall[ AVATAR_JOINT_RIGHT_KNEE ].radius = 0.025; _bodyBall[ AVATAR_JOINT_RIGHT_HEEL ].radius = 0.025; - _bodyBall[ AVATAR_JOINT_RIGHT_TOES ].radius = 0.025; + _bodyBall[ AVATAR_JOINT_RIGHT_TOES ].radius = 0.025; /* - // to aid in hand-shaking and hand-holding, the right hand is not collidable - _bodyBall[ AVATAR_JOINT_RIGHT_ELBOW ].isCollidable = false; - _bodyBall[ AVATAR_JOINT_RIGHT_WRIST ].isCollidable = false; - _bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS].isCollidable = false; - */ + // to aid in hand-shaking and hand-holding, the right hand is not collidable + _bodyBall[ AVATAR_JOINT_RIGHT_ELBOW ].isCollidable = false; + _bodyBall[ AVATAR_JOINT_RIGHT_WRIST ].isCollidable = false; + _bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS].isCollidable = false; + */ } @@ -183,7 +183,7 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa float measuredPitchRate = serialInterface->getLastPitchRate(); float measuredYawRate = serialInterface->getLastYawRate(); float measuredRollRate = serialInterface->getLastRollRate(); - + // Update avatar head position based on measured gyro rates _head.addPitch(measuredPitchRate * AMPLIFY_PITCH * deltaTime); _head.addYaw(measuredYawRate * AMPLIFY_YAW * deltaTime); @@ -193,8 +193,8 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa glm::vec3 headRotationRates(_head.getPitch(), _head.getYaw(), _head.getRoll()); glm::vec3 leaning = (serialInterface->getLastAcceleration() - serialInterface->getGravity()) - * LEAN_SENSITIVITY - * (1.f - fminf(glm::length(headRotationRates), HEAD_RATE_MAX) / HEAD_RATE_MAX); + * LEAN_SENSITIVITY + * (1.f - fminf(glm::length(headRotationRates), HEAD_RATE_MAX) / HEAD_RATE_MAX); leaning.y = 0.f; if (glm::length(leaning) < LEAN_MAX) { _head.setLeanForward(_head.getLeanForward() * (1.f - LEAN_AVERAGING * deltaTime) + @@ -229,7 +229,7 @@ void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int scree const int TITLE_BAR_HEIGHT = 46; float mouseLocationX = (float)mouseX / (float)screenWidth - 0.5f; float mouseLocationY = (float)mouseY / (float)screenHeight - 0.5f; - + if ((mouseX > 1) && (mouseX < screenWidth) && (mouseY > TITLE_BAR_HEIGHT) && (mouseY < screenHeight)) { // // Mouse must be inside screen (not at edge) and not on title bar for movement to happen @@ -262,16 +262,16 @@ void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int scree } void Avatar::simulate(float deltaTime, Transmitter* transmitter) { - - //figure out if the mouse cursor is over any body spheres... + + //figure out if the mouse cursor is over any body spheres... checkForMouseRayTouching(); // copy velocity so we can use it later for acceleration glm::vec3 oldVelocity = getVelocity(); - + // update balls if (_balls) { _balls->simulate(deltaTime); } - + // update avatar skeleton _skeleton.update(deltaTime, getOrientation(), _position); @@ -279,16 +279,16 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { if (_owningAgent) { _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition; } - - //detect and respond to collisions with other avatars... + + //detect and respond to collisions with other avatars... if (!_owningAgent) { 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); - _avatarTouch.simulate(deltaTime); + _avatarTouch.simulate(deltaTime); // apply gravity and collision with the ground/floor if (!_owningAgent && USING_AVATAR_GRAVITY) { @@ -316,7 +316,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // driving the avatar around should only apply if this is my avatar (as opposed to an avatar being driven remotely) const float THRUST_MAG = 600.0f; - + if (!_owningAgent) { _thrust = glm::vec3(0.0f, 0.0f, 0.0f); @@ -330,8 +330,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { if (_driveKeys[DOWN ]) {_thrust -= THRUST_MAG * deltaTime * up;} if (_driveKeys[ROT_RIGHT]) {_bodyYawDelta -= YAW_MAG * deltaTime;} if (_driveKeys[ROT_LEFT ]) {_bodyYawDelta += YAW_MAG * deltaTime;} - - // Add thrusts from Transmitter + + // Add thrusts from Transmitter if (transmitter) { transmitter->checkForLostTransmitter(); glm::vec3 rotation = transmitter->getEstimatedRotation(); @@ -353,28 +353,28 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } if (transmitter->getTouchState()->state == 'D') { _thrust += THRUST_MAG * - (float)(transmitter->getTouchState()->y - TOUCH_POSITION_RANGE_HALF) / TOUCH_POSITION_RANGE_HALF * - TRANSMITTER_LIFT_SCALE * - deltaTime * - up; + (float)(transmitter->getTouchState()->y - TOUCH_POSITION_RANGE_HALF) / TOUCH_POSITION_RANGE_HALF * + TRANSMITTER_LIFT_SCALE * + deltaTime * + up; } } - + // update body yaw by body yaw delta orientation = orientation * glm::quat(glm::radians( - glm::vec3(_bodyPitchDelta, _bodyYawDelta, _bodyRollDelta) * deltaTime)); - + glm::vec3(_bodyPitchDelta, _bodyYawDelta, _bodyRollDelta) * deltaTime)); + // decay body rotation momentum float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime; - if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; } + if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; } _bodyPitchDelta *= bodySpinMomentum; _bodyYawDelta *= bodySpinMomentum; _bodyRollDelta *= bodySpinMomentum; - + // add thrust to velocity _velocity += _thrust * deltaTime; - // calculate speed + // calculate speed _speed = glm::length(_velocity); //pitch and roll the body as a function of forward speed and turning delta @@ -382,23 +382,23 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { const float BODY_ROLL_WHILE_TURNING = 0.2; float forwardComponentOfVelocity = glm::dot(getBodyFrontDirection(), _velocity); orientation = orientation * glm::quat(glm::radians(glm::vec3( - BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, - BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); + BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, + BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); // these forces keep the body upright... const float BODY_UPRIGHT_FORCE = 10.0; float tiltDecay = BODY_UPRIGHT_FORCE * deltaTime; - if (tiltDecay > 1.0f) {tiltDecay = 1.0f;} - + if (tiltDecay > 1.0f) {tiltDecay = 1.0f;} + // update the euler angles setOrientation(orientation); - + //the following will be used to make the avatar upright no matter what gravity is setOrientation(computeRotationFromBodyToWorldUp(tiltDecay) * orientation); - + // update position by velocity _position += _velocity * deltaTime; - + // decay velocity const float VELOCITY_DECAY = 0.9; float decay = 1.0 - VELOCITY_DECAY * deltaTime; @@ -419,7 +419,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } } - // Compute instantaneous acceleration + // Compute instantaneous acceleration float acceleration = glm::distance(getVelocity(), oldVelocity) / deltaTime; const float ACCELERATION_PITCH_DECAY = 0.4f; const float ACCELERATION_YAW_DECAY = 0.4f; @@ -428,7 +428,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { const int OCULUS_YAW_OFFSET_THRESHOLD = 10; // Decay HeadPitch as a function of acceleration, so that you look straight ahead when - // you start moving, but don't do this with an HMD like the Oculus. + // you start moving, but don't do this with an HMD like the Oculus. if (!OculusManager::isConnected()) { _head.setPitch(_head.getPitch() * (1.f - acceleration * ACCELERATION_PITCH_DECAY * deltaTime)); _head.setYaw(_head.getYaw() * (1.f - acceleration * ACCELERATION_YAW_DECAY * deltaTime)); @@ -452,10 +452,10 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { //apply the head lean values to the ball positions... if (USING_HEAD_LEAN) { if (fabs(_head.getLeanSideways() + _head.getLeanForward()) > 0.0f) { - glm::vec3 headLean = - right * _head.getLeanSideways() + - front * _head.getLeanForward(); - + glm::vec3 headLean = + right * _head.getLeanSideways() + + front * _head.getLeanForward(); + _bodyBall[ AVATAR_JOINT_TORSO ].position += headLean * 0.1f; _bodyBall[ AVATAR_JOINT_CHEST ].position += headLean * 0.4f; _bodyBall[ AVATAR_JOINT_NECK_BASE ].position += headLean * 0.7f; @@ -473,24 +473,24 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _bodyBall[ AVATAR_JOINT_RIGHT_WRIST ].position += headLean * 0.1f; _bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += headLean * 0.0f; } - } - - // set head lookat position + } + + // set head lookat position if (!_owningAgent) { if (_interactingOther) { _head.setLookAtPosition(_interactingOther->caclulateAverageEyePosition()); } else { _head.setLookAtPosition(glm::vec3(0.0f, 0.0f, 0.0f)); // 0,0,0 represents NOT looking at anything } - } - + } + _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); _head.setPosition(_bodyBall[ AVATAR_JOINT_HEAD_BASE ].position); _head.setScale (_bodyBall[ AVATAR_JOINT_HEAD_BASE ].radius); _head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2])); _head.simulate(deltaTime, !_owningAgent); - // 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) { _mode = AVATAR_MODE_WALKING; } else { @@ -499,14 +499,14 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } void Avatar::checkForMouseRayTouching() { - - for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { + for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { + glm::vec3 directionToBodySphere = glm::normalize(_bodyBall[b].position - _mouseRayOrigin); float dot = glm::dot(directionToBodySphere, _mouseRayDirection); - + float range = _bodyBall[b].radius * JOINT_TOUCH_RANGE; - + if (dot > (1.0f - range)) { _bodyBall[b].touchForce = (dot - (1.0f - range)) / range; } else { @@ -516,8 +516,8 @@ void Avatar::checkForMouseRayTouching() { } void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction ) { - _mouseRayOrigin = origin; - _mouseRayDirection = direction; + _mouseRayOrigin = origin; + _mouseRayDirection = direction; } void Avatar::setOrientation(const glm::quat& orientation) { @@ -528,35 +528,35 @@ void Avatar::setOrientation(const glm::quat& orientation) { } void Avatar::updateHandMovementAndTouching(float deltaTime) { - + glm::quat orientation = getOrientation(); - + // reset hand and arm positions according to hand movement glm::vec3 right = orientation * AVATAR_RIGHT; glm::vec3 up = orientation * AVATAR_UP; glm::vec3 front = orientation * AVATAR_FRONT; - + glm::vec3 transformedHandMovement = right * _movedHandOffset.x * 2.0f + up * -_movedHandOffset.y * 2.0f + front * -_movedHandOffset.y * 2.0f; _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; - + if (!_owningAgent) { _avatarTouch.setMyBodyPosition(_position); _avatarTouch.setMyOrientation(orientation); - + float closestDistance = std::numeric_limits::max(); _interactingOther = NULL; - + //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(); - + //Test: Show angle between your fwd vector and nearest avatar //glm::vec3 vectorBetweenUs = otherAvatar->getJointPosition(AVATAR_JOINT_PELVIS) - // getJointPosition(AVATAR_JOINT_PELVIS); @@ -576,53 +576,53 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { } if (_interactingOther) { - + _avatarTouch.setHasInteractingOther(true); - _avatarTouch.setYourBodyPosition(_interactingOther->_position); - _avatarTouch.setYourHandPosition(_interactingOther->_bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); + _avatarTouch.setYourBodyPosition(_interactingOther->_position); + _avatarTouch.setYourHandPosition(_interactingOther->_bodyBall[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); _avatarTouch.setYourOrientation (_interactingOther->getOrientation()); - _avatarTouch.setYourHandState (_interactingOther->_handState); + _avatarTouch.setYourHandState (_interactingOther->_handState); //if hand-holding is initiated by either avatar, turn on hand-holding... - if (_avatarTouch.getHandsCloseEnoughToGrasp()) { + if (_avatarTouch.getHandsCloseEnoughToGrasp()) { if ((_handState == HAND_STATE_GRASPING ) || (_interactingOther->_handState == HAND_STATE_GRASPING)) { if (!_avatarTouch.getHoldingHands()) { _avatarTouch.setHoldingHands(true); - } + } } } - + glm::vec3 vectorFromMyHandToYourHand ( - _interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - - _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - ); + _interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position + ); float distanceBetweenOurHands = glm::length(vectorFromMyHandToYourHand); - + /* - // if my arm can no longer reach the other hand, turn off hand-holding - if (!_avatarTouch.getAbleToReachOtherAvatar()) { - _avatarTouch.setHoldingHands(false); - } - if (distanceBetweenOurHands > _maxArmLength) { - _avatarTouch.setHoldingHands(false); - } - */ - + // if my arm can no longer reach the other hand, turn off hand-holding + if (!_avatarTouch.getAbleToReachOtherAvatar()) { + _avatarTouch.setHoldingHands(false); + } + if (distanceBetweenOurHands > _maxArmLength) { + _avatarTouch.setHoldingHands(false); + } + */ + // if neither of us are grasping, turn off hand-holding if ((_handState != HAND_STATE_GRASPING ) && (_interactingOther->_handState != HAND_STATE_GRASPING)) { - _avatarTouch.setHoldingHands(false); + _avatarTouch.setHoldingHands(false); } - + //if holding hands, apply the appropriate forces if (_avatarTouch.getHoldingHands()) { - _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += - ( - _interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - - _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position - ) * 0.5f; + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += + ( + _interactingOther->_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position + - _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position + ) * 0.5f; if (distanceBetweenOurHands > 0.3) { float force = 10.0f * deltaTime; @@ -642,7 +642,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { //Set right hand position and state to be transmitted, and also tell AvatarTouch about it if (!_owningAgent) { setHandPosition(_skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); - + if (_mousePressed) { _handState = HAND_STATE_GRASPING; } else { @@ -688,8 +688,8 @@ void Avatar::updateCollisionWithEnvironment() { float radius = _height * 0.125f; glm::vec3 penetration; if (Application::getInstance()->getEnvironment()->findCapsulePenetration( - _position - up * (_pelvisFloatingHeight - radius), - _position + up * (_height - _pelvisFloatingHeight - radius), radius, penetration)) { + _position - up * (_pelvisFloatingHeight - radius), + _position + up * (_height - _pelvisFloatingHeight - radius), radius, penetration)) { applyCollisionWithScene(penetration); } } @@ -698,8 +698,8 @@ void Avatar::updateCollisionWithVoxels() { float radius = _height * 0.125f; glm::vec3 penetration; if (Application::getInstance()->getVoxels()->findCapsulePenetration( - _position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f), - _position + glm::vec3(0.0f, _height - _pelvisFloatingHeight - radius, 0.0f), radius, penetration)) { + _position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f), + _position + glm::vec3(0.0f, _height - _pelvisFloatingHeight - radius, 0.0f), radius, penetration)) { applyCollisionWithScene(penetration); } } @@ -710,14 +710,14 @@ void Avatar::applyCollisionWithScene(const glm::vec3& penetration) { static float STATIC_FRICTION_DAMPING = 0.0f; static float KINETIC_FRICTION_DAMPING = 0.95f; const float BOUNCE = 0.3f; - + // reflect the velocity component in the direction of penetration float penetrationLength = glm::length(penetration); if (penetrationLength > EPSILON) { glm::vec3 direction = penetration / penetrationLength; _velocity -= 2.0f * glm::dot(_velocity, direction) * direction * BOUNCE; _velocity *= KINETIC_FRICTION_DAMPING; - // If velocity is quite low, apply static friction that takes away energy + // If velocity is quite low, apply static friction that takes away energy if (glm::length(_velocity) < STATIC_FRICTION_VELOCITY) { _velocity *= STATIC_FRICTION_DAMPING; } @@ -725,24 +725,24 @@ void Avatar::applyCollisionWithScene(const glm::vec3& penetration) { } void Avatar::updateAvatarCollisions(float deltaTime) { - + // Reset detector for nearest avatar _distanceToNearestAvatar = std::numeric_limits::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); - } - + //apply forces from collision + applyCollisionWithOtherAvatar(otherAvatar, deltaTime); + } + // test other avatar hand position for proximity glm::vec3 v(_skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position); v -= otherAvatar->getPosition(); @@ -757,35 +757,35 @@ void Avatar::updateAvatarCollisions(float deltaTime) { //detect collisions with other avatars and respond void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime) { - + glm::vec3 bodyPushForce = glm::vec3(0.0f, 0.0f, 0.0f); - + // loop through the joints of each avatar to check for every possible collision for (int b=1; b_bodyBall[o].isCollidable) { - + glm::vec3 vectorBetweenJoints(_bodyBall[b].position - otherAvatar->_bodyBall[o].position); float distanceBetweenJoints = glm::length(vectorBetweenJoints); if (distanceBetweenJoints > 0.0) { // to avoid divide by zero float combinedRadius = _bodyBall[b].radius + otherAvatar->_bodyBall[o].radius; - + // check for collision if (distanceBetweenJoints < combinedRadius * COLLISION_RADIUS_SCALAR) { glm::vec3 directionVector = vectorBetweenJoints / distanceBetweenJoints; - + // push balls away from each other and apply friction float penetration = 1.0f - (distanceBetweenJoints / (combinedRadius * COLLISION_RADIUS_SCALAR)); glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * penetration * deltaTime; - bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime; - - _bodyBall[b].velocity += ballPushForce; + bodyPushForce += directionVector * COLLISION_BODY_FORCE * penetration * deltaTime; + + _bodyBall[b].velocity += ballPushForce; otherAvatar->_bodyBall[o].velocity -= ballPushForce; - + }// check for collision } // to avoid divide by zero } // o loop @@ -793,8 +793,8 @@ void Avatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTime } // b loop } // collidable - //apply force on the whole body - _velocity += bodyPushForce; + //apply force on the whole body + _velocity += bodyPushForce; } @@ -832,7 +832,7 @@ void Avatar::render(bool lookingInMirror) { // 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); - + //render body renderBody(lookingInMirror); @@ -848,7 +848,7 @@ void Avatar::render(bool lookingInMirror) { _balls->render(); glPopMatrix(); } - + if (!_chatMessage.empty()) { int width = 0; int lastWidth; @@ -857,22 +857,18 @@ void Avatar::render(bool lookingInMirror) { } glPushMatrix(); - // extract the view direction from the modelview matrix: transform (0, 0, 1) by the - // transpose of the modelview to get its direction in world space, then use the X/Z - // components to determine the angle - float modelview[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, modelview); + glm::vec3 chatPosition = _bodyBall[AVATAR_JOINT_HEAD_BASE].position + getBodyUpDirection() * chatMessageHeight; + glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); + glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); + glm::vec3 chatAxis = glm::axis(chatRotation); + glRotatef(glm::angle(chatRotation), chatAxis.x, chatAxis.y, chatAxis.z); - glTranslatef(_joint[AVATAR_JOINT_HEAD_BASE].springyPosition.x, - _joint[AVATAR_JOINT_HEAD_BASE].springyPosition.y + chatMessageHeight, - _joint[AVATAR_JOINT_HEAD_BASE].springyPosition.z); - glRotatef(atan2(-modelview[2], -modelview[10]) * 180 / PIf, 0, 1, 0); glColor3f(0, 0.8, 0); glRotatef(180, 0, 1, 0); glRotatef(180, 0, 0, 1); glScalef(chatMessageScale, chatMessageScale, 1.0f); - + glDisable(GL_LIGHTING); glDepthMask(false); if (_keyState == NO_KEY_DOWN) { @@ -887,7 +883,7 @@ void Avatar::render(bool lookingInMirror) { textRenderer()->draw(-width/2, 0, _chatMessage.c_str()); _chatMessage[lastIndex] = lastChar; glColor3f(0, 1, 0); - textRenderer()->draw(width/2 - lastWidth, 0, _chatMessage.c_str() + lastIndex); + textRenderer()->draw(width/2 - lastWidth, 0, _chatMessage.c_str() + lastIndex); } glEnable(GL_LIGHTING); glDepthMask(true); @@ -924,7 +920,7 @@ void Avatar::updateBodyBalls(float deltaTime) { if (length > 0.0f) { // to avoid divide by zero glm::vec3 springDirection = springVector / length; - float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime; + float force = (length - _skeleton.joint[b].length) * BODY_SPRING_FORCE * deltaTime; _bodyBall[b].velocity -= springDirection * force; if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) { @@ -945,11 +941,11 @@ void Avatar::updateBodyBalls(float deltaTime) { } /* - //apply forces from touch... - if (_skeleton.joint[b].touchForce > 0.0) { - _skeleton.joint[b].springyVelocity += _mouseRayDirection * _skeleton.joint[b].touchForce * 0.7f; - } - */ + //apply forces from touch... + if (_skeleton.joint[b].touchForce > 0.0) { + _skeleton.joint[b].springyVelocity += _mouseRayDirection * _skeleton.joint[b].touchForce * 0.7f; + } + */ //update position by velocity... _bodyBall[b].position += _bodyBall[b].velocity * deltaTime; @@ -979,7 +975,7 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { // set elbow position glm::vec3 newElbowPosition = _skeleton.joint[ AVATAR_JOINT_RIGHT_SHOULDER ].position + armVector * ONE_HALF; - + glm::vec3 perpendicular = glm::cross(getBodyRightDirection(), armVector); newElbowPosition += perpendicular * (1.0f - (_maxArmLength / distance)) * ONE_HALF; @@ -1013,17 +1009,17 @@ void Avatar::renderBody(bool lookingInMirror) { const float RENDER_OPAQUE_BEYOND = 1.0f; // Meters beyond which body is shown opaque const float RENDER_TRANSLUCENT_BEYOND = 0.5f; - // Render the body as balls and cones + // Render the body as balls and cones for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { float distanceToCamera = glm::length(_cameraPosition - _skeleton.joint[b].position); float alpha = lookingInMirror ? 1.0f : glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / - (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f); + (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f); if (lookingInMirror || _owningAgent) { alpha = 1.0f; } - + // Always render other people, and render myself when beyond threshold distance if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND * 0.5) { @@ -1035,8 +1031,8 @@ void Avatar::renderBody(bool lookingInMirror) { || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { // Render the sphere at the joint if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW - || b == AVATAR_JOINT_RIGHT_WRIST - || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { + || b == AVATAR_JOINT_RIGHT_WRIST + || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { glColor3f(SKIN_COLOR[0] + _bodyBall[b].touchForce * 0.3f, SKIN_COLOR[1] - _bodyBall[b].touchForce * 0.2f, SKIN_COLOR[2] - _bodyBall[b].touchForce * 0.1f); @@ -1048,7 +1044,7 @@ void Avatar::renderBody(bool lookingInMirror) { } if ((b != AVATAR_JOINT_HEAD_TOP ) - && (b != AVATAR_JOINT_HEAD_BASE )) { + && (b != AVATAR_JOINT_HEAD_BASE )) { glPushMatrix(); glTranslatef(_bodyBall[b].position.x, _bodyBall[b].position.y, _bodyBall[b].position.z); glutSolidSphere(_bodyBall[b].radius, 20.0f, 20.0f); @@ -1058,14 +1054,14 @@ void Avatar::renderBody(bool lookingInMirror) { // Render the cone connecting this joint to its parent if (_skeleton.joint[b].parent != AVATAR_JOINT_NULL) { if ((b != AVATAR_JOINT_HEAD_TOP ) - && (b != AVATAR_JOINT_HEAD_BASE ) - && (b != AVATAR_JOINT_PELVIS ) - && (b != AVATAR_JOINT_TORSO ) - && (b != AVATAR_JOINT_CHEST ) - && (b != AVATAR_JOINT_LEFT_COLLAR ) - && (b != AVATAR_JOINT_LEFT_SHOULDER ) - && (b != AVATAR_JOINT_RIGHT_COLLAR ) - && (b != AVATAR_JOINT_RIGHT_SHOULDER)) { + && (b != AVATAR_JOINT_HEAD_BASE ) + && (b != AVATAR_JOINT_PELVIS ) + && (b != AVATAR_JOINT_TORSO ) + && (b != AVATAR_JOINT_CHEST ) + && (b != AVATAR_JOINT_LEFT_COLLAR ) + && (b != AVATAR_JOINT_LEFT_SHOULDER ) + && (b != AVATAR_JOINT_RIGHT_COLLAR ) + && (b != AVATAR_JOINT_RIGHT_SHOULDER)) { glColor3fv(DARK_SKIN_COLOR); float r1 = _bodyBall[_skeleton.joint[b].parent ].radius * 0.8; @@ -1079,7 +1075,7 @@ void Avatar::renderBody(bool lookingInMirror) { _bodyBall[b ].position, r2, r2 ); } - } + } } } } @@ -1097,7 +1093,7 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity // // SMOOTHING_TIME is the time is seconds over which the head should average to the // absolute eulerAngles passed. - // + // // if (deltaTime == 0.f) { @@ -1105,9 +1101,9 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity _head.setYaw (eulerAngles->x); _head.setPitch(eulerAngles->y); _head.setRoll (eulerAngles->z); - } else { + } else { glm::vec3 angles(_head.getYaw(), _head.getPitch(), _head.getRoll()); - // Increment by detected velocity + // Increment by detected velocity angles += (*angularVelocity) * deltaTime; // Smooth to slowly follow absolute values angles = ((1.f - deltaTime / smoothingTime) * angles) + (deltaTime / smoothingTime) * (*eulerAngles); @@ -1138,25 +1134,25 @@ void Avatar::readAvatarDataFromFile() { // render a makeshift cone section that serves as a body part connecting joint spheres void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2) { - - glBegin(GL_TRIANGLES); - + + glBegin(GL_TRIANGLES); + glm::vec3 axis = position2 - position1; float length = glm::length(axis); - - if (length > 0.0f) { + if (length > 0.0f) { + axis /= length; glm::vec3 perpSin = glm::vec3(1.0f, 0.0f, 0.0f); glm::vec3 perpCos = glm::normalize(glm::cross(axis, perpSin)); perpSin = glm::cross(perpCos, axis); - + float anglea = 0.0; float angleb = 0.0; - - for (int i = 0; i < NUM_BODY_CONE_SIDES; i ++) { + for (int i = 0; i < NUM_BODY_CONE_SIDES; i ++) { + // the rectangles that comprise the sides of the cone section are // referenced by "a" and "b" in one dimension, and "1", and "2" in the other dimension. anglea = angleb; @@ -1166,12 +1162,12 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float sb = sinf(angleb); float ca = cosf(anglea); float cb = cosf(angleb); - - glm::vec3 p1a = position1 + perpSin * sa * radius1 + perpCos * ca * radius1; - glm::vec3 p1b = position1 + perpSin * sb * radius1 + perpCos * cb * radius1; + + glm::vec3 p1a = position1 + perpSin * sa * radius1 + perpCos * ca * radius1; + glm::vec3 p1b = position1 + perpSin * sb * radius1 + perpCos * cb * radius1; glm::vec3 p2a = position2 + perpSin * sa * radius2 + perpCos * ca * radius2; glm::vec3 p2b = position2 + perpSin * sb * radius2 + perpCos * cb * radius2; - + glVertex3f(p1a.x, p1a.y, p1a.z); glVertex3f(p1b.x, p1b.y, p1b.z); glVertex3f(p2a.x, p2a.y, p2a.z); @@ -1182,8 +1178,4 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, } glEnd(); -} - - - - +} \ No newline at end of file