From c46fc5a861f0df65db652db387a70a44c35afab1 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 2 May 2013 17:46:10 -0700 Subject: [PATCH] (1) added avatar tilting while walking; (2) added avatar renderer; (3) tweaked body proportions; (4) --- interface/src/Avatar.cpp | 141 +++++++++++++++++++++------------------ interface/src/Avatar.h | 77 +++++++-------------- interface/src/main.cpp | 6 ++ 3 files changed, 106 insertions(+), 118 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 8cca1a7a9a..4655c0e9ec 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -135,31 +135,31 @@ Avatar::Avatar(bool isMine) { Avatar::Avatar(const Avatar &otherAvatar) { - _velocity = otherAvatar._velocity; - _thrust = otherAvatar._thrust; - _rotation = otherAvatar._rotation; - _bodyYaw = otherAvatar._bodyYaw; - _bodyPitch = otherAvatar._bodyPitch; - _bodyRoll = otherAvatar._bodyRoll; - _bodyPitchDelta = otherAvatar._bodyPitchDelta; - _bodyYawDelta = otherAvatar._bodyYawDelta; - _bodyRollDelta = otherAvatar._bodyRollDelta; - _mousePressed = otherAvatar._mousePressed; - _mode = otherAvatar._mode; - _isMine = otherAvatar._isMine; - _renderYaw = otherAvatar._renderYaw; - _renderPitch = otherAvatar._renderPitch; - _maxArmLength = otherAvatar._maxArmLength; - _transmitterTimer = otherAvatar._transmitterTimer; - _transmitterIsFirstData = otherAvatar._transmitterIsFirstData; - _transmitterTimeLastReceived = otherAvatar._transmitterTimeLastReceived; - _transmitterHz = otherAvatar._transmitterHz; - _transmitterInitialReading = otherAvatar._transmitterInitialReading; - _transmitterPackets = otherAvatar._transmitterPackets; - _TEST_bigSphereRadius = otherAvatar._TEST_bigSphereRadius; - _TEST_bigSpherePosition = otherAvatar._TEST_bigSpherePosition; - _movedHandOffset = otherAvatar._movedHandOffset; - _usingBodySprings = otherAvatar._usingBodySprings; + _velocity = otherAvatar._velocity; + _thrust = otherAvatar._thrust; + _rotation = otherAvatar._rotation; + _bodyYaw = otherAvatar._bodyYaw; + _bodyPitch = otherAvatar._bodyPitch; + _bodyRoll = otherAvatar._bodyRoll; + _bodyPitchDelta = otherAvatar._bodyPitchDelta; + _bodyYawDelta = otherAvatar._bodyYawDelta; + _bodyRollDelta = otherAvatar._bodyRollDelta; + _mousePressed = otherAvatar._mousePressed; + _mode = otherAvatar._mode; + _isMine = otherAvatar._isMine; + _renderYaw = otherAvatar._renderYaw; + _renderPitch = otherAvatar._renderPitch; + _maxArmLength = otherAvatar._maxArmLength; + _transmitterTimer = otherAvatar._transmitterTimer; + _transmitterIsFirstData = otherAvatar._transmitterIsFirstData; + _transmitterTimeLastReceived = otherAvatar._transmitterTimeLastReceived; + _transmitterHz = otherAvatar._transmitterHz; + _transmitterInitialReading = otherAvatar._transmitterInitialReading; + _transmitterPackets = otherAvatar._transmitterPackets; + _TEST_bigSphereRadius = otherAvatar._TEST_bigSphereRadius; + _TEST_bigSpherePosition = otherAvatar._TEST_bigSpherePosition; + _movedHandOffset = otherAvatar._movedHandOffset; + _usingBodySprings = otherAvatar._usingBodySprings; _orientation.set( otherAvatar._orientation ); @@ -347,16 +347,34 @@ void Avatar::simulate(float deltaTime) { // update body yaw by body yaw delta if (_isMine) { - _bodyYaw += _bodyYawDelta * deltaTime; + _bodyPitch += _bodyPitchDelta * deltaTime; + _bodyYaw += _bodyYawDelta * deltaTime; + _bodyRoll += _bodyRollDelta * deltaTime; } - // decay body rotation deltas - _bodyPitchDelta *= (1.0 - BODY_PITCH_DECAY * deltaTime); - _bodyYawDelta *= (1.0 - BODY_YAW_DECAY * deltaTime); - _bodyRollDelta *= (1.0 - BODY_ROLL_DECAY * deltaTime); - + // decay body rotation momentum + float bodySpinMomentum = 1.0 - BODY_SPIN_FRICTION * deltaTime; + if ( bodySpinMomentum < 0.0f ) { bodySpinMomentum = 0.0f; } + _bodyPitchDelta *= bodySpinMomentum; + _bodyYawDelta *= bodySpinMomentum; + _bodyRollDelta *= bodySpinMomentum; + // add thrust to velocity _velocity += _thrust * deltaTime; + + // calculate speed + _speed = glm::length( _velocity ); + + //pitch and roll the body as a function of forward speed and turning delta + float forwardComponentOfVelocity = glm::dot( _orientation.getFront(), _velocity ); + _bodyPitch += BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity; + _bodyRoll += BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta; + + // these forces keep the body upright... + float tiltDecay = 1.0 - BODY_UPRIGHT_FORCE * deltaTime; + if ( tiltDecay < 0.0f ) { tiltDecay = 0.0f; } + _bodyPitch *= tiltDecay; + _bodyRoll *= tiltDecay; // update position by velocity _position += _velocity * deltaTime; @@ -367,11 +385,8 @@ void Avatar::simulate(float deltaTime) { // update head information updateHead(deltaTime); - // calculate speed, and use that to determine walking vs. standing - _speed = glm::length( _velocity ); - float rotationalSpeed = fabs( _bodyYawDelta ); - - if ( _speed + rotationalSpeed > 0.2 ) { + // use speed and angular velocity to determine walking vs. standing + if ( _speed + fabs( _bodyYawDelta ) > 0.2 ) { _mode = AVATAR_MODE_WALKING; } else { _mode = AVATAR_MODE_INTERACTING; @@ -708,6 +723,7 @@ static TextRenderer* textRenderer() { } void Avatar::render(bool lookingInMirror) { + /* // show avatar position @@ -991,6 +1007,7 @@ void Avatar::initializeSkeleton() { _joint[ AVATAR_JOINT_CHEST ].parent = AVATAR_JOINT_TORSO; _joint[ AVATAR_JOINT_NECK_BASE ].parent = AVATAR_JOINT_CHEST; _joint[ AVATAR_JOINT_HEAD_BASE ].parent = AVATAR_JOINT_NECK_BASE; + _joint[ AVATAR_JOINT_HEAD_TOP ].parent = AVATAR_JOINT_HEAD_BASE; _joint[ AVATAR_JOINT_LEFT_COLLAR ].parent = AVATAR_JOINT_CHEST; _joint[ AVATAR_JOINT_LEFT_SHOULDER ].parent = AVATAR_JOINT_LEFT_COLLAR; _joint[ AVATAR_JOINT_LEFT_ELBOW ].parent = AVATAR_JOINT_LEFT_SHOULDER; @@ -1012,32 +1029,28 @@ void Avatar::initializeSkeleton() { // specify the default pose position _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.0 ); + _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_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.1, 0.0 ); - _joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.0 ); - - _joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3( -0.06, 0.04, 0.0 ); - _joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.04, 0.0, 0.0 ); + _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_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_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_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.07, 0.0 ); - - _joint[ AVATAR_JOINT_RIGHT_COLLAR ].defaultPosePosition = glm::vec3( 0.06, 0.04, 0.0 ); - _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.04, 0.0, 0.0 ); + _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_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_FINGERTIPS ].defaultPosePosition = glm::vec3( 0.0, -0.07, 0.0 ); - - _joint[ AVATAR_JOINT_LEFT_HIP ].defaultPosePosition = glm::vec3( -0.05, 0.0, 0.0 ); - _joint[ AVATAR_JOINT_LEFT_KNEE ].defaultPosePosition = glm::vec3( 0.0, -0.22, 0.0 ); - _joint[ AVATAR_JOINT_LEFT_HEEL ].defaultPosePosition = glm::vec3( 0.0, -0.22, 0.0 ); - _joint[ AVATAR_JOINT_LEFT_TOES ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.04 ); - - _joint[ AVATAR_JOINT_RIGHT_HIP ].defaultPosePosition = glm::vec3( 0.05, 0.0, 0.0 ); - _joint[ AVATAR_JOINT_RIGHT_KNEE ].defaultPosePosition = glm::vec3( 0.0, -0.22, 0.0 ); - _joint[ AVATAR_JOINT_RIGHT_HEEL ].defaultPosePosition = glm::vec3( 0.0, -0.22, 0.0 ); - _joint[ AVATAR_JOINT_RIGHT_TOES ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.04 ); + _joint[ AVATAR_JOINT_LEFT_HIP ].defaultPosePosition = glm::vec3( -0.04, 0.0, -0.02 ); + _joint[ AVATAR_JOINT_LEFT_KNEE ].defaultPosePosition = glm::vec3( 0.0, -0.22, 0.02 ); + _joint[ AVATAR_JOINT_LEFT_HEEL ].defaultPosePosition = glm::vec3( 0.0, -0.22, -0.01 ); + _joint[ AVATAR_JOINT_LEFT_TOES ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.05 ); + _joint[ AVATAR_JOINT_RIGHT_HIP ].defaultPosePosition = glm::vec3( 0.04, 0.0, -0.02 ); + _joint[ AVATAR_JOINT_RIGHT_KNEE ].defaultPosePosition = glm::vec3( 0.0, -0.22, 0.02 ); + _joint[ AVATAR_JOINT_RIGHT_HEEL ].defaultPosePosition = glm::vec3( 0.0, -0.22, -0.01 ); + _joint[ AVATAR_JOINT_RIGHT_TOES ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.05 ); // specify the radii of the bone positions _joint[ AVATAR_JOINT_PELVIS ].radius = 0.06; @@ -1046,13 +1059,13 @@ void Avatar::initializeSkeleton() { _joint[ AVATAR_JOINT_NECK_BASE ].radius = 0.03; _joint[ AVATAR_JOINT_HEAD_BASE ].radius = 0.07; - _joint[ AVATAR_JOINT_LEFT_COLLAR ].radius = 0.027; + _joint[ AVATAR_JOINT_LEFT_COLLAR ].radius = 0.029; _joint[ AVATAR_JOINT_LEFT_SHOULDER ].radius = 0.023; _joint[ AVATAR_JOINT_LEFT_ELBOW ].radius = 0.017; _joint[ AVATAR_JOINT_LEFT_WRIST ].radius = 0.017; _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].radius = 0.01; - _joint[ AVATAR_JOINT_RIGHT_COLLAR ].radius = 0.027; + _joint[ AVATAR_JOINT_RIGHT_COLLAR ].radius = 0.029; _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].radius = 0.023; _joint[ AVATAR_JOINT_RIGHT_ELBOW ].radius = 0.015; _joint[ AVATAR_JOINT_RIGHT_WRIST ].radius = 0.015; @@ -1122,12 +1135,7 @@ void Avatar::initializeSkeleton() { _joint[ AVATAR_JOINT_HEAD_BASE ].length + _joint[ AVATAR_JOINT_HEAD_BASE ].radius ); - - printf( "_height = %f\n", _height ); - - - - + //printf( "_height = %f\n", _height ); // generate world positions updateSkeleton(); @@ -1145,9 +1153,12 @@ void Avatar::calculateBoneLengths() { } void Avatar::updateSkeleton() { - // rotate body... + + // rotate body... _orientation.setToIdentity(); - _orientation.yaw( _bodyYaw ); + _orientation.yaw ( _bodyYaw ); + _orientation.pitch( _bodyPitch ); + _orientation.roll ( _bodyRoll ); // calculate positions of all bones by traversing the skeleton tree: for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index c14680df4f..45b43e50bb 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -42,7 +42,6 @@ enum AvatarMode NUM_AVATAR_MODES }; - enum AvatarJointID { AVATAR_JOINT_NULL = -1, @@ -52,19 +51,16 @@ enum AvatarJointID 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, @@ -73,37 +69,8 @@ enum AvatarJointID AVATAR_JOINT_RIGHT_KNEE, AVATAR_JOINT_RIGHT_HEEL, AVATAR_JOINT_RIGHT_TOES, - - /* - 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 - }; @@ -134,9 +101,12 @@ public: void setLeanSideways(float dist); void addLean(float x, float z); - const glm::vec3& getHeadLookatDirection() const { return _orientation.getFront(); }; - const glm::vec3& getHeadLookatDirectionUp() const { return _orientation.getUp(); }; - const glm::vec3& getHeadLookatDirectionRight() const { return _orientation.getRight(); }; + /* + const glm::vec3& getHeadRightDirection() const { return _orientation.getRight(); }; + const glm::vec3& getHeadUpDirection () const { return _orientation.getUp (); }; + const glm::vec3& getHeadFrontDirection() const { return _orientation.getFront(); }; + */ + const glm::vec3& getHeadPosition() const ; const glm::vec3& getJointPosition(AvatarJointID j) const { return _joint[j].position; }; const glm::vec3& getBodyUpDirection() const { return _orientation.getUp(); }; @@ -183,9 +153,10 @@ private: const float DECAY = 0.1; const float THRUST_MAG = 1200.0; const float YAW_MAG = 500.0; - const float BODY_PITCH_DECAY = 5.0; - const float BODY_YAW_DECAY = 5.0; - const float BODY_ROLL_DECAY = 5.0; + const float BODY_SPIN_FRICTION = 5.0; + const float BODY_UPRIGHT_FORCE = 10.0; + const float BODY_PITCH_WHILE_WALKING = 30.0; + const float BODY_ROLL_WHILE_TURNING = 0.1; const float LIN_VEL_DECAY = 5.0; const float MY_HAND_HOLDING_PULL = 0.2; const float YOUR_HAND_HOLDING_PULL = 1.0; @@ -204,20 +175,20 @@ private: struct AvatarJoint { - AvatarJointID parent; // which joint is this joint connected to? - glm::vec3 position; // the position at the "end" of the joint - in global space - glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose" - glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position) - glm::vec3 springyVelocity; // used for special effects ( the velocity of the springy position) - float springBodyTightness; // how tightly the springy position tries to stay on the position - glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orientation) - float yaw; // the yaw Euler angle of the joint rotation off the parent - float pitch; // the pitch Euler angle of the joint rotation off the parent - float roll; // the roll Euler angle of the joint rotation off the parent - Orientation orientation; // three orthogonal normals determined by yaw, pitch, roll - float length; // the length of the joint - float radius; // used for detecting collisions for certain physical effects - bool isCollidable; // when false, the joint position will not register a collision + AvatarJointID parent; // which joint is this joint connected to? + glm::vec3 position; // the position at the "end" of the joint - in global space + glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose" + glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position) + glm::vec3 springyVelocity; // used for special effects ( the velocity of the springy position) + float springBodyTightness; // how tightly the springy position tries to stay on the position + glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orientation) + float yaw; // the yaw Euler angle of the joint rotation off the parent + float pitch; // the pitch Euler angle of the joint rotation off the parent + float roll; // the roll Euler angle of the joint rotation off the parent + Orientation orientation; // three orthogonal normals determined by yaw, pitch, roll + float length; // the length of vector connecting the joint and its parent + float radius; // used for detecting collisions for certain physical effects + bool isCollidable; // when false, the joint position will not register a collision }; struct AvatarHead diff --git a/interface/src/main.cpp b/interface/src/main.cpp index e3788ec236..a8f6a6fec4 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -69,6 +69,7 @@ #include "Camera.h" #include "Avatar.h" +#include "AvatarRenderer.h" #include "Texture.h" #include #include @@ -119,6 +120,9 @@ Avatar myAvatar(true); // The rendered avatar of oneself Camera myCamera; // My view onto the world (sometimes on myself :) Camera viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode + +AvatarRenderer avatarRenderer; + // Starfield information char starFile[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt"; char starCacheFile[] = "cachedStars.txt"; @@ -869,6 +873,7 @@ void display(void) if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { Avatar *avatar = (Avatar *)agent->getLinkedData(); avatar->render(0); + //avatarRenderer.render(avatar, 0); // this will replace the above call } } agentList->unlock(); @@ -881,6 +886,7 @@ void display(void) //Render my own avatar myAvatar.render(::lookingInMirror); + //avatarRenderer.render(&myAvatar, lookingInMirror); // this will replace the above call } glPopMatrix();