mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 07:19:05 +02:00
Splitting hand collisions between other avatars and ourself.
This commit is contained in:
parent
3b3359abce
commit
6c4ecb0246
3 changed files with 88 additions and 67 deletions
|
@ -167,91 +167,106 @@ void Hand::simulate(float deltaTime, bool isMine) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hand::updateCollisions() {
|
void Hand::updateCollisions() {
|
||||||
// use position to obtain the left and right palm indices
|
collideAgainstOtherAvatars();
|
||||||
int leftPalmIndex, rightPalmIndex;
|
collideAgainstOurself();
|
||||||
getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex);
|
}
|
||||||
|
|
||||||
|
void Hand::collideAgainstOtherAvatars() {
|
||||||
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::CollideWithAvatars)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
ModelCollisionList collisions;
|
ModelCollisionList collisions;
|
||||||
// check for collisions
|
float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale();
|
||||||
for (size_t i = 0; i < getNumPalms(); i++) {
|
for (size_t i = 0; i < getNumPalms(); i++) {
|
||||||
PalmData& palm = getPalms()[i];
|
PalmData& palm = getPalms()[i];
|
||||||
if (!palm.isActive()) {
|
if (!palm.isActive()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale();
|
|
||||||
glm::vec3 totalPenetration;
|
glm::vec3 totalPenetration;
|
||||||
|
// check other avatars
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithAvatars)) {
|
foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) {
|
||||||
// check other avatars
|
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
||||||
foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) {
|
if (avatar == _owningAvatar) {
|
||||||
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
// don't collid with our own hands
|
||||||
if (avatar == _owningAvatar) {
|
continue;
|
||||||
// don't collid with our own hands
|
}
|
||||||
continue;
|
collisions.clear();
|
||||||
}
|
if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
|
// Check for palm collisions
|
||||||
// Check for palm collisions
|
glm::vec3 myPalmPosition = palm.getPosition();
|
||||||
glm::vec3 myPalmPosition = palm.getPosition();
|
float palmCollisionDistance = 0.1f;
|
||||||
float palmCollisionDistance = 0.1f;
|
bool wasColliding = palm.getIsCollidingWithPalm();
|
||||||
bool wasColliding = palm.getIsCollidingWithPalm();
|
palm.setIsCollidingWithPalm(false);
|
||||||
palm.setIsCollidingWithPalm(false);
|
// If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound
|
||||||
// If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound
|
for (size_t j = 0; j < avatar->getHand().getNumPalms(); j++) {
|
||||||
for (size_t j = 0; j < avatar->getHand().getNumPalms(); j++) {
|
PalmData& otherPalm = avatar->getHand().getPalms()[j];
|
||||||
PalmData& otherPalm = avatar->getHand().getPalms()[j];
|
if (!otherPalm.isActive()) {
|
||||||
if (!otherPalm.isActive()) {
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
glm::vec3 otherPalmPosition = otherPalm.getPosition();
|
||||||
glm::vec3 otherPalmPosition = otherPalm.getPosition();
|
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
|
||||||
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
|
palm.setIsCollidingWithPalm(true);
|
||||||
palm.setIsCollidingWithPalm(true);
|
if (!wasColliding) {
|
||||||
if (!wasColliding) {
|
const float PALM_COLLIDE_VOLUME = 1.f;
|
||||||
const float PALM_COLLIDE_VOLUME = 1.f;
|
const float PALM_COLLIDE_FREQUENCY = 1000.f;
|
||||||
const float PALM_COLLIDE_FREQUENCY = 1000.f;
|
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
|
||||||
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
|
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
|
||||||
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
|
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
|
||||||
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
|
PALM_COLLIDE_FREQUENCY,
|
||||||
PALM_COLLIDE_FREQUENCY,
|
PALM_COLLIDE_DURATION_MAX,
|
||||||
PALM_COLLIDE_DURATION_MAX,
|
PALM_COLLIDE_DECAY_PER_SAMPLE);
|
||||||
PALM_COLLIDE_DECAY_PER_SAMPLE);
|
// If the other person's palm is in motion, move mine downward to show I was hit
|
||||||
// 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;
|
||||||
const float MIN_VELOCITY_FOR_SLAP = 0.05f;
|
if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) {
|
||||||
if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) {
|
// add slapback here
|
||||||
// add slapback here
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions)) {
|
}
|
||||||
for (int j = 0; j < collisions.size(); ++j) {
|
if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions)) {
|
||||||
// we don't resolve penetrations that would poke the other avatar
|
for (int j = 0; j < collisions.size(); ++j) {
|
||||||
if (!avatar->isPokeable(collisions[j])) {
|
// we don't resolve penetrations that would poke the other avatar
|
||||||
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
if (!avatar->isPokeable(collisions[j])) {
|
||||||
}
|
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// resolve penetration
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HandsCollideWithSelf)) {
|
palm.addToPosition(-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(
|
void Hand::collideAgainstOurself() {
|
||||||
skeletonModel.getLastFreeJointIndex((i == leftPalmIndex) ? skeletonModel.getLeftHandJointIndex() :
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::HandsCollideWithSelf)) {
|
||||||
(i == rightPalmIndex) ? skeletonModel.getRightHandJointIndex() : -1)));
|
return;
|
||||||
if (_owningAvatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions, skipIndex)) {
|
}
|
||||||
for (int j = 0; j < collisions.size(); ++j) {
|
|
||||||
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// resolve penetration
|
||||||
// un-penetrate
|
|
||||||
palm.addToPosition(-totalPenetration);
|
palm.addToPosition(-totalPenetration);
|
||||||
|
|
||||||
// we recycle the collisions container, so we clear it for the next loop
|
|
||||||
collisions.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,9 @@ private:
|
||||||
void renderLeapFingerTrails();
|
void renderLeapFingerTrails();
|
||||||
|
|
||||||
void updateCollisions();
|
void updateCollisions();
|
||||||
|
void collideAgainstOtherAvatars();
|
||||||
|
void collideAgainstOurself();
|
||||||
|
|
||||||
void calculateGeometry();
|
void calculateGeometry();
|
||||||
|
|
||||||
void handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime);
|
void handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime);
|
||||||
|
|
|
@ -1052,6 +1052,9 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) {
|
||||||
setPosition(_position - 0.5f * penetration);
|
setPosition(_position - 0.5f * penetration);
|
||||||
glm::vec3 pushOut = 0.5f * penetration;
|
glm::vec3 pushOut = 0.5f * penetration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// collide their hands against our movable limbs
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue