From b74ceae61ae25bb7220ceb4954ee1acf9cafdc89 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 23 May 2013 22:52:43 -0700 Subject: [PATCH 01/27] added avatar hair --- interface/src/Application.cpp | 4 +- interface/src/Avatar.cpp | 11 ++- interface/src/Avatar.h | 3 +- interface/src/Head.cpp | 167 +++++++++++++++++++++++++++++++++- interface/src/Head.h | 18 +++- 5 files changed, 192 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b9b0948490..c4db1bd71d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1707,13 +1707,13 @@ void Application::displaySide(Camera& whichCamera) { for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { Avatar *avatar = (Avatar *)agent->getLinkedData(); - avatar->render(false); + avatar->render(false, _myCamera.getPosition()); } } agentList->unlock(); // Render my own Avatar - _myAvatar.render(_lookingInMirror->isChecked()); + _myAvatar.render(_lookingInMirror->isChecked(), _myCamera.getPosition()); _myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked()); } diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index bdfd7c8691..a48e4e9b48 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -79,6 +79,7 @@ Avatar::Avatar(bool isMine) : _bodyRollDelta(0.0f), _movedHandOffset(0.0f, 0.0f, 0.0f), _rotation(0.0f, 0.0f, 0.0f, 0.0f), + _cameraPosition(0.0f, 0.0f, 0.0f), _mode(AVATAR_MODE_STANDING), _handHoldingPosition(0.0f, 0.0f, 0.0f), _velocity(0.0f, 0.0f, 0.0f), @@ -725,7 +726,9 @@ void Avatar::setGravity(glm::vec3 gravity) { _head.setGravity(_gravity); } -void Avatar::render(bool lookingInMirror) { +void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { + + _cameraPosition = cameraPosition; if (_isMine && usingBigSphereCollisionTest) { // show TEST big sphere @@ -745,7 +748,7 @@ void Avatar::render(bool lookingInMirror) { // if this is my avatar, then render my interactions with the other avatar if (_isMine) { - _avatarTouch.render(getCameraPosition()); + _avatarTouch.render(_cameraPosition); } // Render the balls @@ -1132,11 +1135,11 @@ void Avatar::renderBody(bool lookingInMirror) { // Render the body as balls and cones for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { - float distanceToCamera = glm::length(getCameraPosition() - _joint[b].position); + float distanceToCamera = glm::length(_cameraPosition - _joint[b].position); // Always render other people, and render myself when beyond threshold distance if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case if (lookingInMirror || !_isMine || distanceToCamera > RENDER_OPAQUE_BEYOND) { - _head.render(lookingInMirror); + _head.render(lookingInMirror, _cameraPosition); } } else if (!_isMine || distanceToCamera > RENDER_TRANSLUCENT_BEYOND) { // Render the sphere at the joint diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 59f9018af3..964a0a04f6 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -107,7 +107,7 @@ public: Head& getHead() { return _head; } void setMousePressed(bool pressed); - void render(bool lookingInMirror); + void render(bool lookingInMirror, glm::vec3 cameraPosition); void renderBody(bool lookingInMirror); void simulate(float deltaTime, Transmitter* transmitter); void setMovedHandOffset(glm::vec3 movedHandOffset) { _movedHandOffset = movedHandOffset; } @@ -162,6 +162,7 @@ private: glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion AvatarJoint _joint[ NUM_AVATAR_JOINTS ]; AvatarMode _mode; + glm::vec3 _cameraPosition; glm::vec3 _handHoldingPosition; glm::vec3 _velocity; glm::vec3 _thrust; diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index cb42c6cc54..c29145774d 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -21,6 +21,13 @@ const float HEAD_MOTION_DECAY = 0.1; const float MINIMUM_EYE_ROTATION_DOT = 0.5f; // based on a dot product: 1.0 is straight ahead, 0.0 is 90 degrees off const float EYEBALL_RADIUS = 0.017; const float EYEBALL_COLOR[3] = { 0.9f, 0.9f, 0.8f }; +const float HAIR_COLOR[3] = { 0.8f, 0.6f, 0.5f }; +const float HAIR_SPRING_FORCE = 10.0f; +const float HAIR_TORQUE_FORCE = 0.1f; +const float HAIR_GRAVITY_FORCE = 0.05f; +const float HAIR_DRAG = 10.0f; +const float HAIR_LENGTH = 0.06f; +const float HAIR_THICKNESS = 0.02f; const float IRIS_RADIUS = 0.007; const float IRIS_PROTRUSION = 0.0145f; const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png"; @@ -55,14 +62,31 @@ Head::Head() : _bodyRotation(0.0f, 0.0f, 0.0f), _headRotation(0.0f, 0.0f, 0.0f), _renderLookatVectors(false) { + + for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { + _hairTuft[t].length = HAIR_LENGTH; + _hairTuft[t].thickness = HAIR_THICKNESS; + _hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f); + _hairTuft[t].midPosition = glm::vec3(0.0f, 0.0f, 0.0f); + _hairTuft[t].endPosition = glm::vec3(0.0f, 0.0f, 0.0f); + _hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + _hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + } } void Head::reset() { _yaw = _pitch = _roll = 0.0f; _leanForward = _leanSideways = 0.0f; + + for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { + _hairTuft[t].basePosition = _position + _orientation.getUp() * _scale * 0.9f; + _hairTuft[t].midPosition = _hairTuft[t].basePosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF; + _hairTuft[t].endPosition = _hairTuft[t].midPosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF; + _hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + _hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + } } - void Head::simulate(float deltaTime, bool isMine) { const float HEAD_MOTION_DECAY = 0.00; @@ -109,7 +133,9 @@ void Head::simulate(float deltaTime, bool isMine) { _browAudioLift *= 0.7f; // based on the nature of the lookat position, determine if the eyes can look / are looking at it. - determineIfLookingAtSomething(); + determineIfLookingAtSomething(); + + updateHair(deltaTime); } void Head::determineIfLookingAtSomething() { @@ -168,7 +194,7 @@ void Head::calculateGeometry(bool lookingInMirror) { } -void Head::render(bool lookingInMirror) { +void Head::render(bool lookingInMirror, glm::vec3 cameraPosition) { calculateGeometry(lookingInMirror); @@ -180,6 +206,7 @@ void Head::render(bool lookingInMirror) { renderEars(); renderMouth(); renderEyeBrows(); + renderHair(cameraPosition); if (_renderLookatVectors && _lookingAtSomething) { renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition); @@ -430,4 +457,138 @@ void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosi } +void Head::updateHair(float deltaTime) { + + for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { + + float fraction = (float)t / (float)(NUM_HAIR_TUFTS-1); + + float angle = -20.0f + 40.0f * fraction; + + float radian = angle * PI_OVER_180; + glm::vec3 baseDirection + = _orientation.getFront() * sinf(radian) + + _orientation.getUp() * cosf(radian); + + _hairTuft[t].basePosition = _position + _scale * 0.9f * baseDirection; + + glm::vec3 midAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition; + glm::vec3 endAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition; + + float midLength = glm::length(midAxis); + float endLength = glm::length(endAxis); + + glm::vec3 midDirection; + glm::vec3 endDirection; + + if (midLength > 0.0f) { + midDirection = midAxis / midLength; + } else { + midDirection = _orientation.getUp(); + } + + if (endLength > 0.0f) { + endDirection = endAxis / endLength; + } else { + endDirection = _orientation.getUp(); + } + + // add spring force + float midForce = midLength - _hairTuft[t].length * ONE_HALF; + float endForce = endLength - _hairTuft[t].length * ONE_HALF; + _hairTuft[t].midVelocity -= midDirection * midForce * HAIR_SPRING_FORCE * deltaTime; + _hairTuft[t].endVelocity -= endDirection * endForce * HAIR_SPRING_FORCE * deltaTime; + + // add gravity force + glm::vec3 gravityForce = _gravity * HAIR_GRAVITY_FORCE * deltaTime; + _hairTuft[t].midVelocity += gravityForce; + _hairTuft[t].endVelocity += gravityForce; + + // add torque force + _hairTuft[t].midVelocity += baseDirection * HAIR_TORQUE_FORCE * deltaTime; + _hairTuft[t].endVelocity += midDirection * HAIR_TORQUE_FORCE * deltaTime; + + // add drag force + float momentum = 1.0f - (HAIR_DRAG * deltaTime); + if (momentum < 0.0f) { + _hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + _hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + } else { + _hairTuft[t].midVelocity *= momentum; + _hairTuft[t].endVelocity *= momentum; + } + + // update position by velocity + _hairTuft[t].midPosition += _hairTuft[t].midVelocity; + _hairTuft[t].endPosition += _hairTuft[t].endVelocity; + + // clamp lengths + glm::vec3 newMidVector = _hairTuft[t].midPosition - _hairTuft[t].basePosition; + glm::vec3 newEndVector = _hairTuft[t].endPosition - _hairTuft[t].midPosition; + + float newMidLength = glm::length(newMidVector); + float newEndLength = glm::length(newEndVector); + + glm::vec3 newMidDirection; + glm::vec3 newEndDirection; + + if (newMidLength > 0.0f) { + newMidDirection = newMidVector/newMidLength; + } else { + newMidDirection = _orientation.getUp(); + } + + if (newEndLength > 0.0f) { + newEndDirection = newEndVector/newEndLength; + } else { + newEndDirection = _orientation.getUp(); + } + + _hairTuft[t].endPosition = _hairTuft[t].midPosition + newEndDirection * _hairTuft[t].length * ONE_HALF; + _hairTuft[t].midPosition = _hairTuft[t].basePosition + newMidDirection * _hairTuft[t].length * ONE_HALF; + } +} + + + +void Head::renderHair(glm::vec3 cameraPosition) { + + for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { + + glm::vec3 baseAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition; + glm::vec3 midAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition; + glm::vec3 viewVector = _hairTuft[t].basePosition - cameraPosition; + + glm::vec3 basePerpendicular = glm::normalize(glm::cross(baseAxis, viewVector)); + glm::vec3 midPerpendicular = glm::normalize(glm::cross(midAxis, viewVector)); + + glm::vec3 base1 = _hairTuft[t].basePosition - basePerpendicular * _hairTuft[t].thickness * ONE_HALF; + glm::vec3 base2 = _hairTuft[t].basePosition + basePerpendicular * _hairTuft[t].thickness * ONE_HALF; + + glm::vec3 mid1 = _hairTuft[t].midPosition - midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; + glm::vec3 mid2 = _hairTuft[t].midPosition + midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; + + glColor3fv(HAIR_COLOR); + + glBegin(GL_TRIANGLES); + + glVertex3f(base1.x, base1.y, base1.z ); + glVertex3f(base2.x, base2.y, base2.z ); + glVertex3f(mid1.x, mid1.y, mid1.z ); + + glVertex3f(base2.x, base2.y, base2.z ); + glVertex3f(mid1.x, mid1.y, mid1.z ); + glVertex3f(mid2.x, mid2.y, mid2.z ); + + glVertex3f(mid1.x, mid1.y, mid1.z ); + glVertex3f(mid2.x, mid2.y, mid2.z ); + glVertex3f(_hairTuft[t].endPosition.x, _hairTuft[t].endPosition.y, _hairTuft[t].endPosition.z ); + + glEnd(); + } +} + + + + diff --git a/interface/src/Head.h b/interface/src/Head.h index 6ea9218bbf..32f7ddab7e 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -24,13 +24,15 @@ enum eyeContactTargets MOUTH }; +const int NUM_HAIR_TUFTS = 4; + class Head : public HeadData { public: Head(); void reset(); void simulate(float deltaTime, bool isMine); - void render(bool lookingInMirror); + void render(bool lookingInMirror, glm::vec3 cameraPosition); void setScale (float scale ) { _scale = scale; } void setPosition (glm::vec3 position ) { _position = position; } @@ -56,6 +58,17 @@ private: Head(const Head&); Head& operator= (const Head&); + struct HairTuft + { + float length; + float thickness; + glm::vec3 basePosition; + glm::vec3 midPosition; + glm::vec3 endPosition; + glm::vec3 midVelocity; + glm::vec3 endVelocity; + }; + bool _returnHeadToCenter; float _audioLoudness; glm::vec3 _skinColor; @@ -80,6 +93,7 @@ private: glm::vec3 _bodyRotation; glm::vec3 _headRotation; bool _renderLookatVectors; + HairTuft _hairTuft[NUM_HAIR_TUFTS]; // private methods void renderHeadSphere(); @@ -90,6 +104,8 @@ private: void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition); void calculateGeometry( bool lookingInMirror); void determineIfLookingAtSomething(); + void updateHair(float deltaTime); + void renderHair(glm::vec3 cameraPosition); }; #endif From f961a40d1c100b6e1e60be2a79503e6169c5e8dc Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 10:55:26 -0700 Subject: [PATCH 02/27] Chat message height doubled to clear mohawk --- interface/src/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index bdfd7c8691..5edf677ea3 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -67,7 +67,7 @@ float lightBlue [] = {0.7, 0.8, 1.0 }; bool usingBigSphereCollisionTest = true; float chatMessageScale = 0.0015; -float chatMessageHeight = 0.10; +float chatMessageHeight = 0.20; Avatar::Avatar(bool isMine) : _isMine(isMine), From 59ac5ebd6638ab98e8def7a88a37fa4ab83b7215 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 11:07:19 -0700 Subject: [PATCH 03/27] Head will always render when body does - no decapitation --- interface/src/Avatar.cpp | 2 +- interface/src/Head.cpp | 33 ++++++++++++++++++++------------- interface/src/Head.h | 1 + 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 5edf677ea3..37b612d41d 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1135,7 +1135,7 @@ void Avatar::renderBody(bool lookingInMirror) { float distanceToCamera = glm::length(getCameraPosition() - _joint[b].position); // Always render other people, and render myself when beyond threshold distance if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case - if (lookingInMirror || !_isMine || distanceToCamera > RENDER_OPAQUE_BEYOND) { + if (lookingInMirror || !_isMine || distanceToCamera > RENDER_TRANSLUCENT_BEYOND) { _head.render(lookingInMirror); } } else if (!_isMine || distanceToCamera > RENDER_TRANSLUCENT_BEYOND) { diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index cc628a448f..22b82b2ff4 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -8,6 +8,7 @@ #include "Util.h" #include #include +#include using namespace std; @@ -55,8 +56,9 @@ Head::Head() : _returnSpringScale(1.0f), _bodyRotation(0.0f, 0.0f, 0.0f), _headRotation(0.0f, 0.0f, 0.0f), - _renderLookatVectors(false) { - createMohawk(); + _renderLookatVectors(false), + _mohawkExists(false) +{ } void Head::reset() { @@ -190,6 +192,7 @@ void Head::render(bool lookingInMirror) { } void Head::createMohawk() { +// int agentId = AgentList::getInstance() float height = 0.05f + randFloat() * 0.10f; float variance = 0.05 + randFloat() * 0.05f; const float RAD_PER_TRIANGLE = (2.3f + randFloat() * 0.2f) / (float)MOHAWK_TRIANGLES; @@ -207,21 +210,25 @@ void Head::createMohawk() { _mohawkColors[i] = randFloat() * basicColor; } - + _mohawkExists = true; } void Head::renderMohawk() { - glPushMatrix(); - glTranslatef(_position.x, _position.y, _position.z); - glRotatef(_bodyRotation.y, 0, 1, 0); - glBegin(GL_TRIANGLE_FAN); - for (int i = 0; i < MOHAWK_TRIANGLES; i++) { - glColor3f(_mohawkColors[i].x, _mohawkColors[i].y, _mohawkColors[i].z); - glVertex3fv(&_mohawkTriangleFan[i].x); - glNormal3fv(&_mohawkColors[i].x); + if (!_mohawkExists) { + createMohawk(); + } else { + glPushMatrix(); + glTranslatef(_position.x, _position.y, _position.z); + glRotatef(_bodyRotation.y, 0, 1, 0); + glBegin(GL_TRIANGLE_FAN); + for (int i = 0; i < MOHAWK_TRIANGLES; i++) { + glColor3f(_mohawkColors[i].x, _mohawkColors[i].y, _mohawkColors[i].z); + glVertex3fv(&_mohawkTriangleFan[i].x); + glNormal3fv(&_mohawkColors[i].x); + } + glEnd(); + glPopMatrix(); } - glEnd(); - glPopMatrix(); } diff --git a/interface/src/Head.h b/interface/src/Head.h index 3b97361e3f..e7cf3c1bce 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -83,6 +83,7 @@ private: bool _renderLookatVectors; glm::vec3* _mohawkTriangleFan; glm::vec3* _mohawkColors; + bool _mohawkExists; // private methods void createMohawk(); From 17c898c151ec1e21b8c47ad3712f964b98c64396 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 11:33:00 -0700 Subject: [PATCH 04/27] Long term averaging of the gyros for better stability --- interface/src/Application.cpp | 2 +- interface/src/SerialInterface.cpp | 43 ++++++++++++++++++++++--------- interface/src/SerialInterface.h | 6 +++-- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 37b8cf31b6..7652c60461 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -884,7 +884,7 @@ void Application::idle() { // Read serial port interface devices if (_serialPort.active) { - _serialPort.readData(); + _serialPort.readData(deltaTime); } // Sample hardware, update view frustum if needed, and send avatar data to mixer/agents diff --git a/interface/src/SerialInterface.cpp b/interface/src/SerialInterface.cpp index 1989736bf8..b730d2a907 100644 --- a/interface/src/SerialInterface.cpp +++ b/interface/src/SerialInterface.cpp @@ -15,6 +15,7 @@ const short NO_READ_MAXIMUM_MSECS = 3000; const int GRAVITY_SAMPLES = 60; // Use the first few samples to baseline values +const int LONG_TERM_RATE_SAMPLES = 1000; const bool USING_INVENSENSE_MPU9150 = 1; @@ -136,6 +137,16 @@ void SerialInterface::renderLevels(int width, int height) { glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + getLastPitchRate(), LEVEL_CORNER_Y + 12); glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 27); glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + getLastRollRate(), LEVEL_CORNER_Y + 27); + // Gyro Estimated Rotation + glColor4f(0, 1, 1, 1); + glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y - 1); + glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _estimatedRotation.y, LEVEL_CORNER_Y - 1); + glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 14); + glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _estimatedRotation.z, LEVEL_CORNER_Y + 14); + glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 29); + glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _estimatedRotation.x, LEVEL_CORNER_Y + 29); + + // Acceleration glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 42); glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)((_lastAccelX - _gravity.x)* ACCEL_VIEW_SCALING), @@ -169,7 +180,7 @@ void convertHexToInt(unsigned char* sourceBuffer, int& destinationInt) { destinationInt = result; } -void SerialInterface::readData() { +void SerialInterface::readData(float deltaTime) { #ifdef __APPLE__ int initialSamples = totalSamples; @@ -207,6 +218,11 @@ void SerialInterface::readData() { _lastYawRate = ((float) -yawRate) * LSB_TO_DEGREES_PER_SECOND; _lastPitchRate = ((float) -pitchRate) * LSB_TO_DEGREES_PER_SECOND; + // Update raw rotation estimates + _estimatedRotation += deltaTime * glm::vec3(_lastRollRate - _averageGyroRates[0], + _lastYawRate - _averageGyroRates[1], + _lastPitchRate - _averageGyroRates[2]); + // Accumulate a set of initial baseline readings for setting gravity if (totalSamples == 0) { _averageGyroRates[0] = _lastRollRate; @@ -216,17 +232,20 @@ void SerialInterface::readData() { _gravity.y = _lastAccelY; _gravity.z = _lastAccelZ; - } - else if (totalSamples < GRAVITY_SAMPLES) { - _gravity = (1.f - 1.f/(float)GRAVITY_SAMPLES) * _gravity + - 1.f/(float)GRAVITY_SAMPLES * glm::vec3(_lastAccelX, _lastAccelY, _lastAccelZ); - - _averageGyroRates[0] = (1.f - 1.f/(float)GRAVITY_SAMPLES) * _averageGyroRates[0] + - 1.f/(float)GRAVITY_SAMPLES * _lastRollRate; - _averageGyroRates[1] = (1.f - 1.f/(float)GRAVITY_SAMPLES) * _averageGyroRates[1] + - 1.f/(float)GRAVITY_SAMPLES * _lastYawRate; - _averageGyroRates[2] = (1.f - 1.f/(float)GRAVITY_SAMPLES) * _averageGyroRates[2] + - 1.f/(float)GRAVITY_SAMPLES * _lastPitchRate; + } + else { + // Cumulate long term average to (hopefully) take DC bias out of rotation rates + _averageGyroRates[0] = (1.f - 1.f/(float)LONG_TERM_RATE_SAMPLES) * _averageGyroRates[0] + + 1.f/(float)LONG_TERM_RATE_SAMPLES * _lastRollRate; + _averageGyroRates[1] = (1.f - 1.f/(float)LONG_TERM_RATE_SAMPLES) * _averageGyroRates[1] + + 1.f/(float)LONG_TERM_RATE_SAMPLES * _lastYawRate; + _averageGyroRates[2] = (1.f - 1.f/(float)LONG_TERM_RATE_SAMPLES) * _averageGyroRates[2] + + 1.f/(float)LONG_TERM_RATE_SAMPLES * _lastPitchRate; + + if (totalSamples < GRAVITY_SAMPLES) { + _gravity = (1.f - 1.f/(float)GRAVITY_SAMPLES) * _gravity + + 1.f/(float)GRAVITY_SAMPLES * glm::vec3(_lastAccelX, _lastAccelY, _lastAccelZ); + } } totalSamples++; diff --git a/interface/src/SerialInterface.h b/interface/src/SerialInterface.h index 9aa7bccf04..42d24367f6 100644 --- a/interface/src/SerialInterface.h +++ b/interface/src/SerialInterface.h @@ -38,7 +38,8 @@ class SerialInterface { public: SerialInterface() : active(false), _gravity(0,0,0), - _averageGyroRates(0,0,0), + _averageGyroRates(0, 0, 0), + _estimatedRotation(0, 0, 0), _lastAccelX(0), _lastAccelY(0), _lastAccelZ(0), @@ -47,7 +48,7 @@ public: _lastRollRate(0) {} void pair(); - void readData(); + void readData(float deltaTime); float getLastYawRate() const { return _lastYawRate - _averageGyroRates[1]; } float getLastPitchRate() const { return _lastPitchRate - _averageGyroRates[2]; } @@ -68,6 +69,7 @@ private: timeval lastGoodRead; glm::vec3 _gravity; glm::vec3 _averageGyroRates; + glm::vec3 _estimatedRotation; float _lastAccelX; float _lastAccelY; float _lastAccelZ; From 51ddf40ffeda137605fa66d578a36215b1d9f039 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 24 May 2013 11:54:55 -0700 Subject: [PATCH 05/27] cleaned up hair code --- interface/src/Head.cpp | 15 +++++++-------- interface/src/Head.h | 6 ++++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index c29145774d..44e540db45 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -64,13 +64,16 @@ Head::Head() : _renderLookatVectors(false) { for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { - _hairTuft[t].length = HAIR_LENGTH; - _hairTuft[t].thickness = HAIR_THICKNESS; + _hairTuft[t].length = HAIR_LENGTH; + _hairTuft[t].thickness = HAIR_THICKNESS; + _hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f); + //_hairTuft[t].baseDirection = glm::vec3(0.0f, 1.0f, 0.0f); + _hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f); _hairTuft[t].midPosition = glm::vec3(0.0f, 0.0f, 0.0f); _hairTuft[t].endPosition = glm::vec3(0.0f, 0.0f, 0.0f); _hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f); - _hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f); + _hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f); } } @@ -79,6 +82,7 @@ void Head::reset() { _leanForward = _leanSideways = 0.0f; for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { + _hairTuft[t].basePosition = _position + _orientation.getUp() * _scale * 0.9f; _hairTuft[t].midPosition = _hairTuft[t].basePosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF; _hairTuft[t].endPosition = _hairTuft[t].midPosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF; @@ -564,7 +568,6 @@ void Head::renderHair(glm::vec3 cameraPosition) { glm::vec3 base1 = _hairTuft[t].basePosition - basePerpendicular * _hairTuft[t].thickness * ONE_HALF; glm::vec3 base2 = _hairTuft[t].basePosition + basePerpendicular * _hairTuft[t].thickness * ONE_HALF; - glm::vec3 mid1 = _hairTuft[t].midPosition - midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; glm::vec3 mid2 = _hairTuft[t].midPosition + midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; @@ -588,7 +591,3 @@ void Head::renderHair(glm::vec3 cameraPosition) { } } - - - - diff --git a/interface/src/Head.h b/interface/src/Head.h index 32f7ddab7e..cdb0ea7cb4 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -24,7 +24,8 @@ enum eyeContactTargets MOUTH }; -const int NUM_HAIR_TUFTS = 4; +const int NUM_HAIR_TUFTS = 4; +const int NUM_HAIR_SEGMENTS = 4; class Head : public HeadData { public: @@ -62,11 +63,12 @@ private: { float length; float thickness; + glm::vec3 basePosition; glm::vec3 midPosition; glm::vec3 endPosition; glm::vec3 midVelocity; - glm::vec3 endVelocity; + glm::vec3 endVelocity; }; bool _returnHeadToCenter; From 8b5901d904a81527c3569bf2601c84a3962abb2c Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 12:04:17 -0700 Subject: [PATCH 06/27] simplified per stephens code review --- interface/src/Head.cpp | 6 +++--- interface/src/Head.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 22b82b2ff4..d25b9de9ea 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -57,7 +57,8 @@ Head::Head() : _bodyRotation(0.0f, 0.0f, 0.0f), _headRotation(0.0f, 0.0f, 0.0f), _renderLookatVectors(false), - _mohawkExists(false) + _mohawkTriangleFan(NULL), + _mohawkColors(NULL) { } @@ -210,11 +211,10 @@ void Head::createMohawk() { _mohawkColors[i] = randFloat() * basicColor; } - _mohawkExists = true; } void Head::renderMohawk() { - if (!_mohawkExists) { + if (!_mohawkTriangleFan) { createMohawk(); } else { glPushMatrix(); diff --git a/interface/src/Head.h b/interface/src/Head.h index e7cf3c1bce..3b97361e3f 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -83,7 +83,6 @@ private: bool _renderLookatVectors; glm::vec3* _mohawkTriangleFan; glm::vec3* _mohawkColors; - bool _mohawkExists; // private methods void createMohawk(); From 36892da4886e6af73be827a256564928e79a5f03 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 May 2013 11:24:21 -0700 Subject: [PATCH 07/27] keep a pointer to owning agent in AgentData --- avatar-mixer/src/main.cpp | 2 +- eve/src/main.cpp | 4 ++-- interface/src/Application.cpp | 6 +++--- interface/src/Avatar.cpp | 3 ++- interface/src/Avatar.h | 2 +- interface/src/VoxelSystem.cpp | 2 +- libraries/audio/src/AudioRingBuffer.cpp | 3 ++- libraries/avatars/src/AvatarData.cpp | 3 ++- libraries/avatars/src/AvatarData.h | 2 +- libraries/shared/src/AgentData.cpp | 6 ++++++ libraries/shared/src/AgentData.h | 7 ++++++- voxel-server/src/VoxelAgentData.cpp | 1 + 12 files changed, 28 insertions(+), 13 deletions(-) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index da2b41b1bd..0e838833f4 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -47,7 +47,7 @@ unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent * void attachAvatarDataToAgent(Agent *newAgent) { if (newAgent->getLinkedData() == NULL) { - newAgent->setLinkedData(new AvatarData()); + newAgent->setLinkedData(new AvatarData(newAgent)); } } diff --git a/eve/src/main.cpp b/eve/src/main.cpp index 62be6e36cd..92355970c6 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -71,7 +71,7 @@ void *receiveAgentData(void *args) { void createAvatarDataForAgent(Agent* agent) { if (!agent->getLinkedData()) { - agent->setLinkedData(new AvatarData()); + agent->setLinkedData(new AvatarData(agent)); } } @@ -95,7 +95,7 @@ int main(int argc, const char* argv[]) { pthread_create(&receiveAgentDataThread, NULL, receiveAgentData, NULL); // create an AvatarData object, "eve" - AvatarData eve; + AvatarData eve(NULL); // move eve away from the origin // pick a random point inside a 10x10 grid diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 37b8cf31b6..80690e162a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -128,7 +128,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _viewFrustumOffsetDistance(25.0), _viewFrustumOffsetUp(0.0), _audioScope(256, 200, true), - _myAvatar(true), + _myAvatar(NULL, true), _manualFirstPerson(false), _mouseX(0), _mouseY(0), @@ -2098,9 +2098,9 @@ QAction* Application::checkedVoxelModeAction() const { return 0; } -void Application::attachNewHeadToAgent(Agent *newAgent) { +void Application::attachNewHeadToAgent(Agent* newAgent) { if (newAgent->getLinkedData() == NULL) { - newAgent->setLinkedData(new Avatar(false)); + newAgent->setLinkedData(new Avatar(newAgent, false)); } } diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index bdfd7c8691..de93fd859c 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -69,7 +69,8 @@ bool usingBigSphereCollisionTest = true; float chatMessageScale = 0.0015; float chatMessageHeight = 0.10; -Avatar::Avatar(bool isMine) : +Avatar::Avatar(Agent* owningAgent, bool isMine) : + AvatarData(owningAgent), _isMine(isMine), _TEST_bigSphereRadius(0.4f), _TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f), diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 59f9018af3..a5f1531417 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -76,7 +76,7 @@ enum AvatarJointID class Avatar : public AvatarData { public: - Avatar(bool isMine); + Avatar(Agent* owningAgent, bool isMine); ~Avatar(); void reset(); diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 026f1dd4ee..68707355bb 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -44,7 +44,7 @@ GLubyte identityIndices[] = { 0,2,1, 0,3,2, // Z- . 10,11,15, 10,15,14, // Y+ 4,5,6, 4,6,7 }; // Z+ . -VoxelSystem::VoxelSystem() { +VoxelSystem::VoxelSystem() : AgentData(NULL) { _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; _writeRenderFullVBO = true; _readRenderFullVBO = true; diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 59b35b18a3..ee693ebde3 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -13,6 +13,7 @@ #include "AudioRingBuffer.h" AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) : + AgentData(NULL), _ringBufferLengthSamples(ringSamples), _bufferLengthSamples(bufferSamples), _endOfLastWrite(NULL), @@ -20,7 +21,7 @@ AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) : _shouldBeAddedToMix(false), _shouldLoopbackForAgent(false), _streamIdentifier() -{ +{ _buffer = new int16_t[_ringBufferLengthSamples]; _nextOutput = _buffer; }; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ab69c28dd0..c660e55347 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -31,7 +31,8 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo return sizeof(uint16_t); } -AvatarData::AvatarData() : +AvatarData::AvatarData(Agent* owningAgent) : + AgentData(owningAgent), _handPosition(0,0,0), _bodyYaw(-90.0), _bodyPitch(0.0), diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 3e3536c3a9..b1582cf9f8 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -29,7 +29,7 @@ enum KeyState class AvatarData : public AgentData { public: - AvatarData(); + AvatarData(Agent* owningAgent); ~AvatarData(); const glm::vec3& getPosition() const { return _position; } diff --git a/libraries/shared/src/AgentData.cpp b/libraries/shared/src/AgentData.cpp index f4710246d7..c910a9c43f 100644 --- a/libraries/shared/src/AgentData.cpp +++ b/libraries/shared/src/AgentData.cpp @@ -8,4 +8,10 @@ #include "AgentData.h" +AgentData::AgentData(Agent* owningAgent) : + _owningAgent(owningAgent) +{ + +} + AgentData::~AgentData() {} \ No newline at end of file diff --git a/libraries/shared/src/AgentData.h b/libraries/shared/src/AgentData.h index 342f501a1e..99cdbaca95 100644 --- a/libraries/shared/src/AgentData.h +++ b/libraries/shared/src/AgentData.h @@ -3,16 +3,21 @@ // hifi // // Created by Stephen Birarda on 2/19/13. -// +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // #ifndef hifi_AgentData_h #define hifi_AgentData_h +class Agent; + class AgentData { public: + AgentData(Agent* owningAgent); virtual ~AgentData() = 0; virtual int parseData(unsigned char* sourceBuffer, int numBytes) = 0; +private: + Agent* _owningAgent; }; #endif diff --git a/voxel-server/src/VoxelAgentData.cpp b/voxel-server/src/VoxelAgentData.cpp index e25defef7a..a017881301 100644 --- a/voxel-server/src/VoxelAgentData.cpp +++ b/voxel-server/src/VoxelAgentData.cpp @@ -12,6 +12,7 @@ #include VoxelAgentData::VoxelAgentData() : + AvatarData(NULL), _viewSent(false), _voxelPacketAvailableBytes(MAX_VOXEL_PACKET_SIZE), _maxSearchLevel(1), From 49b483ef53a38a3aa2b8427f7b441a428138ec28 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 May 2013 11:29:49 -0700 Subject: [PATCH 08/27] maintain a pointer to owning avatar from HeadData --- interface/src/Avatar.cpp | 1 + interface/src/Head.cpp | 4 ++-- interface/src/Head.h | 4 +++- libraries/avatars/src/AvatarData.cpp | 4 ++-- libraries/avatars/src/HeadData.cpp | 5 +++-- libraries/avatars/src/HeadData.h | 5 ++++- 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index de93fd859c..125ef979bb 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -71,6 +71,7 @@ float chatMessageHeight = 0.10; Avatar::Avatar(Agent* owningAgent, bool isMine) : AvatarData(owningAgent), + _head(this), _isMine(isMine), _TEST_bigSphereRadius(0.4f), _TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f), diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index cc628a448f..0d891cf0e6 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -30,8 +30,8 @@ unsigned int IRIS_TEXTURE_WIDTH = 768; unsigned int IRIS_TEXTURE_HEIGHT = 498; vector irisTexture; -Head::Head() : - +Head::Head(Avatar* owningAvatar) : + HeadData((AvatarData*)owningAvatar), yawRate(0.0f), _returnHeadToCenter(false), _audioLoudness(0.0f), diff --git a/interface/src/Head.h b/interface/src/Head.h index 3b97361e3f..c20ce0e255 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -24,9 +24,11 @@ enum eyeContactTargets MOUTH }; +class Avatar; + class Head : public HeadData { public: - Head(); + Head(Avatar* owningAvatar); void reset(); void simulate(float deltaTime, bool isMine); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index c660e55347..4b97a2a047 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -68,7 +68,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // lazily allocate memory for HeadData in case we're not an Avatar instance if (!_headData) { - _headData = new HeadData(); + _headData = new HeadData(this); } // Body world position @@ -149,7 +149,7 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { // lazily allocate memory for HeadData in case we're not an Avatar instance if (!_headData) { - _headData = new HeadData(); + _headData = new HeadData(this); } // increment to push past the packet header diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index 9c01346152..906e10e48f 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -8,13 +8,14 @@ #include "HeadData.h" -HeadData::HeadData() : +HeadData::HeadData(AvatarData* owningAvatar) : _yaw(0.0f), _pitch(0.0f), _roll(0.0f), _lookAtPosition(0.0f, 0.0f, 0.0f), _leanSideways(0.0f), - _leanForward(0.0f) + _leanForward(0.0f), + _owningAvatar(owningAvatar) { } diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index fb16fea00e..1f0a8181b5 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -20,9 +20,11 @@ const float MAX_HEAD_PITCH = 60; const float MIN_HEAD_ROLL = -50; const float MAX_HEAD_ROLL = 50; +class AvatarData; + class HeadData { public: - HeadData(); + HeadData(AvatarData* owningAvatar); float getLeanSideways() const { return _leanSideways; } void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; } @@ -55,6 +57,7 @@ protected: glm::vec3 _lookAtPosition; float _leanSideways; float _leanForward; + AvatarData* _owningAvatar; private: // privatize copy ctor and assignment operator so copies of this object cannot be made HeadData(const HeadData&); From eb25fd3b4648dad9ba197feb9ea87cd1889d7e04 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 May 2013 11:32:17 -0700 Subject: [PATCH 09/27] pass the owning agent for VoxelAgentData constructor --- voxel-server/src/VoxelAgentData.cpp | 4 ++-- voxel-server/src/VoxelAgentData.h | 2 +- voxel-server/src/main.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/voxel-server/src/VoxelAgentData.cpp b/voxel-server/src/VoxelAgentData.cpp index a017881301..07d19a7fb2 100644 --- a/voxel-server/src/VoxelAgentData.cpp +++ b/voxel-server/src/VoxelAgentData.cpp @@ -11,8 +11,8 @@ #include #include -VoxelAgentData::VoxelAgentData() : - AvatarData(NULL), +VoxelAgentData::VoxelAgentData(Agent* owningAgent) : + AvatarData(owningAgent), _viewSent(false), _voxelPacketAvailableBytes(MAX_VOXEL_PACKET_SIZE), _maxSearchLevel(1), diff --git a/voxel-server/src/VoxelAgentData.h b/voxel-server/src/VoxelAgentData.h index fbf5f12d3d..2afc64a6c8 100644 --- a/voxel-server/src/VoxelAgentData.h +++ b/voxel-server/src/VoxelAgentData.h @@ -17,7 +17,7 @@ class VoxelAgentData : public AvatarData { public: - VoxelAgentData(); + VoxelAgentData(Agent* owningAgent); ~VoxelAgentData(); void resetVoxelPacket(); // resets voxel packet to after "V" header diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 4e5f931477..e2ffda0a0a 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -450,9 +450,9 @@ void *distributeVoxelsToListeners(void *args) { pthread_exit(0); } -void attachVoxelAgentDataToAgent(Agent *newAgent) { +void attachVoxelAgentDataToAgent(Agent* newAgent) { if (newAgent->getLinkedData() == NULL) { - newAgent->setLinkedData(new VoxelAgentData()); + newAgent->setLinkedData(new VoxelAgentData(newAgent)); } } From 59a6016f4b2529ace072e4ee0dd9cb9de9198874 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 May 2013 11:49:22 -0700 Subject: [PATCH 10/27] use a NULL default for owningAvatar to simplify constructors --- avatar-mixer/src/main.cpp | 2 +- eve/src/main.cpp | 2 +- interface/src/Application.cpp | 3 +-- interface/src/Avatar.cpp | 35 +++++++++++++++--------------- interface/src/Avatar.h | 3 +-- libraries/avatars/src/AvatarData.h | 4 ++-- libraries/shared/src/AgentData.h | 2 +- 7 files changed, 24 insertions(+), 27 deletions(-) diff --git a/avatar-mixer/src/main.cpp b/avatar-mixer/src/main.cpp index 0e838833f4..eca698e673 100644 --- a/avatar-mixer/src/main.cpp +++ b/avatar-mixer/src/main.cpp @@ -45,7 +45,7 @@ unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent * return currentPosition; } -void attachAvatarDataToAgent(Agent *newAgent) { +void attachAvatarDataToAgent(Agent* newAgent) { if (newAgent->getLinkedData() == NULL) { newAgent->setLinkedData(new AvatarData(newAgent)); } diff --git a/eve/src/main.cpp b/eve/src/main.cpp index 92355970c6..bf32474b33 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -95,7 +95,7 @@ int main(int argc, const char* argv[]) { pthread_create(&receiveAgentDataThread, NULL, receiveAgentData, NULL); // create an AvatarData object, "eve" - AvatarData eve(NULL); + AvatarData eve; // move eve away from the origin // pick a random point inside a 10x10 grid diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 80690e162a..990ca2aeff 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -128,7 +128,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _viewFrustumOffsetDistance(25.0), _viewFrustumOffsetUp(0.0), _audioScope(256, 200, true), - _myAvatar(NULL, true), _manualFirstPerson(false), _mouseX(0), _mouseY(0), @@ -2100,7 +2099,7 @@ QAction* Application::checkedVoxelModeAction() const { void Application::attachNewHeadToAgent(Agent* newAgent) { if (newAgent->getLinkedData() == NULL) { - newAgent->setLinkedData(new Avatar(newAgent, false)); + newAgent->setLinkedData(new Avatar(newAgent)); } } diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 125ef979bb..83a3508b0d 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -69,10 +69,9 @@ bool usingBigSphereCollisionTest = true; float chatMessageScale = 0.0015; float chatMessageHeight = 0.10; -Avatar::Avatar(Agent* owningAgent, bool isMine) : +Avatar::Avatar(Agent* owningAgent) : AvatarData(owningAgent), _head(this), - _isMine(isMine), _TEST_bigSphereRadius(0.4f), _TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f), _mousePressed(false), @@ -231,7 +230,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { updateSkeleton(); //detect and respond to collisions with other avatars... - if (_isMine) { + if (!_owningAgent) { updateAvatarCollisions(deltaTime); } @@ -241,7 +240,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _avatarTouch.simulate(deltaTime); // apply gravity and collision with the ground/floor - if (_isMine && USING_AVATAR_GRAVITY) { + if (!_owningAgent && USING_AVATAR_GRAVITY) { _velocity += _gravity * (GRAVITY_SCALE * deltaTime); updateCollisionWithEnvironment(); @@ -256,12 +255,12 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } // collision response with voxels - if (_isMine) { + if (!_owningAgent) { updateCollisionWithVoxels(); } // driving the avatar around should only apply if this is my avatar (as opposed to an avatar being driven remotely) - if (_isMine) { + if (!_owningAgent) { _thrust = glm::vec3(0.0f, 0.0f, 0.0f); @@ -306,7 +305,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } // update body yaw by body yaw delta - if (_isMine) { + if (!_owningAgent) { _bodyPitch += _bodyPitchDelta * deltaTime; _bodyYaw += _bodyYawDelta * deltaTime; _bodyRoll += _bodyRollDelta * deltaTime; @@ -367,7 +366,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } // If another avatar is near, dampen velocity as a function of closeness - if (_isMine && (_distanceToNearestAvatar < PERIPERSONAL_RADIUS)) { + if (!_owningAgent && (_distanceToNearestAvatar < PERIPERSONAL_RADIUS)) { float closeness = 1.0f - (_distanceToNearestAvatar / PERIPERSONAL_RADIUS); float drag = 1.0f - closeness * AVATAR_BRAKING_STRENGTH * deltaTime; if ( drag > 0.0f ) { @@ -416,7 +415,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } // set head lookat position - if (_isMine) { + if (!_owningAgent) { if (_interactingOther) { _head.setLookAtPosition(_interactingOther->caclulateAverageEyePosition()); } else { @@ -429,7 +428,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius); _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); - _head.simulate(deltaTime, _isMine); + _head.simulate(deltaTime, !_owningAgent); // use speed and angular velocity to determine walking vs. standing if (_speed + fabs(_bodyYawDelta) > 0.2) { @@ -468,7 +467,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position += transformedHandMovement; - if (_isMine) { + if (!_owningAgent) { _avatarTouch.setMyBodyPosition(_position); float closestDistance = std::numeric_limits::max(); @@ -560,7 +559,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { updateArmIKAndConstraints(deltaTime); //Set right hand position and state to be transmitted, and also tell AvatarTouch about it - if (_isMine) { + if (!_owningAgent) { setHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position); if (_mousePressed) { @@ -729,7 +728,7 @@ void Avatar::setGravity(glm::vec3 gravity) { void Avatar::render(bool lookingInMirror) { - if (_isMine && usingBigSphereCollisionTest) { + if (!_owningAgent && usingBigSphereCollisionTest) { // show TEST big sphere glColor4f(0.5f, 0.6f, 0.8f, 0.7); glPushMatrix(); @@ -746,7 +745,7 @@ void Avatar::render(bool lookingInMirror) { renderBody(lookingInMirror); // if this is my avatar, then render my interactions with the other avatar - if (_isMine) { + if (!_owningAgent) { _avatarTouch.render(getCameraPosition()); } @@ -1001,7 +1000,7 @@ void Avatar::updateSkeleton() { } // if this is not my avatar, then hand position comes from transmitted data - if (! _isMine) { + if (_owningAgent) { _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition; } @@ -1137,12 +1136,12 @@ void Avatar::renderBody(bool lookingInMirror) { float distanceToCamera = glm::length(getCameraPosition() - _joint[b].position); // Always render other people, and render myself when beyond threshold distance if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case - if (lookingInMirror || !_isMine || distanceToCamera > RENDER_OPAQUE_BEYOND) { + if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND) { _head.render(lookingInMirror); } - } else if (!_isMine || distanceToCamera > RENDER_TRANSLUCENT_BEYOND) { + } else if (_owningAgent || distanceToCamera > RENDER_TRANSLUCENT_BEYOND) { // Render the sphere at the joint - if (!_isMine) { + if (_owningAgent) { glColor3f(skinColor[0] + _joint[b].touchForce * 0.3f, skinColor[1] - _joint[b].touchForce * 0.2f, skinColor[2] - _joint[b].touchForce * 0.1f); diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index a5f1531417..6d27eed22b 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -76,7 +76,7 @@ enum AvatarJointID class Avatar : public AvatarData { public: - Avatar(Agent* owningAgent, bool isMine); + Avatar(Agent* owningAgent = NULL); ~Avatar(); void reset(); @@ -151,7 +151,6 @@ private: }; Head _head; - bool _isMine; float _TEST_bigSphereRadius; glm::vec3 _TEST_bigSpherePosition; bool _mousePressed; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index b1582cf9f8..5773dedffd 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -22,14 +22,14 @@ const int WANT_DELTA_AT_BIT = 2; enum KeyState { - NO_KEY_DOWN, + NO_KEY_DOWN, INSERT_KEY_DOWN, DELETE_KEY_DOWN }; class AvatarData : public AgentData { public: - AvatarData(Agent* owningAgent); + AvatarData(Agent* owningAgent = NULL); ~AvatarData(); const glm::vec3& getPosition() const { return _position; } diff --git a/libraries/shared/src/AgentData.h b/libraries/shared/src/AgentData.h index 99cdbaca95..7253d85e59 100644 --- a/libraries/shared/src/AgentData.h +++ b/libraries/shared/src/AgentData.h @@ -16,7 +16,7 @@ public: AgentData(Agent* owningAgent); virtual ~AgentData() = 0; virtual int parseData(unsigned char* sourceBuffer, int numBytes) = 0; -private: +protected: Agent* _owningAgent; }; From dc9b2e33b5d162c5c7fba924892d880167fda160 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 12:30:05 -0700 Subject: [PATCH 11/27] Fixing mohawk orientation --- interface/src/Head.cpp | 9 +++++---- interface/src/Head.h | 2 -- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index d25b9de9ea..c7e2e4a31d 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -55,7 +55,6 @@ Head::Head() : _audioAttack(0.0f), _returnSpringScale(1.0f), _bodyRotation(0.0f, 0.0f, 0.0f), - _headRotation(0.0f, 0.0f, 0.0f), _renderLookatVectors(false), _mohawkTriangleFan(NULL), _mohawkColors(NULL) @@ -180,7 +179,7 @@ void Head::render(bool lookingInMirror) { glEnable(GL_DEPTH_TEST); glEnable(GL_RESCALE_NORMAL); - renderMohawk(); + renderMohawk(lookingInMirror); renderHeadSphere(); renderEyeBalls(); renderEars(); @@ -213,13 +212,15 @@ void Head::createMohawk() { } } -void Head::renderMohawk() { +void Head::renderMohawk(bool lookingInMirror) { if (!_mohawkTriangleFan) { createMohawk(); } else { glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); - glRotatef(_bodyRotation.y, 0, 1, 0); + glRotatef(-(_bodyRotation.y + _yaw) - 90, 0, 1, 0); + //glRotatef((lookingInMirror ? _roll: -roll), 0, 0, 1); + glRotatef(-_pitch, 1, 0, 0); glBegin(GL_TRIANGLE_FAN); for (int i = 0; i < MOHAWK_TRIANGLES; i++) { glColor3f(_mohawkColors[i].x, _mohawkColors[i].y, _mohawkColors[i].z); diff --git a/interface/src/Head.h b/interface/src/Head.h index 3b97361e3f..9edd0d348a 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -36,7 +36,6 @@ public: void setScale (float scale ) { _scale = scale; } void setPosition (glm::vec3 position ) { _position = position; } void setBodyRotation (glm::vec3 bodyRotation ) { _bodyRotation = bodyRotation; } - void setRotationOffBody(glm::vec3 headRotation ) { _headRotation = headRotation; } void setGravity (glm::vec3 gravity ) { _gravity = gravity; } void setSkinColor (glm::vec3 skinColor ) { _skinColor = skinColor; } void setSpringScale (float returnSpringScale ) { _returnSpringScale = returnSpringScale; } @@ -79,7 +78,6 @@ private: float _returnSpringScale; //strength of return springs Orientation _orientation; glm::vec3 _bodyRotation; - glm::vec3 _headRotation; bool _renderLookatVectors; glm::vec3* _mohawkTriangleFan; glm::vec3* _mohawkColors; From 6158410658e5dcef5336a95214884c55cec83acb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 May 2013 12:32:00 -0700 Subject: [PATCH 12/27] provide a getter for the owning agent in AgentData --- libraries/shared/src/AgentData.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/shared/src/AgentData.h b/libraries/shared/src/AgentData.h index 7253d85e59..9c931dd65a 100644 --- a/libraries/shared/src/AgentData.h +++ b/libraries/shared/src/AgentData.h @@ -14,8 +14,11 @@ class Agent; class AgentData { public: AgentData(Agent* owningAgent); + virtual ~AgentData() = 0; virtual int parseData(unsigned char* sourceBuffer, int numBytes) = 0; + + Agent* getOwningAgent() { return _owningAgent; } protected: Agent* _owningAgent; }; From cb7381fcd1cc6616bef76a0b5363a9d17afbbd5b Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 12:33:05 -0700 Subject: [PATCH 13/27] incremental fix rotation --- interface/src/Head.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 5c85c982f9..c406a1e267 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -192,7 +192,7 @@ void Head::render(bool lookingInMirror) { } void Head::createMohawk() { -// int agentId = AgentList::getInstance() + //if (_owningAvatar->getOwningAgent) float height = 0.05f + randFloat() * 0.10f; float variance = 0.05 + randFloat() * 0.05f; const float RAD_PER_TRIANGLE = (2.3f + randFloat() * 0.2f) / (float)MOHAWK_TRIANGLES; @@ -219,7 +219,7 @@ void Head::renderMohawk(bool lookingInMirror) { glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); glRotatef(-(_bodyRotation.y + _yaw) - 90, 0, 1, 0); - //glRotatef((lookingInMirror ? _roll: -roll), 0, 0, 1); + glRotatef(lookingInMirror ? _roll: -_roll, 0, 0, 1); glRotatef(-_pitch, 1, 0, 0); glBegin(GL_TRIANGLE_FAN); for (int i = 0; i < MOHAWK_TRIANGLES; i++) { From d12bc85376e1cdc3d57597f2a71b2db9320bbfaf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 May 2013 14:05:22 -0700 Subject: [PATCH 14/27] go directly into oculus mode when the oculus is connected --- interface/src/Application.cpp | 19 +++++++------------ interface/src/Application.h | 7 +++---- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 18d27ee38c..d97e5f83a2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -351,9 +351,8 @@ void Application::paintGL() { whichCamera = _viewFrustumOffsetCamera; } - if (_oculusOn->isChecked()) { + if (OculusManager::isConnected()) { displayOculus(whichCamera); - } else { glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -376,7 +375,7 @@ void Application::resizeGL(int width, int height) { float farClip = camera.getFarClip(); float fov; - if (_oculusOn->isChecked()) { + if (OculusManager::isConnected()) { // more magic numbers; see Oculus SDK docs, p. 32 camera.setAspectRatio(aspectRatio *= 0.5); camera.setFieldOfView(fov = 2 * atan((0.0468 * _oculusDistortionScale) / 0.041) * (180 / PI)); @@ -1008,11 +1007,6 @@ void Application::setRenderFirstPerson(bool firstPerson) { _manualFirstPerson = firstPerson; } -void Application::setOculus(bool oculus) { - resizeGL(_glWidget->width(), _glWidget->height()); - updateCursor(); -} - void Application::setFrustumOffset(bool frustumOffset) { // reshape so that OpenGL will get the right lens details for the camera of choice resizeGL(_glWidget->width(), _glWidget->height()); @@ -1163,7 +1157,7 @@ void Application::initMenu() { (_transmitterDrives = optionsMenu->addAction("Transmitter Drive"))->setCheckable(true); _transmitterDrives->setChecked(true); - optionsMenu->addAction("Fullscreen", this, SLOT(setFullscreen(bool)), Qt::Key_F)->setCheckable(true); + (_fullScreenMode = optionsMenu->addAction("Fullscreen", this, SLOT(setFullscreen(bool)), Qt::Key_F))->setCheckable(true); QMenu* renderMenu = menuBar->addMenu("Render"); (_renderVoxels = renderMenu->addAction("Voxels"))->setCheckable(true); @@ -1184,8 +1178,6 @@ void Application::initMenu() { _renderLookatOn->setChecked(false); renderMenu->addAction("First Person", this, SLOT(setRenderFirstPerson(bool)), Qt::Key_P)->setCheckable(true); - - (_oculusOn = renderMenu->addAction("Oculus", this, SLOT(setOculus(bool)), Qt::Key_O))->setCheckable(true); QMenu* toolsMenu = menuBar->addMenu("Tools"); @@ -1301,6 +1293,9 @@ void Application::init() { QCursor::setPos(_headMouseX, _headMouseY); OculusManager::connect(); + if (OculusManager::isConnected()) { + QMetaObject::invokeMethod(_fullScreenMode, "trigger", Qt::QueuedConnection); + } gettimeofday(&_timerStart, NULL); gettimeofday(&_lastTimeIdle, NULL); @@ -2082,7 +2077,7 @@ void Application::setMenuShortcutsEnabled(bool enabled) { } void Application::updateCursor() { - _glWidget->setCursor(_oculusOn->isChecked() && _window->windowState().testFlag(Qt::WindowFullScreen) ? + _glWidget->setCursor(OculusManager::isConnected() && _window->windowState().testFlag(Qt::WindowFullScreen) ? Qt::BlankCursor : Qt::ArrowCursor); } diff --git a/interface/src/Application.h b/interface/src/Application.h index ca2604b42e..35d49d275a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -78,7 +78,6 @@ private slots: void setFullscreen(bool fullscreen); void setRenderFirstPerson(bool firstPerson); - void setOculus(bool oculus); void setFrustumOffset(bool frustumOffset); void cycleFrustumRenderMode(); @@ -147,8 +146,7 @@ private: 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 - QAction* _oculusOn; // Whether to configure the display for the Oculus Rift + QAction* _renderAvatarsOn; // Whether to render avatars QAction* _renderStatsOn; // Whether to show onscreen text overlay with stats QAction* _renderFrameTimerOn; // Whether to show onscreen text overlay with stats QAction* _renderLookatOn; // Whether to show lookat vectors from avatar eyes if looking at something @@ -161,7 +159,8 @@ private: QAction* _destructiveAddVoxel; // when doing voxel editing do we want them to be destructive QAction* _frustumOn; // Whether or not to display the debug view frustum QAction* _viewFrustumFromOffset; // Whether or not to offset the view of the frustum - QAction* _cameraFrustum; // which frustum to look at + QAction* _cameraFrustum; // which frustum to look at + QAction* _fullScreenMode; // whether we are in full screen mode QAction* _frustumRenderModeAction; SerialInterface _serialPort; From f5c0f84d279f1fead4842a7030fedf0b4ee71c56 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 14:15:53 -0700 Subject: [PATCH 15/27] Mohawk is different/stable for each person, and rotates correctly with head --- interface/src/Head.cpp | 16 ++++++++++++---- interface/src/Head.h | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index c406a1e267..4331b15e0c 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -192,9 +192,16 @@ void Head::render(bool lookingInMirror) { } void Head::createMohawk() { - //if (_owningAvatar->getOwningAgent) - float height = 0.05f + randFloat() * 0.10f; - float variance = 0.05 + randFloat() * 0.05f; + uint16_t agentId = 0; + if (_owningAvatar->getOwningAgent()) { + agentId = _owningAvatar->getOwningAgent()->getAgentID(); + } else { + agentId = AgentList::getInstance()->getOwnerID(); + if (agentId == UNKNOWN_AGENT_ID) return; + } + srand(agentId); + float height = 0.08f + randFloat() * 0.05f; + float variance = 0.03 + randFloat() * 0.03f; const float RAD_PER_TRIANGLE = (2.3f + randFloat() * 0.2f) / (float)MOHAWK_TRIANGLES; _mohawkTriangleFan = new glm::vec3[MOHAWK_TRIANGLES]; _mohawkColors = new glm::vec3[MOHAWK_TRIANGLES]; @@ -218,9 +225,10 @@ void Head::renderMohawk(bool lookingInMirror) { } else { glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); - glRotatef(-(_bodyRotation.y + _yaw) - 90, 0, 1, 0); + glRotatef((lookingInMirror ? (_bodyRotation.y - _yaw) : (_bodyRotation.y + _yaw)), 0, 1, 0); glRotatef(lookingInMirror ? _roll: -_roll, 0, 0, 1); glRotatef(-_pitch, 1, 0, 0); + glBegin(GL_TRIANGLE_FAN); for (int i = 0; i < MOHAWK_TRIANGLES; i++) { glColor3f(_mohawkColors[i].x, _mohawkColors[i].y, _mohawkColors[i].z); diff --git a/interface/src/Head.h b/interface/src/Head.h index 35c9ff3464..f8019b5cb4 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -33,7 +33,7 @@ public: void reset(); void simulate(float deltaTime, bool isMine); void render(bool lookingInMirror); - void renderMohawk(); + void renderMohawk(bool lookingInMirror); void setScale (float scale ) { _scale = scale; } void setPosition (glm::vec3 position ) { _position = position; } From 5ca01842be19dc36dbd090833efeaec65c0ce289 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 24 May 2013 14:24:47 -0700 Subject: [PATCH 16/27] Made the atmospheres twice as thick, made the large planet one's red. --- voxel-server/src/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index e2ffda0a0a..1a93021f09 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -562,12 +562,13 @@ int main(int argc, const char * argv[]) { environmentData[1].setGravity(1.0f); environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE); environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE); - environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.025f); + environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f); environmentData[2].setID(2); environmentData[2].setGravity(1.0f); environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE); environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE); - environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.025f); + environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f); + environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue pthread_t sendVoxelThread; pthread_create(&sendVoxelThread, NULL, distributeVoxelsToListeners, NULL); From 9baf087c9a936aa088c9b63f1d098f4dfb5ab85b Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 14:29:26 -0700 Subject: [PATCH 17/27] Avatar renders right arm in 1P mode --- interface/src/Avatar.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 21dea8886f..7568e45116 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1139,9 +1139,14 @@ void Avatar::renderBody(bool lookingInMirror) { if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND) { _head.render(lookingInMirror); } - } else if (_owningAgent || distanceToCamera > RENDER_TRANSLUCENT_BEYOND) { + } else if (_owningAgent || distanceToCamera > RENDER_TRANSLUCENT_BEYOND + || b == AVATAR_JOINT_RIGHT_ELBOW + || b == AVATAR_JOINT_RIGHT_WRIST + || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { // Render the sphere at the joint - if (_owningAgent) { + if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW + || b == AVATAR_JOINT_RIGHT_WRIST + || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { glColor3f(skinColor[0] + _joint[b].touchForce * 0.3f, skinColor[1] - _joint[b].touchForce * 0.2f, skinColor[2] - _joint[b].touchForce * 0.1f); From d796956a96c0a511e8fa38fb282b4c6e4a719d72 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 14:32:56 -0700 Subject: [PATCH 18/27] fix per review --- interface/src/Head.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 4331b15e0c..6fec0837c6 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -197,7 +197,9 @@ void Head::createMohawk() { agentId = _owningAvatar->getOwningAgent()->getAgentID(); } else { agentId = AgentList::getInstance()->getOwnerID(); - if (agentId == UNKNOWN_AGENT_ID) return; + if (agentId == UNKNOWN_AGENT_ID) { + return; + } } srand(agentId); float height = 0.08f + randFloat() * 0.05f; From 995fbcf4f952f53fe55c62da474c1da12e39b74f Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 14:46:26 -0700 Subject: [PATCH 19/27] mohawk also follows body pitch when accelerating --- interface/src/Head.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 6fec0837c6..99237ba6b4 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -229,7 +229,7 @@ void Head::renderMohawk(bool lookingInMirror) { glTranslatef(_position.x, _position.y, _position.z); glRotatef((lookingInMirror ? (_bodyRotation.y - _yaw) : (_bodyRotation.y + _yaw)), 0, 1, 0); glRotatef(lookingInMirror ? _roll: -_roll, 0, 0, 1); - glRotatef(-_pitch, 1, 0, 0); + glRotatef(-_pitch - _bodyRotation.x, 1, 0, 0); glBegin(GL_TRIANGLE_FAN); for (int i = 0; i < MOHAWK_TRIANGLES; i++) { From 608a4f71bfe423cb784bd85f55d647cbaa1d87ce Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 May 2013 14:51:06 -0700 Subject: [PATCH 20/27] ground surface is 20 meters across. play on! --- interface/src/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d97e5f83a2..c478554903 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1667,7 +1667,8 @@ void Application::displaySide(Camera& whichCamera) { glPopMatrix(); //draw a grid ground plane.... - drawGroundPlaneGrid(10.f); + const float EDGE_SIZE_GROUND_PLANE = 20.f; + drawGroundPlaneGrid(EDGE_SIZE_GROUND_PLANE); // Draw voxels if (_renderVoxels->isChecked()) { From a8b08647d04eb93225fcaecf4b1de6d470e97610 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 May 2013 16:18:36 -0700 Subject: [PATCH 21/27] require that crotch grabbing be explicit, not implicit --- interface/src/Avatar.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 7568e45116..006b19908e 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -838,6 +838,8 @@ void Avatar::initializeSkeleton() { _joint[ AVATAR_JOINT_RIGHT_COLLAR ].parent = AVATAR_JOINT_CHEST; _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].parent = AVATAR_JOINT_RIGHT_COLLAR; _joint[ AVATAR_JOINT_RIGHT_ELBOW ].parent = AVATAR_JOINT_RIGHT_SHOULDER; + _joint[ AVATAR_JOINT_RIGHT_WRIST ].parent = AVATAR_JOINT_RIGHT_ELBOW; + _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].parent = AVATAR_JOINT_RIGHT_WRIST; _joint[ AVATAR_JOINT_LEFT_HIP ].parent = AVATAR_JOINT_PELVIS; _joint[ AVATAR_JOINT_LEFT_KNEE ].parent = AVATAR_JOINT_LEFT_HIP; _joint[ AVATAR_JOINT_LEFT_HEEL ].parent = AVATAR_JOINT_LEFT_KNEE; From 12d0ccb7124dc8835ecd4fa1ac9092dae4105112 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 May 2013 16:32:52 -0700 Subject: [PATCH 22/27] tune the distance attenuation to use log of base 2.5 --- audio-mixer/src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 73263ae05e..e4a4f83b07 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -167,7 +167,8 @@ int main(int argc, const char* argv[]) { float minCoefficient = std::min(1.0f, powf(0.5, - (logf(DISTANCE_RATIO * distanceToAgent) / logf(2)) - 1)); + (logf(DISTANCE_RATIO * distanceToAgent) / logf(2.5)) + - 1)); distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; } From 56438435c165b7f618f800c4a5e068892aff45da Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 24 May 2013 17:12:14 -0700 Subject: [PATCH 23/27] made mouth conform to the head sphere --- interface/src/Head.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index b2818b857c..9306ae8769 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -78,7 +78,6 @@ Head::Head(Avatar* owningAvatar) : _hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f); _hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f); } - } void Head::reset() { @@ -312,6 +311,15 @@ void Head::renderMouth() { glm::vec3 rightTop = _mouthPosition + r * 0.4f + u * 0.7f + f; glm::vec3 leftBottom = _mouthPosition - r * 0.4f - u * 1.0f + f * 0.7f; glm::vec3 rightBottom = _mouthPosition + r * 0.4f - u * 1.0f + f * 0.7f; + + // constrain all mouth vertices to a sphere slightly larger than the head... + float constrainedRadius = _scale + 0.001f; + leftCorner = _position + glm::normalize(leftCorner - _position) * constrainedRadius; + rightCorner = _position + glm::normalize(rightCorner - _position) * constrainedRadius; + leftTop = _position + glm::normalize(leftTop - _position) * constrainedRadius; + rightTop = _position + glm::normalize(rightTop - _position) * constrainedRadius; + leftBottom = _position + glm::normalize(leftBottom - _position) * constrainedRadius; + rightBottom = _position + glm::normalize(rightBottom - _position) * constrainedRadius; glColor3f(0.2f, 0.0f, 0.0f); From 30e951578ed34dbed5aebeecd29a2e72956eb56e Mon Sep 17 00:00:00 2001 From: Freddy Date: Fri, 24 May 2013 17:27:56 -0700 Subject: [PATCH 24/27] procedural voxel create/delete noises --- interface/src/Application.cpp | 83 ++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c478554903..a101d0b03d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include "Application.h" #include "InterfaceConfig.h" @@ -2013,22 +2015,78 @@ void Application::shiftPaintingColor() { _paintingVoxel.blue = (_dominantColor == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100); } + void Application::maybeEditVoxelUnderCursor() { if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) { - if (_mouseVoxel.s != 0) { + if (_mouseVoxel.s != 0) { PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ? - PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); + PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); sendVoxelEditMessage(message, _mouseVoxel); - // create the voxel locally so it appears immediately + // 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 _justEditedVoxel = true; + + AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(22050); + voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z)); + //_myAvatar.getPosition() + voxelInjector->setBearing(-1 * _myAvatar.getAbsoluteHeadYaw()); + voxelInjector->setVolume (16 * pow (_mouseVoxel.s, 2) / .0000001); //255 is max, and also default value + printf("mousevoxelscale is %f\n", _mouseVoxel.s); + + /* for (int i = 0; i + < 22050; i++) { + if (i % 4 == 0) { + voxelInjector->addSample(4000); + } else if (i % 4 == 1) { + voxelInjector->addSample(0); + } else if (i % 4 == 2) { + voxelInjector->addSample(-4000); + } else { + voxelInjector->addSample(0); + } + */ + + + for (int i=0; i < 11025; i++) { + + /* + A440 square wave + if (sin(i * 2 * PIE / 50)>=0) { + voxelInjector->addSample(4000); + } else { + voxelInjector->addSample(-4000); + } + */ + + if (_mouseVoxel.s > .01) { + voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(500*sin((i+1)/200)))); + } else { + voxelInjector->addSample(16000 * sin(i/(1.5 * log (_mouseVoxel.s/.0001) * ((i+11025)/5512.5)))); //808 + } + } + + //voxelInjector->addSample(32500 * sin(i/(2 * 1 * ((i+5000)/5512.5)))); //80 + //voxelInjector->addSample(20000 * sin(i/(6 * (_mouseVoxel.s/.001) *((i+5512.5)/5512.5)))); //808 + //voxelInjector->addSample(20000 * sin(i/(6 * ((i+5512.5)/5512.5)))); //808 + //voxelInjector->addSample(4000 * sin(i * 2 * PIE /50)); //A440 sine wave + //voxelInjector->addSample(4000 * sin(i * 2 * PIE /50) * sin (i/500)); //A440 sine wave with amplitude modulation + + //FM library + //voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(500*sin((i+1)/200)))); //FM 1 dubstep + //voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(300*sin((i+1)/5.0)))); //FM 2 flange sweep + //voxelInjector->addSample(10000 * sin((i * 2 * PIE) /(500*sin((i+1)/500.0)))); //FM 3 resonant pulse + + + + + AudioInjectionManager::threadInjector(voxelInjector); } } else if (_deleteVoxelMode->isChecked()) { - deleteVoxelUnderCursor(); + deleteVoxelUnderCursor(); } } @@ -2036,10 +2094,21 @@ void Application::deleteVoxelUnderCursor() { if (_mouseVoxel.s != 0) { // sending delete to the server is sufficient, server will send new version so we see updates soon enough sendVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, _mouseVoxel); + AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(5000); + voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z)); + voxelInjector->setBearing(0); //straight down the z axis + voxelInjector->setVolume (255); //255 is max, and also default value - // remember the position for drag detection - _justEditedVoxel = true; + + for (int i=0; i < 5000; i++) { + voxelInjector->addSample(10000 * sin((i * 2 * PIE) /(500*sin((i+1)/500.0)))); //FM 3 resonant pulse + // voxelInjector->addSample(20000 * sin((i) /((4 / _mouseVoxel.s) * sin((i)/(20 * _mouseVoxel.s / .001))))); //FM 2 comb filter + } + + AudioInjectionManager::threadInjector(voxelInjector); } + // remember the position for drag detection + _justEditedVoxel = true; } void Application::goHome() { From 6a4bcf32fa6b492aa7f3404b3dbd39e15c378139 Mon Sep 17 00:00:00 2001 From: Freddy Date: Fri, 24 May 2013 17:58:31 -0700 Subject: [PATCH 25/27] Code review fixes --- interface/src/Application.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a101d0b03d..9bb2afa056 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2020,7 +2020,7 @@ 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); + PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); sendVoxelEditMessage(message, _mouseVoxel); // create the voxel locally so it appears immediately @@ -2030,12 +2030,12 @@ void Application::maybeEditVoxelUnderCursor() { // remember the position for drag detection _justEditedVoxel = true; - AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(22050); + AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(11025); voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z)); //_myAvatar.getPosition() voxelInjector->setBearing(-1 * _myAvatar.getAbsoluteHeadYaw()); voxelInjector->setVolume (16 * pow (_mouseVoxel.s, 2) / .0000001); //255 is max, and also default value - printf("mousevoxelscale is %f\n", _mouseVoxel.s); + // printf("mousevoxelscale is %f\n", _mouseVoxel.s); /* for (int i = 0; i < 22050; i++) { @@ -2051,7 +2051,9 @@ void Application::maybeEditVoxelUnderCursor() { */ - for (int i=0; i < 11025; i++) { + const float BIG_VOXEL_MIN_SIZE = .01f; + + for (int i = 0; i < 11025; i++) { /* A440 square wave @@ -2062,10 +2064,10 @@ void Application::maybeEditVoxelUnderCursor() { } */ - if (_mouseVoxel.s > .01) { - voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(500*sin((i+1)/200)))); + if (_mouseVoxel.s > BIG_VOXEL_MIN_SIZE) { + voxelInjector->addSample(20000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 200)))); } else { - voxelInjector->addSample(16000 * sin(i/(1.5 * log (_mouseVoxel.s/.0001) * ((i+11025)/5512.5)))); //808 + voxelInjector->addSample(16000 * sin(i / (1.5 * log (_mouseVoxel.s / .0001) * ((i + 11025) / 5512.5)))); //808 } } @@ -2079,10 +2081,7 @@ void Application::maybeEditVoxelUnderCursor() { //voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(500*sin((i+1)/200)))); //FM 1 dubstep //voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(300*sin((i+1)/5.0)))); //FM 2 flange sweep //voxelInjector->addSample(10000 * sin((i * 2 * PIE) /(500*sin((i+1)/500.0)))); //FM 3 resonant pulse - - - - + AudioInjectionManager::threadInjector(voxelInjector); } } else if (_deleteVoxelMode->isChecked()) { @@ -2100,8 +2099,8 @@ void Application::deleteVoxelUnderCursor() { voxelInjector->setVolume (255); //255 is max, and also default value - for (int i=0; i < 5000; i++) { - voxelInjector->addSample(10000 * sin((i * 2 * PIE) /(500*sin((i+1)/500.0)))); //FM 3 resonant pulse + for (int i = 0; i < 5000; i++) { + voxelInjector->addSample(10000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 500.0)))); //FM 3 resonant pulse // voxelInjector->addSample(20000 * sin((i) /((4 / _mouseVoxel.s) * sin((i)/(20 * _mouseVoxel.s / .001))))); //FM 2 comb filter } From 0c2c90b84da919e1ef53ceae8d7663be14483e0e Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 24 May 2013 18:01:25 -0700 Subject: [PATCH 26/27] cleanup --- interface/src/Head.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 0e6bf28a9e..28b526894b 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -28,8 +28,8 @@ const float HAIR_SPRING_FORCE = 10.0f; const float HAIR_TORQUE_FORCE = 0.1f; const float HAIR_GRAVITY_FORCE = 0.05f; const float HAIR_DRAG = 10.0f; -const float HAIR_LENGTH = 0.06f; -const float HAIR_THICKNESS = 0.02f; +const float HAIR_LENGTH = 0.09f; +const float HAIR_THICKNESS = 0.03f; const float IRIS_RADIUS = 0.007; const float IRIS_PROTRUSION = 0.0145f; const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png"; @@ -65,12 +65,11 @@ Head::Head(Avatar* owningAvatar) : _mohawkTriangleFan(NULL), _mohawkColors(NULL), _renderLookatVectors(false) { - + for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { _hairTuft[t].length = HAIR_LENGTH; _hairTuft[t].thickness = HAIR_THICKNESS; _hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f); - //_hairTuft[t].baseDirection = glm::vec3(0.0f, 1.0f, 0.0f); _hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f); _hairTuft[t].midPosition = glm::vec3(0.0f, 0.0f, 0.0f); @@ -240,6 +239,7 @@ void Head::createMohawk() { _mohawkTriangleFan[0] = glm::vec3(0, 0, 0); glm::vec3 basicColor(randFloat(), randFloat(), randFloat()); _mohawkColors[0] = basicColor; + for (int i = 1; i < MOHAWK_TRIANGLES; i++) { _mohawkTriangleFan[i] = glm::vec3((randFloat() - 0.5f) * variance, height * cosf(i * RAD_PER_TRIANGLE - PI / 2.f) From 1e4771fe27c5a9d8c0d8e0afbef8608f14d4e637 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 24 May 2013 18:05:14 -0700 Subject: [PATCH 27/27] fix --- interface/src/Head.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 28b526894b..1486013c9c 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -530,7 +530,7 @@ void Head::updateHair(float deltaTime) { for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { - float fraction = (float)t / (float)(NUM_HAIR_TUFTS-1); + float fraction = (float)t / (float)(NUM_HAIR_TUFTS - 1); float angle = -20.0f + 40.0f * fraction;