Only resolve our hand collisions that would not move the other avatar.

This helps us only penetrate the moveable parts of other avatars.
This commit is contained in:
Andrew Meadows 2014-02-11 09:23:40 -08:00
parent 861778347f
commit 887fa0c938
5 changed files with 31 additions and 3 deletions

View file

@ -443,9 +443,16 @@ float Avatar::getHeight() const {
return extents.maximum.y - extents.minimum.y;
}
bool Avatar::poke(ModelCollisionInfo& collision) {
// ATM poke() can only affect the Skeleton (not the head)
bool Avatar::isPokeable(ModelCollisionInfo& collision) const {
// ATM only the Skeleton is pokeable
// TODO: make poke affect head
if (collision._model == &_skeletonModel && collision._jointIndex != -1) {
return _skeletonModel.isPokeable(collision);
}
return false;
}
bool Avatar::poke(ModelCollisionInfo& collision) {
if (collision._model == &_skeletonModel && collision._jointIndex != -1) {
return _skeletonModel.poke(collision);
}

View file

@ -128,6 +128,9 @@ public:
float getHeight() const;
/// \return true if we expect the avatar would move as a result of the collision
bool isPokeable(ModelCollisionInfo& collision) const;
/// \param collision a data structure for storing info about collisions against Models
/// \return true if the collision affects the Avatar models
bool poke(ModelCollisionInfo& collision);

View file

@ -224,7 +224,8 @@ void Hand::updateCollisions() {
}
if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, collisions)) {
for (int j = 0; j < collisions.size(); ++j) {
if (!avatar->poke(collisions[j])) {
// we don't resolve penetrations that would poke the other avatar
if (!avatar->isPokeable(collisions[j])) {
totalPenetration = addPenetrations(totalPenetration, collisions[j]._penetration);
}
}

View file

@ -713,6 +713,20 @@ void Model::renderCollisionProxies(float alpha) {
glPopMatrix();
}
bool Model::isPokeable(ModelCollisionInfo& collision) const {
// the joint is pokable by a collision if it exists and is free to move
const FBXJoint& joint = _geometry->getFBXGeometry().joints[collision._jointIndex];
if (joint.parentIndex == -1 ||
_jointStates.isEmpty())
{
return false;
}
// an empty freeLineage means the joint can't move
const FBXGeometry& geometry = _geometry->getFBXGeometry();
const QVector<int>& freeLineage = geometry.joints.at(collision._jointIndex).freeLineage;
return !freeLineage.isEmpty();
}
bool Model::poke(ModelCollisionInfo& collision) {
// This needs work. At the moment it can wiggle joints that are free to move (such as arms)
// but unmovable joints (such as torso) cannot be influenced at all.

View file

@ -164,6 +164,9 @@ public:
void renderCollisionProxies(float alpha);
/// \return true if the collision would move the model
bool isPokeable(ModelCollisionInfo& collision) const;
/// \param collisionInfo info about the collision
/// \return true if collision affects the Model
bool poke(ModelCollisionInfo& collisionInfo);