From 930d9957f3289f0cb7c13aa1213a88d5be8b88e1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 2 Jan 2014 16:09:41 -0800 Subject: [PATCH 01/13] Changed argument names in collision methods for improved readability. --- libraries/shared/src/GeometryUtil.cpp | 100 +++++++++++++------------- libraries/shared/src/GeometryUtil.h | 38 +++++----- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 1da05f9fae..6f48401ce7 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -31,105 +31,105 @@ glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec } } -bool findSpherePenetration(const glm::vec3& penetratorToPenetratee, const glm::vec3& direction, +bool findSpherePenetration(const glm::vec3& localPoint, const glm::vec3& direction, float combinedRadius, glm::vec3& penetration) { - float vectorLength = glm::length(penetratorToPenetratee); + float vectorLength = glm::length(localPoint); if (vectorLength < EPSILON) { penetration = direction * combinedRadius; return true; } float distance = vectorLength - combinedRadius; if (distance < 0.0f) { - penetration = penetratorToPenetratee * (-distance / vectorLength); + penetration = localPoint * (-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 findSpherePointPenetration(const glm::vec3& sphereCenter, float sphereRadius, + const glm::vec3& point, glm::vec3& penetration) { + return findSpherePenetration(point - sphereCenter, glm::vec3(0.0f, -1.0f, 0.0f), + sphereRadius, penetration); } -bool findPointSpherePenetration(const glm::vec3& penetratorLocation, const glm::vec3& penetrateeCenter, - float penetrateeRadius, glm::vec3& penetration) { - return findSpherePenetration(penetrateeCenter - penetratorLocation, glm::vec3(0.0f, -1.0f, 0.0f), - penetrateeRadius, penetration); +bool findPointSpherePenetration(const glm::vec3& point, const glm::vec3& sphereCenter, + float sphereRadius, glm::vec3& penetration) { + return findSpherePenetration(sphereCenter - point, glm::vec3(0.0f, -1.0f, 0.0f), + sphereRadius, 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 findSphereSpherePenetration(const glm::vec3& firstCenter, float firstRadius, + const glm::vec3& secondCenter, float secondRadius, glm::vec3& penetration) { + return findSpherePointPenetration(firstCenter, firstRadius + secondRadius, secondCenter, 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), - glm::vec3(0.0f, -1.0f, 0.0f), penetratorRadius, penetration); +bool findSphereSegmentPenetration(const glm::vec3& sphereCenter, float sphereRadius, + const glm::vec3& segmentStart, const glm::vec3& segmentEnd, glm::vec3& penetration) { + return findSpherePenetration(computeVectorFromPointToSegment(sphereCenter, segmentStart, segmentEnd), + glm::vec3(0.0f, -1.0f, 0.0f), sphereRadius, 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 findSphereCapsulePenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec3& capsuleStart, + const glm::vec3& capsuleEnd, float capsuleRadius, glm::vec3& penetration) { + return findSphereSegmentPenetration(sphereCenter, sphereRadius + capsuleRadius, + capsuleStart, capsuleEnd, penetration); } -bool findPointCapsuleConePenetration(const glm::vec3& penetratorLocation, const glm::vec3& penetrateeStart, - const glm::vec3& penetrateeEnd, float penetrateeStartRadius, float penetrateeEndRadius, glm::vec3& penetration) { +bool findPointCapsuleConePenetration(const glm::vec3& point, const glm::vec3& segmentStart, + const glm::vec3& segmentEnd, float startRadius, float endRadius, glm::vec3& penetration) { // compute the projection of the point vector onto the segment vector - glm::vec3 segmentVector = penetrateeEnd - penetrateeStart; + glm::vec3 segmentVector = segmentEnd - segmentStart; float lengthSquared = glm::dot(segmentVector, segmentVector); if (lengthSquared < EPSILON) { // start and end the same - return findPointSpherePenetration(penetratorLocation, penetrateeStart, - glm::max(penetrateeStartRadius, penetrateeEndRadius), penetration); + return findPointSpherePenetration(point, segmentStart, + glm::max(startRadius, endRadius), penetration); } - float proj = glm::dot(penetratorLocation - penetrateeStart, segmentVector) / lengthSquared; + float proj = glm::dot(point - segmentStart, segmentVector) / lengthSquared; if (proj <= 0.0f) { // closest to the start - return findPointSpherePenetration(penetratorLocation, penetrateeStart, penetrateeStartRadius, penetration); + return findPointSpherePenetration(point, segmentStart, startRadius, penetration); } else if (proj >= 1.0f) { // closest to the end - return findPointSpherePenetration(penetratorLocation, penetrateeEnd, penetrateeEndRadius, penetration); + return findPointSpherePenetration(point, segmentEnd, endRadius, penetration); } else { // closest to the middle - return findPointSpherePenetration(penetratorLocation, penetrateeStart + segmentVector * proj, - glm::mix(penetrateeStartRadius, penetrateeEndRadius, proj), penetration); + return findPointSpherePenetration(point, segmentStart + segmentVector * proj, + glm::mix(startRadius, endRadius, proj), penetration); } } -bool findSphereCapsuleConePenetration(const glm::vec3& penetratorCenter, - float penetratorRadius, const glm::vec3& penetrateeStart, const glm::vec3& penetrateeEnd, - float penetrateeStartRadius, float penetrateeEndRadius, glm::vec3& penetration) { - return findPointCapsuleConePenetration(penetratorCenter, penetrateeStart, penetrateeEnd, - penetrateeStartRadius + penetratorRadius, penetrateeEndRadius + penetratorRadius, penetration); +bool findSphereCapsuleConePenetration(const glm::vec3& sphereCenter, + float sphereRadius, const glm::vec3& segmentStart, const glm::vec3& segmentEnd, + float startRadius, float endRadius, glm::vec3& penetration) { + return findPointCapsuleConePenetration(sphereCenter, segmentStart, segmentEnd, + startRadius + sphereRadius, endRadius + sphereRadius, 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; +bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadius, + const glm::vec4& plane, glm::vec3& penetration) { + float distance = glm::dot(plane, glm::vec4(sphereCenter, 1.0f)) - sphereRadius; if (distance < 0.0f) { - penetration = glm::vec3(penetrateePlane) * distance; + penetration = glm::vec3(plane) * distance; 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)) { +bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius, + const glm::vec3& sphereCenter, float sphereRadius, glm::vec3& penetration) { + if (findSphereCapsulePenetration(sphereCenter, sphereRadius, + capsuleStart, capsuleEnd, capsuleRadius, 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; +bool findCapsulePlanePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius, + const glm::vec4& plane, glm::vec3& penetration) { + float distance = glm::min(glm::dot(plane, glm::vec4(capsuleStart, 1.0f)), + glm::dot(plane, glm::vec4(capsuleEnd, 1.0f))) - capsuleRadius; if (distance < 0.0f) { - penetration = glm::vec3(penetrateePlane) * distance; + penetration = glm::vec3(plane) * distance; return true; } return false; diff --git a/libraries/shared/src/GeometryUtil.h b/libraries/shared/src/GeometryUtil.h index 8cbb29580a..4bba48fe08 100644 --- a/libraries/shared/src/GeometryUtil.h +++ b/libraries/shared/src/GeometryUtil.h @@ -13,39 +13,39 @@ 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, +bool findSpherePenetration(const glm::vec3& localPoint, const glm::vec3& direction, float combinedRadius, glm::vec3& penetration); -bool findSpherePointPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, +bool findSpherePointPenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec3& penetrateeLocation, glm::vec3& penetration); -bool findPointSpherePenetration(const glm::vec3& penetratorLocation, const glm::vec3& penetrateeCenter, - float penetrateeRadius, glm::vec3& penetration); +bool findPointSpherePenetration(const glm::vec3& point, const glm::vec3& sphereCenter, + float sphereRadius, glm::vec3& penetration); -bool findSphereSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, - const glm::vec3& penetrateeCenter, float penetrateeRadius, glm::vec3& penetration); +bool findSphereSpherePenetration(const glm::vec3& firstCenter, float firstRadius, + const glm::vec3& secondCenter, float secondRadius, glm::vec3& penetration); -bool findSphereSegmentPenetration(const glm::vec3& penetratorCenter, float penetratorRadius, +bool findSphereSegmentPenetration(const glm::vec3& sphereCenter, float sphereRadius, 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 findSphereCapsulePenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec3& penetrateeStart, + const glm::vec3& penetrateeEnd, float capsuleRadius, glm::vec3& penetration); -bool findPointCapsuleConePenetration(const glm::vec3& penetratorLocation, const glm::vec3& penetrateeStart, - const glm::vec3& penetrateeEnd, float penetrateeStartRadius, float penetrateeEndRadius, glm::vec3& penetration); +bool findPointCapsuleConePenetration(const glm::vec3& point, const glm::vec3& segmentStart, + const glm::vec3& segmentEnd, float startRadius, float endRadius, glm::vec3& penetration); -bool findSphereCapsuleConePenetration(const glm::vec3& penetratorCenter, - float penetratorRadius, const glm::vec3& penetrateeStart, const glm::vec3& penetrateeEnd, +bool findSphereCapsuleConePenetration(const glm::vec3& sphereCenter, float sphereRadius, + const glm::vec3& penetrateeStart, const glm::vec3& penetrateeEnd, float penetrateeStartRadius, float penetrateeEndRadius, glm::vec3& penetration); -bool findSpherePlanePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, - const glm::vec4& penetrateePlane, glm::vec3& penetration); +bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadius, + const glm::vec4& plane, 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 findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius, + const glm::vec3& sphereCenter, float sphereRadius, glm::vec3& penetration); -bool findCapsulePlanePenetration(const glm::vec3& penetratorStart, const glm::vec3& penetratorEnd, float penetratorRadius, - const glm::vec4& penetrateePlane, glm::vec3& penetration); +bool findCapsulePlanePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius, + const glm::vec4& plane, glm::vec3& penetration); glm::vec3 addPenetrations(const glm::vec3& currentPenetration, const glm::vec3& newPenetration); From ea88f00ce527a40b25bdee0326516990e1af7d71 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 3 Jan 2014 16:01:31 -0800 Subject: [PATCH 02/13] Name changes, formatting, and comments for readability. --- libraries/shared/src/GeometryUtil.cpp | 46 ++++++++++++++------------- libraries/shared/src/GeometryUtil.h | 26 +++++++++------ 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 6f48401ce7..4536c962e5 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -31,16 +31,20 @@ glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec } } -bool findSpherePenetration(const glm::vec3& localPoint, const glm::vec3& direction, - float combinedRadius, glm::vec3& penetration) { - float vectorLength = glm::length(localPoint); +// Computes the penetration between a point and a sphere (centered at the origin) +// if point is inside sphere: returns true and stores the result in 'penetration' +// (the vector that would move the point outside the sphere) +// otherwise returns false +bool findSpherePenetration(const glm::vec3& point, const glm::vec3& defaultDirection, float sphereRadius, + glm::vec3& penetration) { + float vectorLength = glm::length(point); if (vectorLength < EPSILON) { - penetration = direction * combinedRadius; + penetration = defaultDirection * sphereRadius; return true; } - float distance = vectorLength - combinedRadius; + float distance = vectorLength - sphereRadius; if (distance < 0.0f) { - penetration = localPoint * (-distance / vectorLength); + penetration = point * (-distance / vectorLength); return true; } return false; @@ -48,14 +52,12 @@ bool findSpherePenetration(const glm::vec3& localPoint, const glm::vec3& directi bool findSpherePointPenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec3& point, glm::vec3& penetration) { - return findSpherePenetration(point - sphereCenter, glm::vec3(0.0f, -1.0f, 0.0f), - sphereRadius, penetration); + return findSpherePenetration(point - sphereCenter, glm::vec3(0.0f, -1.0f, 0.0f), sphereRadius, penetration); } bool findPointSpherePenetration(const glm::vec3& point, const glm::vec3& sphereCenter, float sphereRadius, glm::vec3& penetration) { - return findSpherePenetration(sphereCenter - point, glm::vec3(0.0f, -1.0f, 0.0f), - sphereRadius, penetration); + return findSpherePenetration(sphereCenter - point, glm::vec3(0.0f, -1.0f, 0.0f), sphereRadius, penetration); } bool findSphereSpherePenetration(const glm::vec3& firstCenter, float firstRadius, @@ -65,8 +67,8 @@ bool findSphereSpherePenetration(const glm::vec3& firstCenter, float firstRadius bool findSphereSegmentPenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec3& segmentStart, const glm::vec3& segmentEnd, glm::vec3& penetration) { - return findSpherePenetration(computeVectorFromPointToSegment(sphereCenter, segmentStart, segmentEnd), - glm::vec3(0.0f, -1.0f, 0.0f), sphereRadius, penetration); + return findSpherePenetration(computeVectorFromPointToSegment(sphereCenter, segmentStart, segmentEnd), + glm::vec3(0.0f, -1.0f, 0.0f), sphereRadius, penetration); } bool findSphereCapsulePenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec3& capsuleStart, @@ -75,32 +77,32 @@ bool findSphereCapsulePenetration(const glm::vec3& sphereCenter, float sphereRad capsuleStart, capsuleEnd, penetration); } -bool findPointCapsuleConePenetration(const glm::vec3& point, const glm::vec3& segmentStart, - const glm::vec3& segmentEnd, float startRadius, float endRadius, glm::vec3& penetration) { +bool findPointCapsuleConePenetration(const glm::vec3& point, const glm::vec3& capsuleStart, + const glm::vec3& capsuleEnd, float startRadius, float endRadius, glm::vec3& penetration) { // compute the projection of the point vector onto the segment vector - glm::vec3 segmentVector = segmentEnd - segmentStart; + glm::vec3 segmentVector = capsuleEnd - capsuleStart; float lengthSquared = glm::dot(segmentVector, segmentVector); if (lengthSquared < EPSILON) { // start and end the same - return findPointSpherePenetration(point, segmentStart, + return findPointSpherePenetration(point, capsuleStart, glm::max(startRadius, endRadius), penetration); } - float proj = glm::dot(point - segmentStart, segmentVector) / lengthSquared; + float proj = glm::dot(point - capsuleStart, segmentVector) / lengthSquared; if (proj <= 0.0f) { // closest to the start - return findPointSpherePenetration(point, segmentStart, startRadius, penetration); + return findPointSpherePenetration(point, capsuleStart, startRadius, penetration); } else if (proj >= 1.0f) { // closest to the end - return findPointSpherePenetration(point, segmentEnd, endRadius, penetration); + return findPointSpherePenetration(point, capsuleEnd, endRadius, penetration); } else { // closest to the middle - return findPointSpherePenetration(point, segmentStart + segmentVector * proj, + return findPointSpherePenetration(point, capsuleStart + segmentVector * proj, glm::mix(startRadius, endRadius, proj), penetration); } } bool findSphereCapsuleConePenetration(const glm::vec3& sphereCenter, - float sphereRadius, const glm::vec3& segmentStart, const glm::vec3& segmentEnd, + float sphereRadius, const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float startRadius, float endRadius, glm::vec3& penetration) { - return findPointCapsuleConePenetration(sphereCenter, segmentStart, segmentEnd, + return findPointCapsuleConePenetration(sphereCenter, capsuleStart, capsuleEnd, startRadius + sphereRadius, endRadius + sphereRadius, penetration); } diff --git a/libraries/shared/src/GeometryUtil.h b/libraries/shared/src/GeometryUtil.h index 4bba48fe08..9d064aef9c 100644 --- a/libraries/shared/src/GeometryUtil.h +++ b/libraries/shared/src/GeometryUtil.h @@ -13,11 +13,17 @@ glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end); -bool findSpherePenetration(const glm::vec3& localPoint, const glm::vec3& direction, - float combinedRadius, glm::vec3& penetration); +/// Computes the penetration between a point and a sphere (centered at the origin) +/// \param point the point location relative to sphere center (origin) +/// \param defaultDirection the direction of the pentration when the point is near the origin +/// \param sphereRadius the radius of the sphere +/// \param penetration the displacement that would move the point out of penetration with the sphere +/// \return true if point is inside sphere, otherwise false +bool findSpherePenetration(const glm::vec3& point, const glm::vec3& defaultDirection, + float sphereRadius, glm::vec3& penetration); bool findSpherePointPenetration(const glm::vec3& sphereCenter, float sphereRadius, - const glm::vec3& penetrateeLocation, glm::vec3& penetration); + const glm::vec3& point, glm::vec3& penetration); bool findPointSpherePenetration(const glm::vec3& point, const glm::vec3& sphereCenter, float sphereRadius, glm::vec3& penetration); @@ -26,17 +32,17 @@ bool findSphereSpherePenetration(const glm::vec3& firstCenter, float firstRadius const glm::vec3& secondCenter, float secondRadius, glm::vec3& penetration); bool findSphereSegmentPenetration(const glm::vec3& sphereCenter, float sphereRadius, - const glm::vec3& penetrateeStart, const glm::vec3& penetrateeEnd, glm::vec3& penetration); + const glm::vec3& segmentStart, const glm::vec3& segmentEnd, glm::vec3& penetration); -bool findSphereCapsulePenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec3& penetrateeStart, - const glm::vec3& penetrateeEnd, float capsuleRadius, glm::vec3& penetration); +bool findSphereCapsulePenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec3& capsuleStart, + const glm::vec3& capsuleEnd, float capsuleRadius, glm::vec3& penetration); -bool findPointCapsuleConePenetration(const glm::vec3& point, const glm::vec3& segmentStart, - const glm::vec3& segmentEnd, float startRadius, float endRadius, glm::vec3& penetration); +bool findPointCapsuleConePenetration(const glm::vec3& point, const glm::vec3& capsuleStart, + const glm::vec3& capsuleEnd, float startRadius, float endRadius, glm::vec3& penetration); bool findSphereCapsuleConePenetration(const glm::vec3& sphereCenter, float sphereRadius, - const glm::vec3& penetrateeStart, const glm::vec3& penetrateeEnd, - float penetrateeStartRadius, float penetrateeEndRadius, glm::vec3& penetration); + const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, + float startRadius, float endRadius, glm::vec3& penetration); bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec4& plane, glm::vec3& penetration); From 74392a88359ff732a4bb619f5efe5e64213c1d17 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 3 Jan 2014 16:03:42 -0800 Subject: [PATCH 03/13] Moved ParticleTreeUpdateArgs into ParticleTreeElement.h --- libraries/particles/src/ParticleTree.h | 5 ----- libraries/particles/src/ParticleTreeElement.h | 8 ++++++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libraries/particles/src/ParticleTree.h b/libraries/particles/src/ParticleTree.h index 3f8b7fda09..7c8d724a17 100644 --- a/libraries/particles/src/ParticleTree.h +++ b/libraries/particles/src/ParticleTree.h @@ -12,11 +12,6 @@ #include #include "ParticleTreeElement.h" -class ParticleTreeUpdateArgs { -public: - std::vector _movingParticles; -}; - class NewlyCreatedParticleHook { public: virtual void particleCreated(const Particle& newParticle, Node* senderNode) = 0; diff --git a/libraries/particles/src/ParticleTreeElement.h b/libraries/particles/src/ParticleTreeElement.h index 34d4054d98..971f5f5481 100644 --- a/libraries/particles/src/ParticleTreeElement.h +++ b/libraries/particles/src/ParticleTreeElement.h @@ -19,7 +19,11 @@ class ParticleTree; class ParticleTreeElement; -class ParticleTreeUpdateArgs; + +class ParticleTreeUpdateArgs { +public: + std::vector _movingParticles; +}; class ParticleTreeElement : public OctreeElement { friend class ParticleTree; // to allow createElement to new us... @@ -95,4 +99,4 @@ protected: std::vector _particles; }; -#endif /* defined(__hifi__ParticleTreeElement__) */ \ No newline at end of file +#endif /* defined(__hifi__ParticleTreeElement__) */ From 71e5de8420c7164b5d911255318372654c096650 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 10 Jan 2014 11:37:01 -0800 Subject: [PATCH 04/13] Adding Particle::_mass and correct elastic collisions between particles --- libraries/particles/src/Particle.cpp | 6 ++ libraries/particles/src/Particle.h | 3 + .../particles/src/ParticleCollisionSystem.cpp | 67 +++++++++++-------- 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index edca3a1fc0..346760b115 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -54,6 +54,7 @@ void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 _position = position; _radius = radius; + _mass = 1.0f; memcpy(_color, color, sizeof(_color)); _velocity = velocity; _damping = damping; @@ -63,6 +64,11 @@ void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 _shouldDie = false; } +void Particle::setMass(float value) { + if (value > 0.0f) { + _mass = value; + } +} bool Particle::appendParticleData(OctreePacketData* packetData) const { diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index 9c92d0ec48..5e80234660 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -67,6 +67,7 @@ public: const rgbColor& getColor() const { return _color; } xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } float getRadius() const { return _radius; } + float getMass() const { return _mass; } const glm::vec3& getVelocity() const { return _velocity; } const glm::vec3& getGravity() const { return _gravity; } bool getInHand() const { return _inHand; } @@ -96,6 +97,7 @@ public: _color[BLUE_INDEX] = value.blue; } void setRadius(float value) { _radius = value; } + void setMass(float value); void setGravity(const glm::vec3& value) { _gravity = value; } void setInHand(bool inHand) { _inHand = inHand; } void setDamping(float value) { _damping = value; } @@ -146,6 +148,7 @@ protected: glm::vec3 _position; rgbColor _color; float _radius; + float _mass; glm::vec3 _velocity; uint32_t _id; static uint32_t _nextID; diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index 1e1f3955fe..0389dddb66 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -87,41 +87,50 @@ void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) { } } -void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particle) { - glm::vec3 center = particle->getPosition() * static_cast(TREE_SCALE); - float radius = particle->getRadius() * static_cast(TREE_SCALE); - const float ELASTICITY = 1.4f; +void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA) { + glm::vec3 center = particleA->getPosition() * (float)TREE_SCALE; + float radius = particleA->getRadius() * (float)TREE_SCALE; + const float ELASTICITY = 0.4f; const float DAMPING = 0.0f; const float COLLISION_FREQUENCY = 0.5f; glm::vec3 penetration; - Particle* penetratedParticle; - if (_particles->findSpherePenetration(center, radius, penetration, (void**)&penetratedParticle)) { + Particle* particleB; + if (_particles->findSpherePenetration(center, radius, penetration, (void**)&particleB)) { + // NOTE: 'penetration' is the depth that 'particleA' overlaps 'particleB'. + // That is, it points from A into B. - // let the particles run their collision scripts if they have them - particle->collisionWithParticle(penetratedParticle); - penetratedParticle->collisionWithParticle(particle); + // Even if the particles overlap... when the particles are already moving appart + // we don't want to count this as a collision. + glm::vec3 relativeVelocity = particleA->getVelocity() - particleB->getVelocity(); + if (glm::dot(relativeVelocity, penetration) > 0.0f) { + particleA->collisionWithParticle(particleB); + particleB->collisionWithParticle(particleA); - penetration /= static_cast(TREE_SCALE); - updateCollisionSound(particle, penetration, COLLISION_FREQUENCY); - - // apply a hard collision to both particles of half the penetration each - - float particleShare, penetratedParticleShare; - if (particle->getInHand() && penetratedParticle->getInHand()) { - particleShare = 0.5f; - penetratedParticleShare = -0.5f; - } else if (particle->getInHand()) { - particleShare = 0.f; - penetratedParticleShare = -1.f; - } else if (penetratedParticle->getInHand()) { - particleShare = -1.f; - penetratedParticleShare = 0.f; - } else { - particleShare = 0.5f; - penetratedParticleShare = -0.5f; + glm::vec3 axis = glm::normalize(penetration); + glm::vec3 axialVelocity = glm::dot(relativeVelocity, axis) * axis; + + // particles that are in hand are assigned an ureasonably large mass for collisions + // which effectively makes them immovable but allows the other ball to reflect correctly. + const float MAX_MASS = 1.0e6f; + float massA = (particleA->getInHand()) ? MAX_MASS : particleA->getMass(); + float massB = (particleB->getInHand()) ? MAX_MASS : particleB->getMass(); + float totalMass = massA + massB; + + particleA->setVelocity(particleA->getVelocity() - axialVelocity * (2.0f * massB / totalMass)); + + ParticleEditHandle particleEditHandle(_packetSender, _particles, particleA->getID()); + particleEditHandle.updateParticle(particleA->getPosition(), particleA->getRadius(), particleA->getXColor(), particleA->getVelocity(), + particleA->getGravity(), particleA->getDamping(), particleA->getInHand(), particleA->getScript()); + + particleB->setVelocity(particleB->getVelocity() + axialVelocity * (2.0f * massA / totalMass)); + + ParticleEditHandle penetratedparticleEditHandle(_packetSender, _particles, particleB->getID()); + penetratedparticleEditHandle.updateParticle(particleB->getPosition(), particleB->getRadius(), particleB->getXColor(), particleB->getVelocity(), + particleB->getGravity(), particleB->getDamping(), particleB->getInHand(), particleB->getScript()); + + penetration /= (float)TREE_SCALE; + updateCollisionSound(particleA, penetration, COLLISION_FREQUENCY); } - applyHardCollision(particle, penetration * particleShare, ELASTICITY, DAMPING); - applyHardCollision(penetratedParticle, penetration * penetratedParticleShare, ELASTICITY, DAMPING); } } From c4c0c389ae105edea3218011ad97c24eff217a27 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 10 Jan 2014 11:42:23 -0800 Subject: [PATCH 05/13] Temporarily disabling DAMPING and non-unity ELASTICITY during particle-particle collisions --- libraries/particles/src/ParticleCollisionSystem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index 0389dddb66..0d3f9dcaff 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -90,8 +90,8 @@ void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) { void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA) { glm::vec3 center = particleA->getPosition() * (float)TREE_SCALE; float radius = particleA->getRadius() * (float)TREE_SCALE; - const float ELASTICITY = 0.4f; - const float DAMPING = 0.0f; + //const float ELASTICITY = 0.4f; + //const float DAMPING = 0.0f; const float COLLISION_FREQUENCY = 0.5f; glm::vec3 penetration; Particle* particleB; From ceb8ca7a23170f901f5257b7ce8d369e9f50d197 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 10 Jan 2014 16:59:01 -0800 Subject: [PATCH 06/13] changes to AssignmentClient architecture to fix fork behaviour --- assignment-client/src/AssignmentClient.cpp | 51 +++++- assignment-client/src/AssignmentClient.h | 5 +- .../src/AssignmentClientMonitor.cpp | 52 ++++++ .../src/AssignmentClientMonitor.h | 31 ++++ assignment-client/src/main.cpp | 155 +----------------- 5 files changed, 136 insertions(+), 158 deletions(-) create mode 100644 assignment-client/src/AssignmentClientMonitor.cpp create mode 100644 assignment-client/src/AssignmentClientMonitor.h diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index cc4292ad15..f3458c8afb 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -24,12 +24,8 @@ const long long ASSIGNMENT_REQUEST_INTERVAL_MSECS = 1 * 1000; int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); -AssignmentClient::AssignmentClient(int &argc, char **argv, - Assignment::Type requestAssignmentType, - const HifiSockAddr& customAssignmentServerSocket, - const char* requestAssignmentPool) : +AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), - _requestAssignment(Assignment::RequestCommand, requestAssignmentType, requestAssignmentPool), _currentAssignment(NULL) { // register meta type is required for queued invoke method on Assignment subclasses @@ -37,12 +33,53 @@ AssignmentClient::AssignmentClient(int &argc, char **argv, // set the logging target to the the CHILD_TARGET_NAME Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); + const char ASSIGNMENT_TYPE_OVVERIDE_OPTION[] = "-t"; + const char* assignmentTypeString = getCmdOption(argc, (const char**)argv, ASSIGNMENT_TYPE_OVVERIDE_OPTION); + + Assignment::Type requestAssignmentType = Assignment::AllTypes; + + if (assignmentTypeString) { + // the user is asking to only be assigned to a particular type of assignment + // so set that as the ::overridenAssignmentType to be used in requests + requestAssignmentType = (Assignment::Type) atoi(assignmentTypeString); + } + + const char ASSIGNMENT_POOL_OPTION[] = "--pool"; + const char* requestAssignmentPool = getCmdOption(argc, (const char**) argv, ASSIGNMENT_POOL_OPTION); + + + // setup our _requestAssignment member variable from the passed arguments + _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, requestAssignmentPool); + // create a NodeList as an unassigned client NodeList* nodeList = NodeList::createInstance(NODE_TYPE_UNASSIGNED); + const char CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION[] = "-a"; + const char CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION[] = "-p"; + + // grab the overriden assignment-server hostname from argv, if it exists + const char* customAssignmentServerHostname = getCmdOption(argc, (const char**)argv, CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION); + const char* customAssignmentServerPortString = getCmdOption(argc,(const char**)argv, CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION); + + HifiSockAddr customAssignmentSocket; + + if (customAssignmentServerHostname || customAssignmentServerPortString) { + + // set the custom port or default if it wasn't passed + unsigned short assignmentServerPort = customAssignmentServerPortString + ? atoi(customAssignmentServerPortString) : DEFAULT_DOMAIN_SERVER_PORT; + + // set the custom hostname or default if it wasn't passed + if (!customAssignmentServerHostname) { + customAssignmentServerHostname = DEFAULT_ASSIGNMENT_SERVER_HOSTNAME; + } + + customAssignmentSocket = HifiSockAddr(customAssignmentServerHostname, assignmentServerPort); + } + // set the custom assignment socket if we have it - if (!customAssignmentServerSocket.isNull()) { - nodeList->setAssignmentServerSocket(customAssignmentServerSocket); + if (!customAssignmentSocket.isNull()) { + nodeList->setAssignmentServerSocket(customAssignmentSocket); } // call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 48311b0275..f19c8015b3 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -16,10 +16,7 @@ class AssignmentClient : public QCoreApplication { Q_OBJECT public: - AssignmentClient(int &argc, char **argv, - Assignment::Type requestAssignmentType = Assignment::AllTypes, - const HifiSockAddr& customAssignmentServerSocket = HifiSockAddr(), - const char* requestAssignmentPool = NULL); + AssignmentClient(int &argc, char **argv); private slots: void sendAssignmentRequest(); void readPendingDatagrams(); diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp new file mode 100644 index 0000000000..d6a6c9b060 --- /dev/null +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -0,0 +1,52 @@ +// +// AssignmentClientMonitor.cpp +// hifi +// +// Created by Stephen Birarda on 1/10/2014. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#include + +#include "AssignmentClientMonitor.h" + +const char* NUM_FORKS_PARAMETER = "-n"; + +const char ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME[] = "assignment-client-monitor"; + +AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks) : + QCoreApplication(argc, argv) +{ + // start the Logging class with the parent's target name + Logging::setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME); + + _childArguments = arguments(); + + // remove the parameter for the number of forks so it isn't passed to the child forked processes + int forksParameterIndex = _childArguments.indexOf(NUM_FORKS_PARAMETER); + + // this removes both the "-n" parameter and the number of forks passed + _childArguments.removeAt(forksParameterIndex); + _childArguments.removeAt(forksParameterIndex); + + // use QProcess to fork off a process for each of the child assignment clients + for (int i = 0; i < numAssignmentClientForks; i++) { + spawnChildClient(); + } +} + +void AssignmentClientMonitor::spawnChildClient() { + QProcess *assignmentClient = new QProcess(this); + assignmentClient->start(applicationFilePath(), _childArguments); + + // link the child processes' finished slot to our childProcessFinished slot + connect(assignmentClient, SIGNAL(finished(int, QProcess::ExitStatus)), this, + SLOT(childProcessFinished(int, QProcess::ExitStatus))); + + qDebug() << "Spawned a child client with PID" << assignmentClient->pid() << "\n"; +} + +void AssignmentClientMonitor::childProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) { + qDebug() << "Replacing dead child assignment client with a new one.\n"; + spawnChildClient(); +} \ No newline at end of file diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h new file mode 100644 index 0000000000..259a6d6db7 --- /dev/null +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -0,0 +1,31 @@ +// +// AssignmentClientMonitor.h +// hifi +// +// Created by Stephen Birarda on 1/10/2014. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__AssignmentClientMonitor__ +#define __hifi__AssignmentClientMonitor__ + +#include +#include + +#include + +extern const char* NUM_FORKS_PARAMETER; + +class AssignmentClientMonitor : public QCoreApplication { + Q_OBJECT +public: + AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks); +private slots: + void childProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); +private: + void spawnChildClient(); + + QStringList _childArguments; +}; + +#endif /* defined(__hifi__AssignmentClientMonitor__) */ diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index 28516b37b8..7ee0ea9e14 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -6,172 +6,33 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -#include -#include -#include -#include -#include - #include -#include -#include #include -#include -#include "Agent.h" #include "Assignment.h" #include "AssignmentClient.h" -#include "audio/AudioMixer.h" -#include "avatars/AvatarMixer.h" - -const char PARENT_TARGET_NAME[] = "assignment-client-monitor"; - -pid_t* childForks = NULL; -HifiSockAddr customAssignmentSocket; -int numForks = 0; -Assignment::Type overiddenAssignmentType = Assignment::AllTypes; -const char* assignmentPool = NULL; - -int argc = 0; -char** argv = NULL; - -int childClient() { - AssignmentClient client(::argc, ::argv, ::overiddenAssignmentType, customAssignmentSocket, ::assignmentPool); - return client.exec(); -} - -void sigchldHandler(int sig) { - pid_t processID; - int status; - - while ((processID = waitpid(-1, &status, WNOHANG)) != -1) { - if (processID == 0) { - // there are no more children to process, break out of here - break; - } - - int newForkProcessID = 0; - - // find the dead process in the array of child forks - for (int i = 0; i < ::numForks; i++) { - if (::childForks[i] == processID) { - - newForkProcessID = fork(); - if (newForkProcessID == 0) { - // this is the child, call childClient - childClient(); - - // break out so we don't fork bomb - break; - } else { - // this is the parent, replace the dead process with the new one - ::childForks[i] = newForkProcessID; - - qDebug("Replaced dead %d with new fork %d\n", processID, newForkProcessID); - - break; - } - } - } - } - -} - -void parentMonitor() { - - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = sigchldHandler; - - sigaction(SIGCHLD, &sa, NULL); - - pid_t childID = 0; - - // don't bail until all children have finished - while ((childID = waitpid(-1, NULL, 0))) { - if (errno == ECHILD) { - break; - } - } - - // delete the array of pid_t holding the forked process IDs - delete[] ::childForks; -} +#include "AssignmentClientMonitor.h" int main(int argc, char* argv[]) { - ::argc = argc; - ::argv = argv; setvbuf(stdout, NULL, _IOLBF, 0); // use the verbose message handler in Logging qInstallMessageHandler(Logging::verboseMessageHandler); - // start the Logging class with the parent's target name - Logging::setTargetName(PARENT_TARGET_NAME); - - const char CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION[] = "-a"; - const char CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION[] = "-p"; - - // grab the overriden assignment-server hostname from argv, if it exists - const char* customAssignmentServerHostname = getCmdOption(argc, (const char**)argv, CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION); - const char* customAssignmentServerPortString = getCmdOption(argc,(const char**)argv, CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION); - - if (customAssignmentServerHostname || customAssignmentServerPortString) { - - // set the custom port or default if it wasn't passed - unsigned short assignmentServerPort = customAssignmentServerPortString - ? atoi(customAssignmentServerPortString) : DEFAULT_DOMAIN_SERVER_PORT; - - // set the custom hostname or default if it wasn't passed - if (!customAssignmentServerHostname) { - customAssignmentServerHostname = DEFAULT_ASSIGNMENT_SERVER_HOSTNAME; - } - - ::customAssignmentSocket = HifiSockAddr(customAssignmentServerHostname, assignmentServerPort); - } - - const char ASSIGNMENT_TYPE_OVVERIDE_OPTION[] = "-t"; - const char* assignmentTypeString = getCmdOption(argc, (const char**)argv, ASSIGNMENT_TYPE_OVVERIDE_OPTION); - - if (assignmentTypeString) { - // the user is asking to only be assigned to a particular type of assignment - // so set that as the ::overridenAssignmentType to be used in requests - ::overiddenAssignmentType = (Assignment::Type) atoi(assignmentTypeString); - } - - const char ASSIGNMENT_POOL_OPTION[] = "--pool"; - ::assignmentPool = getCmdOption(argc, (const char**) argv, ASSIGNMENT_POOL_OPTION); - - const char* NUM_FORKS_PARAMETER = "-n"; const char* numForksString = getCmdOption(argc, (const char**)argv, NUM_FORKS_PARAMETER); - int processID = 0; + int numForks = 0; if (numForksString) { - ::numForks = atoi(numForksString); - qDebug("Starting %d assignment clients\n", ::numForks); - - ::childForks = new pid_t[::numForks]; - - // fire off as many children as we need (this is one less than the parent since the parent will run as well) - for (int i = 0; i < ::numForks; i++) { - processID = fork(); - - if (processID == 0) { - // this is in one of the children, break so we don't start a fork bomb - break; - } else { - // this is in the parent, save the ID of the forked process - childForks[i] = processID; - } - } + numForks = atoi(numForksString); } - if (processID == 0 || ::numForks == 0) { - return childClient(); + if (numForks) { + AssignmentClientMonitor monitor(argc, argv, numForks); + return monitor.exec(); } else { - parentMonitor(); + AssignmentClient client(argc, argv); + return client.exec(); } } \ No newline at end of file From 248754e63ec630d5741f86d1b67d88241a04271a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 10 Jan 2014 17:03:13 -0800 Subject: [PATCH 07/13] make sure STDOUT from child assignment-client bubbles up to parent --- assignment-client/src/AssignmentClientMonitor.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index d6a6c9b060..fa050a0dac 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -37,6 +37,10 @@ AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int num void AssignmentClientMonitor::spawnChildClient() { QProcess *assignmentClient = new QProcess(this); + + // make sure that the output from the child process appears in our output + assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels); + assignmentClient->start(applicationFilePath(), _childArguments); // link the child processes' finished slot to our childProcessFinished slot From 0e25c85eef01057b884a3d639839197185e4f18a Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 13 Jan 2014 11:46:27 -0600 Subject: [PATCH 08/13] Trivial change - testing deploy changes --- interface/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 1bbdbde41e..e1dfa8a6c6 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -227,3 +227,4 @@ INSTALL(TARGETS ${TARGET_NAME} BUNDLE DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/install COMPONENT Runtime RUNTIME DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/install COMPONENT Runtime ) + From 3f2c6504a60ff304adc4c454907f450e891a1aeb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jan 2014 12:27:47 -0800 Subject: [PATCH 09/13] fix for avatar scale bug, closes #1506 --- interface/src/Application.cpp | 4 ++-- interface/src/avatar/Avatar.cpp | 4 ++-- libraries/avatars/src/AvatarData.cpp | 8 ++++---- libraries/avatars/src/AvatarData.h | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 958995daae..0830f6069f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2128,8 +2128,8 @@ void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm:: Avatar* avatar = *fade; const float SHRINK_RATE = 0.9f; avatar->setNewScale(avatar->getNewScale() * SHRINK_RATE); - const float MINIMUM_SCALE = 0.001f; - if (avatar->getNewScale() < MINIMUM_SCALE) { + + if (avatar->getNewScale() < MIN_AVATAR_SCALE) { delete avatar; _avatarFades.erase(fade--); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index b3b4793b39..525644b52b 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -439,14 +439,14 @@ void Avatar::goHome() { } void Avatar::increaseSize() { - if ((1.f + SCALING_RATIO) * _newScale < MAX_SCALE) { + if ((1.f + SCALING_RATIO) * _newScale < MAX_AVATAR_SCALE) { _newScale *= (1.f + SCALING_RATIO); qDebug("Changed scale to %f\n", _newScale); } } void Avatar::decreaseSize() { - if (MIN_SCALE < (1.f - SCALING_RATIO) * _newScale) { + if (MIN_AVATAR_SCALE < (1.f - SCALING_RATIO) * _newScale) { _newScale *= (1.f - SCALING_RATIO); qDebug("Changed scale to %f\n", _newScale); } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 14115ced47..b81a0601bd 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -297,10 +297,10 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { } void AvatarData::setNewScale(float newScale) { - if (newScale > MAX_SCALE) { - newScale = MAX_SCALE; - } else if (newScale < MIN_SCALE) { - newScale = MIN_SCALE; + if (newScale > MAX_AVATAR_SCALE) { + newScale = MAX_AVATAR_SCALE; + } else if (newScale < MIN_AVATAR_SCALE) { + newScale = MIN_AVATAR_SCALE; } _newScale = newScale; qDebug() << "Changed scale to " << _newScale << "\n"; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index e7f359aff2..6ee320eae0 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -32,8 +32,8 @@ const int HAND_STATE_START_BIT = 2; // 3rd and 4th bits const int IS_FACESHIFT_CONNECTED = 4; // 5th bit const int IS_CHAT_CIRCLING_ENABLED = 5; -static const float MAX_SCALE = 1000.f; -static const float MIN_SCALE = .005f; +static const float MAX_AVATAR_SCALE = 1000.f; +static const float MIN_AVATAR_SCALE = .005f; const float MAX_AUDIO_LOUDNESS = 1000.0; // close enough for mouth animation @@ -83,7 +83,7 @@ public: // Scale float getNewScale() const { return _newScale; } - void setNewScale(float); + void setNewScale(float newScale); // Hand State void setHandState(char s) { _handState = s; } From 2d5df389071c0af3f2714644ff92dfacd31b5765 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 13 Jan 2014 13:51:51 -0800 Subject: [PATCH 10/13] Persist the user orientation as well as the position, show up a couple meters in front of (and facing) target. Closes #1367. --- interface/src/Application.cpp | 3 ++- interface/src/DataServerClient.cpp | 24 +++++++++++++++++------- interface/src/DataServerClient.h | 1 + interface/src/Menu.cpp | 5 +++-- interface/src/avatar/Profile.cpp | 26 ++++++++++++++++++++++++-- interface/src/avatar/Profile.h | 6 ++++++ 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 958995daae..6e050df72c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1347,8 +1347,9 @@ void Application::timer() { // ask the node list to check in with the domain server NodeList::getInstance()->sendDomainServerCheckIn(); - // give the MyAvatar object position to the Profile so it can propagate to the data-server + // give the MyAvatar object position, orientation to the Profile so it can propagate to the data-server _profile.updatePosition(_myAvatar.getPosition()); + _profile.updateOrientation(_myAvatar.getOrientation()); } static glm::vec3 getFaceVector(BoxFace face) { diff --git a/interface/src/DataServerClient.cpp b/interface/src/DataServerClient.cpp index 33fa59e3e4..56ab92dba3 100644 --- a/interface/src/DataServerClient.cpp +++ b/interface/src/DataServerClient.cpp @@ -175,25 +175,35 @@ void DataServerClient::processSendFromDataServer(unsigned char* packetData, int } } } - } else if (keyList[i] == DataServerKey::Domain && keyList[i + 1] == DataServerKey::Position - && valueList[i] != " " && valueList[i + 1] != " ") { + } else if (keyList[i] == DataServerKey::Domain && keyList[i + 1] == DataServerKey::Position && + keyList[i + 2] == DataServerKey::Orientation && valueList[i] != " " && + valueList[i + 1] != " " && valueList[i + 2] != " ") { QStringList coordinateItems = valueList[i + 1].split(','); + QStringList orientationItems = valueList[i + 2].split(','); - if (coordinateItems.size() == 3) { + if (coordinateItems.size() == 3 && orientationItems.size() == 3) { // send a node kill request, indicating to other clients that they should play the "disappeared" effect NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1); qDebug() << "Changing domain to" << valueList[i].toLocal8Bit().constData() << - "and position to" << valueList[i + 1].toLocal8Bit().constData() << + ", position to" << valueList[i + 1].toLocal8Bit().constData() << + ", and orientation to" << valueList[i + 2].toLocal8Bit().constData() << "to go to" << userString << "\n"; NodeList::getInstance()->setDomainHostname(valueList[i]); - glm::vec3 newPosition(coordinateItems[0].toFloat(), - coordinateItems[1].toFloat(), - coordinateItems[2].toFloat()); + // orient the user to face the target + glm::quat newOrientation = glm::quat(glm::radians(glm::vec3(orientationItems[0].toFloat(), + orientationItems[1].toFloat(), orientationItems[2].toFloat()))) * + glm::angleAxis(180.0f, 0.0f, 1.0f, 0.0f); + Application::getInstance()->getAvatar()->setOrientation(newOrientation); + + // move the user a couple units away + const float DISTANCE_TO_USER = 2.0f; + glm::vec3 newPosition = glm::vec3(coordinateItems[0].toFloat(), coordinateItems[1].toFloat(), + coordinateItems[2].toFloat()) - newOrientation * IDENTITY_FRONT * DISTANCE_TO_USER; Application::getInstance()->getAvatar()->setPosition(newPosition); } diff --git a/interface/src/DataServerClient.h b/interface/src/DataServerClient.h index b0ccbe13ee..89ec944eb6 100644 --- a/interface/src/DataServerClient.h +++ b/interface/src/DataServerClient.h @@ -41,6 +41,7 @@ namespace DataServerKey { const QString FaceMeshURL = "mesh"; const QString SkeletonURL = "skeleton"; const QString Position = "position"; + const QString Orientation = "orientation"; const QString UUID = "uuid"; } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 545a765dce..c77be1e0a9 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -999,8 +999,9 @@ void Menu::goToUser() { int dialogReturn = userDialog.exec(); if (dialogReturn == QDialog::Accepted && !userDialog.textValue().isEmpty()) { // there's a username entered by the user, make a request to the data-server - DataServerClient::getValuesForKeysAndUserString((QStringList() << DataServerKey::Domain << DataServerKey::Position), - userDialog.textValue()); + DataServerClient::getValuesForKeysAndUserString( + QStringList() << DataServerKey::Domain << DataServerKey::Position << DataServerKey::Orientation, + userDialog.textValue()); } sendFakeEnterEvent(); diff --git a/interface/src/avatar/Profile.cpp b/interface/src/avatar/Profile.cpp index 4a185f5788..316ca195c9 100644 --- a/interface/src/avatar/Profile.cpp +++ b/interface/src/avatar/Profile.cpp @@ -18,6 +18,7 @@ Profile::Profile(const QString &username) : _uuid(), _lastDomain(), _lastPosition(0.0, 0.0, 0.0), + _lastOrientationSend(0), _faceModelURL() { if (!_username.isEmpty()) { @@ -69,6 +70,10 @@ void Profile::updateDomain(const QString& domain) { } } +static QByteArray createByteArray(const glm::vec3& vector) { + return QByteArray::number(vector.x) + ',' + QByteArray::number(vector.y) + ',' + QByteArray::number(vector.z); +} + void Profile::updatePosition(const glm::vec3 position) { if (_lastPosition != position) { @@ -90,12 +95,29 @@ void Profile::updatePosition(const glm::vec3 position) { gettimeofday(&lastPositionSend, NULL); // send the changed position to the data-server - QString positionString = QString("%1,%2,%3").arg(position.x).arg(position.y).arg(position.z); - DataServerClient::putValueForKey(DataServerKey::Position, positionString.toLocal8Bit().constData()); + DataServerClient::putValueForKey(DataServerKey::Position, createByteArray(position).constData()); } } } +void Profile::updateOrientation(const glm::quat& orientation) { + glm::vec3 eulerAngles = safeEulerAngles(orientation); + if (_lastOrientation == eulerAngles) { + return; + } + const uint64_t DATA_SERVER_ORIENTATION_UPDATE_INTERVAL_USECS = 5 * 1000 * 1000; + const float DATA_SERVER_ORIENTATION_CHANGE_THRESHOLD_DEGREES = 5.0f; + + uint64_t now = usecTimestampNow(); + if (now - _lastOrientationSend >= DATA_SERVER_ORIENTATION_UPDATE_INTERVAL_USECS && + glm::distance(_lastOrientation, eulerAngles) >= DATA_SERVER_ORIENTATION_CHANGE_THRESHOLD_DEGREES) { + DataServerClient::putValueForKey(DataServerKey::Orientation, createByteArray(eulerAngles).constData()); + + _lastOrientation = eulerAngles; + _lastOrientationSend = now; + } +} + void Profile::saveData(QSettings* settings) { settings->beginGroup("Profile"); diff --git a/interface/src/avatar/Profile.h b/interface/src/avatar/Profile.h index eb3f531819..06f8de94a3 100644 --- a/interface/src/avatar/Profile.h +++ b/interface/src/avatar/Profile.h @@ -9,11 +9,14 @@ #ifndef __hifi__Profile__ #define __hifi__Profile__ +#include + #include #include #include #include +#include class Profile { public: @@ -34,6 +37,7 @@ public: void updateDomain(const QString& domain); void updatePosition(const glm::vec3 position); + void updateOrientation(const glm::quat& orientation); QString getLastDomain() const { return _lastDomain; } const glm::vec3& getLastPosition() const { return _lastPosition; } @@ -45,6 +49,8 @@ private: QUuid _uuid; QString _lastDomain; glm::vec3 _lastPosition; + glm::vec3 _lastOrientation; + uint64_t _lastOrientationSend; QUrl _faceModelURL; QUrl _skeletonModelURL; }; From 42e3bcfe9198500cc3eb503e312b56d42fccacd4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jan 2014 13:52:41 -0800 Subject: [PATCH 11/13] allow fade scale to get smaller than minimum avatar scale --- interface/src/Application.cpp | 9 ++++++--- interface/src/Menu.cpp | 2 +- interface/src/avatar/Avatar.cpp | 26 +++++++++++++------------- interface/src/avatar/MyAvatar.cpp | 12 ++++++------ libraries/avatars/src/AvatarData.cpp | 20 +++++++++----------- libraries/avatars/src/AvatarData.h | 7 ++++--- 6 files changed, 39 insertions(+), 37 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0830f6069f..5d808ff9d4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2127,9 +2127,12 @@ void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm:: for (vector::iterator fade = _avatarFades.begin(); fade != _avatarFades.end(); fade++) { Avatar* avatar = *fade; const float SHRINK_RATE = 0.9f; - avatar->setNewScale(avatar->getNewScale() * SHRINK_RATE); - - if (avatar->getNewScale() < MIN_AVATAR_SCALE) { + + avatar->setTargetScale(avatar->getScale() * SHRINK_RATE); + + const float MIN_FADE_SCALE = 0.001; + + if (avatar->getTargetScale() < MIN_FADE_SCALE) { delete avatar; _avatarFades.erase(fade--); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 545a765dce..209bc76472 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -891,7 +891,7 @@ void Menu::editPreferences() { _maxVoxelPacketsPerSecond = maxVoxelsPPS->value(); applicationInstance->getAvatar()->setLeanScale(leanScale->value()); - applicationInstance->getAvatar()->setNewScale(avatarScale->value()); + applicationInstance->getAvatar()->setClampedTargetScale(avatarScale->value()); _audioJitterBufferSamples = audioJitterBufferSamples->value(); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 525644b52b..25365dba7a 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -167,8 +167,8 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { follow(NULL); } - if (_scale != _newScale) { - setScale(_newScale); + if (_scale != _targetScale) { + setScale(_targetScale); } // copy velocity so we can use it later for acceleration @@ -439,30 +439,30 @@ void Avatar::goHome() { } void Avatar::increaseSize() { - if ((1.f + SCALING_RATIO) * _newScale < MAX_AVATAR_SCALE) { - _newScale *= (1.f + SCALING_RATIO); - qDebug("Changed scale to %f\n", _newScale); + if ((1.f + SCALING_RATIO) * _targetScale < MAX_AVATAR_SCALE) { + _targetScale *= (1.f + SCALING_RATIO); + qDebug("Changed scale to %f\n", _targetScale); } } void Avatar::decreaseSize() { - if (MIN_AVATAR_SCALE < (1.f - SCALING_RATIO) * _newScale) { - _newScale *= (1.f - SCALING_RATIO); - qDebug("Changed scale to %f\n", _newScale); + if (MIN_AVATAR_SCALE < (1.f - SCALING_RATIO) * _targetScale) { + _targetScale *= (1.f - SCALING_RATIO); + qDebug("Changed scale to %f\n", _targetScale); } } void Avatar::resetSize() { - _newScale = 1.0f; - qDebug("Reseted scale to %f\n", _newScale); + _targetScale = 1.0f; + qDebug("Reseted scale to %f\n", _targetScale); } void Avatar::setScale(const float scale) { _scale = scale; - if (_newScale * (1.f - RESCALING_TOLERANCE) < _scale && - _scale < _newScale * (1.f + RESCALING_TOLERANCE)) { - _scale = _newScale; + if (_targetScale * (1.f - RESCALING_TOLERANCE) < _scale && + _scale < _targetScale * (1.f + RESCALING_TOLERANCE)) { + _scale = _targetScale; } _skeleton.setScale(_scale); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 161ea5b9d8..dabbb7812d 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -92,12 +92,12 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { } // Ajust, scale, position and lookAt position when following an other avatar - if (_leadingAvatar && _newScale != _leadingAvatar->getScale()) { - _newScale = _leadingAvatar->getScale(); + if (_leadingAvatar && _targetScale != _leadingAvatar->getScale()) { + _targetScale = _leadingAvatar->getScale(); } - if (_scale != _newScale) { - float scale = (1.f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _newScale; + if (_scale != _targetScale) { + float scale = (1.f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _targetScale; setScale(scale); Application::getInstance()->getCamera()->setScale(scale); } @@ -513,7 +513,7 @@ void MyAvatar::saveData(QSettings* settings) { settings->setValue("pupilDilation", _head.getPupilDilation()); settings->setValue("leanScale", _leanScale); - settings->setValue("scale", _newScale); + settings->setValue("scale", _targetScale); settings->endGroup(); } @@ -536,7 +536,7 @@ void MyAvatar::loadData(QSettings* settings) { _leanScale = loadSetting(settings, "leanScale", 0.05f); - _newScale = loadSetting(settings, "scale", 1.0f); + _targetScale = loadSetting(settings, "scale", 1.0f); setScale(_scale); Application::getInstance()->getCamera()->setScale(_scale); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b81a0601bd..f663f26cbf 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -29,7 +29,7 @@ AvatarData::AvatarData(Node* owningNode) : _bodyYaw(-90.0), _bodyPitch(0.0), _bodyRoll(0.0), - _newScale(1.0f), + _targetScale(1.0f), _leaderUUID(), _handState(0), _keyState(NO_KEY_DOWN), @@ -76,7 +76,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); // Body scale - destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _newScale); + destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale); // Follow mode info memcpy(destinationBuffer, _leaderUUID.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); @@ -198,7 +198,7 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyRoll); // Body scale - sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, _newScale); + sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, _targetScale); // Follow mode info _leaderUUID = QUuid::fromRfc4122(QByteArray((char*) sourceBuffer, NUM_BYTES_RFC4122_UUID)); @@ -296,12 +296,10 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { return sourceBuffer - startPosition; } -void AvatarData::setNewScale(float newScale) { - if (newScale > MAX_AVATAR_SCALE) { - newScale = MAX_AVATAR_SCALE; - } else if (newScale < MIN_AVATAR_SCALE) { - newScale = MIN_AVATAR_SCALE; - } - _newScale = newScale; - qDebug() << "Changed scale to " << _newScale << "\n"; +void AvatarData::setClampedTargetScale(float targetScale) { + + targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); + + _targetScale = targetScale; + qDebug() << "Changed scale to " << _targetScale << "\n"; } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 6ee320eae0..8b46fd8493 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -82,8 +82,9 @@ public: void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; } // Scale - float getNewScale() const { return _newScale; } - void setNewScale(float newScale); + float getTargetScale() const { return _targetScale; } + void setTargetScale(float targetScale) { _targetScale = targetScale; } + void setClampedTargetScale(float targetScale); // Hand State void setHandState(char s) { _handState = s; } @@ -132,7 +133,7 @@ protected: float _bodyRoll; // Body scale - float _newScale; + float _targetScale; // Following mode infos QUuid _leaderUUID; From 9d831a2ab50b8febee6bb8c785152ba09cbaa032 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 13 Jan 2014 14:43:59 -0800 Subject: [PATCH 12/13] Orbit around voxel center, limit hover distance. --- interface/src/Application.cpp | 13 +++++++------ interface/src/Application.h | 2 +- libraries/voxels/src/VoxelTreeElement.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6e888d7918..8d758974dd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1121,7 +1121,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) { return; } if (_isHoverVoxel) { - _myAvatar.orbit(glm::vec3(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z) * (float)TREE_SCALE, deltaX, deltaY); + _myAvatar.orbit(getMouseVoxelWorldCoordinates(_hoverVoxel), deltaX, deltaY); return; } } @@ -1618,10 +1618,9 @@ void Application::makeVoxel(glm::vec3 position, isDestructive); } -const glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel) { - return glm::vec3((_mouseVoxel.x + _mouseVoxel.s / 2.f) * TREE_SCALE, - (_mouseVoxel.y + _mouseVoxel.s / 2.f) * TREE_SCALE, - (_mouseVoxel.z + _mouseVoxel.s / 2.f) * TREE_SCALE); +glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail& mouseVoxel) { + return glm::vec3((mouseVoxel.x + mouseVoxel.s / 2.f) * TREE_SCALE, (mouseVoxel.y + mouseVoxel.s / 2.f) * TREE_SCALE, + (mouseVoxel.z + mouseVoxel.s / 2.f) * TREE_SCALE); } const float NUDGE_PRECISION_MIN = 1 / pow(2.0, 12.0); @@ -2245,7 +2244,9 @@ void Application::updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin, if (!(_voxels.treeIsBusy() || _mousePressed)) { { PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()"); - _isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face); + const float MAX_HOVER_DISTANCE = 100.0f; + _isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face) && + glm::distance(getMouseVoxelWorldCoordinates(_hoverVoxel), mouseRayOrigin) < MAX_HOVER_DISTANCE; } if (MAKE_SOUND_ON_VOXEL_HOVER && _isHoverVoxel && glm::vec4(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s) != oldVoxel) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 92831ff9ce..1da7de0224 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -142,7 +142,7 @@ public: void removeVoxel(glm::vec3 position, float scale); - const glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel); + glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail& mouseVoxel); QGLWidget* getGLWidget() { return _glWidget; } MyAvatar* getAvatar() { return &_myAvatar; } diff --git a/libraries/voxels/src/VoxelTreeElement.h b/libraries/voxels/src/VoxelTreeElement.h index 1eee7e4a5b..d30007aca1 100644 --- a/libraries/voxels/src/VoxelTreeElement.h +++ b/libraries/voxels/src/VoxelTreeElement.h @@ -92,4 +92,4 @@ protected: }; -#endif /* defined(__hifi__VoxelTreeElement__) */ \ No newline at end of file +#endif /* defined(__hifi__VoxelTreeElement__) */ From f21436a29e7298468408656ee39b2e4a6d933d07 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 13 Jan 2014 15:02:46 -0800 Subject: [PATCH 13/13] Fix (hopefully) for warning on Windows build. --- interface/src/Application.cpp | 4 +--- libraries/metavoxels/src/MetavoxelData.cpp | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8d758974dd..5a6aec5fe8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2244,9 +2244,7 @@ void Application::updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin, if (!(_voxels.treeIsBusy() || _mousePressed)) { { PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()"); - const float MAX_HOVER_DISTANCE = 100.0f; - _isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face) && - glm::distance(getMouseVoxelWorldCoordinates(_hoverVoxel), mouseRayOrigin) < MAX_HOVER_DISTANCE; + _isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face); } if (MAKE_SOUND_ON_VOXEL_HOVER && _isHoverVoxel && glm::vec4(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s) != oldVoxel) { diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 849d85960e..c04ee9f297 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -301,8 +301,8 @@ void MetavoxelNode::clearChildren(const AttributePointer& attribute) { } int MetavoxelPath::operator[](int index) const { - return _array.at(index * BITS_PER_ELEMENT) | (_array.at(index * BITS_PER_ELEMENT + 1) << 1) | - (_array.at(index * BITS_PER_ELEMENT + 2) << 2); + return (int)_array.at(index * BITS_PER_ELEMENT) | ((int)_array.at(index * BITS_PER_ELEMENT + 1) << 1) | + ((int)_array.at(index * BITS_PER_ELEMENT + 2) << 2); } MetavoxelPath& MetavoxelPath::operator+=(int element) {