From 6c4ecb024654aadf9764a8cf427d9f5c3b00c675 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Feb 2014 14:38:31 -0800 Subject: [PATCH] Splitting hand collisions between other avatars and ourself. --- interface/src/avatar/Hand.cpp | 149 ++++++++++++++++-------------- interface/src/avatar/Hand.h | 3 + interface/src/avatar/MyAvatar.cpp | 3 + 3 files changed, 88 insertions(+), 67 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 4dac42a02e..b62e88289f 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -167,91 +167,106 @@ void Hand::simulate(float deltaTime, bool isMine) { } void Hand::updateCollisions() { - // use position to obtain the left and right palm indices - int leftPalmIndex, rightPalmIndex; - getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex); - + collideAgainstOtherAvatars(); + collideAgainstOurself(); +} + +void Hand::collideAgainstOtherAvatars() { + if (!Menu::getInstance()->isOptionChecked(MenuOption::CollideWithAvatars)) { + return; + } ModelCollisionList collisions; - // check for collisions + float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale(); for (size_t i = 0; i < getNumPalms(); i++) { PalmData& palm = getPalms()[i]; if (!palm.isActive()) { continue; } - float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale(); glm::vec3 totalPenetration; - - if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithAvatars)) { - // check other avatars - foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) { - Avatar* avatar = static_cast(avatarPointer.data()); - if (avatar == _owningAvatar) { - // don't collid with our own hands - continue; - } - if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) { - // Check for palm collisions - glm::vec3 myPalmPosition = palm.getPosition(); - float palmCollisionDistance = 0.1f; - bool wasColliding = palm.getIsCollidingWithPalm(); - palm.setIsCollidingWithPalm(false); - // If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound - for (size_t j = 0; j < avatar->getHand().getNumPalms(); j++) { - PalmData& otherPalm = avatar->getHand().getPalms()[j]; - if (!otherPalm.isActive()) { - continue; - } - glm::vec3 otherPalmPosition = otherPalm.getPosition(); - if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) { - palm.setIsCollidingWithPalm(true); - if (!wasColliding) { - const float PALM_COLLIDE_VOLUME = 1.f; - const float PALM_COLLIDE_FREQUENCY = 1000.f; - const float PALM_COLLIDE_DURATION_MAX = 0.75f; - const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f; - Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME, - PALM_COLLIDE_FREQUENCY, - PALM_COLLIDE_DURATION_MAX, - PALM_COLLIDE_DECAY_PER_SAMPLE); - // If the other person's palm is in motion, move mine downward to show I was hit - const float MIN_VELOCITY_FOR_SLAP = 0.05f; - if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) { - // add slapback here - } + // check other avatars + foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) { + Avatar* avatar = static_cast(avatarPointer.data()); + if (avatar == _owningAvatar) { + // don't collid with our own hands + continue; + } + collisions.clear(); + if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) { + // Check for palm collisions + glm::vec3 myPalmPosition = palm.getPosition(); + float palmCollisionDistance = 0.1f; + bool wasColliding = palm.getIsCollidingWithPalm(); + palm.setIsCollidingWithPalm(false); + // If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound + for (size_t j = 0; j < avatar->getHand().getNumPalms(); j++) { + PalmData& otherPalm = avatar->getHand().getPalms()[j]; + if (!otherPalm.isActive()) { + continue; + } + glm::vec3 otherPalmPosition = otherPalm.getPosition(); + if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) { + palm.setIsCollidingWithPalm(true); + if (!wasColliding) { + const float PALM_COLLIDE_VOLUME = 1.f; + const float PALM_COLLIDE_FREQUENCY = 1000.f; + const float PALM_COLLIDE_DURATION_MAX = 0.75f; + const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f; + Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME, + PALM_COLLIDE_FREQUENCY, + PALM_COLLIDE_DURATION_MAX, + PALM_COLLIDE_DECAY_PER_SAMPLE); + // If the other person's palm is in motion, move mine downward to show I was hit + const float MIN_VELOCITY_FOR_SLAP = 0.05f; + if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) { + // add slapback here } } } } - if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions)) { - for (int j = 0; j < collisions.size(); ++j) { - // we don't resolve penetrations that would poke the other avatar - if (!avatar->isPokeable(collisions[j])) { - totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration); - } + } + if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions)) { + for (int j = 0; j < collisions.size(); ++j) { + // we don't resolve penetrations that would poke the other avatar + if (!avatar->isPokeable(collisions[j])) { + totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration); } } } } - - if (Menu::getInstance()->isOptionChecked(MenuOption::HandsCollideWithSelf)) { - // and the current avatar (ignoring everything below the parent of the parent of the last free joint) - collisions.clear(); - const Model& skeletonModel = _owningAvatar->getSkeletonModel(); - int skipIndex = skeletonModel.getParentJointIndex(skeletonModel.getParentJointIndex( - skeletonModel.getLastFreeJointIndex((i == leftPalmIndex) ? skeletonModel.getLeftHandJointIndex() : - (i == rightPalmIndex) ? skeletonModel.getRightHandJointIndex() : -1))); - if (_owningAvatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions, skipIndex)) { - for (int j = 0; j < collisions.size(); ++j) { - totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration); - } + // resolve penetration + palm.addToPosition(-totalPenetration); + } +} + +void Hand::collideAgainstOurself() { + if (!Menu::getInstance()->isOptionChecked(MenuOption::HandsCollideWithSelf)) { + return; + } + + ModelCollisionList collisions; + int leftPalmIndex, rightPalmIndex; + getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex); + float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale(); + + for (size_t i = 0; i < getNumPalms(); i++) { + PalmData& palm = getPalms()[i]; + if (!palm.isActive()) { + continue; + } + glm::vec3 totalPenetration; + // and the current avatar (ignoring everything below the parent of the parent of the last free joint) + collisions.clear(); + const Model& skeletonModel = _owningAvatar->getSkeletonModel(); + int skipIndex = skeletonModel.getParentJointIndex(skeletonModel.getParentJointIndex( + skeletonModel.getLastFreeJointIndex((i == leftPalmIndex) ? skeletonModel.getLeftHandJointIndex() : + (i == rightPalmIndex) ? skeletonModel.getRightHandJointIndex() : -1))); + if (_owningAvatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions, skipIndex)) { + for (int j = 0; j < collisions.size(); ++j) { + totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration); } } - - // un-penetrate + // resolve penetration palm.addToPosition(-totalPenetration); - - // we recycle the collisions container, so we clear it for the next loop - collisions.clear(); } } diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 3c8ec2d562..5a8e3d0e6f 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -97,6 +97,9 @@ private: void renderLeapFingerTrails(); void updateCollisions(); + void collideAgainstOtherAvatars(); + void collideAgainstOurself(); + void calculateGeometry(); void handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5a4512419d..31437182bc 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1052,6 +1052,9 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) { setPosition(_position - 0.5f * penetration); glm::vec3 pushOut = 0.5f * penetration; } + + // collide their hands against our movable limbs + } } }