Ejemplo n.º 1
0
AvatarManager::AvatarManager(QObject* parent) :
    _myAvatar(new MyAvatar(qApp->thread()), [](MyAvatar* ptr) { ptr->deleteLater(); })
{
    // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
    qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");

    auto nodeList = DependencyManager::get<NodeList>();

    // when we hear that the user has ignored an avatar by session UUID
    // immediately remove that avatar instead of waiting for the absence of packets from avatar mixer
    connect(nodeList.data(), &NodeList::ignoredNode, this, [this](const QUuid& nodeID, bool enabled) {
        if (enabled) {
            removeAvatar(nodeID, KillAvatarReason::AvatarIgnored);
        } else {
            auto avatar = std::static_pointer_cast<Avatar>(getAvatarBySessionID(nodeID));
            if (avatar) {
                avatar->createOrb();
            }
        }
    });

    _transitConfig._totalFrames = AVATAR_TRANSIT_FRAME_COUNT;
    _transitConfig._minTriggerDistance = AVATAR_TRANSIT_MIN_TRIGGER_DISTANCE;
    _transitConfig._maxTriggerDistance = AVATAR_TRANSIT_MAX_TRIGGER_DISTANCE;
    _transitConfig._framesPerMeter = AVATAR_TRANSIT_FRAMES_PER_METER;
    _transitConfig._isDistanceBased = AVATAR_TRANSIT_DISTANCE_BASED;
    _transitConfig._abortDistance = AVATAR_TRANSIT_ABORT_DISTANCE;
}
Ejemplo n.º 2
0
void AvatarManager::removeDeadAvatarEntities(const SetOfEntities& deadEntities) {
    auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
    EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
    for (auto entity : deadEntities) {
        QUuid entityOwnerID = entity->getOwningAvatarID();
        AvatarSharedPointer avatar = getAvatarBySessionID(entityOwnerID);
        const bool REQUIRES_REMOVAL_FROM_TREE = false;
        if (avatar) {
            avatar->clearAvatarEntity(entity->getID(), REQUIRES_REMOVAL_FROM_TREE);
        }
        if (entityTree && entity->isMyAvatarEntity()) {
            entityTree->withWriteLock([&] {
                // We only need to delete the direct children (rather than the descendants) because
                // when the child is deleted, it will take care of its own children.  If the child
                // is also an avatar-entity, we'll end up back here.  If it's not, the entity-server
                // will take care of it in the usual way.
                entity->forEachChild([&](SpatiallyNestablePointer child) {
                    EntityItemPointer childEntity = std::dynamic_pointer_cast<EntityItem>(child);
                    if (childEntity) {
                        entityTree->deleteEntity(childEntity->getID(), true, true);
                        if (avatar) {
                            avatar->clearAvatarEntity(childEntity->getID(), REQUIRES_REMOVAL_FROM_TREE);
                        }
                    }
                });
            });
        }
    }
}
Ejemplo n.º 3
0
void AvatarManager::removeDeadAvatarEntities(const SetOfEntities& deadEntities) {
    for (auto entity : deadEntities) {
        QUuid sessionID = entity->getOwningAvatarID();
        AvatarSharedPointer avatar = getAvatarBySessionID(sessionID);
        if (avatar) {
            const bool REQUIRES_REMOVAL_FROM_TREE = false;
            avatar->clearAvatarEntity(entity->getID(), REQUIRES_REMOVAL_FROM_TREE);
        }
    }
}
Ejemplo n.º 4
0
void AvatarActionHold::prepareForPhysicsSimulation() {
    auto avatarManager = DependencyManager::get<AvatarManager>();
    auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));

    if (!holdingAvatar || !holdingAvatar->isMyAvatar()) {
        return;
    }

    withWriteLock([&]{
        glm::vec3 avatarRigidBodyPosition;
        glm::quat avatarRigidBodyRotation;
        getAvatarRigidBodyLocation(avatarRigidBodyPosition, avatarRigidBodyRotation);

        if (_ignoreIK) {
            return;
        }

        glm::vec3 palmPosition;
        glm::quat palmRotation;
        if (_hand == "right") {
            palmPosition = holdingAvatar->getUncachedRightPalmPosition();
            palmRotation = holdingAvatar->getUncachedRightPalmRotation();
        } else {
            palmPosition = holdingAvatar->getUncachedLeftPalmPosition();
            palmRotation = holdingAvatar->getUncachedLeftPalmRotation();
        }


        // determine the difference in translation and rotation between the avatar's
        // rigid body and the palm position.  The avatar's rigid body will be moved by bullet
        // between this call and the call to getTarget, below.  A call to get*PalmPosition in
        // getTarget would get the palm position of the previous location of the avatar (because
        // bullet has moved the av's rigid body but the rigid body's location has not yet been
        // copied out into the Avatar class.
        //glm::quat avatarRotationInverse = glm::inverse(avatarRigidBodyRotation);

        // the offset should be in the frame of the avatar, but something about the order
        // things are updated makes this wrong:
        //   _palmOffsetFromRigidBody = avatarRotationInverse * (palmPosition - avatarRigidBodyPosition);
        // I'll leave it here as a comment in case avatar handling changes.
        _palmOffsetFromRigidBody = palmPosition - avatarRigidBodyPosition;

        // rotation should also be needed, but again, the order of updates makes this unneeded.  leaving
        // code here for future reference.
        // _palmRotationFromRigidBody = avatarRotationInverse * palmRotation;
    });

    activateBody(true);
}
Ejemplo n.º 5
0
bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
                                 glm::vec3& linearVelocity, glm::vec3& angularVelocity,
                                 float& linearTimeScale, float& angularTimeScale) {
    auto avatarManager = DependencyManager::get<AvatarManager>();
    auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));

    if (!holdingAvatar) {
        return false;;
    }

    withReadLock([&]{
        bool isRightHand = (_hand == "right");

        glm::vec3 palmPosition;
        glm::quat palmRotation;

        if (holdingAvatar->isMyAvatar()) {
            std::shared_ptr<MyAvatar> myAvatar = avatarManager->getMyAvatar();

            // fetch the hand controller pose
            controller::Pose pose;
            if (isRightHand) {
                pose = myAvatar->getControllerPoseInWorldFrame(controller::Action::RIGHT_HAND);
            } else {
                pose = myAvatar->getControllerPoseInWorldFrame(controller::Action::LEFT_HAND);
            }

            if (pose.isValid()) {
                linearVelocity = pose.getVelocity();
                angularVelocity = pose.getAngularVelocity();
            }

            if (_ignoreIK && pose.isValid()) {

                // this position/rotation should be the same as the one in scripts/system/libraries/controllers.js
                // otherwise things will do a little hop when you grab them.

                // if (isRightHand) {
                //     pose = myAvatar->getRightHandControllerPoseInAvatarFrame();
                // } else {
                //     pose = myAvatar->getLeftHandControllerPoseInAvatarFrame();
                // }
                // glm::vec3 camRelPos = pose.getTranslation();
                // glm::quat camRelRot = pose.getRotation();

                int camRelIndex = isRightHand ?
                    CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX :
                    CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX;
                glm::vec3 camRelPos = myAvatar->getAbsoluteJointTranslationInObjectFrame(camRelIndex);
                glm::quat camRelRot = myAvatar->getAbsoluteJointRotationInObjectFrame(camRelIndex);

                Transform avatarTransform;
                avatarTransform = myAvatar->getTransform();
                palmPosition = avatarTransform.transform(camRelPos);
                palmRotation = avatarTransform.getRotation() * camRelRot;
            } else {
                glm::vec3 avatarRigidBodyPosition;
                glm::quat avatarRigidBodyRotation;
                getAvatarRigidBodyLocation(avatarRigidBodyPosition, avatarRigidBodyRotation);

                // the offset and rotation between the avatar's rigid body and the palm were determined earlier
                // in prepareForPhysicsSimulation.  At this point, the avatar's rigid body has been moved by bullet
                // and the data in the Avatar class is stale.  This means that the result of get*PalmPosition will
                // be stale.  Instead, determine the current palm position with the current avatar's rigid body
                // location and the saved offsets.

                // this line is more correct but breaks for the current way avatar data is updated.
                // palmPosition = avatarRigidBodyPosition + avatarRigidBodyRotation * _palmOffsetFromRigidBody;
                // instead, use this for now:
                palmPosition = avatarRigidBodyPosition + _palmOffsetFromRigidBody;

                // the item jitters the least by getting the rotation based on the opinion of Avatar.h rather
                // than that of the rigid body.  leaving this next line here for future reference:
                // palmRotation = avatarRigidBodyRotation * _palmRotationFromRigidBody;

                if (isRightHand) {
                    palmRotation = holdingAvatar->getRightPalmRotation();
                } else {
                    palmRotation = holdingAvatar->getLeftPalmRotation();
                }
            }
        } else { // regular avatar
            if (isRightHand) {
                Transform controllerRightTransform = Transform(holdingAvatar->getControllerRightHandMatrix());
                Transform avatarTransform = holdingAvatar->getTransform();
                palmRotation = avatarTransform.getRotation() * controllerRightTransform.getRotation();
                palmPosition = avatarTransform.getTranslation() +
                    (avatarTransform.getRotation() * controllerRightTransform.getTranslation());
            } else {
                Transform controllerLeftTransform = Transform(holdingAvatar->getControllerLeftHandMatrix());
                Transform avatarTransform = holdingAvatar->getTransform();
                palmRotation = avatarTransform.getRotation() * controllerLeftTransform.getRotation();
                palmPosition = avatarTransform.getTranslation() +
                    (avatarTransform.getRotation() * controllerLeftTransform.getTranslation());
            }
        }

        rotation = palmRotation * _relativeRotation;
        position = palmPosition + rotation * _relativePosition;

        // update linearVelocity based on offset via _relativePosition;
        linearVelocity = linearVelocity + glm::cross(angularVelocity, position - palmPosition);

        linearTimeScale = _linearTimeScale;
        angularTimeScale = _angularTimeScale;
    });

    return true;
}
Ejemplo n.º 6
0
float AvatarManager::getAvatarSimulationRate(const QUuid& sessionID, const QString& rateName) const {
    auto avatar = std::static_pointer_cast<Avatar>(getAvatarBySessionID(sessionID));
    return avatar ? avatar->getSimulationRate(rateName) : 0.0f;
}
Ejemplo n.º 7
0
float AvatarManager::getAvatarUpdateRate(const QUuid& sessionID, const QString& rateName) const {
    auto avatar = getAvatarBySessionID(sessionID);
    return avatar ? avatar->getUpdateRate(rateName) : 0.0f;
}
Ejemplo n.º 8
0
bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
                                 glm::vec3& linearVelocity, glm::vec3& angularVelocity) {
    auto avatarManager = DependencyManager::get<AvatarManager>();
    auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));

    if (!holdingAvatar) {
        return false;;
    }

    withReadLock([&]{
        bool isRightHand = (_hand == "right");

        glm::vec3 palmPosition;
        glm::quat palmRotation;

        if (holdingAvatar->isMyAvatar()) {

            // fetch the hand controller pose
            controller::Pose pose;
            if (isRightHand) {
                pose = avatarManager->getMyAvatar()->getRightHandControllerPoseInWorldFrame();
            } else {
                pose = avatarManager->getMyAvatar()->getLeftHandControllerPoseInWorldFrame();
            }

            if (pose.isValid()) {
                linearVelocity = pose.getVelocity();
                angularVelocity = pose.getAngularVelocity();

                if (isRightHand) {
                    pose = avatarManager->getMyAvatar()->getRightHandControllerPoseInAvatarFrame();
                } else {
                    pose = avatarManager->getMyAvatar()->getLeftHandControllerPoseInAvatarFrame();
                }
            }

            if (_ignoreIK && pose.isValid()) {
                Transform avatarTransform;
                auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
                avatarTransform = myAvatar->getTransform();
                palmPosition = avatarTransform.transform(pose.getTranslation() / myAvatar->getTargetScale());
                palmRotation = avatarTransform.getRotation() * pose.getRotation();
            } else {
                glm::vec3 avatarRigidBodyPosition;
                glm::quat avatarRigidBodyRotation;
                getAvatarRigidBodyLocation(avatarRigidBodyPosition, avatarRigidBodyRotation);

                // the offset and rotation between the avatar's rigid body and the palm were determined earlier
                // in prepareForPhysicsSimulation.  At this point, the avatar's rigid body has been moved by bullet
                // and the data in the Avatar class is stale.  This means that the result of get*PalmPosition will
                // be stale.  Instead, determine the current palm position with the current avatar's rigid body
                // location and the saved offsets.

                // this line is more correct but breaks for the current way avatar data is updated.
                // palmPosition = avatarRigidBodyPosition + avatarRigidBodyRotation * _palmOffsetFromRigidBody;
                // instead, use this for now:
                palmPosition = avatarRigidBodyPosition + _palmOffsetFromRigidBody;

                // the item jitters the least by getting the rotation based on the opinion of Avatar.h rather
                // than that of the rigid body.  leaving this next line here for future reference:
                // palmRotation = avatarRigidBodyRotation * _palmRotationFromRigidBody;

                if (isRightHand) {
                    palmRotation = holdingAvatar->getRightPalmRotation();
                } else {
                    palmRotation = holdingAvatar->getLeftPalmRotation();
                }
            }
        } else { // regular avatar
            if (isRightHand) {
                Transform controllerRightTransform = Transform(holdingAvatar->getControllerRightHandMatrix());
                Transform avatarTransform = holdingAvatar->getTransform();
                palmRotation = avatarTransform.getRotation() * controllerRightTransform.getRotation();
                palmPosition = avatarTransform.getTranslation() +
                    (avatarTransform.getRotation() * controllerRightTransform.getTranslation());
            } else {
                Transform controllerLeftTransform = Transform(holdingAvatar->getControllerLeftHandMatrix());
                Transform avatarTransform = holdingAvatar->getTransform();
                palmRotation = avatarTransform.getRotation() * controllerLeftTransform.getRotation();
                palmPosition = avatarTransform.getTranslation() +
                    (avatarTransform.getRotation() * controllerLeftTransform.getTranslation());
            }
        }

        rotation = palmRotation * _relativeRotation;
        position = palmPosition + rotation * _relativePosition;

        // update linearVelocity based on offset via _relativePosition;
        linearVelocity = linearVelocity + glm::cross(angularVelocity, position - palmPosition);
    });

    return true;
}