From 70b25fd6c4192b0de102f9c813019b7053e19505 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Sat, 25 May 2013 19:59:07 -0700 Subject: [PATCH 01/19] 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 d43c5ca52c837c9b1d4f2b19e34f970e51cc9733 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Sun, 26 May 2013 21:56:21 -0700 Subject: [PATCH 02/19] 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 03/19] 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 04/19] 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 05/19] 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 06/19] 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 07/19] 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 08/19] 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 09/19] 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 10/19] 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 11/19] 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 12/19] 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 13/19] 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 14/19] 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 15/19] 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 16/19] 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 17/19] 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 18/19] 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;} From 31ff76836344f2b664ce07c90ed6e334cf495d91 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 29 May 2013 08:30:14 -0700 Subject: [PATCH 19/19] fixed some glitches in avatar render alpha transition between 3p and 1p --- interface/src/Avatar.cpp | 23 ++++++++++++++--------- interface/src/AvatarTouch.cpp | 7 +++---- interface/src/AvatarTouch.h | 4 ++-- interface/src/Head.cpp | 11 +++++++---- interface/src/Head.h | 3 ++- 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 25e1764025..403918c830 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -1114,16 +1114,19 @@ void Avatar::updateArmIKAndConstraints(float deltaTime) { void Avatar::renderBody(bool lookingInMirror) { - const float RENDER_OPAQUE_BEYOND = 1.2f; // Meters beyond which body is shown opaque + const float RENDER_OPAQUE_BEYOND = 1.0f; // Meters beyond which body is shown opaque const float RENDER_TRANSLUCENT_BEYOND = 0.5f; // Render the body as balls and cones for (int b = 0; b < NUM_AVATAR_JOINTS; b++) { float distanceToCamera = glm::length(_cameraPosition - _joint[b].position); + + float alpha = glm::clamp((distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f); + // Always render other people, and render myself when beyond threshold distance if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case - if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND) { - _head.render(lookingInMirror, _cameraPosition); + if (lookingInMirror || _owningAgent || distanceToCamera > RENDER_OPAQUE_BEYOND * 0.5) { + _head.render(lookingInMirror, _cameraPosition, alpha); } } else if (_owningAgent || distanceToCamera > RENDER_TRANSLUCENT_BEYOND || b == AVATAR_JOINT_RIGHT_ELBOW @@ -1140,14 +1143,16 @@ void Avatar::renderBody(bool lookingInMirror) { 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)); + alpha); } - glPushMatrix(); - glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z); - glutSolidSphere(_joint[b].radius, 20.0f, 20.0f); - glPopMatrix(); + if ((b != AVATAR_JOINT_HEAD_TOP ) + && (b != AVATAR_JOINT_HEAD_BASE )) { + 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 its parent if (_joint[b].parent != AVATAR_JOINT_NULL) { diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 499e132922..18f4847d33 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -32,7 +32,7 @@ AvatarTouch::AvatarTouch() { _myOrientation.setToIdentity(); _yourOrientation.setToIdentity(); - for (int p=0; p irisTexture; Head::Head(Avatar* owningAvatar) : HeadData((AvatarData*)owningAvatar), + _renderAlpha(0.0), yawRate(0.0f), _returnHeadToCenter(false), _skinColor(0.0f, 0.0f, 0.0f), @@ -205,8 +206,10 @@ void Head::calculateGeometry(bool lookingInMirror) { } -void Head::render(bool lookingInMirror, glm::vec3 cameraPosition) { +void Head::render(bool lookingInMirror, glm::vec3 cameraPosition, float alpha) { + _renderAlpha = alpha; + calculateGeometry(lookingInMirror); glEnable(GL_DEPTH_TEST); @@ -314,7 +317,7 @@ void Head::renderHeadSphere() { glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); //translate to head position glScalef(_scale, _scale, _scale); //scale to head size - glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); + glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha); glutSolidSphere(1, 30, 30); glPopMatrix(); } @@ -322,13 +325,13 @@ void Head::renderHeadSphere() { void Head::renderEars() { glPushMatrix(); - glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); + glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha); glTranslatef(_leftEarPosition.x, _leftEarPosition.y, _leftEarPosition.z); glutSolidSphere(0.02, 30, 30); glPopMatrix(); glPushMatrix(); - glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); + glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha); glTranslatef(_rightEarPosition.x, _rightEarPosition.y, _rightEarPosition.z); glutSolidSphere(0.02, 30, 30); glPopMatrix(); diff --git a/interface/src/Head.h b/interface/src/Head.h index 07d7351cb3..b98fa8c6b6 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -34,7 +34,7 @@ public: void reset(); void simulate(float deltaTime, bool isMine); - void render(bool lookingInMirror, glm::vec3 cameraPosition); + void render(bool lookingInMirror, glm::vec3 cameraPosition, float alpha); void renderMohawk(bool lookingInMirror, glm::vec3 cameraPosition); void setScale (float scale ) { _scale = scale; } @@ -71,6 +71,7 @@ private: glm::vec3 endVelocity; }; + float _renderAlpha; bool _returnHeadToCenter; glm::vec3 _skinColor; glm::vec3 _position;