Exemplo n.º 1
0
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
    if (!_mine) {
        // if a local script isn't updating this, then we are just getting spring-action data over the wire.
        // let the super-class handle it.
        ObjectActionSpring::updateActionWorker(deltaTimeStep);
        return;
    }

    glm::quat rotation;
    glm::vec3 position;
    glm::vec3 offset;
    bool gotLock = withTryReadLock([&]{
        auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
        glm::vec3 palmPosition;
        glm::quat palmRotation;
        if (_hand == "right") {
            palmPosition = myAvatar->getRightPalmPosition();
            palmRotation = myAvatar->getRightPalmRotation();
        } else {
            palmPosition = myAvatar->getLeftPalmPosition();
            palmRotation = myAvatar->getLeftPalmRotation();
        }

        rotation = palmRotation * _relativeRotation;
        offset = rotation * _relativePosition;
        position = palmPosition + offset;
    });

    if (gotLock) {
        gotLock = withTryWriteLock([&]{
            if (_positionalTarget != position || _rotationalTarget != rotation) {
                auto ownerEntity = _ownerEntity.lock();
                if (ownerEntity) {
                    ownerEntity->setActionDataDirty(true);
                }
                _positionalTarget = position;
                _rotationalTarget = rotation;
            }
        });
    }

    if (gotLock) {
        ObjectActionSpring::updateActionWorker(deltaTimeStep);
    }
}
Exemplo n.º 2
0
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
    bool gotLock = false;
    glm::quat rotation;
    glm::vec3 position;
    glm::vec3 offset;

    gotLock = withTryReadLock([&]{
        auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
        glm::vec3 palmPosition;
        glm::quat palmRotation;
        if (_hand == "right") {
            palmPosition = myAvatar->getRightPalmPosition();
            palmRotation = myAvatar->getRightPalmRotation();
        } else {
            palmPosition = myAvatar->getLeftPalmPosition();
            palmRotation = myAvatar->getLeftPalmRotation();
        }

        rotation = palmRotation * _relativeRotation;
        offset = rotation * _relativePosition;
        position = palmPosition + offset;
    });

    if (gotLock) {
        gotLock = withTryWriteLock([&]{
            _positionalTarget = position;
            _rotationalTarget = rotation;
            _positionalTargetSet = true;
            _rotationalTargetSet = true;
            auto ownerEntity = _ownerEntity.lock();
            if (ownerEntity) {
                ownerEntity->setActionDataDirty(true);
            }
        });
    }
    if (gotLock) {
        ObjectActionSpring::updateActionWorker(deltaTimeStep);
    }
}
Exemplo n.º 3
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 (_ignoreIK && pose.isValid()) {
                // We cannot ignore other avatars IK and this is not the point of this option
                // This is meant to make the grabbing behavior more reactive.
                palmPosition = pose.getTranslation();
                palmRotation = 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) {
                palmPosition = holdingAvatar->getRightPalmPosition();
                palmRotation = holdingAvatar->getRightPalmRotation();
            } else {
                palmPosition = holdingAvatar->getLeftPalmPosition();
                palmRotation = holdingAvatar->getLeftPalmRotation();
            }
        }

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

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

    return true;
}