From f08e639cb295ca190bdbdb4775f28295b6fb4eaf Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 17 Jan 2014 11:22:50 -0800 Subject: [PATCH] fixes for avatar paddle-hands, plus some hackery for demo --- interface/src/avatar/Avatar.cpp | 9 ++++++-- interface/src/avatar/Hand.cpp | 3 +++ interface/src/avatar/Hand.h | 2 +- interface/src/devices/SixenseManager.cpp | 9 ++++++++ libraries/avatars/src/HandData.cpp | 3 ++- libraries/avatars/src/HandData.h | 9 ++++++-- .../particles/src/ParticleCollisionSystem.cpp | 22 +++++++++++++++---- libraries/shared/src/CollisionInfo.h | 2 +- libraries/shared/src/GeometryUtil.cpp | 17 +++++++------- libraries/shared/src/GeometryUtil.h | 5 +++-- libraries/shared/src/PacketHeaders.cpp | 2 +- 11 files changed, 60 insertions(+), 23 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 144c9f4c2a..41698834a4 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -334,7 +334,7 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi if (handData) { for (int i = 0; i < 2; i++) { const PalmData* palm = handData->getPalm(i); - if (palm) { + if (palm && palm->hasPaddle()) { // create a disk collision proxy where the hand is glm::vec3 fingerAxis(0.f); for (size_t f = 0; f < palm->getNumFingers(); ++f) { @@ -356,10 +356,12 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi } glm::vec3 diskCenter = handPosition + HAND_PADDLE_OFFSET * fingerAxis; glm::vec3 diskNormal = palm->getNormal(); + float diskThickness = 0.08f; // collide against the disk if (findSphereDiskPenetration(sphereCenter, sphereRadius, - diskCenter, HAND_PADDLE_RADIUS, diskNormal, collision._penetration)) { + diskCenter, HAND_PADDLE_RADIUS, diskThickness, diskNormal, + collision._penetration)) { collision._addedVelocity = palm->getVelocity(); return true; } @@ -367,11 +369,14 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi } } + /* HACK : disable collisions with avatar proper for now -- sometimes interferes with paddle + * TODO: disable regular collisions with hand capsules if (_skeletonModel.findSpherePenetration(sphereCenter, sphereRadius, collision._penetration)) { collision._penetration /= (float)(TREE_SCALE); collision._addedVelocity = getVelocity(); return true; } + */ return false; } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 0b399c4287..6bd25b5c54 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -187,6 +187,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f const float THROWN_VELOCITY_SCALING = 1.5f; _toyBallInHand[handID] = false; + palm.updateCollisionlessPaddleExpiry(); glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; glm::vec3 ballVelocity = ballFromHand ? palm.getRawVelocity() : palm.getTipVelocity(); glm::quat avatarRotation = _owningAvatar->getOrientation(); @@ -562,6 +563,8 @@ void Hand::renderLeapHands(bool isMine) { continue; } glm::vec3 targetPosition = ballFromHand ? palm.getPosition() : palm.getTipPosition(); + const float BALL_FORWARD_OFFSET = 0.08f; // put the ball a bit forward of fingers + targetPosition += BALL_FORWARD_OFFSET * palm.getNormal(); glPushMatrix(); ParticleTree* particles = Application::getInstance()->getParticles()->getTree(); diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index bc671d1926..0552c021f1 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -31,7 +31,7 @@ class Avatar; class ProgramObject; const float HAND_PADDLE_OFFSET = 0.1f; -const float HAND_PADDLE_THICKNESS = 0.05f; +const float HAND_PADDLE_THICKNESS = 0.01f; const float HAND_PADDLE_RADIUS = 0.15f; class Hand : public HandData { diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 24caa33533..12d045dea3 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -98,6 +98,15 @@ void SixenseManager::update(float deltaTime) { // Compute current velocity from position change glm::vec3 rawVelocity = (position - palm->getRawPosition()) / deltaTime / 1000.f; palm->setRawVelocity(rawVelocity); // meters/sec + /* + if (i == 0) + { + printf("ADEBUG rawVelocity = [%e, %e, %e]\n", + rawVelocity.x, + rawVelocity.y, + rawVelocity.z); + } + */ palm->setRawPosition(position); // use the velocity to determine whether there's any movement (if the hand isn't new) diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 1b942e8f07..291bbcbb13 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -79,7 +79,8 @@ _sixenseID(SIXENSEID_INVALID), _numFramesWithoutData(0), _owningHandData(owningHandData), _isCollidingWithVoxel(false), -_isCollidingWithPalm(false) +_isCollidingWithPalm(false), +_collisionlessPaddleExpiry(0) { for (int i = 0; i < NUM_FINGERS_PER_HAND; ++i) { _fingers.push_back(FingerData(this, owningHandData)); diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index 1aa60da927..1dbce223dd 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -15,6 +15,8 @@ #include #include +#include "SharedUtil.h" + class AvatarData; class FingerData; class PalmData; @@ -51,7 +53,7 @@ public: return _basePosition + _baseOrientation * (leapPosition * LEAP_UNIT_SCALE); } glm::vec3 leapDirectionToWorldDirection(const glm::vec3& leapDirection) { - return glm::normalize(_baseOrientation * leapDirection); + return _baseOrientation * leapDirection; } glm::vec3 worldPositionToLeapPosition(const glm::vec3& worldPosition) const; glm::vec3 worldVectorToLeapVector(const glm::vec3& worldVector) const; @@ -193,6 +195,9 @@ public: bool getIsCollidingWithPalm() const { return _isCollidingWithPalm; } void setIsCollidingWithPalm(bool isCollidingWithPalm) { _isCollidingWithPalm = isCollidingWithPalm; } + bool hasPaddle() const { return _collisionlessPaddleExpiry < usecTimestampNow(); } + void updateCollisionlessPaddleExpiry() { _collisionlessPaddleExpiry = usecTimestampNow() + USECS_PER_SECOND; } + private: std::vector _fingers; glm::quat _rawRotation; @@ -217,7 +222,7 @@ private: bool _isCollidingWithVoxel; /// Whether the finger of this palm is inside a leaf voxel bool _isCollidingWithPalm; - + uint64_t _collisionlessPaddleExpiry; /// Timestamp after which paddle starts colliding }; #endif /* defined(__hifi__HandData__) */ diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index ed62da8791..0e6306f434 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -145,7 +145,7 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { glm::vec3 center = particle->getPosition() * (float)(TREE_SCALE); float radius = particle->getRadius() * (float)(TREE_SCALE); - const float ELASTICITY = 0.95f; + const float ELASTICITY = 0.9f; const float DAMPING = 0.0f; const float COLLISION_FREQUENCY = 0.5f; glm::vec3 penetration; @@ -155,12 +155,26 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { AvatarData* avatar = (AvatarData*)_selfAvatar; CollisionInfo collision; if (avatar->findSphereCollision(center, radius, collision)) { - if (glm::dot(particle->getVelocity(), collision._addedVelocity) < 0.f) { + collision._addedVelocity /= (float)(TREE_SCALE); + glm::vec3 relativeVelocity = collision._addedVelocity - particle->getVelocity(); + if (glm::dot(relativeVelocity, collision._penetration) < 0.f) { // only collide when particle and collision point are moving toward each other + + // HACK BEGIN: to make slow particle-paddle collisions mellower + float elasticity = ELASTICITY; + float damping = glm::length(collision._addedVelocity) / 5.0e-5f; + if (damping < 1.f) { + collision._addedVelocity *= (damping * damping); + elasticity = ELASTICITY * damping; + damping = 0.1f; + } else { + damping = DAMPING; + } + // HACK END + collision._penetration /= (float)(TREE_SCALE); - collision._addedVelocity /= (float)(TREE_SCALE); updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY); - applyHardCollision(particle, collision._penetration, ELASTICITY, DAMPING, collision._addedVelocity); + applyHardCollision(particle, collision._penetration, elasticity, damping, collision._addedVelocity); } } } diff --git a/libraries/shared/src/CollisionInfo.h b/libraries/shared/src/CollisionInfo.h index 4f46a6bfd3..1e4801788e 100644 --- a/libraries/shared/src/CollisionInfo.h +++ b/libraries/shared/src/CollisionInfo.h @@ -18,7 +18,7 @@ public: //glm::vec3 _point; //glm::vec3 _normal; - glm::vec3 _penetration; + glm::vec3 _penetration; // depth that bodyA is penetrates bodyB glm::vec3 _addedVelocity; }; diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 2627a9035a..ac8e4e97c4 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -6,6 +6,7 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. #include +#include #include "SharedUtil.h" #include "GeometryUtil.h" @@ -115,20 +116,18 @@ bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadiu } bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius, - const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal, + const glm::vec3& diskCenter, float diskRadius, float diskThickness, const glm::vec3& diskNormal, glm::vec3& penetration) { glm::vec3 localCenter = sphereCenter - diskCenter; - float verticalDistance = glm::dot(localCenter, diskNormal); - - - if (abs(verticalDistance) < sphereRadius) { + float axialDistance = glm::dot(localCenter, diskNormal); + if (std::fabs(axialDistance) < (sphereRadius + 0.5f * diskThickness)) { // sphere hit the plane, but does it hit the disk? // Note: this algorithm ignores edge hits. - glm::vec3 verticalOffset = verticalDistance * diskNormal; - if (glm::length(localCenter - verticalOffset) < diskRadius) { + glm::vec3 axialOffset = axialDistance * diskNormal; + if (glm::length(localCenter - axialOffset) < diskRadius) { // yes, hit the disk - penetration = (sphereRadius - abs(verticalDistance)) * diskNormal; - if (verticalDistance < 0.f) { + penetration = (std::fabs(axialDistance) - (sphereRadius + 0.5f * diskThickness) ) * diskNormal; + if (axialDistance < 0.f) { // hit the backside of the disk, so negate penetration vector penetration *= -1.f; } diff --git a/libraries/shared/src/GeometryUtil.h b/libraries/shared/src/GeometryUtil.h index 59ad055445..12afc7c59c 100644 --- a/libraries/shared/src/GeometryUtil.h +++ b/libraries/shared/src/GeometryUtil.h @@ -17,7 +17,7 @@ glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec /// \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 +/// \param penetration[out] 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); @@ -53,9 +53,10 @@ bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadiu /// \param diskCenter center of disk /// \param diskRadius radius of disk /// \param diskNormal normal of disk plan +/// \param penetration[out] the depth that the sphere penetrates the disk /// \return true if sphere touches disk (does not handle collisions with disk edge) bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius, - const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal, + const glm::vec3& diskCenter, float diskRadius, float diskThickness, const glm::vec3& diskNormal, glm::vec3& penetration); bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius, diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 973738280f..0d91bd3687 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -70,7 +70,7 @@ bool packetVersionMatch(unsigned char* packetHeader) { if (packetHeader[1] == versionForPacketType(packetHeader[0]) || packetHeader[0] == PACKET_TYPE_STUN_RESPONSE) { return true; } else { - qDebug("There is a packet version mismatch for packet with header %c", packetHeader[0]); + //qDebug("There is a packet version mismatch for packet with header %c", packetHeader[0]); return false; } }