예제 #1
0
파일: Avatar.cpp 프로젝트: MojoK/hifi
bool Avatar::findParticleCollisions(const glm::vec3& particleCenter, float particleRadius, CollisionList& collisions) {
    if (_collisionFlags & COLLISION_GROUP_PARTICLES) {
        return false;
    }
    bool collided = false;
    // first do the hand collisions
    const HandData* handData = getHandData();
    if (handData) {
        for (int i = 0; i < NUM_HANDS; i++) {
            const PalmData* palm = handData->getPalm(i);
            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) {
                    const FingerData& finger = (palm->getFingers())[f];
                    if (finger.isActive()) {
                        // compute finger axis
                        glm::vec3 fingerTip = finger.getTipPosition();
                        glm::vec3 fingerRoot = finger.getRootPosition();
                        fingerAxis = glm::normalize(fingerTip - fingerRoot);
                        break;
                    }
                }

                int jointIndex = -1;
                glm::vec3 handPosition;
                if (i == 0) {
                    _skeletonModel.getLeftHandPosition(handPosition);
                    jointIndex = _skeletonModel.getLeftHandJointIndex();
                }
                else {
                    _skeletonModel.getRightHandPosition(handPosition);
                    jointIndex = _skeletonModel.getRightHandJointIndex();
                }
                glm::vec3 diskCenter = handPosition + HAND_PADDLE_OFFSET * fingerAxis;
                glm::vec3 diskNormal = palm->getNormal();
                const float DISK_THICKNESS = 0.08f;

                // collide against the disk
                glm::vec3 penetration;
                if (findSphereDiskPenetration(particleCenter, particleRadius, 
                            diskCenter, HAND_PADDLE_RADIUS, DISK_THICKNESS, diskNormal,
                            penetration)) {
                    CollisionInfo* collision = collisions.getNewCollision();
                    if (collision) {
                        collision->_type = PADDLE_HAND_COLLISION;
                        collision->_flags = jointIndex;
                        collision->_penetration = penetration;
                        collision->_addedVelocity = palm->getVelocity();
                        collided = true;
                    } else {
                        // collisions are full, so we might as well bail now
                        return collided;
                    }
                }
            }
        }
    }
    // then collide against the models
    int preNumCollisions = collisions.size();
    if (_skeletonModel.findSphereCollisions(particleCenter, particleRadius, collisions)) {
        // the Model doesn't have velocity info, so we have to set it for each new collision
        int postNumCollisions = collisions.size();
        for (int i = preNumCollisions; i < postNumCollisions; ++i) {
            CollisionInfo* collision = collisions.getCollision(i);
            collision->_penetration /= (float)(TREE_SCALE);
            collision->_addedVelocity = getVelocity();
        }
        collided = true;
    }
    return collided;
}