From 70b25fd6c4192b0de102f9c813019b7053e19505 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Sat, 25 May 2013 19:59:07 -0700 Subject: [PATCH 01/23] Sphere/box collisions for voxels, various utility functions. --- interface/src/Avatar.cpp | 12 ++- interface/src/Environment.cpp | 17 ++--- libraries/voxels/src/AABox.cpp | 70 ++++++++++++++++++ libraries/voxels/src/AABox.h | 9 ++- libraries/voxels/src/GeometryUtil.cpp | 102 +++++++++++++++++++++++++- libraries/voxels/src/GeometryUtil.h | 31 +++++++- libraries/voxels/src/VoxelTree.cpp | 26 +++---- 7 files changed, 234 insertions(+), 33 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 7568e45116..5bc7a07bf1 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -615,15 +615,19 @@ void Avatar::updateCollisionWithEnvironment() { void Avatar::updateCollisionWithVoxels() { float radius = _height * 0.125f; glm::vec3 penetration; - if (Application::getInstance()->getVoxels()->findCapsulePenetration( - _position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f), - _position + glm::vec3(0.0f, _height - _pelvisFloatingHeight - radius, 0.0f), radius, penetration)) { + //if (Application::getInstance()->getVoxels()->findCapsulePenetration( + // _position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f), + // _position + glm::vec3(0.0f, _height - _pelvisFloatingHeight - radius, 0.0f), radius, penetration)) { + // applyCollisionWithScene(penetration); + //} + + if (Application::getInstance()->getVoxels()->findSpherePenetration(_position, _height/2, penetration)) { applyCollisionWithScene(penetration); } } void Avatar::applyCollisionWithScene(const glm::vec3& penetration) { - _position += penetration; + _position -= penetration; // reflect the velocity component in the direction of penetration glm::vec3 direction = glm::normalize(penetration); diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 49ef26bb82..5063c990db 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -101,13 +101,7 @@ const EnvironmentData Environment::getClosestData(const glm::vec3& position) { bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) { // collide with the "floor" - bool found = false; - penetration = glm::vec3(0.0f, 0.0f, 0.0f); - float floorDist = qMin(start.y, end.y) - radius; - if (floorDist < 0.0f) { - penetration.y = -floorDist; - found = true; - } + bool found = findCapsulePlanePenetration(start, end, radius, glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), penetration); // get the lock for the duration of the call QMutexLocker locker(&_mutex); @@ -117,11 +111,10 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3 if (environmentData.getGravity() == 0.0f) { continue; // don't bother colliding with gravity-less environments } - glm::vec3 vector = computeVectorFromPointToSegment(environmentData.getAtmosphereCenter(), start, end); - float vectorLength = glm::length(vector); - float distance = vectorLength - environmentData.getAtmosphereInnerRadius() - radius; - if (distance < 0.0f) { - penetration += vector * (-distance / vectorLength); + glm::vec3 environmentPenetration; + if (findCapsuleSpherePenetration(start, end, radius, environmentData.getAtmosphereCenter(), + environmentData.getAtmosphereInnerRadius(), environmentPenetration)) { + penetration = addPenetrations(penetration, environmentPenetration); found = true; } } diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index c26e73e12a..d49c04136b 100644 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -11,6 +11,7 @@ #include "SharedUtil.h" #include "AABox.h" +#include "GeometryUtil.h" void AABox::scale(float scale) { @@ -82,6 +83,17 @@ bool AABox::contains(const glm::vec3& point) const { isWithin(point.z, _corner.z, _size.z); } +// determines whether a value is within the expanded extents +static bool isWithinExpanded(float value, float corner, float size, float expansion) { + return value >= corner - expansion && value <= corner + size + expansion; +} + +bool AABox::expandedContains(const glm::vec3& point, float expansion) const { + return isWithinExpanded(point.x, _corner.x, _size.x, expansion) && + isWithinExpanded(point.y, _corner.y, _size.y, expansion) && + isWithinExpanded(point.z, _corner.z, _size.z, expansion); +} + // finds the intersection between a ray and the facing plane on one axis static bool findIntersection(float origin, float direction, float corner, float size, float& distance) { if (direction > EPSILON) { @@ -126,3 +138,61 @@ bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct } return false; } + +bool AABox::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const { + glm::vec4 center4 = glm::vec4(center, 1.0f); + + float minPenetrationLength = FLT_MAX; + for (int i = 0; i < FACE_COUNT; i++) { + glm::vec3 vector = getClosestPointOnFace(center, (BoxFace)i) - center; + if (glm::dot(center4, getPlane((BoxFace)i)) >= 0.0f) { + return ::findSpherePenetration(vector, radius, penetration); + } + float vectorLength = glm::length(vector); + if (vectorLength < minPenetrationLength) { + penetration = vector * ((vectorLength + radius) / -vectorLength); + minPenetrationLength = vectorLength; + } + } + + return true; +} + +glm::vec3 AABox::getClosestPointOnFace(const glm::vec3& point, BoxFace face) const { + switch (face) { + case MIN_X_FACE: + return glm::clamp(point, glm::vec3(_corner.x, _corner.y, _corner.z), + glm::vec3(_corner.x, _corner.y + _size.y, _corner.z + _size.z)); + + case MAX_X_FACE: + return glm::clamp(point, glm::vec3(_corner.x + _size.x, _corner.y, _corner.z), + glm::vec3(_corner.x + _size.x, _corner.y + _size.y, _corner.z + _size.z)); + + case MIN_Y_FACE: + return glm::clamp(point, glm::vec3(_corner.x, _corner.y, _corner.z), + glm::vec3(_corner.x + _size.x, _corner.y, _corner.z + _size.z)); + + case MAX_Y_FACE: + return glm::clamp(point, glm::vec3(_corner.x, _corner.y + _size.y, _corner.z), + glm::vec3(_corner.x + _size.x, _corner.y + _size.y, _corner.z + _size.z)); + + case MIN_Z_FACE: + return glm::clamp(point, glm::vec3(_corner.x, _corner.y, _corner.z), + glm::vec3(_corner.x + _size.x, _corner.y + _size.y, _corner.z)); + + case MAX_Z_FACE: + return glm::clamp(point, glm::vec3(_corner.x, _corner.y, _corner.z + _size.z), + glm::vec3(_corner.x + _size.x, _corner.y + _size.y, _corner.z + _size.z)); + } +} + +glm::vec4 AABox::getPlane(BoxFace face) const { + switch (face) { + case MIN_X_FACE: return glm::vec4(-1.0f, 0.0f, 0.0f, _corner.x); + case MAX_X_FACE: return glm::vec4(1.0f, 0.0f, 0.0f, -_corner.x - _size.x); + case MIN_Y_FACE: return glm::vec4(0.0f, -1.0f, 0.0f, _corner.y); + case MAX_Y_FACE: return glm::vec4(0.0f, 1.0f, 0.0f, -_corner.y - _size.y); + case MIN_Z_FACE: return glm::vec4(0.0f, 0.0f, -1.0f, _corner.z); + case MAX_Z_FACE: return glm::vec4(0.0f, 0.0f, 1.0f, -_corner.z - _size.z); + } +} diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h index 63d586de22..5f4f84d417 100755 --- a/libraries/voxels/src/AABox.h +++ b/libraries/voxels/src/AABox.h @@ -19,7 +19,8 @@ enum BoxFace { MIN_Y_FACE, MAX_Y_FACE, MIN_Z_FACE, - MAX_Z_FACE + MAX_Z_FACE, + FACE_COUNT }; class AABox @@ -46,9 +47,15 @@ public: const glm::vec3& getCenter() const { return _center; }; bool contains(const glm::vec3& point) const; + bool expandedContains(const glm::vec3& point, float expansion) const; bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; + bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const; private: + + glm::vec3 getClosestPointOnFace(const glm::vec3& point, BoxFace face) const; + glm::vec4 getPlane(BoxFace face) const; + glm::vec3 _corner; glm::vec3 _center; glm::vec3 _size; diff --git a/libraries/voxels/src/GeometryUtil.cpp b/libraries/voxels/src/GeometryUtil.cpp index 46e83018cd..b059645553 100644 --- a/libraries/voxels/src/GeometryUtil.cpp +++ b/libraries/voxels/src/GeometryUtil.cpp @@ -7,7 +7,36 @@ #include "GeometryUtil.h" -glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) { +bool findSpherePenetration(const glm::vec3& penetratorToPenetratee, float combinedRadius, glm::vec3& penetration) { + float vectorLength = glm::length(penetratorToPenetratee); + float distance = vectorLength - combinedRadius; + if (distance < 0.0f) { + penetration = penetratorToPenetratee * (-distance / vectorLength); + return true; + } + return false; +} + +bool findSpherePointPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec3& penetrateeLocation, glm::vec3& penetration) { + return findSpherePenetration(penetrateeLocation - penetratorCenter, penetratorRadius, penetration); +} + +bool findSphereSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec3& penetrateeCenter, float penetrateeRadius, glm::vec3& penetration) { + return findSpherePointPenetration(penetratorCenter, penetratorRadius + penetrateeRadius, penetrateeCenter, penetration); +} + +bool findSphereLinePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec3& penetrateeOrigin, const glm::vec3& penetrateeDirection, + glm::vec3& penetration) { + // compute the projection of the penetrator vector onto the line + float proj = glm::dot(penetratorCenter - penetrateeOrigin, penetrateeDirection); + return findSpherePenetration((penetrateeOrigin + penetrateeDirection*proj) - penetratorCenter, + penetratorRadius, penetration); +} + +static glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) { // compute the projection of the point vector onto the segment vector glm::vec3 segmentVector = end - start; float proj = glm::dot(point - start, segmentVector) / glm::dot(segmentVector, segmentVector); @@ -21,3 +50,74 @@ glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec return start + segmentVector*proj - point; } } + +bool findSphereSegmentPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec3& penetrateeStart, const glm::vec3& penetrateeEnd, glm::vec3& penetration) { + return findSpherePenetration(computeVectorFromPointToSegment(penetratorCenter, penetrateeStart, penetrateeEnd), + penetratorRadius, penetration); +} + +bool findSphereCapsulePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, const glm::vec3& penetrateeStart, + const glm::vec3& penetrateeEnd, float penetrateeRadius, glm::vec3& penetration) { + return findSphereSegmentPenetration(penetratorCenter, penetratorRadius + penetrateeRadius, + penetrateeStart, penetrateeEnd, penetration); +} + +bool findSpherePlanePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec4& penetrateePlane, glm::vec3& penetration) { + float distance = glm::dot(penetrateePlane, glm::vec4(penetratorCenter, 1.0f)) - penetratorRadius; + if (distance < 0.0f) { + penetration = glm::vec3(penetrateePlane) * distance; + return true; + } + return false; +} + +bool findCapsulePointPenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, + const glm::vec3& penetrateeLocation, glm::vec3& penetration) { + if (findSphereSegmentPenetration(penetrateeLocation, penetratorRadius, penetratorStart, penetratorEnd, penetration)) { + penetration = -penetration; + return true; + } + return false; +} + +bool findCapsuleSpherePenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, + const glm::vec3& penetrateeCenter, float penetrateeRadius, glm::vec3& penetration) { + if (findSphereCapsulePenetration(penetrateeCenter, penetrateeRadius, + penetratorStart, penetratorEnd, penetratorRadius, penetration)) { + penetration = -penetration; + return true; + } + return false; +} + +bool findCapsulePlanePenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, + const glm::vec4& penetrateePlane, glm::vec3& penetration) { + float distance = glm::min(glm::dot(penetrateePlane, glm::vec4(penetratorStart, 1.0f)), + glm::dot(penetrateePlane, glm::vec4(penetratorEnd, 1.0f))) - penetratorRadius; + if (distance < 0.0f) { + penetration = glm::vec3(penetrateePlane) * distance; + return true; + } + return false; +} + +glm::vec3 addPenetrations(const glm::vec3& currentPenetration, const glm::vec3& newPenetration) { + // find the component of the new penetration in the direction of the current + float currentLength = glm::length(currentPenetration); + if (currentLength == 0.0f) { + return newPenetration; + } + glm::vec3 currentDirection = currentPenetration / currentLength; + float directionalComponent = glm::dot(newPenetration, currentDirection); + + // if orthogonal or in the opposite direction, we can simply add + if (directionalComponent <= 0.0f) { + return currentPenetration + newPenetration; + } + + // otherwise, we need to take the maximum component of current and new + return currentDirection * glm::max(directionalComponent, currentLength) + + newPenetration - (currentDirection * directionalComponent); +} diff --git a/libraries/voxels/src/GeometryUtil.h b/libraries/voxels/src/GeometryUtil.h index f0c63e5a86..0d80626507 100644 --- a/libraries/voxels/src/GeometryUtil.h +++ b/libraries/voxels/src/GeometryUtil.h @@ -11,6 +11,35 @@ #include -glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end); +bool findSpherePenetration(const glm::vec3& penetratorToPenetratee, float combinedRadius, glm::vec3& penetration); + +bool findSpherePointPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec3& penetrateeLocation, glm::vec3& penetration); + +bool findSphereSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec3& penetrateeCenter, float penetrateeRadius, glm::vec3& penetration); + +bool findSphereLinePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec3& penetrateeOrigin, const glm::vec3& penetrateeDirection, glm::vec3& penetration); + +bool findSphereSegmentPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec3& penetrateeStart, const glm::vec3& penetrateeEnd, glm::vec3& penetration); + +bool findSphereCapsulePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, const glm::vec3& penetrateeStart, + const glm::vec3& penetrateeEnd, float penetrateeRadius, glm::vec3& penetration); + +bool findSpherePlanePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec4& penetrateePlane, glm::vec3& penetration); + +bool findCapsulePointPenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, + const glm::vec3& penetrateeLocation, glm::vec3& penetration); + +bool findCapsuleSpherePenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, + const glm::vec3& penetrateeCenter, float penetrateeRadius, glm::vec3& penetration); + +bool findCapsulePlanePenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, + const glm::vec4& penetrateePlane, glm::vec3& penetration); + +glm::vec3 addPenetrations(const glm::vec3& currentPenetration, const glm::vec3& newPenetration); #endif /* defined(__interface__GeometryUtil__) */ diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 798b447d6c..c97765a3fb 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -716,20 +716,20 @@ public: bool findSpherePenetrationOp(VoxelNode* node, void* extraData) { SphereArgs* args = static_cast(extraData); - // currently, we treat each node as a sphere enveloping the box - const glm::vec3& nodeCenter = node->getCenter(); - glm::vec3 vector = args->center - nodeCenter; - float vectorLength = glm::length(vector); - float distance = vectorLength - node->getEnclosingRadius() - args->radius; - if (distance >= 0.0f) { + // coarse check against bounds + const AABox& box = node->getAABox(); + if (!box.expandedContains(args->center, args->radius)) { return false; } if (!node->isLeaf()) { return true; // recurse on children } if (node->isColored()) { - args->penetration += vector * (-distance * TREE_SCALE / vectorLength); - args->found = true; + glm::vec3 nodePenetration; + if (box.findSpherePenetration(args->center, args->radius, nodePenetration)) { + args->penetration = addPenetrations(args->penetration, nodePenetration * (float)TREE_SCALE); + args->found = true; + } } return false; } @@ -754,18 +754,16 @@ bool findCapsulePenetrationOp(VoxelNode* node, void* extraData) { CapsuleArgs* args = static_cast(extraData); // currently, we treat each node as a sphere enveloping the box - const glm::vec3& nodeCenter = node->getCenter(); - glm::vec3 vector = computeVectorFromPointToSegment(nodeCenter, args->start, args->end); - float vectorLength = glm::length(vector); - float distance = vectorLength - node->getEnclosingRadius() - args->radius; - if (distance >= 0.0f) { + glm::vec3 nodePenetration; + if (!findCapsuleSpherePenetration(args->start, args->end, args->radius, node->getCenter(), + node->getEnclosingRadius(), nodePenetration)) { return false; } if (!node->isLeaf()) { return true; // recurse on children } if (node->isColored()) { - args->penetration += vector * (-distance * TREE_SCALE / vectorLength); + args->penetration = addPenetrations(args->penetration, nodePenetration * (float)TREE_SCALE); args->found = true; } return false; From 9f7e05d4078faa22e8bc5cb84ef93789d9dff26d Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Sun, 26 May 2013 10:18:35 -0700 Subject: [PATCH 02/23] integrated Philip's mohawk colors into my hair code and added a switch to test each version --- interface/src/Head.cpp | 114 ++++++++++++++++++++--------------------- interface/src/Head.h | 7 ++- 2 files changed, 60 insertions(+), 61 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 1486013c9c..72ae41e8d2 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -13,6 +13,7 @@ using namespace std; const int MOHAWK_TRIANGLES = 50; +const bool USING_PHYSICAL_MOHAWK = true; const float EYE_RIGHT_OFFSET = 0.27f; const float EYE_UP_OFFSET = 0.36f; const float EYE_FRONT_OFFSET = 0.8f; @@ -23,7 +24,6 @@ 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; @@ -65,26 +65,29 @@ Head::Head(Avatar* owningAvatar) : _mohawkTriangleFan(NULL), _mohawkColors(NULL), _renderLookatVectors(false) { - - for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { - _hairTuft[t].length = HAIR_LENGTH; - _hairTuft[t].thickness = HAIR_THICKNESS; - _hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f); - - _hairTuft[t].basePosition = glm::vec3(0.0f, 0.0f, 0.0f); - _hairTuft[t].midPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _hairTuft[t].endPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _hairTuft[t].midVelocity = glm::vec3(0.0f, 0.0f, 0.0f); - _hairTuft[t].endVelocity = glm::vec3(0.0f, 0.0f, 0.0f); - } + + if (USING_PHYSICAL_MOHAWK) { + resetHairPhysics(); + } } void Head::reset() { _yaw = _pitch = _roll = 0.0f; _leanForward = _leanSideways = 0.0f; + if (USING_PHYSICAL_MOHAWK) { + resetHairPhysics(); + } +} + + + + +void Head::resetHairPhysics() { for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { + _hairTuft[t].length = HAIR_LENGTH; + _hairTuft[t].thickness = HAIR_THICKNESS; _hairTuft[t].basePosition = _position + _orientation.getUp() * _scale * 0.9f; _hairTuft[t].midPosition = _hairTuft[t].basePosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF; _hairTuft[t].endPosition = _hairTuft[t].midPosition + _orientation.getUp() * _hairTuft[t].length * ONE_HALF; @@ -93,6 +96,7 @@ void Head::reset() { } } + void Head::simulate(float deltaTime, bool isMine) { const float HEAD_MOTION_DECAY = 0.00; @@ -141,7 +145,9 @@ void Head::simulate(float deltaTime, bool isMine) { // based on the nature of the lookat position, determine if the eyes can look / are looking at it. determineIfLookingAtSomething(); - updateHair(deltaTime); + if (USING_PHYSICAL_MOHAWK) { + updateHairPhysics(deltaTime); + } } void Head::determineIfLookingAtSomething() { @@ -207,19 +213,19 @@ void Head::render(bool lookingInMirror, glm::vec3 cameraPosition) { glEnable(GL_DEPTH_TEST); glEnable(GL_RESCALE_NORMAL); - renderMohawk(lookingInMirror); + renderMohawk(lookingInMirror, cameraPosition); renderHeadSphere(); renderEyeBalls(); renderEars(); renderMouth(); renderEyeBrows(); - renderHair(cameraPosition); if (_renderLookatVectors && _lookingAtSomething) { renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition); } } + void Head::createMohawk() { uint16_t agentId = 0; if (_owningAvatar->getOwningAgent()) { @@ -251,9 +257,41 @@ void Head::createMohawk() { } } -void Head::renderMohawk(bool lookingInMirror) { +void Head::renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition) { + if (!_mohawkTriangleFan) { createMohawk(); + } + + if (USING_PHYSICAL_MOHAWK) { + for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { + + glm::vec3 baseAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition; + glm::vec3 midAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition; + glm::vec3 viewVector = _hairTuft[t].basePosition - cameraPosition; + + glm::vec3 basePerpendicular = glm::normalize(glm::cross(baseAxis, viewVector)); + glm::vec3 midPerpendicular = glm::normalize(glm::cross(midAxis, viewVector)); + + glm::vec3 base1 = _hairTuft[t].basePosition - basePerpendicular * _hairTuft[t].thickness * ONE_HALF; + glm::vec3 base2 = _hairTuft[t].basePosition + basePerpendicular * _hairTuft[t].thickness * ONE_HALF; + glm::vec3 mid1 = _hairTuft[t].midPosition - midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; + glm::vec3 mid2 = _hairTuft[t].midPosition + midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; + + glColor3f(_mohawkColors[t].x, _mohawkColors[t].y, _mohawkColors[t].z); + + glBegin(GL_TRIANGLES); + glVertex3f(base1.x, base1.y, base1.z ); + glVertex3f(base2.x, base2.y, base2.z ); + glVertex3f(mid1.x, mid1.y, mid1.z ); + glVertex3f(base2.x, base2.y, base2.z ); + glVertex3f(mid1.x, mid1.y, mid1.z ); + glVertex3f(mid2.x, mid2.y, mid2.z ); + glVertex3f(mid1.x, mid1.y, mid1.z ); + glVertex3f(mid2.x, mid2.y, mid2.z ); + glVertex3f(_hairTuft[t].endPosition.x, _hairTuft[t].endPosition.y, _hairTuft[t].endPosition.z ); + glEnd(); + } } else { glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); @@ -269,7 +307,7 @@ void Head::renderMohawk(bool lookingInMirror) { } glEnd(); glPopMatrix(); - } + } } @@ -526,7 +564,7 @@ void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosi } -void Head::updateHair(float deltaTime) { +void Head::updateHairPhysics(float deltaTime) { for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { @@ -618,41 +656,3 @@ void Head::updateHair(float deltaTime) { } } - - -void Head::renderHair(glm::vec3 cameraPosition) { - - for (int t = 0; t < NUM_HAIR_TUFTS; t ++) { - - glm::vec3 baseAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition; - glm::vec3 midAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition; - glm::vec3 viewVector = _hairTuft[t].basePosition - cameraPosition; - - glm::vec3 basePerpendicular = glm::normalize(glm::cross(baseAxis, viewVector)); - glm::vec3 midPerpendicular = glm::normalize(glm::cross(midAxis, viewVector)); - - glm::vec3 base1 = _hairTuft[t].basePosition - basePerpendicular * _hairTuft[t].thickness * ONE_HALF; - glm::vec3 base2 = _hairTuft[t].basePosition + basePerpendicular * _hairTuft[t].thickness * ONE_HALF; - glm::vec3 mid1 = _hairTuft[t].midPosition - midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; - glm::vec3 mid2 = _hairTuft[t].midPosition + midPerpendicular * _hairTuft[t].thickness * ONE_HALF * ONE_HALF; - - glColor3fv(HAIR_COLOR); - - glBegin(GL_TRIANGLES); - - glVertex3f(base1.x, base1.y, base1.z ); - glVertex3f(base2.x, base2.y, base2.z ); - glVertex3f(mid1.x, mid1.y, mid1.z ); - - glVertex3f(base2.x, base2.y, base2.z ); - glVertex3f(mid1.x, mid1.y, mid1.z ); - glVertex3f(mid2.x, mid2.y, mid2.z ); - - glVertex3f(mid1.x, mid1.y, mid1.z ); - glVertex3f(mid2.x, mid2.y, mid2.z ); - glVertex3f(_hairTuft[t].endPosition.x, _hairTuft[t].endPosition.y, _hairTuft[t].endPosition.z ); - - glEnd(); - } -} - diff --git a/interface/src/Head.h b/interface/src/Head.h index bdf519fcfe..23afa7e29a 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -25,7 +25,6 @@ enum eyeContactTargets }; const int NUM_HAIR_TUFTS = 4; -const int NUM_HAIR_SEGMENTS = 4; class Avatar; @@ -36,7 +35,7 @@ public: void reset(); void simulate(float deltaTime, bool isMine); void render(bool lookingInMirror, glm::vec3 cameraPosition); - void renderMohawk(bool lookingInMirror); + void renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition); void setScale (float scale ) { _scale = scale; } void setPosition (glm::vec3 position ) { _position = position; } @@ -110,8 +109,8 @@ private: void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition); void calculateGeometry( bool lookingInMirror); void determineIfLookingAtSomething(); - void updateHair(float deltaTime); - void renderHair(glm::vec3 cameraPosition); + void resetHairPhysics(); + void updateHairPhysics(float deltaTime); }; #endif From 883d21a5e46469a59bee17b071fb43eab99d6f1f Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Sun, 26 May 2013 15:17:58 -0700 Subject: [PATCH 03/23] added facing other av requirement for camera shift to 1p; improved ease-in/out for camera mode shift; did some clean up on the camera code --- interface/src/Application.cpp | 43 +++------- interface/src/Avatar.cpp | 2 + interface/src/AvatarTouch.cpp | 47 ++++------- interface/src/AvatarTouch.h | 50 ++++++------ interface/src/Camera.cpp | 145 +++++++++++++++++++--------------- interface/src/Camera.h | 35 +++----- 6 files changed, 148 insertions(+), 174 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a0979eb4b9..9671e66f54 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -918,31 +918,21 @@ void Application::idle() { if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { if (_manualFirstPerson) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) { - Camera::CameraFollowingAttributes a; - a.upShift = 0.0f; - a.distance = 0.0f; - a.tightness = 100.0f; - _myCamera.setMode(CAMERA_MODE_FIRST_PERSON, a); + _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + _myCamera.setModeShiftRate(1.0f); } } else { if (_myAvatar.getIsNearInteractingOther()) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { - - Camera::CameraFollowingAttributes a; - a.upShift = 0.0f; - a.distance = 0.0f; - a.tightness = 100.0f; - _myCamera.setMode(CAMERA_MODE_FIRST_PERSON, a); + _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + _myCamera.setModeShiftRate(1.0f); } } else { if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { - Camera::CameraFollowingAttributes a; - a.upShift = -0.2f; - a.distance = 1.5f; - a.tightness = 8.0f; - _myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); + _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); + _myCamera.setModeShiftRate(1.0f); } } } @@ -981,17 +971,11 @@ void Application::setHead(bool head) { #endif if (head) { - Camera::CameraFollowingAttributes a; - a.upShift = 0.0f; - a.distance = 0.2f; - a.tightness = 100.0f; - _myCamera.setMode(CAMERA_MODE_MIRROR, a); + _myCamera.setMode(CAMERA_MODE_MIRROR); + _myCamera.setModeShiftRate(100.0f); } else { - Camera::CameraFollowingAttributes a; - a.upShift = -0.2f; - a.distance = 1.5f; - a.tightness = 8.0f; - _myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); + _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); + _myCamera.setModeShiftRate(1.0f); } } @@ -1285,11 +1269,8 @@ void Application::init() { _stars.readInput(STAR_FILE, STAR_CACHE_FILE, 0); _myAvatar.setPosition(START_LOCATION); - Camera::CameraFollowingAttributes a; - a.upShift = -0.2f; - a.distance = 1.5f; - a.tightness = 8.0f; - _myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); + _myCamera.setMode(CAMERA_MODE_THIRD_PERSON ); + _myCamera.setModeShiftRate(1.0f); _myAvatar.setDisplayingLookatVectors(false); QCursor::setPos(_headMouseX, _headMouseY); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 8ce1abb05b..b3dd505f40 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -486,6 +486,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { if (!_owningAgent) { _avatarTouch.setMyBodyPosition(_position); + _avatarTouch.setMyOrientation(_orientation); float closestDistance = std::numeric_limits::max(); @@ -518,6 +519,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { if (_interactingOther) { _avatarTouch.setYourBodyPosition(_interactingOther->_position); + _avatarTouch.setYourOrientation (_interactingOther->_orientation); _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandState (_interactingOther->_handState); diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 7651a0a9a8..2072848902 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -27,55 +27,38 @@ AvatarTouch::AvatarTouch() { _weAreHoldingHands = false; _canReachToOtherAvatar = false; _handsCloseEnoughToGrasp = false; + _myOrientation.setToIdentity(); + _yourOrientation.setToIdentity(); for (int p=0; p 0.1f)) { + facingEachOther = true; + } - if (distanceBetweenBodies < _reachableRadius) { + if ((distanceBetweenBodies < _reachableRadius) + && (facingEachOther)) { _vectorBetweenHands = _yourHandPosition - _myHandPosition; - float distanceBetweenHands = glm::length(_vectorBetweenHands); + float distanceBetweenHands = glm::length(_vectorBetweenHands); if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP) { _handsCloseEnoughToGrasp = true; } else { _handsCloseEnoughToGrasp = false; } - + _canReachToOtherAvatar = true; } else { _canReachToOtherAvatar = false; @@ -92,7 +75,7 @@ void AvatarTouch::render(glm::vec3 cameraPosition) { p.y = 0.0005f; renderCircle(p, _reachableRadius, glm::vec3(0.0f, 1.0f, 0.0f), 30); - // show is we are golding hands... + // show if we are golding hands... if (_weAreHoldingHands) { renderBeamBetweenHands(); diff --git a/interface/src/AvatarTouch.h b/interface/src/AvatarTouch.h index 2111c0ecf1..fb90efa5fd 100644 --- a/interface/src/AvatarTouch.h +++ b/interface/src/AvatarTouch.h @@ -9,6 +9,7 @@ #define __interface__AvatarTouch__ #include +#include "Orientation.h" enum AvatarHandState { @@ -26,18 +27,17 @@ public: void simulate(float deltaTime); void render(glm::vec3 cameraPosition); - - void setMyHandPosition (glm::vec3 position); - void setYourHandPosition(glm::vec3 position); - void setMyBodyPosition (glm::vec3 position); - void setYourBodyPosition(glm::vec3 position); - void setMyHandState (int state); - void setYourHandState (int state); - void setReachableRadius (float r); - - void setAbleToReachOtherAvatar (bool a) {_canReachToOtherAvatar = a;} - void setHandsCloseEnoughToGrasp(bool h) {_handsCloseEnoughToGrasp = h;} - void setHoldingHands (bool h) {_weAreHoldingHands = h;} + + void setMyHandPosition (glm::vec3 position ) { _myHandPosition = position; } + void setYourHandPosition(glm::vec3 position ) { _yourHandPosition = position; } + void setMyOrientation (Orientation orientation) { _myOrientation = orientation; } + void setYourOrientation (Orientation orientation) { _yourOrientation = orientation; } + void setMyBodyPosition (glm::vec3 position ) { _myBodyPosition = position; } + void setYourBodyPosition(glm::vec3 position ) { _yourBodyPosition = position; } + void setMyHandState (int state ) { _myHandState = state; } + void setYourHandState (int state ) { _yourHandState = state; } + void setReachableRadius (float radius ) { _reachableRadius = radius; } + void setHoldingHands (bool holding ) { _weAreHoldingHands = holding; } bool getAbleToReachOtherAvatar () const {return _canReachToOtherAvatar; } bool getHandsCloseEnoughToGrasp() const {return _handsCloseEnoughToGrasp;} @@ -47,18 +47,20 @@ private: static const int NUM_POINTS = 100; - bool _weAreHoldingHands; - glm::vec3 _point [NUM_POINTS]; - glm::vec3 _myBodyPosition; - glm::vec3 _yourBodyPosition; - glm::vec3 _myHandPosition; - glm::vec3 _yourHandPosition; - glm::vec3 _vectorBetweenHands; - int _myHandState; - int _yourHandState; - bool _canReachToOtherAvatar; - bool _handsCloseEnoughToGrasp; - float _reachableRadius; + bool _weAreHoldingHands; + glm::vec3 _point [NUM_POINTS]; + glm::vec3 _myBodyPosition; + glm::vec3 _yourBodyPosition; + glm::vec3 _myHandPosition; + glm::vec3 _yourHandPosition; + Orientation _myOrientation; + Orientation _yourOrientation; + glm::vec3 _vectorBetweenHands; + int _myHandState; + int _yourHandState; + bool _canReachToOtherAvatar; + bool _handsCloseEnoughToGrasp; + float _reachableRadius; void renderBeamBetweenHands(); }; diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index b408135c40..1b1dc56ae2 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -11,49 +11,51 @@ #include "Camera.h" -const float MODE_SHIFT_RATE = 6.0f; +const float CAMERA_MINIMUM_MODE_SHIFT_RATE = 0.5f; + +const float CAMERA_FIRST_PERSON_MODE_UP_SHIFT = 0.0f; +const float CAMERA_FIRST_PERSON_MODE_DISTANCE = 0.0f; +const float CAMERA_FIRST_PERSON_MODE_TIGHTNESS = 100.0f; + +const float CAMERA_THIRD_PERSON_MODE_UP_SHIFT = -0.2f; +const float CAMERA_THIRD_PERSON_MODE_DISTANCE = 1.5f; +const float CAMERA_THIRD_PERSON_MODE_TIGHTNESS = 8.0f; + +const float CAMERA_MIRROR_MODE_UP_SHIFT = 0.0f; +const float CAMERA_MIRROR_MODE_DISTANCE = 0.2f; +const float CAMERA_MIRROR_MODE_TIGHTNESS = 100.0f; Camera::Camera() { _needsToInitialize = true; _frustumNeedsReshape = true; - _modeShift = 0.0; - _mode = CAMERA_MODE_THIRD_PERSON; - _tightness = 10.0; // default - _fieldOfView = 60.0; // default - _nearClip = 0.08; // default - _farClip = 50.0 * TREE_SCALE; // default - _yaw = 0.0; - _pitch = 0.0; - _roll = 0.0; - _upShift = 0.0; - _distance = 0.0; - _idealYaw = 0.0; - _idealPitch = 0.0; - _idealRoll = 0.0; - _targetPosition = glm::vec3(0.0, 0.0, 0.0); - _position = glm::vec3(0.0, 0.0, 0.0); - _idealPosition = glm::vec3(0.0, 0.0, 0.0); + _modeShift = 0.0f; + _modeShiftRate = 1.0f; + _linearModeShift = 0.0f; + _mode = CAMERA_MODE_THIRD_PERSON; + _tightness = 10.0f; // default + _fieldOfView = 60.0f; // default + _nearClip = 0.08f; // default + _farClip = 50.0f * TREE_SCALE; // default + _yaw = 0.0f; + _pitch = 0.0f; + _roll = 0.0f; + _upShift = 0.0f; + _distance = 0.0f; + _previousUpShift = 0.0f; + _previousDistance = 0.0f; + _previousTightness = 0.0f; + _newUpShift = 0.0f; + _newDistance = 0.0f; + _newTightness = 0.0f; + _idealYaw = 0.0f; + _idealPitch = 0.0f; + _idealRoll = 0.0f; + _targetPosition = glm::vec3(0.0f, 0.0f, 0.0f); + _position = glm::vec3(0.0f, 0.0f, 0.0f); + _idealPosition = glm::vec3(0.0f, 0.0f, 0.0f); _orientation.setToIdentity(); - - _attributes[CAMERA_MODE_FIRST_PERSON].upShift = CAMERA_DEFAULT_FIRST_PERSON_MODE_UP_SHIFT; - _attributes[CAMERA_MODE_FIRST_PERSON].distance = CAMERA_DEFAULT_FIRST_PERSON_MODE_DISTANCE; - _attributes[CAMERA_MODE_FIRST_PERSON].tightness = CAMERA_DEFAULT_FIRST_PERSON_MODE_TIGHTNESS; - - _attributes[CAMERA_MODE_THIRD_PERSON].upShift = CAMERA_DEFAULT_THIRD_PERSON_MODE_UP_SHIFT; - _attributes[CAMERA_MODE_THIRD_PERSON].distance = CAMERA_DEFAULT_THIRD_PERSON_MODE_DISTANCE; - _attributes[CAMERA_MODE_THIRD_PERSON].tightness = CAMERA_DEFAULT_THIRD_PERSON_MODE_TIGHTNESS; - - _attributes[CAMERA_MODE_MIRROR ].upShift = CAMERA_DEFAULT_MIRROR_MODE_UP_SHIFT; - _attributes[CAMERA_MODE_MIRROR ].distance = CAMERA_DEFAULT_MIRROR_MODE_DISTANCE; - _attributes[CAMERA_MODE_MIRROR ].tightness = CAMERA_DEFAULT_MIRROR_MODE_TIGHTNESS; - - for (int m = 0; m < NUM_CAMERA_MODES; m ++) { - _previousAttributes[m].upShift = 0.0f; - _previousAttributes[m].distance = 0.0f; - _previousAttributes[m].tightness = 0.0f; - } } void Camera::update(float deltaTime) { @@ -67,7 +69,6 @@ void Camera::update(float deltaTime) { generateOrientation(); } - // generate the ortho-normals for the orientation based on the three Euler angles void Camera::generateOrientation() { _orientation.setToIdentity(); @@ -79,15 +80,26 @@ void Camera::generateOrientation() { // use iterative forces to keep the camera at the desired position and angle void Camera::updateFollowMode(float deltaTime) { - if (_modeShift < 1.0f) { - _modeShift += 5.0f * deltaTime; - if (_modeShift > 1.0f ) { + if (_linearModeShift < 1.0f) { + _linearModeShift += _modeShiftRate * deltaTime; + + _modeShift = ONE_HALF - ONE_HALF * cosf(_linearModeShift * PIE * 1.0); + + _upShift = _previousUpShift * (1.0f - _modeShift) + _newUpShift * _modeShift; + _distance = _previousDistance * (1.0f - _modeShift) + _newDistance * _modeShift; + _tightness = _previousTightness * (1.0f - _modeShift) + _newTightness * _modeShift; + + if (_linearModeShift > 1.0f ) { + _linearModeShift = 1.0f; _modeShift = 1.0f; + _upShift = _newUpShift; + _distance = _newDistance; + _tightness = _newTightness; } } // derive t from tightness - float t = _tightness * deltaTime; + float t = _tightness * _modeShift * deltaTime; if (t > 1.0) { t = 1.0; } @@ -103,10 +115,6 @@ void Camera::updateFollowMode(float deltaTime) { _pitch += (_idealPitch - _pitch) * t; _roll += (_idealRoll - _roll ) * t; } - - _orientation.yaw (_yaw ); - _orientation.pitch(_pitch); - _orientation.roll (_roll ); float radian = (_yaw / 180.0) * PIE; @@ -124,32 +132,45 @@ void Camera::updateFollowMode(float deltaTime) { // force position towards ideal position _position += (_idealPosition - _position) * t; } - - float inverseModeShift = 1.0f - _modeShift; - _upShift = _attributes[_mode].upShift * _modeShift + _previousAttributes[_mode].upShift * inverseModeShift; - _distance = _attributes[_mode].distance * _modeShift + _previousAttributes[_mode].distance * inverseModeShift; - _upShift = _attributes[_mode].upShift * _modeShift + _previousAttributes[_mode].upShift * inverseModeShift; } - -void Camera::setMode(CameraMode m, CameraFollowingAttributes a) { - - _previousAttributes[m].upShift = _attributes[m].upShift; - _previousAttributes[m].distance = _attributes[m].distance; - _previousAttributes[m].tightness = _attributes[m].tightness; - - _attributes[m].upShift = a.upShift; - _attributes[m].distance = a.distance; - _attributes[m].tightness = a.tightness; +void Camera::setModeShiftRate ( float rate ) { - setMode(m); + _modeShiftRate = rate; + + if (_modeShiftRate < CAMERA_MINIMUM_MODE_SHIFT_RATE ) { + _modeShiftRate = CAMERA_MINIMUM_MODE_SHIFT_RATE; + } } -void Camera::setMode(CameraMode m) { +void Camera::setMode(CameraMode m) { + _mode = m; _modeShift = 0.0; + _linearModeShift = 0.0; + + _previousUpShift = _upShift; + _previousDistance = _distance; + _previousTightness = _tightness; + + if (_mode == CAMERA_MODE_THIRD_PERSON) { + _newUpShift = CAMERA_THIRD_PERSON_MODE_UP_SHIFT; + _newDistance = CAMERA_THIRD_PERSON_MODE_DISTANCE; + _newTightness = CAMERA_THIRD_PERSON_MODE_TIGHTNESS; + + } else if (_mode == CAMERA_MODE_FIRST_PERSON) { + _newUpShift = CAMERA_FIRST_PERSON_MODE_UP_SHIFT; + _newDistance = CAMERA_FIRST_PERSON_MODE_DISTANCE; + _newTightness = CAMERA_FIRST_PERSON_MODE_TIGHTNESS; + + } else if (_mode == CAMERA_MODE_MIRROR) { + _newUpShift = CAMERA_MIRROR_MODE_UP_SHIFT; + _newDistance = CAMERA_MIRROR_MODE_DISTANCE; + _newTightness = CAMERA_MIRROR_MODE_TIGHTNESS; + } } + void Camera::setTargetRotation( float yaw, float pitch, float roll ) { _idealYaw = yaw; _idealPitch = pitch; diff --git a/interface/src/Camera.h b/interface/src/Camera.h index b01839d97a..ae3e3ef7b2 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -21,31 +21,11 @@ enum CameraMode NUM_CAMERA_MODES }; - -const float CAMERA_DEFAULT_FIRST_PERSON_MODE_UP_SHIFT = 0.0f; -const float CAMERA_DEFAULT_FIRST_PERSON_MODE_DISTANCE = 0.0f; -const float CAMERA_DEFAULT_FIRST_PERSON_MODE_TIGHTNESS = 100.0f; - -const float CAMERA_DEFAULT_THIRD_PERSON_MODE_UP_SHIFT = -0.2f; -const float CAMERA_DEFAULT_THIRD_PERSON_MODE_DISTANCE = 1.5f; -const float CAMERA_DEFAULT_THIRD_PERSON_MODE_TIGHTNESS = 8.0f; - -const float CAMERA_DEFAULT_MIRROR_MODE_UP_SHIFT = 0.0f; -const float CAMERA_DEFAULT_MIRROR_MODE_DISTANCE = 0.2f; -const float CAMERA_DEFAULT_MIRROR_MODE_TIGHTNESS = 100.0f; - class Camera { public: Camera(); - struct CameraFollowingAttributes - { - float upShift; - float distance; - float tightness; - }; - void initialize(); // instantly put the camera at the ideal position and rotation. void update( float deltaTime ); @@ -62,7 +42,7 @@ public: void setTargetRotation( float yaw, float pitch, float roll ); void setMode ( CameraMode m ); - void setMode ( CameraMode m, CameraFollowingAttributes attributes ); + void setModeShiftRate ( float r ); void setFieldOfView ( float f ); void setAspectRatio ( float a ); void setNearClip ( float n ); @@ -102,18 +82,23 @@ private: float _yaw; float _pitch; float _roll; - float _upShift; float _idealYaw; float _idealPitch; float _idealRoll; + float _upShift; float _distance; float _tightness; + float _previousUpShift; + float _previousDistance; + float _previousTightness; + float _newUpShift; + float _newDistance; + float _newTightness; Orientation _orientation; float _modeShift; + float _linearModeShift; + float _modeShiftRate; - CameraFollowingAttributes _attributes[NUM_CAMERA_MODES]; - CameraFollowingAttributes _previousAttributes[NUM_CAMERA_MODES]; - void generateOrientation(); void updateFollowMode( float deltaTime ); }; From 2b31e79a0b599f5ab8a9cd23637a196557081a48 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Sun, 26 May 2013 15:23:44 -0700 Subject: [PATCH 04/23] cleanup --- interface/src/AvatarTouch.cpp | 2 +- interface/src/Camera.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 2072848902..c598cc9a03 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -75,7 +75,7 @@ void AvatarTouch::render(glm::vec3 cameraPosition) { p.y = 0.0005f; renderCircle(p, _reachableRadius, glm::vec3(0.0f, 1.0f, 0.0f), 30); - // show if we are golding hands... + // show if we are holding hands... if (_weAreHoldingHands) { renderBeamBetweenHands(); diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 1b1dc56ae2..fa0744bf49 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -83,7 +83,7 @@ void Camera::updateFollowMode(float deltaTime) { if (_linearModeShift < 1.0f) { _linearModeShift += _modeShiftRate * deltaTime; - _modeShift = ONE_HALF - ONE_HALF * cosf(_linearModeShift * PIE * 1.0); + _modeShift = ONE_HALF - ONE_HALF * cosf(_linearModeShift * PIE ); _upShift = _previousUpShift * (1.0f - _modeShift) + _newUpShift * _modeShift; _distance = _previousDistance * (1.0f - _modeShift) + _newDistance * _modeShift; From 4e4a672f327e8dbc5f1283069283c78306481f83 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Sun, 26 May 2013 17:17:15 -0700 Subject: [PATCH 05/23] fixed visual glitch where mouth penetrates head sphere --- interface/src/Head.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 72ae41e8d2..e9621ab2c5 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -18,7 +18,7 @@ const float EYE_RIGHT_OFFSET = 0.27f; const float EYE_UP_OFFSET = 0.36f; const float EYE_FRONT_OFFSET = 0.8f; const float EAR_RIGHT_OFFSET = 1.0; -const float MOUTH_FRONT_OFFSET = 0.9f; +//const float MOUTH_FRONT_OFFSET = 0.9f; const float MOUTH_UP_OFFSET = -0.3f; const float HEAD_MOTION_DECAY = 0.1; const float MINIMUM_EYE_ROTATION_DOT = 0.5f; // based on a dot product: 1.0 is straight ahead, 0.0 is 90 degrees off @@ -202,7 +202,7 @@ void Head::calculateGeometry(bool lookingInMirror) { //calculate the mouth position _mouthPosition = _position + _orientation.getUp () * _scale * MOUTH_UP_OFFSET - + _orientation.getFront() * _scale * MOUTH_FRONT_OFFSET; + + _orientation.getFront() * _scale; } @@ -343,6 +343,7 @@ void Head::renderMouth() { glm::vec3 u = _orientation.getUp () * _scale * (0.05f + s * 0.0040f ); glm::vec3 f = _orientation.getFront() * _scale * 0.09f; + glm::vec3 middle = _mouthPosition; glm::vec3 leftCorner = _mouthPosition - r * 1.0f; glm::vec3 rightCorner = _mouthPosition + r * 1.0f; glm::vec3 leftTop = _mouthPosition - r * 0.4f + u * 0.7f + f; @@ -352,6 +353,7 @@ void Head::renderMouth() { // constrain all mouth vertices to a sphere slightly larger than the head... float constrainedRadius = _scale + 0.001f; + middle = _position + glm::normalize(middle - _position) * constrainedRadius; leftCorner = _position + glm::normalize(leftCorner - _position) * constrainedRadius; rightCorner = _position + glm::normalize(rightCorner - _position) * constrainedRadius; leftTop = _position + glm::normalize(leftTop - _position) * constrainedRadius; @@ -366,10 +368,16 @@ void Head::renderMouth() { glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z ); glVertex3f(leftTop.x, leftTop.y, leftTop.z ); glVertex3f(leftTop.x, leftTop.y, leftTop.z ); + glVertex3f(middle.x, middle.y, middle.z ); glVertex3f(rightTop.x, rightTop.y, rightTop.z ); + glVertex3f(leftTop.x, leftTop.y, leftTop.z ); + glVertex3f(middle.x, middle.y, middle.z ); glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z ); + glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z ); + glVertex3f(middle.x, middle.y, middle.z ); + glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z); glVertex3f(rightTop.x, rightTop.y, rightTop.z ); - glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z ); + glVertex3f(middle.x, middle.y, middle.z ); glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z); glVertex3f(rightTop.x, rightTop.y, rightTop.z ); glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z); From ad5d097ed4196a1955526e8f71af2fbf9fdb85d7 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Sun, 26 May 2013 17:44:52 -0700 Subject: [PATCH 06/23] improved neck rendering --- interface/src/Avatar.cpp | 45 ++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index b3dd505f40..bf6238779c 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -874,8 +874,8 @@ void Avatar::initializeSkeleton() { _joint[ AVATAR_JOINT_PELVIS ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 ); _joint[ AVATAR_JOINT_TORSO ].defaultPosePosition = glm::vec3( 0.0, 0.09, 0.01 ); _joint[ AVATAR_JOINT_CHEST ].defaultPosePosition = glm::vec3( 0.0, 0.09, 0.01 ); - _joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.12, -0.01 ); - _joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.08, 0.00 ); + _joint[ AVATAR_JOINT_NECK_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.14, -0.01 ); + _joint[ AVATAR_JOINT_HEAD_BASE ].defaultPosePosition = glm::vec3( 0.0, 0.04, 0.00 ); _joint[ AVATAR_JOINT_LEFT_COLLAR ].defaultPosePosition = glm::vec3( -0.06, 0.04, -0.01 ); _joint[ AVATAR_JOINT_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.05, 0.0, -0.01 ); @@ -1180,38 +1180,43 @@ void Avatar::renderBody(bool lookingInMirror) { glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f)); } + glPushMatrix(); glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z); glutSolidSphere(_joint[b].radius, 20.0f, 20.0f); glPopMatrix(); - // Render the cone connecting this joint to it's parent - - if (_joint[b].parent != AVATAR_JOINT_NULL) + // Render the cone connecting this joint to its parent + if (_joint[b].parent != AVATAR_JOINT_NULL) { if ((b != AVATAR_JOINT_HEAD_TOP ) - && (b != AVATAR_JOINT_HEAD_BASE ) - && (b != AVATAR_JOINT_PELVIS ) - && (b != AVATAR_JOINT_TORSO ) - && (b != AVATAR_JOINT_CHEST ) - && (b != AVATAR_JOINT_LEFT_COLLAR ) - && (b != AVATAR_JOINT_LEFT_SHOULDER ) - && (b != AVATAR_JOINT_RIGHT_COLLAR ) - && (b != AVATAR_JOINT_RIGHT_SHOULDER)) { - // Render cone sections connecting the joint positions + && (b != AVATAR_JOINT_HEAD_BASE ) + && (b != AVATAR_JOINT_PELVIS ) + && (b != AVATAR_JOINT_TORSO ) + && (b != AVATAR_JOINT_CHEST ) + && (b != AVATAR_JOINT_LEFT_COLLAR ) + && (b != AVATAR_JOINT_LEFT_SHOULDER ) + && (b != AVATAR_JOINT_RIGHT_COLLAR ) + && (b != AVATAR_JOINT_RIGHT_SHOULDER)) { glColor3fv(darkSkinColor); + + float r1 = _joint[_joint[b].parent ].radius * 0.8; + float r2 = _joint[b ].radius * 0.8; + if (b == AVATAR_JOINT_HEAD_BASE) { + r1 *= 0.5f; + } renderJointConnectingCone ( _joint[_joint[b].parent ].springyPosition, - _joint[b ].springyPosition, - _joint[_joint[b].parent ].radius * 0.8, - _joint[b ].radius * 0.8 + _joint[b ].springyPosition, r2, r2 ); - } - + } + } } - } } + + + void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity, float deltaTime, float smoothingTime) { // // Given absolute position and angular velocity information, update the avatar's head angles From d43c5ca52c837c9b1d4f2b19e34f970e51cc9733 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Sun, 26 May 2013 21:56:21 -0700 Subject: [PATCH 07/23] normalized body spring tightness --- interface/src/Avatar.cpp | 64 +++++++++++++--------------------------- 1 file changed, 21 insertions(+), 43 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index bf6238779c..65be82f4ec 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -34,7 +34,7 @@ const float BODY_UPRIGHT_FORCE = 10.0; const float VELOCITY_DECAY = 5.0; const float MY_HAND_HOLDING_PULL = 0.2; const float YOUR_HAND_HOLDING_PULL = 1.0; -const float BODY_SPRING_DEFAULT_TIGHTNESS = 1500.0f; +const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f; const float BODY_SPRING_FORCE = 300.0f; const float BODY_SPRING_DECAY = 16.0f; const float COLLISION_RADIUS_SCALAR = 1.8; @@ -928,31 +928,6 @@ void Avatar::initializeSkeleton() { _joint[ AVATAR_JOINT_RIGHT_HEEL ].radius = 0.025; _joint[ AVATAR_JOINT_RIGHT_TOES ].radius = 0.025; - // specify the tightness of the springy positions as far as attraction to rigid body - _joint[ AVATAR_JOINT_PELVIS ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 1.0; - _joint[ AVATAR_JOINT_TORSO ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.8; - _joint[ AVATAR_JOINT_CHEST ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_NECK_BASE ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.4; - _joint[ AVATAR_JOINT_HEAD_BASE ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.3; - _joint[ AVATAR_JOINT_LEFT_COLLAR ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_LEFT_SHOULDER ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_LEFT_ELBOW ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_LEFT_WRIST ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.3; - _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.3; - _joint[ AVATAR_JOINT_RIGHT_COLLAR ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_RIGHT_ELBOW ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.5; - _joint[ AVATAR_JOINT_RIGHT_WRIST ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.3; - _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS * 0.3; - _joint[ AVATAR_JOINT_LEFT_HIP ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_LEFT_KNEE ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_LEFT_HEEL ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_LEFT_TOES ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_RIGHT_HIP ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_RIGHT_KNEE ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_RIGHT_HEEL ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - _joint[ AVATAR_JOINT_RIGHT_TOES ].springBodyTightness = BODY_SPRING_DEFAULT_TIGHTNESS; - // to aid in hand-shaking and hand-holding, the right hand is not collidable _joint[ AVATAR_JOINT_RIGHT_ELBOW ].isCollidable = false; _joint[ AVATAR_JOINT_RIGHT_WRIST ].isCollidable = false; @@ -1283,33 +1258,36 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, glBegin(GL_TRIANGLES); - int num = 10; + int num = 9; - glm::vec3 axis = glm::normalize(position2 - position1); + glm::vec3 axis = position2 - position1; float length = glm::length(axis); if (length > 0.0f) { - glm::vec3 perpSin = glm::vec3(axis.y, axis.z, axis.x); - glm::vec3 perpCos = glm::vec3(axis.z, axis.x, axis.y); + axis /= length; + + glm::vec3 perpSin = glm::vec3(1.0f, 0.0f, 0.0f); + glm::vec3 perpCos = glm::normalize(glm::cross(axis, perpSin)); + perpSin = glm::cross(perpCos, axis); - float angle1 = 0.0; - float angle2 = 0.0; + float anglea = 0.0; + float angleb = 0.0; for (int i = 0; i < num; i ++) { - angle1 = angle2; - angle2 = ((float)(i+1) / (float)num) * PI * 2.0; + anglea = angleb; + angleb = ((float)(i+1) / (float)num) * PI * 2.0f; - float s1 = sinf(angle1); - float s2 = sinf(angle2); - float c1 = cosf(angle1); - float c2 = cosf(angle2); - - glm::vec3 p1a = position1 + perpSin * s1 * radius1 + perpCos * c1 * radius1; - glm::vec3 p1b = position1 + perpSin * s2 * radius1 + perpCos * c2 * radius1; - glm::vec3 p2a = position2 + perpSin * s1 * radius2 + perpCos * c1 * radius2; - glm::vec3 p2b = position2 + perpSin * s2 * radius2 + perpCos * c2 * radius2; + float sa = sinf(anglea); + float sb = sinf(angleb); + float ca = cosf(anglea); + float cb = cosf(angleb); + + glm::vec3 p1a = position1 + perpSin * sa * radius1 + perpCos * ca * radius1; + glm::vec3 p1b = position1 + perpSin * sb * radius1 + perpCos * cb * radius1; + glm::vec3 p2a = position2 + perpSin * sa * radius2 + perpCos * ca * radius2; + glm::vec3 p2b = position2 + perpSin * sb * radius2 + perpCos * cb * radius2; glVertex3f(p1a.x, p1a.y, p1a.z); glVertex3f(p1b.x, p1b.y, p1b.z); From 096e465d3657458f25ffb21fadb50af6b9525768 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 27 May 2013 10:31:31 -0700 Subject: [PATCH 08/23] cleaned up some formatting and in-line functions in Avatar.cpp --- interface/src/Avatar.cpp | 53 ++++++++++-------------------- interface/src/Avatar.h | 71 ++++++++++++++++++++-------------------- 2 files changed, 52 insertions(+), 72 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 65be82f4ec..0127ffa4c8 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -54,15 +54,12 @@ const float JOINT_TOUCH_RANGE = 0.0005f; const float ANGULAR_RIGHTING_SPEED = 45.0f; const float FLOATING_HEIGHT = 0.13f; const bool USING_HEAD_LEAN = false; - -const float LEAN_SENSITIVITY = 0.15; -const float LEAN_MAX = 0.45; -const float LEAN_AVERAGING = 10.0; -const float HEAD_RATE_MAX = 50.f; - -float skinColor [] = {1.0, 0.84, 0.66}; -float darkSkinColor[] = {0.9, 0.78, 0.63}; -float lightBlue [] = {0.7, 0.8, 1.0 }; +const float LEAN_SENSITIVITY = 0.15; +const float LEAN_MAX = 0.45; +const float LEAN_AVERAGING = 10.0; +const float HEAD_RATE_MAX = 50.f; +const float SKIN_COLOR[] = {1.0, 0.84, 0.66}; +const float DARK_SKIN_COLOR[] = {0.9, 0.78, 0.63}; bool usingBigSphereCollisionTest = true; @@ -80,8 +77,8 @@ Avatar::Avatar(Agent* owningAgent) : _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), + _cameraPosition(0.0f, 0.0f, 0.0f), _handHoldingPosition(0.0f, 0.0f, 0.0f), _velocity(0.0f, 0.0f, 0.0f), _thrust(0.0f, 0.0f, 0.0f), @@ -165,14 +162,6 @@ float Avatar::getAbsoluteHeadPitch() const { return _bodyPitch + _head.getPitch(); } -void Avatar::setMousePressed(bool mousePressed) { - _mousePressed = mousePressed; -} - -bool Avatar::getIsNearInteractingOther() { - return _avatarTouch.getAbleToReachOtherAvatar(); -} - void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight) { // Update yaw based on mouse behavior const float MOUSE_MOVE_RADIUS = 0.15f; @@ -444,7 +433,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _head.setPosition(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition); _head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius); _head.setAudioLoudness(_audioLoudness); - _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); + _head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2])); _head.simulate(deltaTime, !_owningAgent); // use speed and angular velocity to determine walking vs. standing @@ -471,7 +460,8 @@ void Avatar::checkForMouseRayTouching() { } void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction ) { - _mouseRayOrigin = origin; _mouseRayDirection = direction; + _mouseRayOrigin = origin; + _mouseRayDirection = direction; } void Avatar::updateHandMovementAndTouching(float deltaTime) { @@ -1077,15 +1067,6 @@ void Avatar::updateBodySprings(float deltaTime) { } } - -const glm::vec3& Avatar::getSpringyHeadPosition() const { - return _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition; -} - -const glm::vec3& Avatar::getHeadPosition() const { - return _joint[ AVATAR_JOINT_HEAD_BASE ].position; -} - void Avatar::updateArmIKAndConstraints(float deltaTime) { // determine the arm vector @@ -1145,13 +1126,13 @@ void Avatar::renderBody(bool lookingInMirror) { if (_owningAgent || b == AVATAR_JOINT_RIGHT_ELBOW || b == AVATAR_JOINT_RIGHT_WRIST || b == AVATAR_JOINT_RIGHT_FINGERTIPS ) { - glColor3f(skinColor[0] + _joint[b].touchForce * 0.3f, - skinColor[1] - _joint[b].touchForce * 0.2f, - skinColor[2] - _joint[b].touchForce * 0.1f); + glColor3f(SKIN_COLOR[0] + _joint[b].touchForce * 0.3f, + SKIN_COLOR[1] - _joint[b].touchForce * 0.2f, + SKIN_COLOR[2] - _joint[b].touchForce * 0.1f); } else { - glColor4f(skinColor[0] + _joint[b].touchForce * 0.3f, - skinColor[1] - _joint[b].touchForce * 0.2f, - skinColor[2] - _joint[b].touchForce * 0.1f, + glColor4f(SKIN_COLOR[0] + _joint[b].touchForce * 0.3f, + SKIN_COLOR[1] - _joint[b].touchForce * 0.2f, + SKIN_COLOR[2] - _joint[b].touchForce * 0.1f, glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f)); } @@ -1172,7 +1153,7 @@ void Avatar::renderBody(bool lookingInMirror) { && (b != AVATAR_JOINT_LEFT_SHOULDER ) && (b != AVATAR_JOINT_RIGHT_COLLAR ) && (b != AVATAR_JOINT_RIGHT_SHOULDER)) { - glColor3fv(darkSkinColor); + glColor3fv(DARK_SKIN_COLOR); float r1 = _joint[_joint[b].parent ].radius * 0.8; float r2 = _joint[b ].radius * 0.8; diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 1a715b613d..abeea56277 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -2,7 +2,6 @@ // Avatar.h // interface // -// Created by Philip Rosedale on 9/11/12. // Copyright (c) 2012 High Fidelity, Inc. All rights reserved. // @@ -79,50 +78,47 @@ public: Avatar(Agent* owningAgent = NULL); ~Avatar(); - void reset(); - void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); - void updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight); - void setNoise (float mag) {_head.noise = mag;} - float getLastMeasuredHeadYaw() const {return _head.yawRate;} - float getBodyYaw() {return _bodyYaw;}; - void addBodyYaw(float y) {_bodyYaw += y;}; - void setGravity(glm::vec3 gravity); - - void setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction ); - bool getIsNearInteractingOther(); - - float getAbsoluteHeadYaw() const; - float getAbsoluteHeadPitch() const; - glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) - const glm::vec3& getHeadPosition() const ; // get the position of the avatar's rigid body head - const glm::vec3& getSpringyHeadPosition() const ; // get the springy position of the avatar's head - const glm::vec3& getJointPosition(AvatarJointID j) const { return _joint[j].springyPosition; }; - const glm::vec3& getBodyUpDirection() const { return _orientation.getUp(); }; - float getSpeed() const { return _speed; } - const glm::vec3& getVelocity() const { return _velocity; }; - float getGirth(); - float getHeight() const { return _height; } - - AvatarMode getMode() const { return _mode; } - Head& getHead() { return _head; } - - void setMousePressed(bool pressed); - void render(bool lookingInMirror, glm::vec3 cameraPosition); - void renderBody(bool lookingInMirror); + void reset(); void simulate(float deltaTime, Transmitter* transmitter); - void setMovedHandOffset(glm::vec3 movedHandOffset) { _movedHandOffset = movedHandOffset; } - void updateArmIKAndConstraints( float deltaTime ); - void setDisplayingLookatVectors(bool displayingLookatVectors) { _head.setRenderLookatVectors(displayingLookatVectors); } - + void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); + void updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight); + void addBodyYaw(float y) {_bodyYaw += y;}; + void render(bool lookingInMirror, glm::vec3 cameraPosition); + + //setters + void setMousePressed (bool mousePressed ) { _mousePressed = mousePressed;} + void setNoise (float mag ) { _head.noise = mag;} + void setMovedHandOffset (glm::vec3 movedHandOffset ) { _movedHandOffset = movedHandOffset;} + void setThrust (glm::vec3 newThrust ) { _thrust = newThrust; }; + void setDisplayingLookatVectors(bool displayingLookatVectors) { _head.setRenderLookatVectors(displayingLookatVectors);} + void setGravity (glm::vec3 gravity); + void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction); + + //getters + float getLastMeasuredHeadYaw () const { return _head.yawRate;} + float getBodyYaw () const { return _bodyYaw;} + bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();} + const glm::vec3& getHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].position;} + const glm::vec3& getSpringyHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition;} + const glm::vec3& getJointPosition (AvatarJointID j) const { return _joint[j].springyPosition;} + const glm::vec3& getBodyUpDirection () const { return _orientation.getUp();} + const glm::vec3& getVelocity () const { return _velocity;} + float getSpeed () const { return _speed;} + float getHeight () const { return _height;} + AvatarMode getMode () const { return _mode;} + float getAbsoluteHeadYaw () const; + float getAbsoluteHeadPitch () const; + Head& getHead () {return _head; } + // Set what driving keys are being pressed to control thrust levels void setDriveKeys(int key, bool val) { _driveKeys[key] = val; }; bool getDriveKeys(int key) { return _driveKeys[key]; }; // Set/Get update the thrust that will move the avatar around - void setThrust(glm::vec3 newThrust) { _thrust = newThrust; }; void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; glm::vec3 getThrust() { return _thrust; }; + //read/write avatar data void writeAvatarDataToFile(); void readAvatarDataFromFile(); @@ -184,6 +180,8 @@ private: bool _isMouseTurningRight; // private methods... + glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) + void renderBody(bool lookingInMirror); void initializeSkeleton(); void updateSkeleton(); void initializeBodySprings(); @@ -192,6 +190,7 @@ private: void readSensors(); void updateHandMovementAndTouching(float deltaTime); void updateAvatarCollisions(float deltaTime); + void updateArmIKAndConstraints( float deltaTime ); void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime ); void updateCollisionWithEnvironment(); void updateCollisionWithVoxels(); From cfb66bee955a5e2948f6b940bf176f0b1823345f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 27 May 2013 14:05:44 -0700 Subject: [PATCH 09/23] Capsule/box collisions. --- interface/src/Avatar.cpp | 10 +- libraries/voxels/src/AABox.cpp | 131 +++++++++++++++++++++++++- libraries/voxels/src/AABox.h | 5 + libraries/voxels/src/GeometryUtil.cpp | 76 +++++++-------- libraries/voxels/src/GeometryUtil.h | 13 +-- libraries/voxels/src/VoxelTree.cpp | 14 +-- 6 files changed, 186 insertions(+), 63 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 5bc7a07bf1..17958a4fa2 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -615,13 +615,9 @@ void Avatar::updateCollisionWithEnvironment() { void Avatar::updateCollisionWithVoxels() { float radius = _height * 0.125f; glm::vec3 penetration; - //if (Application::getInstance()->getVoxels()->findCapsulePenetration( - // _position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f), - // _position + glm::vec3(0.0f, _height - _pelvisFloatingHeight - radius, 0.0f), radius, penetration)) { - // applyCollisionWithScene(penetration); - //} - - if (Application::getInstance()->getVoxels()->findSpherePenetration(_position, _height/2, penetration)) { + if (Application::getInstance()->getVoxels()->findCapsulePenetration( + _position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f), + _position + glm::vec3(0.0f, _height - _pelvisFloatingHeight - radius, 0.0f), radius, penetration)) { applyCollisionWithScene(penetration); } } diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index d49c04136b..ce6d653eb0 100644 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -107,6 +107,30 @@ static bool findIntersection(float origin, float direction, float corner, float return false; } +bool AABox::expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const { + // handle the trivial cases where the expanded box contains the start or end + if (expandedContains(start, expansion) || expandedContains(end, expansion)) { + return true; + } + // check each axis + glm::vec3 expandedCorner = _corner - glm::vec3(expansion, expansion, expansion); + glm::vec3 expandedSize = _size + glm::vec3(expansion, expansion, expansion) * 2.0f; + glm::vec3 direction = end - start; + float axisDistance; + return (findIntersection(start.x, direction.x, expandedCorner.x, expandedSize.x, axisDistance) && + axisDistance >= 0.0f && axisDistance <= 1.0f && + isWithin(start.y + axisDistance*direction.y, expandedCorner.y, expandedSize.y) && + isWithin(start.z + axisDistance*direction.z, expandedCorner.z, expandedSize.z)) || + (findIntersection(start.y, direction.y, expandedCorner.y, expandedSize.y, axisDistance) && + axisDistance >= 0.0f && axisDistance <= 1.0f && + isWithin(start.x + axisDistance*direction.x, expandedCorner.x, expandedSize.x) && + isWithin(start.z + axisDistance*direction.z, expandedCorner.z, expandedSize.z)) || + (findIntersection(start.z, direction.z, expandedCorner.z, expandedSize.z, axisDistance) && + axisDistance >= 0.0f && axisDistance <= 1.0f && + isWithin(start.y + axisDistance*direction.y, expandedCorner.y, expandedSize.y) && + isWithin(start.x + axisDistance*direction.x, expandedCorner.x, expandedSize.x)); +} + bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const { // handle the trivial case where the box contains the origin if (contains(origin)) { @@ -144,12 +168,15 @@ bool AABox::findSpherePenetration(const glm::vec3& center, float radius, glm::ve float minPenetrationLength = FLT_MAX; for (int i = 0; i < FACE_COUNT; i++) { + glm::vec4 facePlane = getPlane((BoxFace)i); glm::vec3 vector = getClosestPointOnFace(center, (BoxFace)i) - center; if (glm::dot(center4, getPlane((BoxFace)i)) >= 0.0f) { - return ::findSpherePenetration(vector, radius, penetration); + // outside this face, so use vector to closest point to determine penetration + return ::findSpherePenetration(vector, glm::vec3(-facePlane), radius, penetration); } float vectorLength = glm::length(vector); if (vectorLength < minPenetrationLength) { + // remember the smallest penetration vector; if we're inside all faces, we'll use that penetration = vector * ((vectorLength + radius) / -vectorLength); minPenetrationLength = vectorLength; } @@ -158,6 +185,33 @@ bool AABox::findSpherePenetration(const glm::vec3& center, float radius, glm::ve return true; } +bool AABox::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) const { + glm::vec4 start4 = glm::vec4(start, 1.0f); + glm::vec4 end4 = glm::vec4(end, 1.0f); + glm::vec4 startToEnd = glm::vec4(end - start, 0.0f); + + float minPenetrationLength = FLT_MAX; + for (int i = 0; i < FACE_COUNT; i++) { + // find the vector from the segment to the closest point on the face (starting from deeper end) + glm::vec4 facePlane = getPlane((BoxFace)i); + glm::vec3 closest = (glm::dot(start4, facePlane) <= glm::dot(end4, facePlane)) ? + getClosestPointOnFace(start4, startToEnd, (BoxFace)i) : getClosestPointOnFace(end4, -startToEnd, (BoxFace)i); + glm::vec3 vector = -computeVectorFromPointToSegment(closest, start, end); + if (glm::dot(vector, glm::vec3(facePlane)) < 0.0f) { + // outside this face, so use vector to closest point to determine penetration + return ::findSpherePenetration(vector, glm::vec3(-facePlane), radius, penetration); + } + float vectorLength = glm::length(vector); + if (vectorLength < minPenetrationLength) { + // remember the smallest penetration vector; if we're inside all faces, we'll use that + penetration = vector * ((vectorLength + radius) / -vectorLength); + minPenetrationLength = vectorLength; + } + } + + return true; +} + glm::vec3 AABox::getClosestPointOnFace(const glm::vec3& point, BoxFace face) const { switch (face) { case MIN_X_FACE: @@ -186,6 +240,70 @@ glm::vec3 AABox::getClosestPointOnFace(const glm::vec3& point, BoxFace face) con } } +glm::vec3 AABox::getClosestPointOnFace(const glm::vec4& origin, const glm::vec4& direction, BoxFace face) const { + // check against the four planes that border the face + BoxFace oppositeFace = getOppositeFace(face); + bool anyOutside = false; + for (int i = 0; i < FACE_COUNT; i++) { + if (i == face || i == oppositeFace) { + continue; + } + glm::vec4 iPlane = getPlane((BoxFace)i); + float originDistance = glm::dot(origin, iPlane); + if (originDistance < 0.0f) { + continue; // inside the border + } + anyOutside = true; + float divisor = glm::dot(direction, iPlane); + if (fabs(divisor) < EPSILON) { + continue; // segment is parallel to plane + } + // find intersection and see if it lies within face bounds + float directionalDistance = -originDistance / divisor; + glm::vec4 intersection = origin + direction * directionalDistance; + BoxFace iOppositeFace = getOppositeFace((BoxFace)i); + for (int j = 0; j < FACE_COUNT; j++) { + if (j == face || j == oppositeFace || j == i || j == iOppositeFace) { + continue; + } + if (glm::dot(intersection, getPlane((BoxFace)j)) > 0.0f) { + goto outerContinue; // intersection is out of bounds + } + } + return getClosestPointOnFace(glm::vec3(intersection), face); + + outerContinue: ; + } + + // if we were outside any of the sides, we must check against the diagonals + if (anyOutside) { + int faceAxis = face / 2; + int secondAxis = (faceAxis + 1) % 3; + int thirdAxis = (faceAxis + 2) % 3; + + glm::vec4 secondAxisMinPlane = getPlane((BoxFace)(secondAxis * 2)); + glm::vec4 secondAxisMaxPlane = getPlane((BoxFace)(secondAxis * 2 + 1)); + glm::vec4 thirdAxisMaxPlane = getPlane((BoxFace)(thirdAxis * 2 + 1)); + + glm::vec4 offset = glm::vec4(0.0f, 0.0f, 0.0f, + glm::dot(glm::vec3(secondAxisMaxPlane + thirdAxisMaxPlane), _size) * 0.5f); + glm::vec4 diagonals[] = { secondAxisMinPlane + thirdAxisMaxPlane + offset, + secondAxisMaxPlane + thirdAxisMaxPlane + offset }; + + for (int i = 0; i < sizeof(diagonals) / sizeof(diagonals[0]); i++) { + float divisor = glm::dot(direction, diagonals[i]); + if (fabs(divisor) < EPSILON) { + continue; // segment is parallel to diagonal plane + } + float directionalDistance = -glm::dot(origin, diagonals[i]) / divisor; + return getClosestPointOnFace(glm::vec3(origin + direction * directionalDistance), face); + } + } + + // last resort or all inside: clamp origin to face + return getClosestPointOnFace(glm::vec3(origin), face); +} + glm::vec4 AABox::getPlane(BoxFace face) const { switch (face) { case MIN_X_FACE: return glm::vec4(-1.0f, 0.0f, 0.0f, _corner.x); @@ -196,3 +314,14 @@ glm::vec4 AABox::getPlane(BoxFace face) const { case MAX_Z_FACE: return glm::vec4(0.0f, 0.0f, 1.0f, -_corner.z - _size.z); } } + +BoxFace AABox::getOppositeFace(BoxFace face) { + switch (face) { + case MIN_X_FACE: return MAX_X_FACE; + case MAX_X_FACE: return MIN_X_FACE; + case MIN_Y_FACE: return MAX_Y_FACE; + case MAX_Y_FACE: return MIN_Y_FACE; + case MIN_Z_FACE: return MAX_Z_FACE; + case MAX_Z_FACE: return MIN_Z_FACE; + } +} diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h index 5f4f84d417..591704d4a3 100755 --- a/libraries/voxels/src/AABox.h +++ b/libraries/voxels/src/AABox.h @@ -48,14 +48,19 @@ public: bool contains(const glm::vec3& point) const; bool expandedContains(const glm::vec3& point, float expansion) const; + bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const; bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const; + bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) const; private: glm::vec3 getClosestPointOnFace(const glm::vec3& point, BoxFace face) const; + glm::vec3 getClosestPointOnFace(const glm::vec4& origin, const glm::vec4& direction, BoxFace face) const; glm::vec4 getPlane(BoxFace face) const; + static BoxFace getOppositeFace(BoxFace face); + glm::vec3 _corner; glm::vec3 _center; glm::vec3 _size; diff --git a/libraries/voxels/src/GeometryUtil.cpp b/libraries/voxels/src/GeometryUtil.cpp index b059645553..aceaa32b37 100644 --- a/libraries/voxels/src/GeometryUtil.cpp +++ b/libraries/voxels/src/GeometryUtil.cpp @@ -5,41 +5,18 @@ // Created by Andrzej Kapolka on 5/21/13. // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +#include + #include "GeometryUtil.h" -bool findSpherePenetration(const glm::vec3& penetratorToPenetratee, float combinedRadius, glm::vec3& penetration) { - float vectorLength = glm::length(penetratorToPenetratee); - float distance = vectorLength - combinedRadius; - if (distance < 0.0f) { - penetration = penetratorToPenetratee * (-distance / vectorLength); - return true; - } - return false; -} - -bool findSpherePointPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, - const glm::vec3& penetrateeLocation, glm::vec3& penetration) { - return findSpherePenetration(penetrateeLocation - penetratorCenter, penetratorRadius, penetration); -} - -bool findSphereSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, - const glm::vec3& penetrateeCenter, float penetrateeRadius, glm::vec3& penetration) { - return findSpherePointPenetration(penetratorCenter, penetratorRadius + penetrateeRadius, penetrateeCenter, penetration); -} - -bool findSphereLinePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, - const glm::vec3& penetrateeOrigin, const glm::vec3& penetrateeDirection, - glm::vec3& penetration) { - // compute the projection of the penetrator vector onto the line - float proj = glm::dot(penetratorCenter - penetrateeOrigin, penetrateeDirection); - return findSpherePenetration((penetrateeOrigin + penetrateeDirection*proj) - penetratorCenter, - penetratorRadius, penetration); -} - -static glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) { +glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) { // compute the projection of the point vector onto the segment vector glm::vec3 segmentVector = end - start; - float proj = glm::dot(point - start, segmentVector) / glm::dot(segmentVector, segmentVector); + float lengthSquared = glm::dot(segmentVector, segmentVector); + if (lengthSquared < EPSILON) { + return start - point; // start and end the same + } + float proj = glm::dot(point - start, segmentVector) / lengthSquared; if (proj <= 0.0f) { // closest to the start return start - point; @@ -51,10 +28,36 @@ static glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const g } } +bool findSpherePenetration(const glm::vec3& penetratorToPenetratee, const glm::vec3& direction, + float combinedRadius, glm::vec3& penetration) { + float vectorLength = glm::length(penetratorToPenetratee); + if (vectorLength < EPSILON) { + penetration = direction * combinedRadius; + return true; + } + float distance = vectorLength - combinedRadius; + if (distance < 0.0f) { + penetration = penetratorToPenetratee * (-distance / vectorLength); + return true; + } + return false; +} + +bool findSpherePointPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec3& penetrateeLocation, glm::vec3& penetration) { + return findSpherePenetration(penetrateeLocation - penetratorCenter, glm::vec3(0.0f, -1.0f, 0.0f), + penetratorRadius, penetration); +} + +bool findSphereSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, + const glm::vec3& penetrateeCenter, float penetrateeRadius, glm::vec3& penetration) { + return findSpherePointPenetration(penetratorCenter, penetratorRadius + penetrateeRadius, penetrateeCenter, penetration); +} + bool findSphereSegmentPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, const glm::vec3& penetrateeStart, const glm::vec3& penetrateeEnd, glm::vec3& penetration) { return findSpherePenetration(computeVectorFromPointToSegment(penetratorCenter, penetrateeStart, penetrateeEnd), - penetratorRadius, penetration); + glm::vec3(0.0f, -1.0f, 0.0f), penetratorRadius, penetration); } bool findSphereCapsulePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, const glm::vec3& penetrateeStart, @@ -73,15 +76,6 @@ bool findSpherePlanePenetration(const glm::vec3& penetratorCenter, float penetra return false; } -bool findCapsulePointPenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, - const glm::vec3& penetrateeLocation, glm::vec3& penetration) { - if (findSphereSegmentPenetration(penetrateeLocation, penetratorRadius, penetratorStart, penetratorEnd, penetration)) { - penetration = -penetration; - return true; - } - return false; -} - bool findCapsuleSpherePenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, const glm::vec3& penetrateeCenter, float penetrateeRadius, glm::vec3& penetration) { if (findSphereCapsulePenetration(penetrateeCenter, penetrateeRadius, diff --git a/libraries/voxels/src/GeometryUtil.h b/libraries/voxels/src/GeometryUtil.h index 0d80626507..01cd87a4f3 100644 --- a/libraries/voxels/src/GeometryUtil.h +++ b/libraries/voxels/src/GeometryUtil.h @@ -11,17 +11,17 @@ #include -bool findSpherePenetration(const glm::vec3& penetratorToPenetratee, float combinedRadius, glm::vec3& penetration); +glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end); + +bool findSpherePenetration(const glm::vec3& penetratorToPenetratee, const glm::vec3& direction, + float combinedRadius, glm::vec3& penetration); bool findSpherePointPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, const glm::vec3& penetrateeLocation, glm::vec3& penetration); bool findSphereSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, const glm::vec3& penetrateeCenter, float penetrateeRadius, glm::vec3& penetration); - -bool findSphereLinePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, - const glm::vec3& penetrateeOrigin, const glm::vec3& penetrateeDirection, glm::vec3& penetration); - + bool findSphereSegmentPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, const glm::vec3& penetrateeStart, const glm::vec3& penetrateeEnd, glm::vec3& penetration); @@ -30,9 +30,6 @@ bool findSphereCapsulePenetration(const glm::vec3& penetratorCenter, float penet bool findSpherePlanePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, const glm::vec4& penetrateePlane, glm::vec3& penetration); - -bool findCapsulePointPenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, - const glm::vec3& penetrateeLocation, glm::vec3& penetration); bool findCapsuleSpherePenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, const glm::vec3& penetrateeCenter, float penetrateeRadius, glm::vec3& penetration); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index c97765a3fb..39a7fceff6 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -753,18 +753,20 @@ public: bool findCapsulePenetrationOp(VoxelNode* node, void* extraData) { CapsuleArgs* args = static_cast(extraData); - // currently, we treat each node as a sphere enveloping the box - glm::vec3 nodePenetration; - if (!findCapsuleSpherePenetration(args->start, args->end, args->radius, node->getCenter(), - node->getEnclosingRadius(), nodePenetration)) { + // coarse check against bounds + const AABox& box = node->getAABox(); + if (!box.expandedIntersectsSegment(args->start, args->end, args->radius)) { return false; } if (!node->isLeaf()) { return true; // recurse on children } if (node->isColored()) { - args->penetration = addPenetrations(args->penetration, nodePenetration * (float)TREE_SCALE); - args->found = true; + glm::vec3 nodePenetration; + if (box.findCapsulePenetration(args->start, args->end, args->radius, nodePenetration)) { + args->penetration = addPenetrations(args->penetration, nodePenetration * (float)TREE_SCALE); + args->found = true; + } } return false; } From 949befee09fae741220540001d3f1080793fdec0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 27 May 2013 14:37:07 -0700 Subject: [PATCH 10/23] Fix for NaN. --- interface/src/Avatar.cpp | 7 +++++-- libraries/voxels/src/AABox.cpp | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 17958a4fa2..4713d09a21 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -626,8 +626,11 @@ void Avatar::applyCollisionWithScene(const glm::vec3& penetration) { _position -= penetration; // reflect the velocity component in the direction of penetration - glm::vec3 direction = glm::normalize(penetration); - _velocity -= 2.0f * glm::dot(_velocity, direction) * direction * BOUNCE; + float penetrationLength = glm::length(penetration); + if (penetrationLength > EPSILON) { + glm::vec3 direction = penetration / penetrationLength; + _velocity -= 2.0f * glm::dot(_velocity, direction) * direction * BOUNCE; + } } void Avatar::updateAvatarCollisions(float deltaTime) { diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index ce6d653eb0..b7580b243e 100644 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -177,7 +177,8 @@ bool AABox::findSpherePenetration(const glm::vec3& center, float radius, glm::ve float vectorLength = glm::length(vector); if (vectorLength < minPenetrationLength) { // remember the smallest penetration vector; if we're inside all faces, we'll use that - penetration = vector * ((vectorLength + radius) / -vectorLength); + penetration = (vectorLength < EPSILON) ? glm::vec3(-facePlane) * radius : + vector * ((vectorLength + radius) / -vectorLength); minPenetrationLength = vectorLength; } } @@ -204,7 +205,8 @@ bool AABox::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float vectorLength = glm::length(vector); if (vectorLength < minPenetrationLength) { // remember the smallest penetration vector; if we're inside all faces, we'll use that - penetration = vector * ((vectorLength + radius) / -vectorLength); + penetration = (vectorLength < EPSILON) ? glm::vec3(-facePlane) * radius : + vector * ((vectorLength + radius) / -vectorLength); minPenetrationLength = vectorLength; } } From 278ff009260d81cb756e2df04890725096f3e68f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 27 May 2013 14:46:16 -0700 Subject: [PATCH 11/23] Fixed Linux build error and a warning on call to Avatar.simulate, moved grid size constant to world.h and made gravity bounds match. --- interface/src/Application.cpp | 3 +-- interface/src/Environment.cpp | 4 ++-- interface/src/OculusManager.cpp | 2 ++ interface/src/world.h | 2 ++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a0979eb4b9..b94103c576 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -901,7 +901,7 @@ void Application::idle() { for(AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { if (agent->getLinkedData() != NULL) { Avatar *avatar = (Avatar *)agent->getLinkedData(); - avatar->simulate(deltaTime, false); + avatar->simulate(deltaTime, NULL); avatar->setMouseRay(mouseRayOrigin, mouseRayDirection); } } @@ -1669,7 +1669,6 @@ void Application::displaySide(Camera& whichCamera) { glPopMatrix(); //draw a grid ground plane.... - const float EDGE_SIZE_GROUND_PLANE = 20.f; drawGroundPlaneGrid(EDGE_SIZE_GROUND_PLANE); // Draw voxels diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 5063c990db..fec4ba0529 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -60,8 +60,8 @@ void Environment::renderAtmospheres(Camera& camera) { glm::vec3 Environment::getGravity (const glm::vec3& position) { // the "original gravity" glm::vec3 gravity; - if (position.x > 0.0f && position.x < 10.0f && position.y > 0.0f && - position.y < 3.0f && position.z > 0.0f && position.z < 10.0f) { + if (position.x > 0.0f && position.x < EDGE_SIZE_GROUND_PLANE && position.y > 0.0f && + position.y < 3.0f && position.z > 0.0f && position.z < EDGE_SIZE_GROUND_PLANE) { gravity = glm::vec3(0.0f, -1.0f, 0.0f); } diff --git a/interface/src/OculusManager.cpp b/interface/src/OculusManager.cpp index 168616ec83..17775b9f9c 100644 --- a/interface/src/OculusManager.cpp +++ b/interface/src/OculusManager.cpp @@ -38,9 +38,11 @@ void OculusManager::connect() { } void OculusManager::updateYawOffset() { +#ifdef __APPLE__ float yaw, pitch, roll; _sensorFusion.GetOrientation().GetEulerAngles(&yaw, &pitch, &roll); _yawOffset = yaw; +#endif } void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) { diff --git a/interface/src/world.h b/interface/src/world.h index 7d22aab6a2..c0c514c26d 100644 --- a/interface/src/world.h +++ b/interface/src/world.h @@ -17,4 +17,6 @@ const float WORLD_SIZE = 10.0; #define PIf 3.14159265f #define GRAVITY_EARTH 9.80665f; +const float EDGE_SIZE_GROUND_PLANE = 20.f; + #endif From 75b57d17a768d8963dfc11c6cf8eddd4f1516c34 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 27 May 2013 18:54:44 -0700 Subject: [PATCH 12/23] fixed some things based on recent code review --- interface/src/Audio.cpp | 2 +- interface/src/Avatar.cpp | 12 +++++++----- interface/src/Avatar.h | 36 +++--------------------------------- 3 files changed, 11 insertions(+), 39 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 596751ac27..9870f31b29 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -208,7 +208,7 @@ int audioCallback (const void* inputBuffer, // if we haven't fired off the flange effect, check if we should // TODO: lastMeasuredHeadYaw is now relative to body - check if this still works. - int lastYawMeasured = fabsf(interfaceAvatar->getLastMeasuredHeadYaw()); + int lastYawMeasured = fabsf(interfaceAvatar->getHeadYawRate()); if (!::samplesLeftForFlange && lastYawMeasured > MIN_FLANGE_EFFECT_THRESHOLD) { // we should flange for one second diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 0127ffa4c8..9976dfa951 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -60,6 +60,8 @@ const float LEAN_AVERAGING = 10.0; const float HEAD_RATE_MAX = 50.f; const float SKIN_COLOR[] = {1.0, 0.84, 0.66}; const float DARK_SKIN_COLOR[] = {0.9, 0.78, 0.63}; +const int NUM_BODY_CONE_SIDES = 9; + bool usingBigSphereCollisionTest = true; @@ -1238,9 +1240,7 @@ void Avatar::readAvatarDataFromFile() { void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2) { glBegin(GL_TRIANGLES); - - int num = 9; - + glm::vec3 axis = position2 - position1; float length = glm::length(axis); @@ -1255,10 +1255,12 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float anglea = 0.0; float angleb = 0.0; - for (int i = 0; i < num; i ++) { + for (int i = 0; i < NUM_BODY_CONE_SIDES; i ++) { + // the rectangles that comprise the sides of the cone section are + // referenced by "a" and "b" in one dimension, and "1", and "2" in the other dimension. anglea = angleb; - angleb = ((float)(i+1) / (float)num) * PI * 2.0f; + angleb = ((float)(i+1) / (float)NUM_BODY_CONE_SIDES) * PI * 2.0f; float sa = sinf(anglea); float sb = sinf(angleb); diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index abeea56277..1ef5675d9b 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -18,6 +18,7 @@ #include "SerialInterface.h" #include "Balls.h" #include "Head.h" +#include "Skeleton.h" #include "Transmitter.h" enum DriveKeys @@ -41,38 +42,6 @@ enum AvatarMode NUM_AVATAR_MODES }; -enum AvatarJointID -{ - AVATAR_JOINT_NULL = -1, - AVATAR_JOINT_PELVIS, - AVATAR_JOINT_TORSO, - AVATAR_JOINT_CHEST, - AVATAR_JOINT_NECK_BASE, - AVATAR_JOINT_HEAD_BASE, - AVATAR_JOINT_HEAD_TOP, - AVATAR_JOINT_LEFT_COLLAR, - AVATAR_JOINT_LEFT_SHOULDER, - AVATAR_JOINT_LEFT_ELBOW, - AVATAR_JOINT_LEFT_WRIST, - AVATAR_JOINT_LEFT_FINGERTIPS, - AVATAR_JOINT_RIGHT_COLLAR, - AVATAR_JOINT_RIGHT_SHOULDER, - AVATAR_JOINT_RIGHT_ELBOW, - AVATAR_JOINT_RIGHT_WRIST, - AVATAR_JOINT_RIGHT_FINGERTIPS, - AVATAR_JOINT_LEFT_HIP, - AVATAR_JOINT_LEFT_KNEE, - AVATAR_JOINT_LEFT_HEEL, - AVATAR_JOINT_LEFT_TOES, - AVATAR_JOINT_RIGHT_HIP, - AVATAR_JOINT_RIGHT_KNEE, - AVATAR_JOINT_RIGHT_HEEL, - AVATAR_JOINT_RIGHT_TOES, - - NUM_AVATAR_JOINTS -}; - - class Avatar : public AvatarData { public: Avatar(Agent* owningAgent = NULL); @@ -95,7 +64,7 @@ public: void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction); //getters - float getLastMeasuredHeadYaw () const { return _head.yawRate;} + float getHeadYawRate () const { return _head.yawRate;} float getBodyYaw () const { return _bodyYaw;} bool getIsNearInteractingOther() const { return _avatarTouch.getAbleToReachOtherAvatar();} const glm::vec3& getHeadPosition () const { return _joint[ AVATAR_JOINT_HEAD_BASE ].position;} @@ -147,6 +116,7 @@ private: }; Head _head; + Skeleton _skeleton; float _TEST_bigSphereRadius; glm::vec3 _TEST_bigSpherePosition; bool _mousePressed; From 5715860f6b580d3058200590830839f8ab9be829 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 27 May 2013 18:55:23 -0700 Subject: [PATCH 13/23] added Skeleton class (to be completed soon) --- interface/src/Skeleton.cpp | 20 ++++++++++++++ interface/src/Skeleton.h | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 interface/src/Skeleton.cpp create mode 100644 interface/src/Skeleton.h diff --git a/interface/src/Skeleton.cpp b/interface/src/Skeleton.cpp new file mode 100644 index 0000000000..49e8dea053 --- /dev/null +++ b/interface/src/Skeleton.cpp @@ -0,0 +1,20 @@ +// +// Skeleton.cpp +// interface +// +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. + +#include "Skeleton.h" + +Skeleton::Skeleton() { +} + +void Skeleton::initialize() { +} + +void Skeleton::render() { +} + +void Skeleton::simulate(float deltaTime) { +} + diff --git a/interface/src/Skeleton.h b/interface/src/Skeleton.h new file mode 100644 index 0000000000..01f0546f4a --- /dev/null +++ b/interface/src/Skeleton.h @@ -0,0 +1,54 @@ +// +// Skeleton.h +// interface +// +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef hifi_Skeleton_h +#define hifi_Skeleton_h + +enum AvatarJointID +{ + AVATAR_JOINT_NULL = -1, + AVATAR_JOINT_PELVIS, + AVATAR_JOINT_TORSO, + AVATAR_JOINT_CHEST, + AVATAR_JOINT_NECK_BASE, + AVATAR_JOINT_HEAD_BASE, + AVATAR_JOINT_HEAD_TOP, + AVATAR_JOINT_LEFT_COLLAR, + AVATAR_JOINT_LEFT_SHOULDER, + AVATAR_JOINT_LEFT_ELBOW, + AVATAR_JOINT_LEFT_WRIST, + AVATAR_JOINT_LEFT_FINGERTIPS, + AVATAR_JOINT_RIGHT_COLLAR, + AVATAR_JOINT_RIGHT_SHOULDER, + AVATAR_JOINT_RIGHT_ELBOW, + AVATAR_JOINT_RIGHT_WRIST, + AVATAR_JOINT_RIGHT_FINGERTIPS, + AVATAR_JOINT_LEFT_HIP, + AVATAR_JOINT_LEFT_KNEE, + AVATAR_JOINT_LEFT_HEEL, + AVATAR_JOINT_LEFT_TOES, + AVATAR_JOINT_RIGHT_HIP, + AVATAR_JOINT_RIGHT_KNEE, + AVATAR_JOINT_RIGHT_HEEL, + AVATAR_JOINT_RIGHT_TOES, + + NUM_AVATAR_JOINTS +}; + + +class Skeleton { +public: + Skeleton(); + + void initialize(); + void simulate(float deltaTime); + void render(); + +private: +}; + +#endif From 9f2c0adec74fee4052e749707ca955c8e72e5e3f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 May 2013 12:22:51 -0700 Subject: [PATCH 14/23] move audioLoudness to HeadData --- interface/src/Application.cpp | 2 +- interface/src/Avatar.cpp | 3 +-- interface/src/Head.cpp | 1 - interface/src/Head.h | 2 -- libraries/avatars/src/AvatarData.cpp | 6 +++--- libraries/avatars/src/AvatarData.h | 9 +-------- libraries/avatars/src/HeadData.cpp | 1 + libraries/avatars/src/HeadData.h | 3 +++ 8 files changed, 10 insertions(+), 17 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b94103c576..da06341f15 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1336,7 +1336,7 @@ void Application::updateAvatar(float deltaTime) { // Get audio loudness data from audio input device #ifndef _WIN32 - _myAvatar.setLoudness(_audio.getLastInputLoudness()); + _myAvatar.getHead().setAudioLoudness(_audio.getLastInputLoudness()); #endif // Update Avatar with latest camera and view frustum data... diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 23221b1c70..15d2bd2774 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -80,8 +80,8 @@ Avatar::Avatar(Agent* owningAgent) : _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), + _cameraPosition(0.0f, 0.0f, 0.0f), _handHoldingPosition(0.0f, 0.0f, 0.0f), _velocity(0.0f, 0.0f, 0.0f), _thrust(0.0f, 0.0f, 0.0f), @@ -443,7 +443,6 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); _head.setPosition(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition); _head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius); - _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); _head.simulate(deltaTime, !_owningAgent); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 1486013c9c..ede5e73b20 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -42,7 +42,6 @@ Head::Head(Avatar* owningAvatar) : HeadData((AvatarData*)owningAvatar), yawRate(0.0f), _returnHeadToCenter(false), - _audioLoudness(0.0f), _skinColor(0.0f, 0.0f, 0.0f), _position(0.0f, 0.0f, 0.0f), _rotation(0.0f, 0.0f, 0.0f), diff --git a/interface/src/Head.h b/interface/src/Head.h index bdf519fcfe..a116a45fa3 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -45,7 +45,6 @@ public: void setSkinColor (glm::vec3 skinColor ) { _skinColor = skinColor; } void setSpringScale (float returnSpringScale ) { _returnSpringScale = returnSpringScale; } void setAverageLoudness(float averageLoudness ) { _averageLoudness = averageLoudness; } - void setAudioLoudness (float audioLoudness ) { _audioLoudness = audioLoudness; } void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } void setRenderLookatVectors(bool onOff ) { _renderLookatVectors = onOff; } @@ -74,7 +73,6 @@ private: }; bool _returnHeadToCenter; - float _audioLoudness; glm::vec3 _skinColor; glm::vec3 _position; glm::vec3 _rotation; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 4b97a2a047..99e3b61656 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -37,7 +37,6 @@ AvatarData::AvatarData(Agent* owningAgent) : _bodyYaw(-90.0), _bodyPitch(0.0), _bodyRoll(0.0), - _audioLoudness(0), _handState(0), _cameraPosition(0,0,0), _cameraDirection(0,0,0), @@ -53,6 +52,7 @@ AvatarData::AvatarData(Agent* owningAgent) : _wantDelta(false), _headData(NULL) { + } AvatarData::~AvatarData() { @@ -104,7 +104,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += sizeof(char); // Instantaneous audio loudness (used to drive facial animation) - memcpy(destinationBuffer, &_audioLoudness, sizeof(float)); + memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float)); destinationBuffer += sizeof(float); // camera details @@ -198,7 +198,7 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(char); // Instantaneous audio loudness (used to drive facial animation) - memcpy(&_audioLoudness, sourceBuffer, sizeof(float)); + memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float)); sourceBuffer += sizeof(float); // camera details diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 5773dedffd..18bbacf810 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -51,11 +51,7 @@ public: // Hand State void setHandState(char s) { _handState = s; }; char getHandState() const {return _handState; }; - - // Instantaneous audio loudness to drive mouth/facial animation - void setLoudness(float l) { _audioLoudness = l; }; - float getLoudness() const {return _audioLoudness; }; - + // getters for camera details const glm::vec3& getCameraPosition() const { return _cameraPosition; }; const glm::vec3& getCameraDirection() const { return _cameraDirection; } @@ -103,9 +99,6 @@ protected: float _bodyPitch; float _bodyRoll; - // Audio loudness (used to drive facial animation) - float _audioLoudness; - // Hand state (are we grabbing something or not) char _handState; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index 906e10e48f..89a431908f 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -15,6 +15,7 @@ HeadData::HeadData(AvatarData* owningAvatar) : _lookAtPosition(0.0f, 0.0f, 0.0f), _leanSideways(0.0f), _leanForward(0.0f), + _audioLoudness(0.0f), _owningAvatar(owningAvatar) { diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index 0eb135b899..d2ec5b1cb6 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -41,6 +41,8 @@ public: float getRoll() const { return _roll; } void setRoll(float roll) { _roll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } + void setAudioLoudness(float audioLoudness) { _audioLoudness = audioLoudness; } + void addYaw(float yaw); void addPitch(float pitch); void addRoll(float roll); @@ -57,6 +59,7 @@ protected: glm::vec3 _lookAtPosition; float _leanSideways; float _leanForward; + float _audioLoudness; AvatarData* _owningAvatar; private: // privatize copy ctor and assignment operator so copies of this object cannot be made From badab39ef1739ae5de05b8da1b1607df60f83798 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 May 2013 15:58:57 -0700 Subject: [PATCH 15/23] resolve conflict on merge with upstream master --- 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 621203d7b2..3981d4f76d 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -434,7 +434,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); _head.setPosition(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition); _head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius); - _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); + _head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2])); _head.simulate(deltaTime, !_owningAgent); // use speed and angular velocity to determine walking vs. standing From 55954899e61e8114b630d4aef8b8c698c4cd0c28 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 May 2013 16:20:23 -0700 Subject: [PATCH 16/23] fix silent audio on client --- interface/src/Audio.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 9870f31b29..2926aa9a73 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -116,7 +116,7 @@ int audioCallback (const void* inputBuffer, printLog("got output\n"); } - if (inputLeft != NULL) { + if (inputLeft) { // Measure the loudness of the signal from the microphone and store in audio object float loudness = 0; @@ -457,7 +457,7 @@ void Audio::addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBy gettimeofday(&_firstPlaybackTime, NULL); } - _ringBuffer.parseData((unsigned char *)receivedData, PACKET_LENGTH_BYTES); + _ringBuffer.parseData((unsigned char *)receivedData, PACKET_LENGTH_BYTES + sizeof(PACKET_HEADER)); _lastReceiveTime = currentReceiveTime; } From 8118e3bf69bc4eb8fced11496dbbe21fd226e899 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 May 2013 16:23:54 -0700 Subject: [PATCH 17/23] type squish in Audio.cpp --- interface/src/Audio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 2926aa9a73..8acb70ebcc 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -457,7 +457,7 @@ void Audio::addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBy gettimeofday(&_firstPlaybackTime, NULL); } - _ringBuffer.parseData((unsigned char *)receivedData, PACKET_LENGTH_BYTES + sizeof(PACKET_HEADER)); + _ringBuffer.parseData((unsigned char*) receivedData, PACKET_LENGTH_BYTES + sizeof(PACKET_HEADER)); _lastReceiveTime = currentReceiveTime; } From 65f10cb99a7ccf077093b07a2da3f6c19ab32aba Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 May 2013 16:26:18 -0700 Subject: [PATCH 18/23] fix the enum in AABox, fix a warning in Head --- interface/src/Head.cpp | 6 +++--- libraries/voxels/src/AABox.h | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index e0a97db7e1..51d85db5ab 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -61,10 +61,10 @@ Head::Head(Avatar* owningAvatar) : _audioAttack(0.0f), _returnSpringScale(1.0f), _bodyRotation(0.0f, 0.0f, 0.0f), + _renderLookatVectors(false), _mohawkTriangleFan(NULL), - _mohawkColors(NULL), - _renderLookatVectors(false) { - + _mohawkColors(NULL) +{ if (USING_PHYSICAL_MOHAWK) { resetHairPhysics(); } diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h index 591704d4a3..f0d8e005aa 100755 --- a/libraries/voxels/src/AABox.h +++ b/libraries/voxels/src/AABox.h @@ -19,10 +19,11 @@ enum BoxFace { MIN_Y_FACE, MAX_Y_FACE, MIN_Z_FACE, - MAX_Z_FACE, - FACE_COUNT + MAX_Z_FACE }; +const int FACE_COUNT = 6; + class AABox { From 923c39cdc018d7de981fcb162e6d886f22a7ec5c Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 28 May 2013 17:57:11 -0700 Subject: [PATCH 19/23] fixed third person shift bug --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9671e66f54..8a0ccdc8c3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -915,7 +915,7 @@ void Application::idle() { _myAvatar.simulate(deltaTime, NULL); } - if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { + if (_myCamera.getMode() != CAMERA_MODE_MIRROR && !OculusManager::isConnected()) { if (_manualFirstPerson) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); From 82683dbabcc2f317a1ebfc23989eae2f78ff7a20 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 28 May 2013 17:58:02 -0700 Subject: [PATCH 20/23] merge --- libraries/voxels/src/AABox.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 libraries/voxels/src/AABox.h diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h old mode 100755 new mode 100644 From e4c0aeb9a0018159bc9b2ff30a6e7e2d78db4af6 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 28 May 2013 18:15:29 -0700 Subject: [PATCH 21/23] added AVATAR_FACING_THRESHOLD to avatarTouch --- interface/src/Application.cpp | 2 +- interface/src/AvatarTouch.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 17a533c102..a8e62a68e7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -937,7 +937,7 @@ void Application::idle() { } } } - + // Update audio stats for procedural sounds #ifndef _WIN32 _audio.setLastAcceleration(_myAvatar.getThrust()); diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index c598cc9a03..16c8cc64c7 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -13,6 +13,7 @@ const float THREAD_RADIUS = 0.007; const float HANDS_CLOSE_ENOUGH_TO_GRASP = 0.2; +const float AVATAR_FACING_THRESHOLD = 0.1f; // (-1 to 1) (larger value indicates narrower angle of influence AvatarTouch::AvatarTouch() { @@ -43,8 +44,8 @@ void AvatarTouch::simulate (float deltaTime) { bool facingEachOther = false; - if (( glm::dot(_myOrientation.getFront(), _yourOrientation.getFront()) < -0.1f) - && ( glm::dot(_myOrientation.getFront(), directionBetweenBodies ) > 0.1f)) { + if (( glm::dot(_myOrientation.getFront(), _yourOrientation.getFront()) < -AVATAR_FACING_THRESHOLD) + && ( glm::dot(_myOrientation.getFront(), directionBetweenBodies ) > AVATAR_FACING_THRESHOLD)) { facingEachOther = true; } From b98d03337d911293649132995cc7c05d3c7f74a0 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 28 May 2013 18:49:16 -0700 Subject: [PATCH 22/23] fixed bug causing camera to not get updated position of other av --- interface/src/Avatar.cpp | 3 ++ interface/src/AvatarTouch.cpp | 55 +++++++++++++++++++++-------------- interface/src/AvatarTouch.h | 2 ++ 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 3981d4f76d..25e1764025 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -509,6 +509,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { if (_interactingOther) { + _avatarTouch.setHasInteractingOther(true); _avatarTouch.setYourBodyPosition(_interactingOther->_position); _avatarTouch.setYourOrientation (_interactingOther->_orientation); _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); @@ -561,6 +562,8 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { _velocity += vectorFromMyHandToYourHand * force; } } + } else { + _avatarTouch.setHasInteractingOther(false); } }//if (_isMine) diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 16c8cc64c7..0d2157cbad 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -28,6 +28,7 @@ AvatarTouch::AvatarTouch() { _weAreHoldingHands = false; _canReachToOtherAvatar = false; _handsCloseEnoughToGrasp = false; + _hasInteractingOther = false; _myOrientation.setToIdentity(); _yourOrientation.setToIdentity(); @@ -36,36 +37,46 @@ AvatarTouch::AvatarTouch() { } } + +void AvatarTouch::setHasInteractingOther(bool hasInteractingOther) { + _hasInteractingOther = hasInteractingOther; +} + + void AvatarTouch::simulate (float deltaTime) { - glm::vec3 vectorBetweenBodies = _yourBodyPosition - _myBodyPosition; - float distanceBetweenBodies = glm::length(vectorBetweenBodies); - glm::vec3 directionBetweenBodies = vectorBetweenBodies / distanceBetweenBodies; - - bool facingEachOther = false; - - if (( glm::dot(_myOrientation.getFront(), _yourOrientation.getFront()) < -AVATAR_FACING_THRESHOLD) - && ( glm::dot(_myOrientation.getFront(), directionBetweenBodies ) > AVATAR_FACING_THRESHOLD)) { - facingEachOther = true; - } + _canReachToOtherAvatar = false; // default - if ((distanceBetweenBodies < _reachableRadius) - && (facingEachOther)) { - _vectorBetweenHands = _yourHandPosition - _myHandPosition; + if (_hasInteractingOther) { + + glm::vec3 vectorBetweenBodies = _yourBodyPosition - _myBodyPosition; + float distanceBetweenBodies = glm::length(vectorBetweenBodies); + glm::vec3 directionBetweenBodies = vectorBetweenBodies / distanceBetweenBodies; - float distanceBetweenHands = glm::length(_vectorBetweenHands); - if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP) { - _handsCloseEnoughToGrasp = true; - } else { - _handsCloseEnoughToGrasp = false; + bool facingEachOther = false; + + if (( glm::dot(_myOrientation.getFront(), _yourOrientation.getFront()) < -AVATAR_FACING_THRESHOLD) // we're facing each other + && ( glm::dot(_myOrientation.getFront(), directionBetweenBodies ) > AVATAR_FACING_THRESHOLD)) { // I'm facing you + facingEachOther = true; } - _canReachToOtherAvatar = true; - } else { - _canReachToOtherAvatar = false; - } + if ((distanceBetweenBodies < _reachableRadius) + && (facingEachOther)) { + _canReachToOtherAvatar = true; + + _vectorBetweenHands = _yourHandPosition - _myHandPosition; + + float distanceBetweenHands = glm::length(_vectorBetweenHands); + if (distanceBetweenHands < HANDS_CLOSE_ENOUGH_TO_GRASP) { + _handsCloseEnoughToGrasp = true; + } else { + _handsCloseEnoughToGrasp = false; + } + } + } } + void AvatarTouch::render(glm::vec3 cameraPosition) { if (_canReachToOtherAvatar) { diff --git a/interface/src/AvatarTouch.h b/interface/src/AvatarTouch.h index fb90efa5fd..dd45d3bd44 100644 --- a/interface/src/AvatarTouch.h +++ b/interface/src/AvatarTouch.h @@ -28,6 +28,7 @@ public: void simulate(float deltaTime); void render(glm::vec3 cameraPosition); + void setHasInteractingOther(bool hasInteractingOther); void setMyHandPosition (glm::vec3 position ) { _myHandPosition = position; } void setYourHandPosition(glm::vec3 position ) { _yourHandPosition = position; } void setMyOrientation (Orientation orientation) { _myOrientation = orientation; } @@ -47,6 +48,7 @@ private: static const int NUM_POINTS = 100; + bool _hasInteractingOther; bool _weAreHoldingHands; glm::vec3 _point [NUM_POINTS]; glm::vec3 _myBodyPosition; From 0e329af03eafce530b6e9ae2decf807a838577a2 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 28 May 2013 18:55:21 -0700 Subject: [PATCH 23/23] made inline --- interface/src/AvatarTouch.cpp | 6 ------ interface/src/AvatarTouch.h | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 0d2157cbad..499e132922 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -37,12 +37,6 @@ AvatarTouch::AvatarTouch() { } } - -void AvatarTouch::setHasInteractingOther(bool hasInteractingOther) { - _hasInteractingOther = hasInteractingOther; -} - - void AvatarTouch::simulate (float deltaTime) { _canReachToOtherAvatar = false; // default diff --git a/interface/src/AvatarTouch.h b/interface/src/AvatarTouch.h index dd45d3bd44..6b6b75d956 100644 --- a/interface/src/AvatarTouch.h +++ b/interface/src/AvatarTouch.h @@ -28,17 +28,17 @@ public: void simulate(float deltaTime); void render(glm::vec3 cameraPosition); - void setHasInteractingOther(bool hasInteractingOther); - void setMyHandPosition (glm::vec3 position ) { _myHandPosition = position; } - void setYourHandPosition(glm::vec3 position ) { _yourHandPosition = position; } - void setMyOrientation (Orientation orientation) { _myOrientation = orientation; } - void setYourOrientation (Orientation orientation) { _yourOrientation = orientation; } - void setMyBodyPosition (glm::vec3 position ) { _myBodyPosition = position; } - void setYourBodyPosition(glm::vec3 position ) { _yourBodyPosition = position; } - void setMyHandState (int state ) { _myHandState = state; } - void setYourHandState (int state ) { _yourHandState = state; } - void setReachableRadius (float radius ) { _reachableRadius = radius; } - void setHoldingHands (bool holding ) { _weAreHoldingHands = holding; } + void setHasInteractingOther(bool hasInteractingOther) { _hasInteractingOther = hasInteractingOther;} + void setMyHandPosition (glm::vec3 position ) { _myHandPosition = position;} + void setYourHandPosition (glm::vec3 position ) { _yourHandPosition = position;} + void setMyOrientation (Orientation orientation ) { _myOrientation = orientation;} + void setYourOrientation (Orientation orientation ) { _yourOrientation = orientation;} + void setMyBodyPosition (glm::vec3 position ) { _myBodyPosition = position;} + void setYourBodyPosition (glm::vec3 position ) { _yourBodyPosition = position;} + void setMyHandState (int state ) { _myHandState = state;} + void setYourHandState (int state ) { _yourHandState = state;} + void setReachableRadius (float radius ) { _reachableRadius = radius;} + void setHoldingHands (bool holding ) { _weAreHoldingHands = holding;} bool getAbleToReachOtherAvatar () const {return _canReachToOtherAvatar; } bool getHandsCloseEnoughToGrasp() const {return _handsCloseEnoughToGrasp;}