diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index da06341f15..1152c466df 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -918,31 +918,21 @@ void Application::idle() { if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { if (_manualFirstPerson) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) { - Camera::CameraFollowingAttributes a; - a.upShift = 0.0f; - a.distance = 0.0f; - a.tightness = 100.0f; - _myCamera.setMode(CAMERA_MODE_FIRST_PERSON, a); + _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + _myCamera.setModeShiftRate(1.0f); } } else { if (_myAvatar.getIsNearInteractingOther()) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { - - Camera::CameraFollowingAttributes a; - a.upShift = 0.0f; - a.distance = 0.0f; - a.tightness = 100.0f; - _myCamera.setMode(CAMERA_MODE_FIRST_PERSON, a); + _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + _myCamera.setModeShiftRate(1.0f); } } else { if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { - Camera::CameraFollowingAttributes a; - a.upShift = -0.2f; - a.distance = 1.5f; - a.tightness = 8.0f; - _myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); + _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); + _myCamera.setModeShiftRate(1.0f); } } } @@ -981,17 +971,11 @@ void Application::setHead(bool head) { #endif if (head) { - Camera::CameraFollowingAttributes a; - a.upShift = 0.0f; - a.distance = 0.2f; - a.tightness = 100.0f; - _myCamera.setMode(CAMERA_MODE_MIRROR, a); + _myCamera.setMode(CAMERA_MODE_MIRROR); + _myCamera.setModeShiftRate(100.0f); } else { - Camera::CameraFollowingAttributes a; - a.upShift = -0.2f; - a.distance = 1.5f; - a.tightness = 8.0f; - _myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); + _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); + _myCamera.setModeShiftRate(1.0f); } } @@ -1285,11 +1269,8 @@ void Application::init() { _stars.readInput(STAR_FILE, STAR_CACHE_FILE, 0); _myAvatar.setPosition(START_LOCATION); - Camera::CameraFollowingAttributes a; - a.upShift = -0.2f; - a.distance = 1.5f; - a.tightness = 8.0f; - _myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); + _myCamera.setMode(CAMERA_MODE_THIRD_PERSON ); + _myCamera.setModeShiftRate(1.0f); _myAvatar.setDisplayingLookatVectors(false); QCursor::setPos(_headMouseX, _headMouseY); diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 596751ac27..9870f31b29 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -208,7 +208,7 @@ int audioCallback (const void* inputBuffer, // if we haven't fired off the flange effect, check if we should // TODO: lastMeasuredHeadYaw is now relative to body - check if this still works. - int lastYawMeasured = fabsf(interfaceAvatar->getLastMeasuredHeadYaw()); + int lastYawMeasured = fabsf(interfaceAvatar->getHeadYawRate()); if (!::samplesLeftForFlange && lastYawMeasured > MIN_FLANGE_EFFECT_THRESHOLD) { // we should flange for one second diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 15d2bd2774..621203d7b2 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -34,7 +34,7 @@ const float BODY_UPRIGHT_FORCE = 10.0; const float VELOCITY_DECAY = 5.0; const float MY_HAND_HOLDING_PULL = 0.2; const float YOUR_HAND_HOLDING_PULL = 1.0; -const float BODY_SPRING_DEFAULT_TIGHTNESS = 1500.0f; +const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f; const float BODY_SPRING_FORCE = 300.0f; const float BODY_SPRING_DECAY = 16.0f; const float COLLISION_RADIUS_SCALAR = 1.8; @@ -54,15 +54,14 @@ const float JOINT_TOUCH_RANGE = 0.0005f; const float ANGULAR_RIGHTING_SPEED = 45.0f; const float FLOATING_HEIGHT = 0.13f; const bool USING_HEAD_LEAN = false; +const float LEAN_SENSITIVITY = 0.15; +const float LEAN_MAX = 0.45; +const float LEAN_AVERAGING = 10.0; +const float HEAD_RATE_MAX = 50.f; +const float SKIN_COLOR[] = {1.0, 0.84, 0.66}; +const float DARK_SKIN_COLOR[] = {0.9, 0.78, 0.63}; +const int NUM_BODY_CONE_SIDES = 9; -const float LEAN_SENSITIVITY = 0.15; -const float LEAN_MAX = 0.45; -const float LEAN_AVERAGING = 10.0; -const float HEAD_RATE_MAX = 50.f; - -float skinColor [] = {1.0, 0.84, 0.66}; -float darkSkinColor[] = {0.9, 0.78, 0.63}; -float lightBlue [] = {0.7, 0.8, 1.0 }; bool usingBigSphereCollisionTest = true; @@ -165,14 +164,6 @@ float Avatar::getAbsoluteHeadPitch() const { return _bodyPitch + _head.getPitch(); } -void Avatar::setMousePressed(bool mousePressed) { - _mousePressed = mousePressed; -} - -bool Avatar::getIsNearInteractingOther() { - return _avatarTouch.getAbleToReachOtherAvatar(); -} - void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight) { // Update yaw based on mouse behavior const float MOUSE_MOVE_RADIUS = 0.15f; @@ -470,7 +461,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::updateHandMovementAndTouching(float deltaTime) { @@ -485,6 +477,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { if (!_owningAgent) { _avatarTouch.setMyBodyPosition(_position); + _avatarTouch.setMyOrientation(_orientation); float closestDistance = std::numeric_limits::max(); @@ -517,6 +510,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { if (_interactingOther) { _avatarTouch.setYourBodyPosition(_interactingOther->_position); + _avatarTouch.setYourOrientation (_interactingOther->_orientation); _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandState (_interactingOther->_handState); @@ -874,8 +868,8 @@ void Avatar::initializeSkeleton() { _joint[ AVATAR_JOINT_PELVIS ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 ); _joint[ AVATAR_JOINT_TORSO ].defaultPosePosition = glm::vec3( 0.0, 0.09, 0.01 ); _joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, 0.01 ); - _joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.12, -0.01 ); - _joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.00 ); + _joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.14, -0.01 ); + _joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.04, 0.00 ); _joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3( -0.06, 0.04, -0.01 ); _joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.05, 0.0, -0.01 ); @@ -928,31 +922,6 @@ void Avatar::initializeSkeleton() { _joint[ AVATAR_JOINT_RIGHT_HEEL ].radius = 0.025; _joint[ AVATAR_JOINT_RIGHT_TOES ].radius = 0.025; - // specify the tightness of the springy positions as far as attraction to rigid body - _joint[ AVATAR_JOINT_PELVIS ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 1.0; - _joint[ AVATAR_JOINT_TORSO ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.8; - _joint[ AVATAR_JOINT_CHEST ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_NECK_BASE ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.4; - _joint[ AVATAR_JOINT_HEAD_BASE ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.3; - _joint[ AVATAR_JOINT_LEFT_COLLAR ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_LEFT_SHOULDER ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_LEFT_ELBOW ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_LEFT_WRIST ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.3; - _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.3; - _joint[ AVATAR_JOINT_RIGHT_COLLAR ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_RIGHT_ELBOW ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_RIGHT_WRIST ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.3; - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.3; - _joint[ AVATAR_JOINT_LEFT_HIP ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_LEFT_KNEE ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_LEFT_HEEL ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_LEFT_TOES ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_RIGHT_HIP ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_RIGHT_KNEE ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_RIGHT_HEEL ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_RIGHT_TOES ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - // to aid in hand-shaking and hand-holding, the right hand is not collidable _joint[ AVATAR_JOINT_RIGHT_ELBOW ].isCollidable = false; _joint[ AVATAR_JOINT_RIGHT_WRIST ].isCollidable = false; @@ -1102,15 +1071,6 @@ void Avatar::updateBodySprings(float deltaTime) { } } - -const glm::vec3& Avatar::getSpringyHeadPosition() const { - return _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition; -} - -const glm::vec3& Avatar::getHeadPosition() const { - return _joint[ AVATAR_JOINT_HEAD_BASE ].position; -} - void Avatar::updateArmIKAndConstraints(float deltaTime) { // determine the arm vector @@ -1170,48 +1130,53 @@ void Avatar::renderBody(bool lookingInMirror) { if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW || b == AVATAR_JOINT_RIGHT_WRIST || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { - glColor3f(skinColor[0] + _joint[b].touchForce * 0.3f, - skinColor[1] - _joint[b].touchForce * 0.2f, - skinColor[2] - _joint[b].touchForce * 0.1f); + glColor3f(SKIN_COLOR[0] + _joint[b].touchForce * 0.3f, + SKIN_COLOR[1] - _joint[b].touchForce * 0.2f, + SKIN_COLOR[2] - _joint[b].touchForce * 0.1f); } else { - glColor4f(skinColor[0] + _joint[b].touchForce * 0.3f, - skinColor[1] - _joint[b].touchForce * 0.2f, - skinColor[2] - _joint[b].touchForce * 0.1f, + glColor4f(SKIN_COLOR[0] + _joint[b].touchForce * 0.3f, + SKIN_COLOR[1] - _joint[b].touchForce * 0.2f, + SKIN_COLOR[2] - _joint[b].touchForce * 0.1f, glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f)); } + glPushMatrix(); glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z); glutSolidSphere(_joint[b].radius, 20.0f, 20.0f); glPopMatrix(); - // Render the cone connecting this joint to it's parent - - if (_joint[b].parent != AVATAR_JOINT_NULL) + // Render the cone connecting this joint to its parent + if (_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)) { - // Render cone sections connecting the joint positions - glColor3fv(darkSkinColor); + && (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 = _joint[_joint[b].parent ].radius * 0.8; + float r2 = _joint[b ].radius * 0.8; + if (b == AVATAR_JOINT_HEAD_BASE) { + r1 *= 0.5f; + } renderJointConnectingCone ( _joint[_joint[b].parent ].springyPosition, - _joint[b ].springyPosition, - _joint[_joint[b].parent ].radius * 0.8, - _joint[b ].radius * 0.8 + _joint[b ].springyPosition, r2, r2 ); - } - + } + } } - } } + + + void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity, float deltaTime, float smoothingTime) { // // Given absolute position and angular velocity information, update the avatar's head angles @@ -1277,34 +1242,37 @@ void Avatar::readAvatarDataFromFile() { void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2) { glBegin(GL_TRIANGLES); - - int num = 10; - - glm::vec3 axis = glm::normalize(position2 - position1); + + glm::vec3 axis = position2 - position1; float length = glm::length(axis); if (length > 0.0f) { - glm::vec3 perpSin = glm::vec3(axis.y, axis.z, axis.x); - glm::vec3 perpCos = glm::vec3(axis.z, axis.x, axis.y); - - float angle1 = 0.0; - float angle2 = 0.0; - - for (int i = 0; i < num; i ++) { + axis /= length; - angle1 = angle2; - angle2 = ((float)(i+1) / (float)num) * PI * 2.0; + 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 ++) { + + // 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; + angleb = ((float)(i+1) / (float)NUM_BODY_CONE_SIDES) * PI * 2.0f; - float s1 = sinf(angle1); - float s2 = sinf(angle2); - float c1 = cosf(angle1); - float c2 = cosf(angle2); - - glm::vec3 p1a = position1 + perpSin * s1 * radius1 + perpCos * c1 * radius1; - glm::vec3 p1b = position1 + perpSin * s2 * radius1 + perpCos * c2 * radius1; - glm::vec3 p2a = position2 + perpSin * s1 * radius2 + perpCos * c1 * radius2; - glm::vec3 p2b = position2 + perpSin * s2 * radius2 + perpCos * c2 * radius2; + float sa = sinf(anglea); + 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 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); diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 1a715b613d..1ef5675d9b 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -2,7 +2,6 @@ // Avatar.h // interface // -// Created by Philip Rosedale on 9/11/12. // Copyright (c) 2012 High Fidelity, Inc. All rights reserved. // @@ -19,6 +18,7 @@ #include "SerialInterface.h" #include "Balls.h" #include "Head.h" +#include "Skeleton.h" #include "Transmitter.h" enum DriveKeys @@ -42,87 +42,52 @@ enum AvatarMode NUM_AVATAR_MODES }; -enum AvatarJointID -{ - AVATAR_JOINT_NULL = -1, - AVATAR_JOINT_PELVIS, - AVATAR_JOINT_TORSO, - AVATAR_JOINT_CHEST, - AVATAR_JOINT_NECK_BASE, - AVATAR_JOINT_HEAD_BASE, - AVATAR_JOINT_HEAD_TOP, - AVATAR_JOINT_LEFT_COLLAR, - AVATAR_JOINT_LEFT_SHOULDER, - AVATAR_JOINT_LEFT_ELBOW, - AVATAR_JOINT_LEFT_WRIST, - AVATAR_JOINT_LEFT_FINGERTIPS, - AVATAR_JOINT_RIGHT_COLLAR, - AVATAR_JOINT_RIGHT_SHOULDER, - AVATAR_JOINT_RIGHT_ELBOW, - AVATAR_JOINT_RIGHT_WRIST, - AVATAR_JOINT_RIGHT_FINGERTIPS, - AVATAR_JOINT_LEFT_HIP, - AVATAR_JOINT_LEFT_KNEE, - AVATAR_JOINT_LEFT_HEEL, - AVATAR_JOINT_LEFT_TOES, - AVATAR_JOINT_RIGHT_HIP, - AVATAR_JOINT_RIGHT_KNEE, - AVATAR_JOINT_RIGHT_HEEL, - AVATAR_JOINT_RIGHT_TOES, - - NUM_AVATAR_JOINTS -}; - - class Avatar : public AvatarData { public: Avatar(Agent* owningAgent = NULL); ~Avatar(); - void reset(); - void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); - void updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight); - void setNoise (float mag) {_head.noise = mag;} - float getLastMeasuredHeadYaw() const {return _head.yawRate;} - float getBodyYaw() {return _bodyYaw;}; - void addBodyYaw(float y) {_bodyYaw += y;}; - void setGravity(glm::vec3 gravity); - - void setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction ); - bool getIsNearInteractingOther(); - - float getAbsoluteHeadYaw() const; - float getAbsoluteHeadPitch() const; - glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) - const glm::vec3& getHeadPosition() const ; // get the position of the avatar's rigid body head - const glm::vec3& getSpringyHeadPosition() const ; // get the springy position of the avatar's head - const glm::vec3& getJointPosition(AvatarJointID j) const { return _joint[j].springyPosition; }; - const glm::vec3& getBodyUpDirection() const { return _orientation.getUp(); }; - float getSpeed() const { return _speed; } - const glm::vec3& getVelocity() const { return _velocity; }; - float getGirth(); - float getHeight() const { return _height; } - - AvatarMode getMode() const { return _mode; } - Head& getHead() { return _head; } - - void setMousePressed(bool pressed); - void render(bool lookingInMirror, glm::vec3 cameraPosition); - void renderBody(bool lookingInMirror); + void reset(); void simulate(float deltaTime, Transmitter* transmitter); - void setMovedHandOffset(glm::vec3 movedHandOffset) { _movedHandOffset = movedHandOffset; } - void updateArmIKAndConstraints( float deltaTime ); - void setDisplayingLookatVectors(bool displayingLookatVectors) { _head.setRenderLookatVectors(displayingLookatVectors); } - + void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); + void updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight); + void addBodyYaw(float y) {_bodyYaw += y;}; + void render(bool lookingInMirror, glm::vec3 cameraPosition); + + //setters + void setMousePressed (bool mousePressed ) { _mousePressed = mousePressed;} + void setNoise (float mag ) { _head.noise = mag;} + void setMovedHandOffset (glm::vec3 movedHandOffset ) { _movedHandOffset = movedHandOffset;} + void setThrust (glm::vec3 newThrust ) { _thrust = newThrust; }; + void setDisplayingLookatVectors(bool displayingLookatVectors) { _head.setRenderLookatVectors(displayingLookatVectors);} + void setGravity (glm::vec3 gravity); + void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction); + + //getters + float getHeadYawRate () const { return _head.yawRate;} + float getBodyYaw () const { return _bodyYaw;} + bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();} + const glm::vec3& getHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].position;} + const glm::vec3& getSpringyHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition;} + const glm::vec3& getJointPosition (AvatarJointID j) const { return _joint[j].springyPosition;} + const glm::vec3& getBodyUpDirection () const { return _orientation.getUp();} + const glm::vec3& getVelocity () const { return _velocity;} + float getSpeed () const { return _speed;} + float getHeight () const { return _height;} + AvatarMode getMode () const { return _mode;} + float getAbsoluteHeadYaw () const; + float getAbsoluteHeadPitch () const; + Head& getHead () {return _head; } + // Set what driving keys are being pressed to control thrust levels void setDriveKeys(int key, bool val) { _driveKeys[key] = val; }; bool getDriveKeys(int key) { return _driveKeys[key]; }; // Set/Get update the thrust that will move the avatar around - void setThrust(glm::vec3 newThrust) { _thrust = newThrust; }; void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; glm::vec3 getThrust() { return _thrust; }; + //read/write avatar data void writeAvatarDataToFile(); void readAvatarDataFromFile(); @@ -151,6 +116,7 @@ private: }; Head _head; + Skeleton _skeleton; float _TEST_bigSphereRadius; glm::vec3 _TEST_bigSpherePosition; bool _mousePressed; @@ -184,6 +150,8 @@ private: bool _isMouseTurningRight; // private methods... + glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) + void renderBody(bool lookingInMirror); void initializeSkeleton(); void updateSkeleton(); void initializeBodySprings(); @@ -192,6 +160,7 @@ private: void readSensors(); void updateHandMovementAndTouching(float deltaTime); void updateAvatarCollisions(float deltaTime); + void updateArmIKAndConstraints( float deltaTime ); void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime ); void updateCollisionWithEnvironment(); void updateCollisionWithVoxels(); diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 7651a0a9a8..c598cc9a03 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -27,55 +27,38 @@ AvatarTouch::AvatarTouch() { _weAreHoldingHands = false; _canReachToOtherAvatar = false; _handsCloseEnoughToGrasp = false; + _myOrientation.setToIdentity(); + _yourOrientation.setToIdentity(); for (int p=0; p 0.1f)) { + facingEachOther = true; + } - if (distanceBetweenBodies < _reachableRadius) { + if ((distanceBetweenBodies < _reachableRadius) + && (facingEachOther)) { _vectorBetweenHands = _yourHandPosition - _myHandPosition; - float distanceBetweenHands = glm::length(_vectorBetweenHands); + float distanceBetweenHands = glm::length(_vectorBetweenHands); if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP) { _handsCloseEnoughToGrasp = true; } else { _handsCloseEnoughToGrasp = false; } - + _canReachToOtherAvatar = true; } else { _canReachToOtherAvatar = false; @@ -92,7 +75,7 @@ void AvatarTouch::render(glm::vec3 cameraPosition) { p.y = 0.0005f; renderCircle(p, _reachableRadius, glm::vec3(0.0f, 1.0f, 0.0f), 30); - // show is we are golding hands... + // show if we are holding hands... if (_weAreHoldingHands) { renderBeamBetweenHands(); diff --git a/interface/src/AvatarTouch.h b/interface/src/AvatarTouch.h index 2111c0ecf1..fb90efa5fd 100644 --- a/interface/src/AvatarTouch.h +++ b/interface/src/AvatarTouch.h @@ -9,6 +9,7 @@ #define __interface__AvatarTouch__ #include +#include "Orientation.h" enum AvatarHandState { @@ -26,18 +27,17 @@ public: void simulate(float deltaTime); void render(glm::vec3 cameraPosition); - - void setMyHandPosition (glm::vec3 position); - void setYourHandPosition(glm::vec3 position); - void setMyBodyPosition (glm::vec3 position); - 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 setHoldingHands (bool h) {_weAreHoldingHands = h;} + + void setMyHandPosition (glm::vec3 position ) { _myHandPosition = position; } + void setYourHandPosition(glm::vec3 position ) { _yourHandPosition = position; } + void setMyOrientation (Orientation orientation) { _myOrientation = orientation; } + void setYourOrientation (Orientation orientation) { _yourOrientation = orientation; } + void setMyBodyPosition (glm::vec3 position ) { _myBodyPosition = position; } + void setYourBodyPosition(glm::vec3 position ) { _yourBodyPosition = position; } + void setMyHandState (int state ) { _myHandState = state; } + void setYourHandState (int state ) { _yourHandState = state; } + void setReachableRadius (float radius ) { _reachableRadius = radius; } + void setHoldingHands (bool holding ) { _weAreHoldingHands = holding; } bool getAbleToReachOtherAvatar () const {return _canReachToOtherAvatar; } bool getHandsCloseEnoughToGrasp() const {return _handsCloseEnoughToGrasp;} @@ -47,18 +47,20 @@ private: static const int NUM_POINTS = 100; - bool _weAreHoldingHands; - glm::vec3 _point [NUM_POINTS]; - glm::vec3 _myBodyPosition; - glm::vec3 _yourBodyPosition; - glm::vec3 _myHandPosition; - glm::vec3 _yourHandPosition; - glm::vec3 _vectorBetweenHands; - int _myHandState; - int _yourHandState; - bool _canReachToOtherAvatar; - bool _handsCloseEnoughToGrasp; - float _reachableRadius; + bool _weAreHoldingHands; + glm::vec3 _point [NUM_POINTS]; + glm::vec3 _myBodyPosition; + glm::vec3 _yourBodyPosition; + glm::vec3 _myHandPosition; + glm::vec3 _yourHandPosition; + Orientation _myOrientation; + Orientation _yourOrientation; + glm::vec3 _vectorBetweenHands; + int _myHandState; + int _yourHandState; + bool _canReachToOtherAvatar; + bool _handsCloseEnoughToGrasp; + float _reachableRadius; void renderBeamBetweenHands(); }; diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index b408135c40..fa0744bf49 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -11,49 +11,51 @@ #include "Camera.h" -const float MODE_SHIFT_RATE = 6.0f; +const float CAMERA_MINIMUM_MODE_SHIFT_RATE = 0.5f; + +const float CAMERA_FIRST_PERSON_MODE_UP_SHIFT = 0.0f; +const float CAMERA_FIRST_PERSON_MODE_DISTANCE = 0.0f; +const float CAMERA_FIRST_PERSON_MODE_TIGHTNESS = 100.0f; + +const float CAMERA_THIRD_PERSON_MODE_UP_SHIFT = -0.2f; +const float CAMERA_THIRD_PERSON_MODE_DISTANCE = 1.5f; +const float CAMERA_THIRD_PERSON_MODE_TIGHTNESS = 8.0f; + +const float CAMERA_MIRROR_MODE_UP_SHIFT = 0.0f; +const float CAMERA_MIRROR_MODE_DISTANCE = 0.2f; +const float CAMERA_MIRROR_MODE_TIGHTNESS = 100.0f; Camera::Camera() { _needsToInitialize = true; _frustumNeedsReshape = true; - _modeShift = 0.0; - _mode = CAMERA_MODE_THIRD_PERSON; - _tightness = 10.0; // default - _fieldOfView = 60.0; // default - _nearClip = 0.08; // default - _farClip = 50.0 * TREE_SCALE; // default - _yaw = 0.0; - _pitch = 0.0; - _roll = 0.0; - _upShift = 0.0; - _distance = 0.0; - _idealYaw = 0.0; - _idealPitch = 0.0; - _idealRoll = 0.0; - _targetPosition = glm::vec3(0.0, 0.0, 0.0); - _position = glm::vec3(0.0, 0.0, 0.0); - _idealPosition = glm::vec3(0.0, 0.0, 0.0); + _modeShift = 0.0f; + _modeShiftRate = 1.0f; + _linearModeShift = 0.0f; + _mode = CAMERA_MODE_THIRD_PERSON; + _tightness = 10.0f; // default + _fieldOfView = 60.0f; // default + _nearClip = 0.08f; // default + _farClip = 50.0f * TREE_SCALE; // default + _yaw = 0.0f; + _pitch = 0.0f; + _roll = 0.0f; + _upShift = 0.0f; + _distance = 0.0f; + _previousUpShift = 0.0f; + _previousDistance = 0.0f; + _previousTightness = 0.0f; + _newUpShift = 0.0f; + _newDistance = 0.0f; + _newTightness = 0.0f; + _idealYaw = 0.0f; + _idealPitch = 0.0f; + _idealRoll = 0.0f; + _targetPosition = glm::vec3(0.0f, 0.0f, 0.0f); + _position = glm::vec3(0.0f, 0.0f, 0.0f); + _idealPosition = glm::vec3(0.0f, 0.0f, 0.0f); _orientation.setToIdentity(); - - _attributes[CAMERA_MODE_FIRST_PERSON].upShift = CAMERA_DEFAULT_FIRST_PERSON_MODE_UP_SHIFT; - _attributes[CAMERA_MODE_FIRST_PERSON].distance = CAMERA_DEFAULT_FIRST_PERSON_MODE_DISTANCE; - _attributes[CAMERA_MODE_FIRST_PERSON].tightness = CAMERA_DEFAULT_FIRST_PERSON_MODE_TIGHTNESS; - - _attributes[CAMERA_MODE_THIRD_PERSON].upShift = CAMERA_DEFAULT_THIRD_PERSON_MODE_UP_SHIFT; - _attributes[CAMERA_MODE_THIRD_PERSON].distance = CAMERA_DEFAULT_THIRD_PERSON_MODE_DISTANCE; - _attributes[CAMERA_MODE_THIRD_PERSON].tightness = CAMERA_DEFAULT_THIRD_PERSON_MODE_TIGHTNESS; - - _attributes[CAMERA_MODE_MIRROR ].upShift = CAMERA_DEFAULT_MIRROR_MODE_UP_SHIFT; - _attributes[CAMERA_MODE_MIRROR ].distance = CAMERA_DEFAULT_MIRROR_MODE_DISTANCE; - _attributes[CAMERA_MODE_MIRROR ].tightness = CAMERA_DEFAULT_MIRROR_MODE_TIGHTNESS; - - for (int m = 0; m < NUM_CAMERA_MODES; m ++) { - _previousAttributes[m].upShift = 0.0f; - _previousAttributes[m].distance = 0.0f; - _previousAttributes[m].tightness = 0.0f; - } } void Camera::update(float deltaTime) { @@ -67,7 +69,6 @@ void Camera::update(float deltaTime) { generateOrientation(); } - // generate the ortho-normals for the orientation based on the three Euler angles void Camera::generateOrientation() { _orientation.setToIdentity(); @@ -79,15 +80,26 @@ void Camera::generateOrientation() { // use iterative forces to keep the camera at the desired position and angle void Camera::updateFollowMode(float deltaTime) { - if (_modeShift < 1.0f) { - _modeShift += 5.0f * deltaTime; - if (_modeShift > 1.0f ) { + if (_linearModeShift < 1.0f) { + _linearModeShift += _modeShiftRate * deltaTime; + + _modeShift = ONE_HALF - ONE_HALF * cosf(_linearModeShift * PIE ); + + _upShift = _previousUpShift * (1.0f - _modeShift) + _newUpShift * _modeShift; + _distance = _previousDistance * (1.0f - _modeShift) + _newDistance * _modeShift; + _tightness = _previousTightness * (1.0f - _modeShift) + _newTightness * _modeShift; + + if (_linearModeShift > 1.0f ) { + _linearModeShift = 1.0f; _modeShift = 1.0f; + _upShift = _newUpShift; + _distance = _newDistance; + _tightness = _newTightness; } } // derive t from tightness - float t = _tightness * deltaTime; + float t = _tightness * _modeShift * deltaTime; if (t > 1.0) { t = 1.0; } @@ -103,10 +115,6 @@ void Camera::updateFollowMode(float deltaTime) { _pitch += (_idealPitch - _pitch) * t; _roll += (_idealRoll - _roll ) * t; } - - _orientation.yaw (_yaw ); - _orientation.pitch(_pitch); - _orientation.roll (_roll ); float radian = (_yaw / 180.0) * PIE; @@ -124,32 +132,45 @@ void Camera::updateFollowMode(float deltaTime) { // force position towards ideal position _position += (_idealPosition - _position) * t; } - - float inverseModeShift = 1.0f - _modeShift; - _upShift = _attributes[_mode].upShift * _modeShift + _previousAttributes[_mode].upShift * inverseModeShift; - _distance = _attributes[_mode].distance * _modeShift + _previousAttributes[_mode].distance * inverseModeShift; - _upShift = _attributes[_mode].upShift * _modeShift + _previousAttributes[_mode].upShift * inverseModeShift; } - -void Camera::setMode(CameraMode m, CameraFollowingAttributes a) { - - _previousAttributes[m].upShift = _attributes[m].upShift; - _previousAttributes[m].distance = _attributes[m].distance; - _previousAttributes[m].tightness = _attributes[m].tightness; - - _attributes[m].upShift = a.upShift; - _attributes[m].distance = a.distance; - _attributes[m].tightness = a.tightness; +void Camera::setModeShiftRate ( float rate ) { - setMode(m); + _modeShiftRate = rate; + + if (_modeShiftRate < CAMERA_MINIMUM_MODE_SHIFT_RATE ) { + _modeShiftRate = CAMERA_MINIMUM_MODE_SHIFT_RATE; + } } -void Camera::setMode(CameraMode m) { +void Camera::setMode(CameraMode m) { + _mode = m; _modeShift = 0.0; + _linearModeShift = 0.0; + + _previousUpShift = _upShift; + _previousDistance = _distance; + _previousTightness = _tightness; + + if (_mode == CAMERA_MODE_THIRD_PERSON) { + _newUpShift = CAMERA_THIRD_PERSON_MODE_UP_SHIFT; + _newDistance = CAMERA_THIRD_PERSON_MODE_DISTANCE; + _newTightness = CAMERA_THIRD_PERSON_MODE_TIGHTNESS; + + } else if (_mode == CAMERA_MODE_FIRST_PERSON) { + _newUpShift = CAMERA_FIRST_PERSON_MODE_UP_SHIFT; + _newDistance = CAMERA_FIRST_PERSON_MODE_DISTANCE; + _newTightness = CAMERA_FIRST_PERSON_MODE_TIGHTNESS; + + } else if (_mode == CAMERA_MODE_MIRROR) { + _newUpShift = CAMERA_MIRROR_MODE_UP_SHIFT; + _newDistance = CAMERA_MIRROR_MODE_DISTANCE; + _newTightness = CAMERA_MIRROR_MODE_TIGHTNESS; + } } + void Camera::setTargetRotation( float yaw, float pitch, float roll ) { _idealYaw = yaw; _idealPitch = pitch; diff --git a/interface/src/Camera.h b/interface/src/Camera.h index b01839d97a..ae3e3ef7b2 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -21,31 +21,11 @@ enum CameraMode NUM_CAMERA_MODES }; - -const float CAMERA_DEFAULT_FIRST_PERSON_MODE_UP_SHIFT = 0.0f; -const float CAMERA_DEFAULT_FIRST_PERSON_MODE_DISTANCE = 0.0f; -const float CAMERA_DEFAULT_FIRST_PERSON_MODE_TIGHTNESS = 100.0f; - -const float CAMERA_DEFAULT_THIRD_PERSON_MODE_UP_SHIFT = -0.2f; -const float CAMERA_DEFAULT_THIRD_PERSON_MODE_DISTANCE = 1.5f; -const float CAMERA_DEFAULT_THIRD_PERSON_MODE_TIGHTNESS = 8.0f; - -const float CAMERA_DEFAULT_MIRROR_MODE_UP_SHIFT = 0.0f; -const float CAMERA_DEFAULT_MIRROR_MODE_DISTANCE = 0.2f; -const float CAMERA_DEFAULT_MIRROR_MODE_TIGHTNESS = 100.0f; - class Camera { public: Camera(); - struct CameraFollowingAttributes - { - float upShift; - float distance; - float tightness; - }; - void initialize(); // instantly put the camera at the ideal position and rotation. void update( float deltaTime ); @@ -62,7 +42,7 @@ public: void setTargetRotation( float yaw, float pitch, float roll ); void setMode ( CameraMode m ); - void setMode ( CameraMode m, CameraFollowingAttributes attributes ); + void setModeShiftRate ( float r ); void setFieldOfView ( float f ); void setAspectRatio ( float a ); void setNearClip ( float n ); @@ -102,18 +82,23 @@ private: float _yaw; float _pitch; float _roll; - float _upShift; float _idealYaw; float _idealPitch; float _idealRoll; + float _upShift; float _distance; float _tightness; + float _previousUpShift; + float _previousDistance; + float _previousTightness; + float _newUpShift; + float _newDistance; + float _newTightness; Orientation _orientation; float _modeShift; + float _linearModeShift; + float _modeShiftRate; - CameraFollowingAttributes _attributes[NUM_CAMERA_MODES]; - CameraFollowingAttributes _previousAttributes[NUM_CAMERA_MODES]; - void generateOrientation(); void updateFollowMode( float deltaTime ); }; diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index ede5e73b20..e0a97db7e1 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -13,17 +13,17 @@ using namespace std; const int MOHAWK_TRIANGLES = 50; +const bool USING_PHYSICAL_MOHAWK = true; const float EYE_RIGHT_OFFSET = 0.27f; const float EYE_UP_OFFSET = 0.36f; const float EYE_FRONT_OFFSET = 0.8f; const float EAR_RIGHT_OFFSET = 1.0; -const float MOUTH_FRONT_OFFSET = 0.9f; +//const float MOUTH_FRONT_OFFSET = 0.9f; const float MOUTH_UP_OFFSET = -0.3f; const float HEAD_MOTION_DECAY = 0.1; const float MINIMUM_EYE_ROTATION_DOT = 0.5f; // based on a dot product: 1.0 is straight ahead, 0.0 is 90 degrees off const float EYEBALL_RADIUS = 0.017; const float EYEBALL_COLOR[3] = { 0.9f, 0.9f, 0.8f }; -const float HAIR_COLOR[3] = { 0.8f, 0.6f, 0.5f }; const float HAIR_SPRING_FORCE = 10.0f; const float HAIR_TORQUE_FORCE = 0.1f; const float HAIR_GRAVITY_FORCE = 0.05f; @@ -64,26 +64,29 @@ Head::Head(Avatar* owningAvatar) : _mohawkTriangleFan(NULL), _mohawkColors(NULL), _renderLookatVectors(false) { - - for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { - _hairTuft[t].length = HAIR_LENGTH; - _hairTuft[t].thickness = HAIR_THICKNESS; - _hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f); - - _hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f); - _hairTuft[t].midPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _hairTuft[t].endPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f); - _hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f); - } + + if (USING_PHYSICAL_MOHAWK) { + resetHairPhysics(); + } } void Head::reset() { _yaw = _pitch = _roll = 0.0f; _leanForward = _leanSideways = 0.0f; + if (USING_PHYSICAL_MOHAWK) { + resetHairPhysics(); + } +} + + + + +void Head::resetHairPhysics() { for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { + _hairTuft[t].length = HAIR_LENGTH; + _hairTuft[t].thickness = HAIR_THICKNESS; _hairTuft[t].basePosition = _position + _orientation.getUp() * _scale * 0.9f; _hairTuft[t].midPosition = _hairTuft[t].basePosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF; _hairTuft[t].endPosition = _hairTuft[t].midPosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF; @@ -92,6 +95,7 @@ void Head::reset() { } } + void Head::simulate(float deltaTime, bool isMine) { const float HEAD_MOTION_DECAY = 0.00; @@ -140,7 +144,9 @@ void Head::simulate(float deltaTime, bool isMine) { // based on the nature of the lookat position, determine if the eyes can look / are looking at it. determineIfLookingAtSomething(); - updateHair(deltaTime); + if (USING_PHYSICAL_MOHAWK) { + updateHairPhysics(deltaTime); + } } void Head::determineIfLookingAtSomething() { @@ -195,7 +201,7 @@ void Head::calculateGeometry(bool lookingInMirror) { //calculate the mouth position _mouthPosition = _position + _orientation.getUp () * _scale * MOUTH_UP_OFFSET - + _orientation.getFront() * _scale * MOUTH_FRONT_OFFSET; + + _orientation.getFront() * _scale; } @@ -206,19 +212,19 @@ void Head::render(bool lookingInMirror, glm::vec3 cameraPosition) { glEnable(GL_DEPTH_TEST); glEnable(GL_RESCALE_NORMAL); - renderMohawk(lookingInMirror); + renderMohawk(lookingInMirror, cameraPosition); renderHeadSphere(); renderEyeBalls(); renderEars(); renderMouth(); renderEyeBrows(); - renderHair(cameraPosition); if (_renderLookatVectors && _lookingAtSomething) { renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition); } } + void Head::createMohawk() { uint16_t agentId = 0; if (_owningAvatar->getOwningAgent()) { @@ -250,9 +256,41 @@ void Head::createMohawk() { } } -void Head::renderMohawk(bool lookingInMirror) { +void Head::renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition) { + if (!_mohawkTriangleFan) { createMohawk(); + } + + if (USING_PHYSICAL_MOHAWK) { + for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { + + glm::vec3 baseAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition; + glm::vec3 midAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition; + glm::vec3 viewVector = _hairTuft[t].basePosition - cameraPosition; + + glm::vec3 basePerpendicular = glm::normalize(glm::cross(baseAxis, viewVector)); + glm::vec3 midPerpendicular = glm::normalize(glm::cross(midAxis, viewVector)); + + glm::vec3 base1 = _hairTuft[t].basePosition - basePerpendicular * _hairTuft[t].thickness * ONE_HALF; + glm::vec3 base2 = _hairTuft[t].basePosition + basePerpendicular * _hairTuft[t].thickness * ONE_HALF; + glm::vec3 mid1 = _hairTuft[t].midPosition - midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; + glm::vec3 mid2 = _hairTuft[t].midPosition + midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; + + glColor3f(_mohawkColors[t].x, _mohawkColors[t].y, _mohawkColors[t].z); + + glBegin(GL_TRIANGLES); + glVertex3f(base1.x, base1.y, base1.z ); + glVertex3f(base2.x, base2.y, base2.z ); + glVertex3f(mid1.x, mid1.y, mid1.z ); + glVertex3f(base2.x, base2.y, base2.z ); + glVertex3f(mid1.x, mid1.y, mid1.z ); + glVertex3f(mid2.x, mid2.y, mid2.z ); + glVertex3f(mid1.x, mid1.y, mid1.z ); + glVertex3f(mid2.x, mid2.y, mid2.z ); + glVertex3f(_hairTuft[t].endPosition.x, _hairTuft[t].endPosition.y, _hairTuft[t].endPosition.z ); + glEnd(); + } } else { glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); @@ -268,7 +306,7 @@ void Head::renderMohawk(bool lookingInMirror) { } glEnd(); glPopMatrix(); - } + } } @@ -304,6 +342,7 @@ void Head::renderMouth() { glm::vec3 u = _orientation.getUp () * _scale * (0.05f + s * 0.0040f ); glm::vec3 f = _orientation.getFront() * _scale * 0.09f; + glm::vec3 middle = _mouthPosition; glm::vec3 leftCorner = _mouthPosition - r * 1.0f; glm::vec3 rightCorner = _mouthPosition + r * 1.0f; glm::vec3 leftTop = _mouthPosition - r * 0.4f + u * 0.7f + f; @@ -313,6 +352,7 @@ void Head::renderMouth() { // constrain all mouth vertices to a sphere slightly larger than the head... float constrainedRadius = _scale + 0.001f; + middle = _position + glm::normalize(middle - _position) * constrainedRadius; leftCorner = _position + glm::normalize(leftCorner - _position) * constrainedRadius; rightCorner = _position + glm::normalize(rightCorner - _position) * constrainedRadius; leftTop = _position + glm::normalize(leftTop - _position) * constrainedRadius; @@ -327,10 +367,16 @@ void Head::renderMouth() { glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z ); glVertex3f(leftTop.x, leftTop.y, leftTop.z ); glVertex3f(leftTop.x, leftTop.y, leftTop.z ); + glVertex3f(middle.x, middle.y, middle.z ); glVertex3f(rightTop.x, rightTop.y, rightTop.z ); + glVertex3f(leftTop.x, leftTop.y, leftTop.z ); + glVertex3f(middle.x, middle.y, middle.z ); glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z ); + glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z ); + glVertex3f(middle.x, middle.y, middle.z ); + glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z); glVertex3f(rightTop.x, rightTop.y, rightTop.z ); - glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z ); + glVertex3f(middle.x, middle.y, middle.z ); glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z); glVertex3f(rightTop.x, rightTop.y, rightTop.z ); glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z); @@ -525,7 +571,7 @@ void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosi } -void Head::updateHair(float deltaTime) { +void Head::updateHairPhysics(float deltaTime) { for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { @@ -617,41 +663,3 @@ void Head::updateHair(float deltaTime) { } } - - -void Head::renderHair(glm::vec3 cameraPosition) { - - for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { - - glm::vec3 baseAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition; - glm::vec3 midAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition; - glm::vec3 viewVector = _hairTuft[t].basePosition - cameraPosition; - - glm::vec3 basePerpendicular = glm::normalize(glm::cross(baseAxis, viewVector)); - glm::vec3 midPerpendicular = glm::normalize(glm::cross(midAxis, viewVector)); - - glm::vec3 base1 = _hairTuft[t].basePosition - basePerpendicular * _hairTuft[t].thickness * ONE_HALF; - glm::vec3 base2 = _hairTuft[t].basePosition + basePerpendicular * _hairTuft[t].thickness * ONE_HALF; - glm::vec3 mid1 = _hairTuft[t].midPosition - midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; - glm::vec3 mid2 = _hairTuft[t].midPosition + midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; - - glColor3fv(HAIR_COLOR); - - glBegin(GL_TRIANGLES); - - glVertex3f(base1.x, base1.y, base1.z ); - glVertex3f(base2.x, base2.y, base2.z ); - glVertex3f(mid1.x, mid1.y, mid1.z ); - - glVertex3f(base2.x, base2.y, base2.z ); - glVertex3f(mid1.x, mid1.y, mid1.z ); - glVertex3f(mid2.x, mid2.y, mid2.z ); - - glVertex3f(mid1.x, mid1.y, mid1.z ); - glVertex3f(mid2.x, mid2.y, mid2.z ); - glVertex3f(_hairTuft[t].endPosition.x, _hairTuft[t].endPosition.y, _hairTuft[t].endPosition.z ); - - glEnd(); - } -} - diff --git a/interface/src/Head.h b/interface/src/Head.h index a116a45fa3..07d7351cb3 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -25,7 +25,6 @@ enum eyeContactTargets }; const int NUM_HAIR_TUFTS = 4; -const int NUM_HAIR_SEGMENTS = 4; class Avatar; @@ -36,7 +35,7 @@ public: void reset(); void simulate(float deltaTime, bool isMine); void render(bool lookingInMirror, glm::vec3 cameraPosition); - void renderMohawk(bool lookingInMirror); + void renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition); void setScale (float scale ) { _scale = scale; } void setPosition (glm::vec3 position ) { _position = position; } @@ -108,8 +107,8 @@ private: void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition); void calculateGeometry( bool lookingInMirror); void determineIfLookingAtSomething(); - void updateHair(float deltaTime); - void renderHair(glm::vec3 cameraPosition); + void resetHairPhysics(); + void updateHairPhysics(float deltaTime); }; #endif diff --git a/interface/src/Skeleton.cpp b/interface/src/Skeleton.cpp new file mode 100644 index 0000000000..49e8dea053 --- /dev/null +++ b/interface/src/Skeleton.cpp @@ -0,0 +1,20 @@ +// +// Skeleton.cpp +// interface +// +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. + +#include "Skeleton.h" + +Skeleton::Skeleton() { +} + +void Skeleton::initialize() { +} + +void Skeleton::render() { +} + +void Skeleton::simulate(float deltaTime) { +} + diff --git a/interface/src/Skeleton.h b/interface/src/Skeleton.h new file mode 100644 index 0000000000..01f0546f4a --- /dev/null +++ b/interface/src/Skeleton.h @@ -0,0 +1,54 @@ +// +// Skeleton.h +// interface +// +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef hifi_Skeleton_h +#define hifi_Skeleton_h + +enum AvatarJointID +{ + AVATAR_JOINT_NULL = -1, + AVATAR_JOINT_PELVIS, + AVATAR_JOINT_TORSO, + AVATAR_JOINT_CHEST, + AVATAR_JOINT_NECK_BASE, + AVATAR_JOINT_HEAD_BASE, + AVATAR_JOINT_HEAD_TOP, + AVATAR_JOINT_LEFT_COLLAR, + AVATAR_JOINT_LEFT_SHOULDER, + AVATAR_JOINT_LEFT_ELBOW, + AVATAR_JOINT_LEFT_WRIST, + AVATAR_JOINT_LEFT_FINGERTIPS, + AVATAR_JOINT_RIGHT_COLLAR, + AVATAR_JOINT_RIGHT_SHOULDER, + AVATAR_JOINT_RIGHT_ELBOW, + AVATAR_JOINT_RIGHT_WRIST, + AVATAR_JOINT_RIGHT_FINGERTIPS, + AVATAR_JOINT_LEFT_HIP, + AVATAR_JOINT_LEFT_KNEE, + AVATAR_JOINT_LEFT_HEEL, + AVATAR_JOINT_LEFT_TOES, + AVATAR_JOINT_RIGHT_HIP, + AVATAR_JOINT_RIGHT_KNEE, + AVATAR_JOINT_RIGHT_HEEL, + AVATAR_JOINT_RIGHT_TOES, + + NUM_AVATAR_JOINTS +}; + + +class Skeleton { +public: + Skeleton(); + + void initialize(); + void simulate(float deltaTime); + void render(); + +private: +}; + +#endif