From 5a4813d5c9730b56c4acbfcf3a7f53d567cc859f Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Sat, 18 May 2013 14:31:27 -0700 Subject: [PATCH 01/23] improved algorithm for rotating eyes to look at target --- interface/src/Avatar.cpp | 3 +- interface/src/Head.cpp | 132 +++++++++++++++++++++++++-------------- interface/src/Head.h | 2 +- 3 files changed, 86 insertions(+), 51 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 9b351a7684..2fe26f56eb 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -394,12 +394,11 @@ void Avatar::simulate(float deltaTime) { ); _head.setBodyYaw(_bodyYaw); - + //the following is still being prototyped (making the eyes look at a specific location), it should be finished by 5/20/13 if (_interactingOther) { _head.setLooking(true); _head.setLookatPosition(_interactingOther->getSpringyHeadPosition()); -//_head.setLookatPosition(_interactingOther->getApproximateEyePosition()); } else { _head.setLooking(false); } diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 3a583479fd..ed0f9dba87 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -15,12 +15,16 @@ using namespace std; const float HEAD_MOTION_DECAY = 0.1; const float MINIMUM_EYE_ROTATION = 0.7f; // based on a dot product: 1.0 is straight ahead, 0.0 is 90 degrees off +const float EYEBALL_RADIUS = 0.02; +const float IRIS_RADIUS = 0.007; +const float IRIS_PROTRUSION = 0.018f; + float _browColor [] = {210.0/255.0, 105.0/255.0, 30.0/255.0}; float _mouthColor[] = {1, 0, 0}; -float _BrowRollAngle [5] = {0, 15, 30, -30, -15}; -float _BrowPitchAngle[3] = {-70, -60, -50}; -float _eyeColor [3] = {1,1,1}; +float _BrowRollAngle [5] = { 0.0f, 15.0f, 30.0f, -30.0f, -15.0f}; +float _BrowPitchAngle[3] = {-70.0f, -60.0f, -50.0f}; +float _eyeColor [3] = { 0.9f, 0.9f, 0.8f}; float _MouthWidthChoices[3] = {0.5, 0.77, 0.3}; @@ -58,20 +62,21 @@ Head::Head() : _scale(1.0f), _eyeContact(1), _browAudioLift(0.0f), - _eyeContactTarget(LEFT_EYE), - _bodyYaw(0.0f), - _lastLoudness(0.0f), - _averageLoudness(0.0f), - _audioAttack(0.0f), _gravity(0.0f, -1.0f, 0.0f), _returnSpringScale(1.0f) { - _eyebrowPitch[0] = -30; - _eyebrowPitch[1] = -30; - _eyebrowRoll [0] = 20; - _eyebrowRoll [1] = -20; + _eyebrowPitch[0] = -30; + _eyebrowPitch[1] = -30; + _eyebrowRoll [0] = 20; + _eyebrowRoll [1] = -20; + _bodyYaw = 0.0f; + _audioAttack = 0.0f; + _averageLoudness = 0.0f; + _lastLoudness = 0.0f; + _eyeContactTarget = LEFT_EYE; } + void Head::setPositionRotationAndScale(glm::vec3 p, glm::vec3 r, float s) { _position = p; _scale = s; @@ -221,14 +226,14 @@ void Head::updateEyePositions() { void Head::setLooking(bool looking) { - _looking = looking; + _lookingAtSomething = looking; glm::vec3 averageEyePosition = _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - averageEyePosition); float dot = glm::dot(targetLookatAxis, _orientation.getFront()); if (dot < MINIMUM_EYE_ROTATION) { - _looking = false; + _lookingAtSomething = false; } } @@ -245,9 +250,8 @@ void Head::render(bool lookingInMirror) { glPushMatrix(); - glTranslatef(_position.x, _position.y, _position.z); - - glScalef(_scale, _scale, _scale); + glTranslatef(_position.x, _position.y, _position.z); //translate to head position + glScalef(_scale, _scale, _scale); //scale to head size if (lookingInMirror) { glRotatef(_bodyYaw - _yaw, 0, 1, 0); @@ -329,10 +333,12 @@ void Head::render(bool lookingInMirror) { //a new version of eyeballs that has the ability to look at specific targets in the world (algo still not finished yet) renderEyeBalls(); - if (_looking) { + /* + if (_lookingAtSomething) { // Render lines originating from the eyes and converging on the lookatPosition debugRenderLookatVectors(_leftEyePosition, _rightEyePosition, _lookatPosition); } + */ } void Head::renderEyeBalls() { @@ -345,7 +351,7 @@ void Head::renderEyeBalls() { } } - // setup the texutre to be used on each eye + // setup the texutre to be used on each iris GLUquadric* irisQuadric = gluNewQuadric(); gluQuadricTexture(irisQuadric, GL_TRUE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -353,60 +359,90 @@ void Head::renderEyeBalls() { gluQuadricOrientation(irisQuadric, GLU_OUTSIDE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, IRIS_TEXTURE_WIDTH, IRIS_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, &::irisTexture[0]); - - // left eyeball + + // render white ball of left eyeball glPushMatrix(); glColor3fv(_eyeColor); glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); - gluSphere(irisQuadric, 0.02, 30, 30); + gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30); glPopMatrix(); - // left iris + // render left iris glPushMatrix(); { - glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); - glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _leftEyePosition); - - if (!_looking) { - targetLookatAxis = _orientation.getFront(); - } + glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position glPushMatrix(); - glm::vec3 rotationAxis = glm::cross(targetLookatAxis, glm::vec3(0.0f, 1.0f, 0.0f)); - float angle = 180.0f - angleBetween(targetLookatAxis, glm::vec3(0.0f, 1.0f, 0.0f)); - glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); - glTranslatef( 0.0f, -0.018f, 0.0f);//push the iris out a bit (otherwise - inside of eyeball!) + + if (_lookingAtSomething) { + + //rotate the eyeball to aim towards the lookat position + glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _leftEyePosition); // the lookat direction + glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP); + float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); + glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); + glRotatef(180.0, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations + } else { + + //rotate the eyeball to aim straight ahead + glm::vec3 rotationAxisToHeadFront = glm::cross(_orientation.getFront(), IDENTITY_UP); + float angleToHeadFront = 180.0f - angleBetween(_orientation.getFront(), IDENTITY_UP); + glRotatef(angleToHeadFront, rotationAxisToHeadFront.x, rotationAxisToHeadFront.y, rotationAxisToHeadFront.z); + + //set the amount of roll (for correction after previous rotations) + float rollRotation = angleBetween(_orientation.getFront(), IDENTITY_FRONT); + float dot = glm::dot(_orientation.getFront(), -IDENTITY_RIGHT); + if ( dot < 0.0f ) { rollRotation = -rollRotation; } + glRotatef(rollRotation, 0.0f, 1.0f, 0.0f); //roll the iris or correct roll about the lookat vector + } + + glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);//push the iris out a bit (otherwise - inside of eyeball!) glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris glEnable(GL_TEXTURE_2D); - gluSphere(irisQuadric, 0.007, 15, 15); + gluSphere(irisQuadric, IRIS_RADIUS, 15, 15); glDisable(GL_TEXTURE_2D); glPopMatrix(); } glPopMatrix(); - //right eyeball + //render white ball of right eyeball glPushMatrix(); glColor3fv(_eyeColor); glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); - gluSphere(irisQuadric, 0.02, 30, 30); + gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30); glPopMatrix(); - //right iris + // render right iris glPushMatrix(); { - glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); - glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _rightEyePosition); - - if (!_looking) { - targetLookatAxis = _orientation.getFront(); - } + glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position glPushMatrix(); - glm::vec3 rotationAxis = glm::cross(targetLookatAxis, glm::vec3(0.0f, 1.0f, 0.0f)); - float angle = 180.0f - angleBetween(targetLookatAxis, glm::vec3(0.0f, 1.0f, 0.0f)); - glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); - glTranslatef( 0.0f, -0.018f, 0.0f);//push the iris out a bit (otherwise - inside of eyeball!) + + if (_lookingAtSomething) { + + //rotate the eyeball to aim towards the lookat position + glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _rightEyePosition); + glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP); + float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); + glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); + glRotatef(180.0f, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations + } else { + + //rotate the eyeball to aim straight ahead + glm::vec3 rotationAxisToHeadFront = glm::cross(_orientation.getFront(), IDENTITY_UP); + float angleToHeadFront = 180.0f - angleBetween(_orientation.getFront(), IDENTITY_UP); + glRotatef(angleToHeadFront, rotationAxisToHeadFront.x, rotationAxisToHeadFront.y, rotationAxisToHeadFront.z); + + //set the amount of roll (for correction after previous rotations) + float rollRotation = angleBetween(_orientation.getFront(), IDENTITY_FRONT); + float dot = glm::dot(_orientation.getFront(), -IDENTITY_RIGHT); + if ( dot < 0.0f ) { rollRotation = -rollRotation; } + glRotatef(rollRotation, 0.0f, 1.0f, 0.0f); //roll the iris or correct roll about the lookat vector + } + + glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);//push the iris out a bit (otherwise - inside of eyeball!) glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris glEnable(GL_TEXTURE_2D); - gluSphere(irisQuadric, 0.007, 15, 15); + gluSphere(irisQuadric, IRIS_RADIUS, 15, 15); glDisable(GL_TEXTURE_2D); glPopMatrix(); } diff --git a/interface/src/Head.h b/interface/src/Head.h index 8f5afd052a..4ee20e3cfd 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -81,7 +81,7 @@ private: float _scale; int _eyeContact; float _browAudioLift; - bool _looking; + bool _lookingAtSomething; glm::vec3 _gravity; float _lastLoudness; float _averageLoudness; From bbeac7701ae825d6d16416d28013414176de6624 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Sat, 18 May 2013 14:43:23 -0700 Subject: [PATCH 02/23] small fix --- interface/src/Head.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index ed0f9dba87..3b751651b2 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -63,17 +63,17 @@ Head::Head() : _eyeContact(1), _browAudioLift(0.0f), _gravity(0.0f, -1.0f, 0.0f), - _returnSpringScale(1.0f) + _lastLoudness(0.0f), + _averageLoudness(0.0f), + _audioAttack(0.0f), + _returnSpringScale(1.0f), + _bodyYaw(0.0f), + _eyeContactTarget(LEFT_EYE) { _eyebrowPitch[0] = -30; _eyebrowPitch[1] = -30; - _eyebrowRoll [0] = 20; + _eyebrowRoll [0] = 20; _eyebrowRoll [1] = -20; - _bodyYaw = 0.0f; - _audioAttack = 0.0f; - _averageLoudness = 0.0f; - _lastLoudness = 0.0f; - _eyeContactTarget = LEFT_EYE; } @@ -224,6 +224,7 @@ void Head::updateEyePositions() { + _orientation.getFront() * frontShift; } + void Head::setLooking(bool looking) { _lookingAtSomething = looking; @@ -330,7 +331,6 @@ void Head::render(bool lookingInMirror) { glPopMatrix(); - //a new version of eyeballs that has the ability to look at specific targets in the world (algo still not finished yet) renderEyeBalls(); /* From 7f0d2e572ee43c223c8dfa90f503b22cc167e5d3 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 07:38:00 -0700 Subject: [PATCH 03/23] some preliminary work on avatarRenderer --- interface/src/Application.cpp | 2 +- interface/src/Application.h | 3 ++ interface/src/Avatar.cpp | 20 ++++--------- interface/src/Avatar.h | 1 + interface/src/AvatarRenderer.cpp | 48 +++++++++++++++++++------------- interface/src/AvatarRenderer.h | 7 +++-- 6 files changed, 43 insertions(+), 38 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1f34ed3c09..7553ef2b1a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -302,7 +302,6 @@ void Application::paintGL() { _myCamera.setTargetRotation(_myAvatar.getBodyYaw() - 180.0f, 0.0f, 0.0f); - } else { if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); @@ -1635,6 +1634,7 @@ void Application::displaySide(Camera& whichCamera) { // Render my own Avatar _myAvatar.render(_lookingInMirror, _myCamera.getPosition()); + //_avatarRenderer.render(); } // Render the world box diff --git a/interface/src/Application.h b/interface/src/Application.h index 8a949fa183..a42ffccafd 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -186,6 +186,9 @@ private: Oscilloscope _audioScope; Avatar _myAvatar; // The rendered avatar of oneself + + //AvatarRenderer _avatarRenderer; + Camera _myCamera; // My view onto the world Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 2fe26f56eb..1eb252dcb5 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -58,6 +58,7 @@ bool usingBigSphereCollisionTest = true; float chatMessageScale = 0.0015; float chatMessageHeight = 0.45; + Avatar::Avatar(bool isMine) { _orientation.setToIdentity(); @@ -691,19 +692,6 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { _cameraPosition = cameraPosition; // store this for use in various parts of the code - // 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); - - /* - // show avatar position - glColor4f(0.5f, 0.5f, 0.5f, 0.6); - glPushMatrix(); - glTranslatef(_position.x, _position.y, _position.z); - glScalef(0.03, 0.03, 0.03); - glutSolidSphere(1, 10, 10); - glPopMatrix(); - */ - if (usingBigSphereCollisionTest) { // show TEST big sphere glColor4f(0.5f, 0.6f, 0.8f, 0.7); @@ -714,10 +702,12 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { glPopMatrix(); } + // 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); - // if this is my avatar, then render my interactions with the other avatar if (_isMine) { _avatarTouch.render(_cameraPosition); @@ -1038,10 +1028,12 @@ void Avatar::updateBodySprings(float deltaTime) { _joint[b].springyVelocity = glm::vec3(0.0f, 0.0f, 0.0f); } + /* //apply forces from touch... if (_joint[b].touchForce > 0.0) { _joint[b].springyVelocity += _mouseRayDirection * _joint[b].touchForce * 0.7f; } + */ //update position by velocity... _joint[b].springyPosition += _joint[b].springyVelocity * deltaTime; diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index f7dcb8853c..fc4b6d123b 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -15,6 +15,7 @@ #include #include "world.h" #include "AvatarTouch.h" +#include "AvatarRenderer.h" #include "InterfaceConfig.h" #include "SerialInterface.h" #include "Balls.h" diff --git a/interface/src/AvatarRenderer.cpp b/interface/src/AvatarRenderer.cpp index 45ce46084f..45c10c4441 100644 --- a/interface/src/AvatarRenderer.cpp +++ b/interface/src/AvatarRenderer.cpp @@ -10,54 +10,61 @@ #include "AvatarRenderer.h" #include "InterfaceConfig.h" +/* AvatarRenderer::AvatarRenderer() { } // this method renders the avatar -void AvatarRenderer::render(Avatar *avatarToRender, bool lookingInMirror, glm::vec3 cameraPosition) { +void AvatarRenderer::render() { - avatar = avatarToRender; - /* // show avatar position glColor4f(0.5f, 0.5f, 0.5f, 0.6); glPushMatrix(); - glm::vec3 j( avatar->getJointPosition( AVATAR_JOINT_PELVIS ) ); + glm::vec3 j( getJointPosition( AVATAR_JOINT_PELVIS ) ); glTranslatef(j.x, j.y, j.z); glScalef(0.08, 0.08, 0.08); glutSolidSphere(1, 10, 10); glPopMatrix(); - */ - //renderDiskShadow(avatar->getJointPosition( AVATAR_JOINT_PELVIS ), glm::vec3(0.0f, 1.0f, 0.0f), 0.1f, 0.2f); + renderDiskShadow(getJointPosition( AVATAR_JOINT_PELVIS ), glm::vec3(0.0f, 1.0f, 0.0f), 0.1f, 0.2f); - //renderBody(); + //renderBody(lookingInMirror); } - - - - - void AvatarRenderer::renderBody() { -/* // Render joint positions as spheres for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - if (b != AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case in "renderHead" + if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case + if (_displayingHead) { + _head.render(lookingInMirror); + } + } else { //show direction vectors of the bone orientation //renderOrientationDirections(_joint[b].springyPosition, _joint[b].orientation, _joint[b].radius * 2.0); - glm::vec3 j( avatar->getJointPosition( AVATAR_JOINT_PELVIS ) ); - glColor3fv(skinColor); + glColor3fv(_avatar->skinColor); glPushMatrix(); - glTranslatef(j.x, j.y, j.z); - glutSolidSphere(_joint[b].radius, 20.0f, 20.0f); + glTranslatef(_avatar->[b].springyPosition.x, _avatar->_joint[b].springyPosition.y, _avatar->_joint[b].springyPosition.z); + glutSolidSphere(_avatar->_joint[b].radius, 20.0f, 20.0f); + glPopMatrix(); + } + + if (_joint[b].touchForce > 0.0f) { + + float alpha = _joint[b].touchForce * 0.2; + float r = _joint[b].radius * 1.1f + 0.005f; + glColor4f(0.5f, 0.2f, 0.2f, alpha); + glPushMatrix(); + glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z); + glScalef(r, r, r); + glutSolidSphere(1, 20, 20); glPopMatrix(); } } - + // Render lines connecting the joint positions glColor3f(0.4f, 0.5f, 0.6f); glLineWidth(3.0); @@ -71,5 +78,6 @@ void AvatarRenderer::renderBody() { glEnd(); } } - */ } +*/ + diff --git a/interface/src/AvatarRenderer.h b/interface/src/AvatarRenderer.h index e0e9d7bbb3..36a4d58e0c 100644 --- a/interface/src/AvatarRenderer.h +++ b/interface/src/AvatarRenderer.h @@ -11,16 +11,17 @@ #include "Avatar.h" #include -class AvatarRenderer { +/* +class AvatarRenderer : public Avatar { public: AvatarRenderer(); - void render(Avatar *avatarToRender, bool lookingInMirror, glm::vec3 cameraPosition ); + void render(); private: - Avatar *avatar; void renderBody(); }; +*/ #endif From ffbc70814a37b116d76bb8d7e6a4251a731d2eb6 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 11:41:21 -0700 Subject: [PATCH 04/23] preparing to add transmitted lookat position data --- interface/src/Avatar.cpp | 9 ++++++--- libraries/avatars/src/AvatarData.cpp | 8 ++++++++ libraries/avatars/src/AvatarData.h | 7 +++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 1eb252dcb5..6b34f50e67 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -396,14 +396,17 @@ void Avatar::simulate(float deltaTime) { _head.setBodyYaw(_bodyYaw); - //the following is still being prototyped (making the eyes look at a specific location), it should be finished by 5/20/13 if (_interactingOther) { _head.setLooking(true); - _head.setLookatPosition(_interactingOther->getSpringyHeadPosition()); + + if (_isMine) { + setLookatPosition(_interactingOther->getSpringyHeadPosition()); + } } else { _head.setLooking(false); } - + + _head.setLookatPosition(_lookatPosition); _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); _head.simulate(deltaTime, _isMine); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 2e11e8aa84..85b3fde0e6 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -63,6 +63,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // Hand Position memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3; + + // Lookat Position + memcpy(destinationBuffer, &_lookatPosition, sizeof(float) * 3); + destinationBuffer += sizeof(float) * 3; // Hand State (0 = not grabbing, 1 = grabbing) memcpy(destinationBuffer, &_handState, sizeof(char)); @@ -146,6 +150,10 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3); sourceBuffer += sizeof(float) * 3; + // Lookat Position + memcpy(&_lookatPosition, sourceBuffer, sizeof(float) * 3); + sourceBuffer += sizeof(float) * 3; + // Hand State memcpy(&_handState, sourceBuffer, sizeof(char)); sourceBuffer += sizeof(char); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index f37c4f3396..fdb3c89251 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -30,6 +30,7 @@ class AvatarData : public AgentData { public: AvatarData() : _handPosition(0,0,0), + _lookatPosition(0,0,0), _bodyYaw(-90.0), _bodyPitch(0.0), _bodyRoll(0.0), @@ -53,9 +54,10 @@ public: _wantColor(true) { }; const glm::vec3& getPosition() const { return _position; } - void setPosition(const glm::vec3 position) { _position = position; } - void setHandPosition(const glm::vec3 handPosition) { _handPosition = handPosition; } + void setPosition (const glm::vec3 position ) { _position = position; } + void setHandPosition (const glm::vec3 handPosition ) { _handPosition = handPosition; } + void setLookatPosition(const glm::vec3 lookatPosition) { _lookatPosition = lookatPosition; } int getBroadcastData(unsigned char* destinationBuffer); int parseData(unsigned char* sourceBuffer, int numBytes); @@ -138,6 +140,7 @@ protected: glm::vec3 _position; glm::vec3 _handPosition; + glm::vec3 _lookatPosition; // Body rotation float _bodyYaw; From 570d2e104a46f7adb60514e447d673a921904951 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 11:53:42 -0700 Subject: [PATCH 05/23] test --- libraries/avatars/src/AvatarData.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 85b3fde0e6..1cc927aeb1 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -65,8 +65,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += sizeof(float) * 3; // Lookat Position - memcpy(destinationBuffer, &_lookatPosition, sizeof(float) * 3); - destinationBuffer += sizeof(float) * 3; + //memcpy(destinationBuffer, &_lookatPosition, sizeof(float) * 3); + //destinationBuffer += sizeof(float) * 3; // Hand State (0 = not grabbing, 1 = grabbing) memcpy(destinationBuffer, &_handState, sizeof(char)); @@ -151,8 +151,8 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(float) * 3; // Lookat Position - memcpy(&_lookatPosition, sourceBuffer, sizeof(float) * 3); - sourceBuffer += sizeof(float) * 3; + //memcpy(&_lookatPosition, sourceBuffer, sizeof(float) * 3); + //sourceBuffer += sizeof(float) * 3; // Hand State memcpy(&_handState, sourceBuffer, sizeof(char)); From 4e6b2f9c501499ff6989b5cf4500033bd0290825 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 11:55:55 -0700 Subject: [PATCH 06/23] test --- libraries/avatars/src/AvatarData.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 1cc927aeb1..85b3fde0e6 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -65,8 +65,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += sizeof(float) * 3; // Lookat Position - //memcpy(destinationBuffer, &_lookatPosition, sizeof(float) * 3); - //destinationBuffer += sizeof(float) * 3; + memcpy(destinationBuffer, &_lookatPosition, sizeof(float) * 3); + destinationBuffer += sizeof(float) * 3; // Hand State (0 = not grabbing, 1 = grabbing) memcpy(destinationBuffer, &_handState, sizeof(char)); @@ -151,8 +151,8 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(float) * 3; // Lookat Position - //memcpy(&_lookatPosition, sourceBuffer, sizeof(float) * 3); - //sourceBuffer += sizeof(float) * 3; + memcpy(&_lookatPosition, sourceBuffer, sizeof(float) * 3); + sourceBuffer += sizeof(float) * 3; // Hand State memcpy(&_handState, sourceBuffer, sizeof(char)); From d384e36af1b0530ad13504158222c070767f20e1 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 11:59:19 -0700 Subject: [PATCH 07/23] test --- interface/src/Avatar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 6b34f50e67..e5c758c29f 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -396,6 +396,8 @@ void Avatar::simulate(float deltaTime) { _head.setBodyYaw(_bodyYaw); +setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); + if (_interactingOther) { _head.setLooking(true); @@ -406,6 +408,7 @@ void Avatar::simulate(float deltaTime) { _head.setLooking(false); } + _head.setLookatPosition(_lookatPosition); _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); From 85dc14bb94d995206f7c8cb7eee7bf3245e5ebeb Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 20 May 2013 12:01:33 -0700 Subject: [PATCH 08/23] Drag support for adding/removing (as well as coloring) voxels. I had to ensure that the "last" voxel edited was the one under the cursor after the operation, not the one operated on. --- interface/src/Application.cpp | 51 +++++++++++++++++++++-------------- interface/src/Application.h | 3 ++- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7974b2bdf8..f5f0970394 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -138,6 +138,7 @@ Application::Application(int& argc, char** argv) : _mouseY(0), _mousePressed(false), _mouseVoxelScale(1.0f / 1024.0f), + _justEditedVoxel(false), _paintOn(false), _dominantColor(0), _perfStatsOn(false), @@ -737,8 +738,13 @@ void Application::mouseMoveEvent(QMouseEvent* event) { // detect drag glm::vec3 mouseVoxelPos(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); - if (_colorVoxelMode->isChecked() && event->buttons().testFlag(Qt::LeftButton) && mouseVoxelPos != _lastMouseVoxelPos) { - addVoxelUnderCursor(); + if (!_justEditedVoxel && mouseVoxelPos != _lastMouseVoxelPos) { + if (event->buttons().testFlag(Qt::LeftButton)) { + maybeEditVoxelUnderCursor(); + + } else if (event->buttons().testFlag(Qt::RightButton) && checkedVoxelModeAction() != 0) { + deleteVoxelUnderCursor(); + } } } @@ -747,13 +753,8 @@ void Application::mousePressEvent(QMouseEvent* event) { _mouseX = event->x(); _mouseY = event->y(); _mousePressed = true; - - if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) { - addVoxelUnderCursor(); + maybeEditVoxelUnderCursor(); - } else if (_deleteVoxelMode->isChecked()) { - deleteVoxelUnderCursor(); - } } else if (event->button() == Qt::RightButton && checkedVoxelModeAction() != 0) { deleteVoxelUnderCursor(); } @@ -926,6 +927,12 @@ void Application::idle() { _mouseVoxel.green = paintColor.green(); _mouseVoxel.blue = paintColor.blue(); } + + // if we just edited, use the currently selected voxel as the "last" for drag detection + if (_justEditedVoxel) { + _lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); + _justEditedVoxel = false; + } } // walking triggers the handControl to stop @@ -2015,18 +2022,22 @@ void Application::shiftPaintingColor() { _paintingVoxel.blue = (_dominantColor == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100); } -void Application::addVoxelUnderCursor() { - if (_mouseVoxel.s != 0) { - PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ? - PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); - sendVoxelEditMessage(message, _mouseVoxel); +void Application::maybeEditVoxelUnderCursor() { + if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) { + if (_mouseVoxel.s != 0) { + PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ? + PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); + sendVoxelEditMessage(message, _mouseVoxel); + + // create the voxel locally so it appears immediately + _voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s, + _mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel->isChecked()); - // create the voxel locally so it appears immediately - _voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s, - _mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel->isChecked()); - - // remember the position for drag detection - _lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); + // remember the position for drag detection + _justEditedVoxel = true; + } + } else if (_deleteVoxelMode->isChecked()) { + deleteVoxelUnderCursor(); } } @@ -2038,7 +2049,7 @@ void Application::deleteVoxelUnderCursor() { _voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); // remember the position for drag detection - _lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); + _justEditedVoxel = true; } } diff --git a/interface/src/Application.h b/interface/src/Application.h index da3898ab9f..87ea615ad8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -116,7 +116,7 @@ private: void setupPaintingVoxel(); void shiftPaintingColor(); - void addVoxelUnderCursor(); + void maybeEditVoxelUnderCursor(); void deleteVoxelUnderCursor(); void resetSensors(); @@ -202,6 +202,7 @@ private: VoxelDetail _mouseVoxel; // details of the voxel under the mouse cursor float _mouseVoxelScale; // the scale for adding/removing voxels glm::vec3 _lastMouseVoxelPos; // the position of the last mouse voxel edit + bool _justEditedVoxel; // set when we've just added/deleted/colored a voxel bool _paintOn; // Whether to paint voxels as you fly around unsigned char _dominantColor; // The dominant color of the voxel we're painting From a192a21ef06a83817889d90a31ffd2fe481b465a Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 12:08:58 -0700 Subject: [PATCH 09/23] added _lookatPosition to avatar Data --- interface/src/Avatar.cpp | 1 + libraries/avatars/src/AvatarData.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index e5c758c29f..71c2c1d1ab 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -396,6 +396,7 @@ void Avatar::simulate(float deltaTime) { _head.setBodyYaw(_bodyYaw); +//test setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); if (_interactingOther) { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 85b3fde0e6..57955a1f5e 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -65,8 +65,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += sizeof(float) * 3; // Lookat Position - memcpy(destinationBuffer, &_lookatPosition, sizeof(float) * 3); - destinationBuffer += sizeof(float) * 3; + memcpy(destinationBuffer, &_lookatPosition, sizeof(_lookatPosition)); + destinationBuffer += sizeof(_lookatPosition); // Hand State (0 = not grabbing, 1 = grabbing) memcpy(destinationBuffer, &_handState, sizeof(char)); @@ -151,8 +151,8 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(float) * 3; // Lookat Position - memcpy(&_lookatPosition, sourceBuffer, sizeof(float) * 3); - sourceBuffer += sizeof(float) * 3; + memcpy(&_lookatPosition, sourceBuffer, sizeof(_lookatPosition)); + sourceBuffer += sizeof(_lookatPosition); // Hand State memcpy(&_handState, sourceBuffer, sizeof(char)); From f09cbca00b62d4512fd7a1a6ed10b61acaab801b Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 12:12:46 -0700 Subject: [PATCH 10/23] cleanup --- interface/src/Application.cpp | 1 - interface/src/Application.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c822038e87..dda6095c75 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1710,7 +1710,6 @@ void Application::displaySide(Camera& whichCamera) { // Render my own Avatar _myAvatar.render(_lookingInMirror, _myCamera.getPosition()); - //_avatarRenderer.render(); } // Render the world box diff --git a/interface/src/Application.h b/interface/src/Application.h index e4849ae14f..3818850e13 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -187,8 +187,6 @@ private: Avatar _myAvatar; // The rendered avatar of oneself - //AvatarRenderer _avatarRenderer; - Camera _myCamera; // My view onto the world Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode From 3f0fd2f9766bff7efc67059a23b5f4e81b8461a7 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 20 May 2013 12:13:23 -0700 Subject: [PATCH 11/23] Added toggle for voxel textures; they may be slowing some machines down. --- interface/src/Application.cpp | 4 +++- interface/src/Application.h | 1 + interface/src/VoxelSystem.cpp | 18 +++++++++++------- interface/src/VoxelSystem.h | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f5f0970394..119fd0f509 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1204,6 +1204,8 @@ void Application::initMenu() { (_renderVoxels = renderMenu->addAction("Voxels"))->setCheckable(true); _renderVoxels->setChecked(true); _renderVoxels->setShortcut(Qt::Key_V); + (_renderVoxelTextures = renderMenu->addAction("Voxel Textures"))->setCheckable(true); + _renderVoxelTextures->setChecked(true); (_renderStarsOn = renderMenu->addAction("Stars"))->setCheckable(true); _renderStarsOn->setChecked(true); _renderStarsOn->setShortcut(Qt::Key_Asterisk); @@ -1680,7 +1682,7 @@ void Application::displaySide(Camera& whichCamera) { // Draw voxels if (_renderVoxels->isChecked()) { - _voxels.render(); + _voxels.render(_renderVoxelTextures->isChecked()); } // indicate what we'll be adding/removing in mouse mode, if anything diff --git a/interface/src/Application.h b/interface/src/Application.h index 87ea615ad8..713b50e4ef 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -134,6 +134,7 @@ private: QAction* _lookingInMirror; // Are we currently rendering one's own head as if in mirror? QAction* _gyroLook; // Whether to allow the gyro data from head to move your view QAction* _renderVoxels; // Whether to render voxels + QAction* _renderVoxelTextures; // Whether to render noise textures on voxels QAction* _renderStarsOn; // Whether to display the stars QAction* _renderAtmosphereOn; // Whether to display the atmosphere QAction* _renderAvatarsOn; // Whether to render avatars diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index d578bb3504..914d4b630a 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -617,7 +617,7 @@ void VoxelSystem::updateVBOs() { _callsToTreesToArrays = 0; // clear it } -void VoxelSystem::render() { +void VoxelSystem::render(bool texture) { PerformanceWarning warn(_renderWarningsOn, "render()"); glPushMatrix(); updateVBOs(); @@ -635,9 +635,11 @@ void VoxelSystem::render() { glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); - _perlinModulateProgram->bind(); - glBindTexture(GL_TEXTURE_2D, _permutationNormalTextureID); - + if (texture) { + _perlinModulateProgram->bind(); + glBindTexture(GL_TEXTURE_2D, _permutationNormalTextureID); + } + // for performance, disable blending and enable backface culling glDisable(GL_BLEND); glEnable(GL_CULL_FACE); @@ -650,9 +652,11 @@ void VoxelSystem::render() { glEnable(GL_BLEND); glDisable(GL_CULL_FACE); - _perlinModulateProgram->release(); - glBindTexture(GL_TEXTURE_2D, 0); - + if (texture) { + _perlinModulateProgram->release(); + glBindTexture(GL_TEXTURE_2D, 0); + } + // deactivate vertex and color arrays after drawing glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 2d6d9717f6..d9dd844657 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -36,7 +36,7 @@ public: void init(); void simulate(float deltaTime) { }; - void render(); + void render(bool texture); unsigned long getVoxelsUpdated() const {return _voxelsUpdated;}; unsigned long getVoxelsRendered() const {return _voxelsInReadArrays;}; From 1e9b04d28fb6c22477a7269df2caf8253f1f6a39 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 12:16:18 -0700 Subject: [PATCH 12/23] cleanup --- interface/src/Avatar.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index ef77fea9fd..d7dbfbada8 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -394,10 +394,7 @@ void Avatar::simulate(float deltaTime) { _joint[ AVATAR_JOINT_HEAD_BASE ].radius ); - _head.setBodyYaw(_bodyYaw); - -//test -setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); + setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 if (_interactingOther) { _head.setLooking(true); @@ -409,7 +406,7 @@ setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); _head.setLooking(false); } - + _head.setBodyYaw(_bodyYaw); _head.setLookatPosition(_lookatPosition); _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); From d144fb7f8418a2ecbfdd2dbc5917dbc7a8e5b16d Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 14:34:39 -0700 Subject: [PATCH 13/23] fix --- interface/src/Avatar.cpp | 70 ++++++++++++++++++++++++++++++++++++---- interface/src/Avatar.h | 1 + 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index d7dbfbada8..befedcf524 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -50,8 +50,9 @@ const float PERIPERSONAL_RADIUS = 1.0f; const float AVATAR_BRAKING_STRENGTH = 40.0f; const float JOINT_TOUCH_RANGE = 0.0005f; -float skinColor [] = {1.0, 0.84, 0.66}; -float lightBlue [] = {0.7, 0.8, 1.0}; +float skinColor [] = {1.0, 0.84, 0.66}; +float darkSkinColor[] = {0.8, 0.74, 0.6 }; +float lightBlue [] = {0.7, 0.8, 1.0 }; bool usingBigSphereCollisionTest = true; @@ -1128,14 +1129,27 @@ void Avatar::renderBody(bool lookingInMirror) { glPopMatrix(); } } - - // Render lines connecting the joint positions - glColor3f(0.4f, 0.5f, 0.6f); - glLineWidth(3.0); for (int b = 1; b < NUM_AVATAR_JOINTS; b++) { if (_joint[b].parent != AVATAR_JOINT_NULL) if (b != AVATAR_JOINT_HEAD_TOP) { + + /* + // Render cone sections connecting the joint positions + glColor3fv(darkSkinColor); + renderJointConnectingCone + ( + _joint[_joint[b].parent ].springyPosition, + _joint[b ].springyPosition, + _joint[_joint[b].parent ].radius, + _joint[b ].radius + ); + */ + + + // Render lines connecting the joint positions + glColor3f(0.4f, 0.5f, 0.6f); + glLineWidth(3.0); glBegin(GL_LINE_STRIP); glVertex3fv(&_joint[ _joint[ b ].parent ].springyPosition.x); glVertex3fv(&_joint[ b ].springyPosition.x); @@ -1373,3 +1387,47 @@ void Avatar::readAvatarDataFromFile() { fclose(avatarFile); } } + +void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2) { + + glBegin(GL_TRIANGLES); + + int num = 5; + + glm::vec3 axis = glm::normalize(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); + + for (int i = 0; i < num; i ++) { + + float angle1 = ((float)i / (float)num) * PI * 2.0; + float angle2 = ((float)(i+1) / (float)num) * PI * 2.0; + + glm::vec3 p1a = position1 + perpSin * sin(angle1) * radius1; + glm::vec3 p1b = position1 + perpCos * cos(angle2) * radius1; + + glm::vec3 p2a = position2 + perpSin * sin(angle1) * radius2; + glm::vec3 p2b = position2 + perpCos * cos(angle2) * radius2; + + glVertex3f(p1a.x, p1a.y, p1a.z); + glVertex3f(p1b.x, p1b.y, p1b.z); + glVertex3f(p2a.x, p2a.y, p2a.z); + + /* + glVertex3f(p1b.x, p1b.y, p1b.z); + glVertex3f(p2a.x, p2a.y, p2a.z); + glVertex3f(p2b.x, p2b.y, p2b.z); + */ + } + } + + glEnd(); +} + + + + diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index fc4b6d123b..61fda4edda 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -218,6 +218,7 @@ private: void applyCollisionWithOtherAvatar( Avatar * other, float deltaTime ); void setHeadFromGyros(glm::vec3 * eulerAngles, glm::vec3 * angularVelocity, float deltaTime, float smoothingTime); void checkForMouseRayTouching(); + void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2); }; #endif From 44ef5d4bacb3e2d725c9eb01030eab2f959c0cce Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 14:37:09 -0700 Subject: [PATCH 14/23] fix --- libraries/avatars/src/AvatarData.cpp | 1 + libraries/avatars/src/AvatarData.h | 27 +-------------------------- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 4dc5d80086..56218c61ad 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -35,6 +35,7 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo AvatarData::AvatarData() : _handPosition(0,0,0), + _lookatPosition(0,0,0), _bodyYaw(-90.0), _bodyPitch(0.0), _bodyRoll(0.0), diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 5b5c2980df..2c676d6120 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -28,32 +28,7 @@ enum KeyState class AvatarData : public AgentData { public: - AvatarData() : - _handPosition(0,0,0), - _lookatPosition(0,0,0), - _bodyYaw(-90.0), - _bodyPitch(0.0), - _bodyRoll(0.0), - _headYaw(0), - _headPitch(0), - _headRoll(0), - _headLeanSideways(0), - _headLeanForward(0), - _audioLoudness(0), - _handState(0), - _cameraPosition(0,0,0), - _cameraDirection(0,0,0), - _cameraUp(0,0,0), - _cameraRight(0,0,0), - _cameraFov(0.0f), - _cameraAspectRatio(0.0f), - _cameraNearClip(0.0f), - _cameraFarClip(0.0f), - _keyState(NO_KEY_DOWN), - _wantResIn(false), - _wantColor(true), - _wantDelta(false) - { }; + AvatarData(); const glm::vec3& getPosition() const { return _position; } From 8d522cd3edad7c69894581ac73ba1acc1b67777d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 20 May 2013 15:15:44 -0700 Subject: [PATCH 15/23] I believe the problem with voxel rendering is caused by the update thread's writing the data while the render thread is attempting to read it. This should fix the issue. --- interface/src/VoxelSystem.cpp | 79 ++++++++++++++++++++--------------- interface/src/VoxelSystem.h | 6 ++- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 914d4b630a..01e7a9940f 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -46,7 +46,8 @@ GLubyte identityIndices[] = { 0,2,1, 0,3,2, // Z- . VoxelSystem::VoxelSystem() { _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; - _renderFullVBO = true; + _writeRenderFullVBO = true; + _readRenderFullVBO = true; _tree = new VoxelTree(); pthread_mutex_init(&_bufferWriteLock, NULL); pthread_mutex_init(&_treeLock, NULL); @@ -57,7 +58,8 @@ VoxelSystem::~VoxelSystem() { delete[] _writeVerticesArray; delete[] _readColorsArray; delete[] _writeColorsArray; - delete[] _voxelDirtyArray; + delete[] _writeVoxelDirtyArray; + delete[] _readVoxelDirtyArray; delete _tree; pthread_mutex_destroy(&_bufferWriteLock); pthread_mutex_destroy(&_treeLock); @@ -183,11 +185,11 @@ void VoxelSystem::setupNewVoxelsForDrawing() { if (_tree->isDirty()) { static char buffer[64] = { 0 }; if (_renderWarningsOn) { - sprintf(buffer, "newTreeToArrays() _renderFullVBO=%s", (_renderFullVBO ? "yes" : "no")); + sprintf(buffer, "newTreeToArrays() _writeRenderFullVBO=%s", (_writeRenderFullVBO ? "yes" : "no")); }; PerformanceWarning warn(_renderWarningsOn, buffer); _callsToTreesToArrays++; - if (_renderFullVBO) { + if (_writeRenderFullVBO) { _voxelsInWriteArrays = 0; // reset our VBO } _voxelsUpdated = newTreeToArrays(_tree->rootNode); @@ -195,10 +197,14 @@ void VoxelSystem::setupNewVoxelsForDrawing() { // since we called treeToArrays, we can assume that our VBO is in sync, and so partial updates to the VBOs are // ok again, until/unless we call removeOutOfView() - _renderFullVBO = false; + _writeRenderFullVBO = false; } else { _voxelsUpdated = 0; } + + // lock on the buffer write lock so we can't modify the data when the GPU is reading it + pthread_mutex_lock(&_bufferWriteLock); + if (_voxelsUpdated) { _voxelsDirty=true; } @@ -206,6 +212,8 @@ void VoxelSystem::setupNewVoxelsForDrawing() { // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated copyWrittenDataToReadArrays(); + pthread_mutex_unlock(&_bufferWriteLock); + double end = usecTimestampNow(); double elapsedmsec = (end - start) / 1000.0; _setupNewVoxelsForDrawingLastFinished = end; @@ -218,30 +226,25 @@ void VoxelSystem::cleanupRemovedVoxels() { while (!_removedVoxels.isEmpty()) { delete _removedVoxels.extract(); } - _renderFullVBO = true; // if we remove voxels, we must update our full VBOs + _writeRenderFullVBO = true; // if we remove voxels, we must update our full VBOs } } void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() { - // lock on the buffer write lock so we can't modify the data when the GPU is reading it - pthread_mutex_lock(&_bufferWriteLock); int bytesOfVertices = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat); int bytesOfColors = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte); memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices); memcpy(_readColorsArray, _writeColorsArray, bytesOfColors ); _voxelsInReadArrays = _voxelsInWriteArrays; - pthread_mutex_unlock(&_bufferWriteLock); } void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { - // lock on the buffer write lock so we can't modify the data when the GPU is reading it - pthread_mutex_lock(&_bufferWriteLock); - glBufferIndex segmentStart = 0; glBufferIndex segmentEnd = 0; bool inSegment = false; for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { - bool thisVoxelDirty = _voxelDirtyArray[i]; + bool thisVoxelDirty = _writeVoxelDirtyArray[i]; + _readVoxelDirtyArray[i] |= thisVoxelDirty; if (!inSegment) { if (thisVoxelDirty) { segmentStart = i; @@ -290,14 +293,15 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { // update our length _voxelsInReadArrays = _voxelsInWriteArrays; - - pthread_mutex_unlock(&_bufferWriteLock); + + // clear our dirty flags + memset(_writeVoxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool)); } void VoxelSystem::copyWrittenDataToReadArrays() { PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); if (_voxelsDirty && _voxelsUpdated) { - if (_renderFullVBO) { + if (_readRenderFullVBO) { copyWrittenDataToReadArraysFullVBOs(); } else { copyWrittenDataToReadArraysPartialVBOs(); @@ -327,7 +331,7 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) { } } } - if (_renderFullVBO) { + if (_writeRenderFullVBO) { voxelsUpdated += updateNodeInArraysAsFullVBO(node); } else { voxelsUpdated += updateNodeInArraysAsPartialVBO(node); @@ -365,7 +369,7 @@ int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) { *(writeColorsAt +j) = node->getColor()[j % 3]; } node->setBufferIndex(nodeIndex); - _voxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode + _writeVoxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode _voxelsInWriteArrays++; // our know vertices in the arrays return 1; // rendered } @@ -402,7 +406,7 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { node->setBufferIndex(nodeIndex); _voxelsInWriteArrays++; } - _voxelDirtyArray[nodeIndex] = true; + _writeVoxelDirtyArray[nodeIndex] = true; // populate the array with points for the 8 vertices // and RGB color for each added vertex @@ -431,9 +435,11 @@ void VoxelSystem::init() { _voxelsInReadArrays = 0; _unusedArraySpace = 0; - // we will track individual dirty sections with this array of bools - _voxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM]; - memset(_voxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); + // we will track individual dirty sections with these arrays of bools + _writeVoxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM]; + memset(_writeVoxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); + _readVoxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM]; + memset(_readVoxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); // prep the data structures for incoming voxel data _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; @@ -530,7 +536,7 @@ void VoxelSystem::init() { void VoxelSystem::updateFullVBOs() { glBufferIndex segmentStart = 0; - glBufferIndex segmentEnd = _voxelsInWriteArrays; + glBufferIndex segmentEnd = _voxelsInReadArrays; int segmentLength = (segmentEnd - segmentStart) + 1; GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); @@ -544,21 +550,21 @@ void VoxelSystem::updateFullVBOs() { glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); - // consider the _voxelDirtyArray[] clean! - memset(_voxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool)); + // consider the _readVoxelDirtyArray[] clean! + memset(_readVoxelDirtyArray, false, _voxelsInReadArrays * sizeof(bool)); } void VoxelSystem::updatePartialVBOs() { glBufferIndex segmentStart = 0; glBufferIndex segmentEnd = 0; bool inSegment = false; - for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { - bool thisVoxelDirty = _voxelDirtyArray[i]; + for (glBufferIndex i = 0; i < _voxelsInReadArrays; i++) { + bool thisVoxelDirty = _readVoxelDirtyArray[i]; if (!inSegment) { if (thisVoxelDirty) { segmentStart = i; inSegment = true; - _voxelDirtyArray[i] = false; // consider us clean! + _readVoxelDirtyArray[i] = false; // consider us clean! } } else { if (!thisVoxelDirty) { @@ -578,13 +584,13 @@ void VoxelSystem::updatePartialVBOs() { glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); } - _voxelDirtyArray[i] = false; // consider us clean! + _readVoxelDirtyArray[i] = false; // consider us clean! } } // if we got to the end of the array, and we're in an active dirty segment... if (inSegment) { - segmentEnd = _voxelsInWriteArrays - 1; + segmentEnd = _voxelsInReadArrays - 1; inSegment = false; int segmentLength = (segmentEnd - segmentStart) + 1; GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); @@ -603,22 +609,27 @@ void VoxelSystem::updatePartialVBOs() { void VoxelSystem::updateVBOs() { static char buffer[40] = { 0 }; if (_renderWarningsOn) { - sprintf(buffer, "updateVBOs() _renderFullVBO=%s", (_renderFullVBO ? "yes" : "no")); + sprintf(buffer, "updateVBOs() _readRenderFullVBO=%s", (_readRenderFullVBO ? "yes" : "no")); }; PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays if (_voxelsDirty) { - if (_renderFullVBO) { + if (_readRenderFullVBO) { updateFullVBOs(); } else { updatePartialVBOs(); } _voxelsDirty = false; + _readRenderFullVBO = false; } _callsToTreesToArrays = 0; // clear it } void VoxelSystem::render(bool texture) { PerformanceWarning warn(_renderWarningsOn, "render()"); + + // get the lock so that the update thread won't change anything + pthread_mutex_lock(&_bufferWriteLock); + glPushMatrix(); updateVBOs(); // tell OpenGL where to find vertex and color information @@ -668,6 +679,8 @@ void VoxelSystem::render(bool texture) { // scale back down to 1 so heads aren't massive glPopMatrix(); + + pthread_mutex_unlock(&_bufferWriteLock); } int VoxelSystem::_nodeCount = 0; @@ -1016,7 +1029,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { glBufferIndex maxDirty = 0; for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { - if (_voxelDirtyArray[i]) { + if (_writeVoxelDirtyArray[i]) { minDirty = std::min(minDirty,i); maxDirty = std::max(maxDirty,i); } diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index d9dd844657..0e955c90a5 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -118,13 +118,15 @@ private: GLubyte* _readColorsArray; GLfloat* _writeVerticesArray; GLubyte* _writeColorsArray; - bool* _voxelDirtyArray; + bool* _writeVoxelDirtyArray; + bool* _readVoxelDirtyArray; unsigned long _voxelsUpdated; unsigned long _voxelsInWriteArrays; unsigned long _voxelsInReadArrays; unsigned long _unusedArraySpace; - bool _renderFullVBO; + bool _writeRenderFullVBO; + bool _readRenderFullVBO; double _setupNewVoxelsForDrawingLastElapsed; double _setupNewVoxelsForDrawingLastFinished; From 257a1d1f2e0013c50bb3a47a3a9e638ba6aa7380 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 May 2013 15:21:02 -0700 Subject: [PATCH 16/23] move head rotations to new HeadData class to be used for transmission --- interface/src/Application.cpp | 11 +++--- interface/src/Avatar.cpp | 54 +++++++++++++--------------- interface/src/Avatar.h | 1 + interface/src/Head.cpp | 12 ++----- interface/src/Head.h | 7 ++-- libraries/avatars/src/AvatarData.cpp | 37 +++++++++---------- libraries/avatars/src/AvatarData.h | 24 ++++--------- libraries/avatars/src/HeadData.cpp | 53 +++++++++++++++++++++++++++ libraries/avatars/src/HeadData.h | 36 +++++++++++++++++++ 9 files changed, 151 insertions(+), 84 deletions(-) create mode 100644 libraries/avatars/src/HeadData.cpp create mode 100644 libraries/avatars/src/HeadData.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a3e91e023b..7c577589f9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -297,8 +297,9 @@ void Application::paintGL() { _myCamera.setDistance (0.0f); _myCamera.setTightness (100.0f); _myCamera.setTargetPosition(_myAvatar.getHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getBodyYaw() + _myAvatar.getHeadYaw(), - -_myAvatar.getHeadPitch(), _myAvatar.getHeadRoll()); + _myCamera.setTargetRotation(_myAvatar.getBodyYaw() + _myAvatar.getHead().getYaw(), + -_myAvatar.getHead().getPitch(), + _myAvatar.getHead().getRoll()); } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myCamera.setTightness (100.0f); @@ -1375,9 +1376,9 @@ void Application::updateAvatar(float deltaTime) { float yaw, pitch, roll; OculusManager::getEulerAngles(yaw, pitch, roll); - _myAvatar.setHeadYaw(-yaw); - _myAvatar.setHeadPitch(pitch); - _myAvatar.setHeadRoll(roll); + _myAvatar.getHead().setYaw(-yaw); + _myAvatar.getHead().setPitch(pitch); + _myAvatar.getHead().setRoll(roll); } // Get audio loudness data from audio input device diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index befedcf524..589c99e462 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -59,8 +59,11 @@ bool usingBigSphereCollisionTest = true; float chatMessageScale = 0.0015; float chatMessageHeight = 0.45; - -Avatar::Avatar(bool isMine) { +Avatar::Avatar(bool isMine) : _head() { + + // give the pointer to our head to inherited _headData variable from AvatarData + _headData = &_head; + _orientation.setToIdentity(); _velocity = glm::vec3(0.0f, 0.0f, 0.0f); @@ -109,7 +112,9 @@ Avatar::Avatar(bool isMine) { } void Avatar::reset() { - _headPitch = _headYaw = _headRoll = 0; + _head.setYaw(0.0f); + _head.setRoll(0.0f); + _head.setPitch(0.0f); _head.leanForward = _head.leanSideways = 0; } @@ -124,23 +129,16 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa measuredRollRate = serialInterface->getLastRollRate(); // Update avatar head position based on measured gyro rates - const float MAX_YAW = 85; - const float MIN_YAW = -85; - const float MAX_ROLL = 50; - const float MIN_ROLL = -50; - addHeadPitch(measuredPitchRate * deltaTime); - addHeadYaw(measuredYawRate * deltaTime); - addHeadRoll(measuredRollRate * deltaTime); - - setHeadYaw(glm::clamp(getHeadYaw(), MIN_YAW, MAX_YAW)); - setHeadRoll(glm::clamp(getHeadRoll(), MIN_ROLL, MAX_ROLL)); + _head.addPitch(measuredPitchRate * deltaTime); + _head.addYaw(measuredYawRate * deltaTime); + _head.addRoll(measuredRollRate * deltaTime); // Update head lean distance based on accelerometer data const float LEAN_SENSITIVITY = 0.15; const float LEAN_MAX = 0.45; const float LEAN_AVERAGING = 10.0; - glm::vec3 headRotationRates(getHeadPitch(), getHeadYaw(), getHeadRoll()); + glm::vec3 headRotationRates(_head.getPitch(), _head.getYaw(), _head.getRoll()); float headRateMax = 50.f; @@ -159,11 +157,11 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa } float Avatar::getAbsoluteHeadYaw() const { - return _bodyYaw + _headYaw; + return _bodyYaw + _head.getYaw(); } float Avatar::getAbsoluteHeadPitch() const { - return _bodyPitch + _headPitch; + return _bodyPitch + _head.getPitch(); } void Avatar::addLean(float x, float z) { @@ -221,7 +219,7 @@ void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int scree if (fabs(mouseLocationY) > MOUSE_MOVE_RADIUS) { float mousePitchAdd = (fabs(mouseLocationY) - MOUSE_MOVE_RADIUS) / (0.5f - MOUSE_MOVE_RADIUS) * MOUSE_PITCH_SPEED; bool downPitching = (mouseLocationY > 0.f); - setHeadPitch(getHeadPitch() + (downPitching ? mousePitchAdd : -mousePitchAdd)); + _head.setPitch(_head.getPitch() + (downPitching ? mousePitchAdd : -mousePitchAdd)); } } @@ -354,7 +352,7 @@ void Avatar::simulate(float deltaTime) { // 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. if (!OculusManager::isConnected()) { - setHeadPitch(getHeadPitch() * (1.f - acceleration * ACCELERATION_PITCH_DECAY * deltaTime)); + _head.setPitch(_head.getPitch() * (1.f - acceleration * ACCELERATION_PITCH_DECAY * deltaTime)); } // Get head position data from network for other people @@ -389,11 +387,7 @@ void Avatar::simulate(float deltaTime) { } // update head state - _head.setPositionRotationAndScale( - _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition, - glm::vec3(_headYaw, _headPitch, _headRoll), - _joint[ AVATAR_JOINT_HEAD_BASE ].radius - ); + _head.setPositionAndScale(_joint[AVATAR_JOINT_HEAD_BASE].springyPosition, _joint[AVATAR_JOINT_HEAD_BASE].radius); setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 @@ -1343,18 +1337,18 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity if (deltaTime == 0.f) { // On first sample, set head to absolute position - setHeadYaw(eulerAngles->x); - setHeadPitch(eulerAngles->y); - setHeadRoll(eulerAngles->z); + _head.setYaw(eulerAngles->x); + _head.setPitch(eulerAngles->y); + _head.setRoll(eulerAngles->z); } else { - glm::vec3 angles(getHeadYaw(), getHeadPitch(), getHeadRoll()); + glm::vec3 angles(_head.getYaw(), _head.getPitch(), _head.getRoll()); // Increment by detected velocity angles += (*angularVelocity) * deltaTime; // Smooth to slowly follow absolute values angles = ((1.f - deltaTime / smoothingTime) * angles) + (deltaTime / smoothingTime) * (*eulerAngles); - setHeadYaw(fmin(fmax(angles.x, MIN_YAW), MAX_YAW)); - setHeadPitch(fmin(fmax(angles.y, MIN_PITCH), MAX_PITCH)); - setHeadRoll(fmin(fmax(angles.z, MIN_ROLL), MAX_ROLL)); + _head.setYaw(angles.x); + _head.setPitch(angles.y); + _head.setRoll(angles.z); //printLog("Y/P/R: %3.1f, %3.1f, %3.1f\n", angles.x, angles.y, angles.z); } } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 61fda4edda..3845b9cb60 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -106,6 +106,7 @@ public: float getHeight() const { return _height; } AvatarMode getMode() const { return _mode; } + Head getHead() const { return _head; } void setMousePressed(bool pressed); void render(bool lookingInMirror, glm::vec3 cameraPosition); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 3b751651b2..587e6279af 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -46,9 +46,6 @@ Head::Head() : _position(0.0f, 0.0f, 0.0f), _rotation(0.0f, 0.0f, 0.0f), _lookatPosition(0.0f, 0.0f, 0.0f), - _yaw(0.0f), - _pitch(0.0f), - _roll(0.0f), _eyeballPitch(), _eyeballYaw(), _interBrowDistance(0.75f), @@ -77,12 +74,9 @@ Head::Head() : } -void Head::setPositionRotationAndScale(glm::vec3 p, glm::vec3 r, float s) { - _position = p; - _scale = s; - _yaw = r.x; - _pitch = r.y; - _roll = r.z; +void Head::setPositionAndScale(glm::vec3 position, float scale) { + _position = position; + _scale = scale; } void Head::setNewTarget(float pitch, float yaw) { diff --git a/interface/src/Head.h b/interface/src/Head.h index 4ee20e3cfd..49f67e6dab 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -23,7 +23,7 @@ enum eyeContactTargets MOUTH }; -class Head { +class Head : public HeadData { public: Head(); @@ -31,7 +31,7 @@ public: void render(bool lookingInMirror); void setLooking(bool looking); - void setPositionRotationAndScale(glm::vec3 position, glm::vec3 rotation, float scale); + void setPositionAndScale(glm::vec3 position, float scale); void setNewTarget(float, float); void setLookatPosition (glm::vec3 lookatPosition ) { _lookatPosition = lookatPosition; } @@ -63,9 +63,6 @@ private: glm::vec3 _lookatPosition; glm::vec3 _leftEyePosition; glm::vec3 _rightEyePosition; - float _yaw; - float _pitch; - float _roll; float _eyeballPitch[2]; float _eyeballYaw [2]; float _eyebrowPitch[2]; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 56218c61ad..b0fb963984 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 4/9/13. -// +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // #include @@ -39,9 +39,6 @@ AvatarData::AvatarData() : _bodyYaw(-90.0), _bodyPitch(0.0), _bodyRoll(0.0), - _headYaw(0), - _headPitch(0), - _headRoll(0), _headLeanSideways(0), _headLeanForward(0), _audioLoudness(0), @@ -57,11 +54,16 @@ AvatarData::AvatarData() : _keyState(NO_KEY_DOWN), _wantResIn(false), _wantColor(true), - _wantDelta(false) + _wantDelta(false), + _headData(NULL) { } +AvatarData::~AvatarData() { + delete _headData; +} + int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { unsigned char* bufferStart = destinationBuffer; @@ -79,9 +81,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headYaw); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headPitch); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headRoll); + printf("Current values are %f,%f,%f\n", _headData->getYaw(), _headData->getPitch(), _headData->getRoll()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getYaw()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getPitch()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getRoll()); // Head lean X,Z (head lateral and fwd/back motion relative to torso) memcpy(destinationBuffer, &_headLeanSideways, sizeof(float)); @@ -165,9 +168,14 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headYaw); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headPitch); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headRoll); + float headYaw, headPitch, headRoll; + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headYaw); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headPitch); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headRoll); + + _headData->setYaw(headYaw); + _headData->setPitch(headPitch); + _headData->setRoll(headRoll); // Head position relative to pelvis memcpy(&_headLeanSideways, sourceBuffer, sizeof(float)); @@ -226,11 +234,4 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { _wantDelta = oneAtBit(wantItems,WANT_DELTA_AT_BIT); return sourceBuffer - startPosition; -} - -void AvatarData::setHeadPitch(float p) { - // Set head pitch and apply limits - const float MAX_PITCH = 60; - const float MIN_PITCH = -60; - _headPitch = glm::clamp(p, MIN_PITCH, MAX_PITCH); } \ No newline at end of file diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 2c676d6120..19a2332c8b 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 4/9/13. -// +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // #ifndef __hifi__AvatarData__ @@ -14,6 +14,7 @@ #include #include +#include "HeadData.h" const int WANT_RESIN_AT_BIT = 0; const int WANT_COLOR_AT_BIT = 1; @@ -29,6 +30,7 @@ enum KeyState class AvatarData : public AgentData { public: AvatarData(); + ~AvatarData(); const glm::vec3& getPosition() const { return _position; } @@ -47,17 +49,6 @@ public: float getBodyRoll() const {return _bodyRoll; } void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; } - // Head Rotation - void setHeadPitch(float p); - void setHeadYaw(float y) {_headYaw = y; } - void setHeadRoll(float r) {_headRoll = r; }; - float getHeadPitch() const { return _headPitch; }; - float getHeadYaw() const { return _headYaw; }; - float getHeadRoll() const { return _headRoll; }; - void addHeadPitch(float p) { setHeadPitch(_headPitch - p); } - void addHeadYaw(float y){_headYaw -= y; } - void addHeadRoll(float r){_headRoll += r; } - // Head vector deflection from pelvix in X,Z void setHeadLeanSideways(float s) {_headLeanSideways = s; }; float getHeadLeanSideways() const { return _headLeanSideways; }; @@ -108,6 +99,8 @@ public: void setWantColor(bool wantColor) { _wantColor = wantColor; } void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; } + void setHeadData(HeadData* headData) { _headData = headData; } + protected: // privatize the copy constructor and assignment operator so they cannot be called AvatarData(const AvatarData&); @@ -122,11 +115,6 @@ protected: float _bodyPitch; float _bodyRoll; - // Head rotation (relative to body) - float _headYaw; - float _headPitch; - float _headRoll; - float _headLeanSideways; float _headLeanForward; @@ -158,6 +146,8 @@ protected: bool _wantResIn; bool _wantColor; bool _wantDelta; + + HeadData* _headData; }; #endif /* defined(__hifi__AvatarData__) */ diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp new file mode 100644 index 0000000000..e806fe0b6b --- /dev/null +++ b/libraries/avatars/src/HeadData.cpp @@ -0,0 +1,53 @@ +// +// HeadData.cpp +// hifi +// +// Created by Stephen Birarda on 5/20/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include "HeadData.h" + +#include + +HeadData::HeadData() : + _yaw(0.0f), + _pitch(0.0f), + _roll(0.0f) +{ + +} + +void HeadData::setYaw(float yaw) { + const float MAX_YAW = 85; + const float MIN_YAW = -85; + + _yaw = glm::clamp(yaw, MIN_YAW, MAX_YAW); +} + +void HeadData::setPitch(float pitch) { + // set head pitch and apply limits + const float MAX_PITCH = 60; + const float MIN_PITCH = -60; + + _pitch = glm::clamp(pitch, MIN_PITCH, MAX_PITCH); +} + +void HeadData::setRoll(float roll) { + const float MAX_ROLL = 50; + const float MIN_ROLL = -50; + + _roll = glm::clamp(roll, MIN_ROLL, MAX_ROLL); +} + +void HeadData::addYaw(float yaw) { + setYaw(_yaw + yaw); +} + +void HeadData::addPitch(float pitch) { + setPitch(_pitch + pitch); +} + +void HeadData::addRoll(float roll) { + setRoll(_roll + roll); +} \ No newline at end of file diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h new file mode 100644 index 0000000000..d5647f0275 --- /dev/null +++ b/libraries/avatars/src/HeadData.h @@ -0,0 +1,36 @@ +// +// HeadData.h +// hifi +// +// Created by Stephen Birarda on 5/20/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__HeadData__ +#define __hifi__HeadData__ + +#include + +class HeadData { +public: + HeadData(); + + float getYaw() const { return _yaw; } + void setYaw(float yaw); + + float getPitch() const { return _pitch; } + void setPitch(float pitch); + + float getRoll() const { return _roll; } + void setRoll(float roll); + + void addYaw(float yaw); + void addPitch(float pitch); + void addRoll(float roll); +protected: + float _yaw; + float _pitch; + float _roll; +}; + +#endif /* defined(__hifi__HeadData__) */ From 06c78c2f1240f7d175b1cbe3397e32b735bb9d4f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 20 May 2013 15:41:19 -0700 Subject: [PATCH 17/23] Tweak: let the reader know when it needs to load the full VBO. --- interface/src/VoxelSystem.cpp | 17 +++++++++++------ interface/src/VoxelSystem.h | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 01e7a9940f..b345f34709 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -182,6 +182,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { _lastViewCullingElapsed = (endViewCulling - start) / 1000.0; } + bool didWriteFullVBO = _writeRenderFullVBO; if (_tree->isDirty()) { static char buffer[64] = { 0 }; if (_renderWarningsOn) { @@ -210,7 +211,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { } // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated - copyWrittenDataToReadArrays(); + copyWrittenDataToReadArrays(didWriteFullVBO); pthread_mutex_unlock(&_bufferWriteLock); @@ -236,6 +237,12 @@ void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() { memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices); memcpy(_readColorsArray, _writeColorsArray, bytesOfColors ); _voxelsInReadArrays = _voxelsInWriteArrays; + + // clear our dirty flags + memset(_writeVoxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool)); + + // let the reader know to get the full array + _readRenderFullVBO = true; } void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { @@ -245,6 +252,7 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { bool thisVoxelDirty = _writeVoxelDirtyArray[i]; _readVoxelDirtyArray[i] |= thisVoxelDirty; + _writeVoxelDirtyArray[i] = false; if (!inSegment) { if (thisVoxelDirty) { segmentStart = i; @@ -293,15 +301,12 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { // update our length _voxelsInReadArrays = _voxelsInWriteArrays; - - // clear our dirty flags - memset(_writeVoxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool)); } -void VoxelSystem::copyWrittenDataToReadArrays() { +void VoxelSystem::copyWrittenDataToReadArrays(bool fullVBOs) { PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); if (_voxelsDirty && _voxelsUpdated) { - if (_readRenderFullVBO) { + if (fullVBOs) { copyWrittenDataToReadArraysFullVBOs(); } else { copyWrittenDataToReadArraysPartialVBOs(); diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 0e955c90a5..6ce5855080 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -150,7 +150,7 @@ private: void cleanupRemovedVoxels(); void setupNewVoxelsForDrawing(); - void copyWrittenDataToReadArrays(); + void copyWrittenDataToReadArrays(bool fullVBOs); bool _voxelsDirty; From de84b7803f14e304a25258ea36ab95d1e0de48be Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 May 2013 15:51:40 -0700 Subject: [PATCH 18/23] move _lookAtPosition to HeadData class --- interface/src/Avatar.cpp | 16 +++++++--------- interface/src/Avatar.h | 1 + interface/src/Head.cpp | 7 +++---- interface/src/Head.h | 2 -- libraries/avatars/src/AvatarData.cpp | 14 ++++++++------ libraries/avatars/src/AvatarData.h | 2 -- libraries/avatars/src/HeadData.cpp | 5 ++--- libraries/avatars/src/HeadData.h | 8 ++++++++ 8 files changed, 29 insertions(+), 26 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 589c99e462..cc41e0d585 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -111,6 +111,11 @@ Avatar::Avatar(bool isMine) : _head() { else { _balls = NULL; } } +Avatar::~Avatar() { + // if _balls is something that's sticking around other than Philip playing around it needs to be delete here too + _headData = NULL; +} + void Avatar::reset() { _head.setYaw(0.0f); _head.setRoll(0.0f); @@ -389,20 +394,19 @@ void Avatar::simulate(float deltaTime) { // update head state _head.setPositionAndScale(_joint[AVATAR_JOINT_HEAD_BASE].springyPosition, _joint[AVATAR_JOINT_HEAD_BASE].radius); - setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 + _head.setLookAtPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 if (_interactingOther) { _head.setLooking(true); if (_isMine) { - setLookatPosition(_interactingOther->getSpringyHeadPosition()); + _head.setLookAtPosition(_interactingOther->getSpringyHeadPosition()); } } else { _head.setLooking(false); } _head.setBodyYaw(_bodyYaw); - _head.setLookatPosition(_lookatPosition); _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); _head.simulate(deltaTime, _isMine); @@ -1328,12 +1332,6 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity // absolute eulerAngles passed. // // - float const MAX_YAW = 90.f; - float const MIN_YAW = -90.f; - float const MAX_PITCH = 85.f; - float const MIN_PITCH = -85.f; - float const MAX_ROLL = 90.f; - float const MIN_ROLL = -90.f; if (deltaTime == 0.f) { // On first sample, set head to absolute position diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 3845b9cb60..90735c5876 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -77,6 +77,7 @@ enum AvatarJointID class Avatar : public AvatarData { public: Avatar(bool isMine); + ~Avatar(); void reset(); void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 587e6279af..c59dd9ac1d 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -45,7 +45,6 @@ Head::Head() : _skinColor(0.0f, 0.0f, 0.0f), _position(0.0f, 0.0f, 0.0f), _rotation(0.0f, 0.0f, 0.0f), - _lookatPosition(0.0f, 0.0f, 0.0f), _eyeballPitch(), _eyeballYaw(), _interBrowDistance(0.75f), @@ -224,7 +223,7 @@ void Head::setLooking(bool looking) { _lookingAtSomething = looking; glm::vec3 averageEyePosition = _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; - glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - averageEyePosition); + glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - averageEyePosition); float dot = glm::dot(targetLookatAxis, _orientation.getFront()); if (dot < MINIMUM_EYE_ROTATION) { @@ -370,7 +369,7 @@ void Head::renderEyeBalls() { if (_lookingAtSomething) { //rotate the eyeball to aim towards the lookat position - glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _leftEyePosition); // the lookat direction + glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - _leftEyePosition); // the lookat direction glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP); float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); @@ -414,7 +413,7 @@ void Head::renderEyeBalls() { if (_lookingAtSomething) { //rotate the eyeball to aim towards the lookat position - glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _rightEyePosition); + glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - _rightEyePosition); glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP); float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); diff --git a/interface/src/Head.h b/interface/src/Head.h index 49f67e6dab..a731a7b87e 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -34,7 +34,6 @@ public: void setPositionAndScale(glm::vec3 position, float scale); void setNewTarget(float, float); - void setLookatPosition (glm::vec3 lookatPosition ) { _lookatPosition = lookatPosition; } void setGravity (glm::vec3 gravity ) { _gravity = gravity; } void setSkinColor (glm::vec3 skinColor ) { _skinColor = skinColor; } void setBodyYaw (float bodyYaw ) { _bodyYaw = bodyYaw; } @@ -60,7 +59,6 @@ private: glm::vec3 _skinColor; glm::vec3 _position; glm::vec3 _rotation; - glm::vec3 _lookatPosition; glm::vec3 _leftEyePosition; glm::vec3 _rightEyePosition; float _eyeballPitch[2]; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b0fb963984..27f4286bbd 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -35,7 +35,6 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo AvatarData::AvatarData() : _handPosition(0,0,0), - _lookatPosition(0,0,0), _bodyYaw(-90.0), _bodyPitch(0.0), _bodyRoll(0.0), @@ -97,8 +96,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += sizeof(float) * 3; // Lookat Position - memcpy(destinationBuffer, &_lookatPosition, sizeof(_lookatPosition)); - destinationBuffer += sizeof(_lookatPosition); + memcpy(destinationBuffer, &_headData->_lookAtPosition, sizeof(_headData->_lookAtPosition)); + destinationBuffer += sizeof(_headData->_lookAtPosition); // Hand State (0 = not grabbing, 1 = grabbing) memcpy(destinationBuffer, &_handState, sizeof(char)); @@ -148,7 +147,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // called on the other agents - assigns it to my views of the others int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { -//printf("AvatarData::parseData()\n"); + // lazily allocate memory for HeadData in case we're not an Avatar instance + if (!_headData) { + _headData = new HeadData(); + } // increment to push past the packet header sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA); @@ -188,8 +190,8 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(float) * 3; // Lookat Position - memcpy(&_lookatPosition, sourceBuffer, sizeof(_lookatPosition)); - sourceBuffer += sizeof(_lookatPosition); + memcpy(&_headData->_lookAtPosition, sourceBuffer, sizeof(_headData->_lookAtPosition)); + sourceBuffer += sizeof(_headData->_lookAtPosition); // Hand State memcpy(&_handState, sourceBuffer, sizeof(char)); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 19a2332c8b..e3621095d3 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -36,7 +36,6 @@ public: void setPosition (const glm::vec3 position ) { _position = position; } void setHandPosition (const glm::vec3 handPosition ) { _handPosition = handPosition; } - void setLookatPosition(const glm::vec3 lookatPosition) { _lookatPosition = lookatPosition; } int getBroadcastData(unsigned char* destinationBuffer); int parseData(unsigned char* sourceBuffer, int numBytes); @@ -108,7 +107,6 @@ protected: glm::vec3 _position; glm::vec3 _handPosition; - glm::vec3 _lookatPosition; // Body rotation float _bodyYaw; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index e806fe0b6b..c95f1b68e9 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -8,12 +8,11 @@ #include "HeadData.h" -#include - HeadData::HeadData() : _yaw(0.0f), _pitch(0.0f), - _roll(0.0f) + _roll(0.0f), + _lookAtPosition(0.0f, 0.0f, 0.0f) { } diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index d5647f0275..eca16ef6b0 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -11,6 +11,8 @@ #include +#include + class HeadData { public: HeadData(); @@ -27,10 +29,16 @@ public: void addYaw(float yaw); void addPitch(float pitch); void addRoll(float roll); + + const glm::vec3& getLookAtPosition() const { return _lookAtPosition; } + void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; } + + friend class AvatarData; protected: float _yaw; float _pitch; float _roll; + glm::vec3 _lookAtPosition; }; #endif /* defined(__hifi__HeadData__) */ From 570dfba934fccdbe349d5371cdcda6a4efd24114 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 May 2013 16:12:38 -0700 Subject: [PATCH 19/23] code review comments, cleanup Avatar constructor --- interface/src/Application.cpp | 16 ------ interface/src/Avatar.cpp | 85 +++++++++++++++--------------- interface/src/Avatar.h | 4 +- libraries/avatars/src/HeadData.cpp | 22 -------- libraries/avatars/src/HeadData.h | 13 +++-- 5 files changed, 54 insertions(+), 86 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7c577589f9..88c41665ee 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1356,22 +1356,6 @@ void Application::updateAvatar(float deltaTime) { _headMouseY = max(_headMouseY, 0); _headMouseY = min(_headMouseY, _glWidget->height()); - // Update head and body pitch and yaw based on measured gyro rates - if (_gyroLook->isChecked()) { - // Render Yaw - /* NOTE: PER - Leave here until I get back and can modify to couple gyros to head pitch, yaw - float renderYawSpring = fabs(_headMouseX - _glWidget->width() / 2.f) / (_glWidget->width() / 2.f); - const float RENDER_YAW_MULTIPLY = 4.f; - _myAvatar.setRenderYaw((1.f - renderYawSpring * deltaTime) * _myAvatar.getRenderYaw() + - renderYawSpring * deltaTime * -_myAvatar.getHeadYaw() * RENDER_YAW_MULTIPLY); - // Render Pitch - float renderPitchSpring = fabs(_headMouseY - _glWidget->height() / 2.f) / (_glWidget->height() / 2.f); - const float RENDER_PITCH_MULTIPLY = 4.f; - _myAvatar.setRenderPitch((1.f - renderPitchSpring * deltaTime) * _myAvatar.getRenderPitch() + - renderPitchSpring * deltaTime * -_myAvatar.getHeadPitch() * RENDER_PITCH_MULTIPLY); - */ - } - if (OculusManager::isConnected()) { float yaw, pitch, roll; OculusManager::getEulerAngles(yaw, pitch, roll); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index cc41e0d585..d4e6ae0a8b 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -59,61 +59,62 @@ bool usingBigSphereCollisionTest = true; float chatMessageScale = 0.0015; float chatMessageHeight = 0.45; -Avatar::Avatar(bool isMine) : _head() { +Avatar::Avatar(bool isMine) : + _isMine(isMine), + _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), + _rotation(0.0f, 0.0f, 0.0f, 0.0f), + _mode(AVATAR_MODE_STANDING), + _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), + _orientation(), + _transmitterIsFirstData(true), + _transmitterHz(0.0f), + _transmitterPackets(0), + _transmitterInitialReading(0.0f, 0.0f, 0.0f), + _isTransmitterV2Connected(false), + _pelvisStandingHeight(0.0f), + _displayingHead(true), + _distanceToNearestAvatar(std::numeric_limits::max()), + _gravity(0.0f, -1.0f, 0.0f), + _mouseRayOrigin(0.0f, 0.0f, 0.0f), + _mouseRayDirection(0.0f, 0.0f, 0.0f), + _cameraPosition(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; - - _orientation.setToIdentity(); - - _velocity = glm::vec3(0.0f, 0.0f, 0.0f); - _thrust = glm::vec3(0.0f, 0.0f, 0.0f); - _rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f); - _bodyYaw = -90.0; - _bodyPitch = 0.0; - _bodyRoll = 0.0; - _bodyPitchDelta = 0.0; - _bodyYawDelta = 0.0; - _bodyRollDelta = 0.0; - _mousePressed = false; - _mode = AVATAR_MODE_STANDING; - _isMine = isMine; - _maxArmLength = 0.0; - _transmitterHz = 0.0; - _transmitterPackets = 0; - _transmitterIsFirstData = true; - _transmitterInitialReading = glm::vec3(0.f, 0.f, 0.f); - _isTransmitterV2Connected = false; - _speed = 0.0; - _pelvisStandingHeight = 0.0f; - _displayingHead = true; - _TEST_bigSphereRadius = 0.4f; - _TEST_bigSpherePosition = glm::vec3(5.0f, _TEST_bigSphereRadius, 5.0f); - _mouseRayOrigin = glm::vec3(0.0f, 0.0f, 0.0f); - _mouseRayDirection = glm::vec3(0.0f, 0.0f, 0.0f); - _cameraPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _interactingOther = NULL; - for (int i = 0; i < MAX_DRIVE_KEYS; i++) _driveKeys[i] = false; - - _movedHandOffset = glm::vec3(0.0f, 0.0f, 0.0f); - _handHoldingPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _distanceToNearestAvatar = std::numeric_limits::max(); - _gravity = glm::vec3(0.0f, -1.0f, 0.0f); - _cumulativeMouseYaw = 0.f; - _isMouseTurningRight = false; + + for (int i = 0; i < MAX_DRIVE_KEYS; i++) { + _driveKeys[i] = false; + } initializeSkeleton(); _avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS); - if (BALLS_ON) { _balls = new Balls(100); } - else { _balls = NULL; } + if (BALLS_ON) { + _balls = new Balls(100); + } else { + _balls = NULL; + } } Avatar::~Avatar() { - // if _balls is something that's sticking around other than Philip playing around it needs to be delete here too _headData = NULL; + delete _balls; } void Avatar::reset() { diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 90735c5876..5e2ce0fd47 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -165,8 +165,8 @@ private: Head _head; bool _isMine; - glm::vec3 _TEST_bigSpherePosition; float _TEST_bigSphereRadius; + glm::vec3 _TEST_bigSpherePosition; bool _mousePressed; float _bodyPitchDelta; float _bodyYawDelta; @@ -182,8 +182,6 @@ private: float _maxArmLength; Orientation _orientation; int _driveKeys[MAX_DRIVE_KEYS]; - float _renderYaw; - float _renderPitch; // Pitch from view frustum when this is own head bool _transmitterIsFirstData; timeval _transmitterTimeLastReceived; timeval _transmitterTimer; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index c95f1b68e9..bc400b96bb 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -17,28 +17,6 @@ HeadData::HeadData() : } -void HeadData::setYaw(float yaw) { - const float MAX_YAW = 85; - const float MIN_YAW = -85; - - _yaw = glm::clamp(yaw, MIN_YAW, MAX_YAW); -} - -void HeadData::setPitch(float pitch) { - // set head pitch and apply limits - const float MAX_PITCH = 60; - const float MIN_PITCH = -60; - - _pitch = glm::clamp(pitch, MIN_PITCH, MAX_PITCH); -} - -void HeadData::setRoll(float roll) { - const float MAX_ROLL = 50; - const float MIN_ROLL = -50; - - _roll = glm::clamp(roll, MIN_ROLL, MAX_ROLL); -} - void HeadData::addYaw(float yaw) { setYaw(_yaw + yaw); } diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index eca16ef6b0..7da3085fe7 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -13,18 +13,25 @@ #include +const float MIN_HEAD_YAW = -85; +const float MAX_HEAD_YAW = 85; +const float MIN_HEAD_PITCH = -60; +const float MAX_HEAD_PITCH = 60; +const float MIN_HEAD_ROLL = -50; +const float MAX_HEAD_ROLL = 50; + class HeadData { public: HeadData(); float getYaw() const { return _yaw; } - void setYaw(float yaw); + void setYaw(float yaw) { _yaw = glm::clamp(yaw, MIN_HEAD_YAW, MAX_HEAD_YAW); } float getPitch() const { return _pitch; } - void setPitch(float pitch); + void setPitch(float pitch) { _pitch = glm::clamp(pitch, MIN_HEAD_PITCH, MAX_HEAD_PITCH); } float getRoll() const { return _roll; } - void setRoll(float roll); + void setRoll(float roll) { _roll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } void addYaw(float yaw); void addPitch(float pitch); From 28bab24e7046d58e28f184e7df52fafb89a85d39 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 May 2013 16:17:49 -0700 Subject: [PATCH 20/23] type squishes in AvatarData --- libraries/avatars/src/AvatarData.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 27f4286bbd..8c6f4fb894 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -80,10 +80,9 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) - printf("Current values are %f,%f,%f\n", _headData->getYaw(), _headData->getPitch(), _headData->getRoll()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getYaw()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getPitch()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getRoll()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_yaw); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_pitch); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_roll); // Head lean X,Z (head lateral and fwd/back motion relative to torso) memcpy(destinationBuffer, &_headLeanSideways, sizeof(float)); @@ -165,15 +164,15 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(float) * 3; // Body rotation (NOTE: This needs to become a quaternion to save two bytes) - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyYaw); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyYaw); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyPitch); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyRoll); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) float headYaw, headPitch, headRoll; - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headYaw); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headPitch); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headRoll); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headPitch); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headRoll); _headData->setYaw(headYaw); _headData->setPitch(headPitch); From 5b0640bbbf67b7e2828f3e6da22702db517e0a39 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 20 May 2013 16:52:40 -0700 Subject: [PATCH 21/23] Whoops--fixed a matrix stack issue that was breaking Oculus rendering. --- interface/src/Environment.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index fb7c8c7271..81d983d635 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -21,7 +21,6 @@ void Environment::init() { } void Environment::renderAtmosphere(Camera& camera) { - glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(getAtmosphereCenter().x, getAtmosphereCenter().y, getAtmosphereCenter().z); @@ -72,10 +71,7 @@ void Environment::renderAtmosphere(Camera& camera) { program->release(); - glPopMatrix(); - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + glPopMatrix(); } ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { From 564244ddd371cdc0a4cf9cbcb3a184c1fb360eb5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 May 2013 17:13:40 -0700 Subject: [PATCH 22/23] move _leanSideways and _leanForwards to HeadData --- interface/src/Avatar.cpp | 40 ++++++---------------------- interface/src/Avatar.h | 3 --- interface/src/Head.cpp | 11 +++++--- interface/src/Head.h | 3 +-- libraries/avatars/src/AvatarData.cpp | 16 +++++------ libraries/avatars/src/AvatarData.h | 9 ------- libraries/avatars/src/HeadData.cpp | 10 ++++++- libraries/avatars/src/HeadData.h | 9 +++++++ 8 files changed, 41 insertions(+), 60 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index d4e6ae0a8b..d789f3751a 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -118,10 +118,7 @@ Avatar::~Avatar() { } void Avatar::reset() { - _head.setYaw(0.0f); - _head.setRoll(0.0f); - _head.setPitch(0.0f); - _head.leanForward = _head.leanSideways = 0; + _head.reset(); } // Update avatar head rotation with sensor data @@ -153,13 +150,11 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa * (1.f - fminf(glm::length(headRotationRates), headRateMax) / headRateMax); leaning.y = 0.f; if (glm::length(leaning) < LEAN_MAX) { - _head.leanForward = _head.leanForward * (1.f - LEAN_AVERAGING * deltaTime) + - (LEAN_AVERAGING * deltaTime) * leaning.z * LEAN_SENSITIVITY; - _head.leanSideways = _head.leanSideways * (1.f - LEAN_AVERAGING * deltaTime) + - (LEAN_AVERAGING * deltaTime) * leaning.x * LEAN_SENSITIVITY; + _head.setLeanForward(_head.getLeanForward() * (1.f - LEAN_AVERAGING * deltaTime) + + (LEAN_AVERAGING * deltaTime) * leaning.z * LEAN_SENSITIVITY); + _head.setLeanSideways(_head.getLeanSideways() * (1.f - LEAN_AVERAGING * deltaTime) + + (LEAN_AVERAGING * deltaTime) * leaning.x * LEAN_SENSITIVITY); } - setHeadLeanSideways(_head.leanSideways); - setHeadLeanForward(_head.leanForward); } float Avatar::getAbsoluteHeadYaw() const { @@ -170,20 +165,6 @@ float Avatar::getAbsoluteHeadPitch() const { return _bodyPitch + _head.getPitch(); } -void Avatar::addLean(float x, float z) { - //Add lean as impulse - _head.leanSideways += x; - _head.leanForward += z; -} - -void Avatar::setLeanForward(float dist){ - _head.leanForward = dist; -} - -void Avatar::setLeanSideways(float dist){ - _head.leanSideways = dist; -} - void Avatar::setMousePressed(bool mousePressed) { _mousePressed = mousePressed; } @@ -361,17 +342,12 @@ void Avatar::simulate(float deltaTime) { _head.setPitch(_head.getPitch() * (1.f - acceleration * ACCELERATION_PITCH_DECAY * deltaTime)); } - // Get head position data from network for other people - if (!_isMine) { - _head.leanSideways = getHeadLeanSideways(); - _head.leanForward = getHeadLeanForward(); - } //apply the head lean values to the springy position... - if (fabs(_head.leanSideways + _head.leanForward) > 0.0f) { + if (fabs(_head.getLeanSideways() + _head.getLeanForward()) > 0.0f) { glm::vec3 headLean = - _orientation.getRight() * _head.leanSideways + - _orientation.getFront() * _head.leanForward; + _orientation.getRight() * _head.getLeanSideways() + + _orientation.getFront() * _head.getLeanForward(); // this is not a long-term solution, but it works ok for initial purposes of making the avatar lean _joint[ AVATAR_JOINT_TORSO ].springyPosition += headLean * 0.1f; diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 5e2ce0fd47..3832fa1902 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -93,9 +93,6 @@ public: float getAbsoluteHeadYaw() const; float getAbsoluteHeadPitch() const; - void setLeanForward(float dist); - void setLeanSideways(float dist); - void addLean(float x, float z); glm::vec3 getApproximateEyePosition(); 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 diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index c59dd9ac1d..4b1be7f51e 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -39,8 +39,6 @@ vector irisTexture; Head::Head() : yawRate(0.0f), noise(0.0f), - leanForward(0.0f), - leanSideways(0.0f), _audioLoudness(0.0f), _skinColor(0.0f, 0.0f, 0.0f), _position(0.0f, 0.0f, 0.0f), @@ -83,6 +81,11 @@ void Head::setNewTarget(float pitch, float yaw) { _yawTarget = yaw; } +void Head::reset() { + _yaw = _pitch = _roll = 0.0f; + _leanForward = _leanSideways = 0.0f; +} + void Head::simulate(float deltaTime, bool isMine) { //generate orientation directions based on Euler angles... @@ -115,8 +118,8 @@ void Head::simulate(float deltaTime, bool isMine) { _roll *= 1.f - (HEAD_MOTION_DECAY * deltaTime); } - leanForward *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime); - leanSideways *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime); + _leanForward *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime); + _leanSideways *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime); // Update where the avatar's eyes are // diff --git a/interface/src/Head.h b/interface/src/Head.h index a731a7b87e..c192980349 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -27,6 +27,7 @@ class Head : public HeadData { public: Head(); + void reset(); void simulate(float deltaTime, bool isMine); void render(bool lookingInMirror); @@ -49,8 +50,6 @@ public: //some public members (left-over from pulling Head out of Avatar - I may see about privatizing these later). float yawRate; float noise; - float leanForward; - float leanSideways; private: diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 8c6f4fb894..fb97052151 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -38,8 +38,6 @@ AvatarData::AvatarData() : _bodyYaw(-90.0), _bodyPitch(0.0), _bodyRoll(0.0), - _headLeanSideways(0), - _headLeanForward(0), _audioLoudness(0), _handState(0), _cameraPosition(0,0,0), @@ -85,10 +83,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_roll); // Head lean X,Z (head lateral and fwd/back motion relative to torso) - memcpy(destinationBuffer, &_headLeanSideways, sizeof(float)); - destinationBuffer += sizeof(float); - memcpy(destinationBuffer, &_headLeanForward, sizeof(float)); - destinationBuffer += sizeof(float); + memcpy(destinationBuffer, &_headData->_leanSideways, sizeof(_headData->_leanSideways)); + destinationBuffer += sizeof(_headData->_leanSideways); + memcpy(destinationBuffer, &_headData->_leanForward, sizeof(_headData->_leanForward)); + destinationBuffer += sizeof(_headData->_leanForward); // Hand Position memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); @@ -179,10 +177,10 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { _headData->setRoll(headRoll); // Head position relative to pelvis - memcpy(&_headLeanSideways, sourceBuffer, sizeof(float)); - sourceBuffer += sizeof(float); - memcpy(&_headLeanForward, sourceBuffer, sizeof(float)); + memcpy(&_headData->_leanSideways, sourceBuffer, sizeof(_headData->_leanSideways)); sourceBuffer += sizeof(float); + memcpy(&_headData->_leanForward, sourceBuffer, sizeof(_headData->_leanForward)); + sourceBuffer += sizeof(_headData->_leanForward); // Hand Position memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index e3621095d3..8924b5f937 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -47,12 +47,6 @@ public: void setBodyPitch(float bodyPitch) { _bodyPitch = bodyPitch; } float getBodyRoll() const {return _bodyRoll; } void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; } - - // Head vector deflection from pelvix in X,Z - void setHeadLeanSideways(float s) {_headLeanSideways = s; }; - float getHeadLeanSideways() const { return _headLeanSideways; }; - void setHeadLeanForward(float f) {_headLeanForward = f; }; - float getHeadLeanForward() const { return _headLeanForward; }; // Hand State void setHandState(char s) { _handState = s; }; @@ -112,9 +106,6 @@ protected: float _bodyYaw; float _bodyPitch; float _bodyRoll; - - float _headLeanSideways; - float _headLeanForward; // Audio loudness (used to drive facial animation) float _audioLoudness; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index bc400b96bb..e7d6cee46a 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -12,7 +12,9 @@ HeadData::HeadData() : _yaw(0.0f), _pitch(0.0f), _roll(0.0f), - _lookAtPosition(0.0f, 0.0f, 0.0f) + _lookAtPosition(0.0f, 0.0f, 0.0f), + _leanSideways(0.0f), + _leanForward(0.0f) { } @@ -27,4 +29,10 @@ void HeadData::addPitch(float pitch) { void HeadData::addRoll(float roll) { setRoll(_roll + roll); +} + +void HeadData::addLean(float sideways, float forwards) { + // Add lean as impulse + _leanSideways += sideways; + _leanForward += forwards; } \ No newline at end of file diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index 7da3085fe7..8c9e99e6d9 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -24,6 +24,12 @@ class HeadData { public: HeadData(); + float getLeanSideways() const { return _leanSideways; } + void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; } + + float getLeanForward() const { return _leanForward; } + void setLeanForward(float leanForward) { _leanForward = leanForward; } + float getYaw() const { return _yaw; } void setYaw(float yaw) { _yaw = glm::clamp(yaw, MIN_HEAD_YAW, MAX_HEAD_YAW); } @@ -36,6 +42,7 @@ public: void addYaw(float yaw); void addPitch(float pitch); void addRoll(float roll); + void addLean(float sideways, float forwards); const glm::vec3& getLookAtPosition() const { return _lookAtPosition; } void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; } @@ -46,6 +53,8 @@ protected: float _pitch; float _roll; glm::vec3 _lookAtPosition; + float _leanSideways; + float _leanForward; }; #endif /* defined(__hifi__HeadData__) */ From d2b2d36fcf5593a794bd158f1a853120cb50b8e0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 May 2013 17:31:33 -0700 Subject: [PATCH 23/23] lazy allocation of HeadData in getBroadcastData --- libraries/avatars/src/AvatarData.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index fb97052151..5aaae9f3ad 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -68,6 +68,11 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // that can pack any type given the number of bytes // and return the number of bytes to push the pointer + // lazily allocate memory for HeadData in case we're not an Avatar instance + if (!_headData) { + _headData = new HeadData(); + } + // Body world position memcpy(destinationBuffer, &_position, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3;