Ejemplo n.º 1
0
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
    if (_kinematic) {
        if (prepareForTractorUpdate(deltaTimeStep)) {
            doKinematicUpdate(deltaTimeStep);
        }
    } else {
        forceBodyNonStatic();
        ObjectActionTractor::updateActionWorker(deltaTimeStep);
    }
}
Ejemplo n.º 2
0
btTypedConstraint* ObjectConstraintBallSocket::getConstraint() {
    btPoint2PointConstraint* constraint { nullptr };
    QUuid otherEntityID;
    glm::vec3 pivotInA;
    glm::vec3 pivotInB;

    withReadLock([&]{
        constraint = static_cast<btPoint2PointConstraint*>(_constraint);
        pivotInA = _pivotInA;
        otherEntityID = _otherID;
        pivotInB = _pivotInB;
    });
    if (constraint) {
        return constraint;
    }

    static QString repeatedBallSocketNoRigidBody = LogHandler::getInstance().addRepeatedMessageRegex(
        "ObjectConstraintBallSocket::getConstraint -- no rigidBody.*");

    btRigidBody* rigidBodyA = getRigidBody();
    if (!rigidBodyA) {
        qCDebug(physics) << "ObjectConstraintBallSocket::getConstraint -- no rigidBodyA";
        return nullptr;
    }

    if (!otherEntityID.isNull()) {
        // This constraint is between two entities... find the other rigid body.

        btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID);
        if (!rigidBodyB) {
            qCDebug(physics) << "ObjectConstraintBallSocket::getConstraint -- no rigidBodyB";
            return nullptr;
        }

        constraint = new btPoint2PointConstraint(*rigidBodyA, *rigidBodyB, glmToBullet(pivotInA), glmToBullet(pivotInB));
    } else {
        // This constraint is between an entity and the world-frame.

        constraint = new btPoint2PointConstraint(*rigidBodyA, glmToBullet(pivotInA));
    }

    withWriteLock([&]{
        _constraint = constraint;
    });

    // if we don't wake up rigidBodyA, we may not send the dynamicData property over the network
    forceBodyNonStatic();
    activateBody();

    updateBallSocket();

    return constraint;
}
Ejemplo n.º 3
0
void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) {
    auto ownerEntity = _ownerEntity.lock();
    if (!ownerEntity) {
        qDebug() << "AvatarActionHold::doKinematicUpdate -- no owning entity";
        return;
    }
    void* physicsInfo = ownerEntity->getPhysicsInfo();
    if (!physicsInfo) {
        qDebug() << "AvatarActionHold::doKinematicUpdate -- no owning physics info";
        return;
    }
    ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
    btRigidBody* rigidBody = motionState ? motionState->getRigidBody() : nullptr;
    if (!rigidBody) {
        qDebug() << "AvatarActionHold::doKinematicUpdate -- no rigidBody";
        return;
    }

    withWriteLock([&]{
        if (_kinematicSetVelocity) {
            rigidBody->setLinearVelocity(glmToBullet(_linearVelocityTarget));
            rigidBody->setAngularVelocity(glmToBullet(_angularVelocityTarget));
        }

        btTransform worldTrans = rigidBody->getWorldTransform();
        worldTrans.setOrigin(glmToBullet(_positionalTarget));
        worldTrans.setRotation(glmToBullet(_rotationalTarget));
        rigidBody->setWorldTransform(worldTrans);

        motionState->dirtyInternalKinematicChanges();

        _previousPositionalTarget = _positionalTarget;
        _previousRotationalTarget = _rotationalTarget;
        _previousDeltaTimeStep = deltaTimeStep;
        _previousSet = true;
    });

    forceBodyNonStatic();
    activateBody(true);
}
Ejemplo n.º 4
0
btTypedConstraint* ObjectConstraintSlider::getConstraint() {
    btSliderConstraint* constraint { nullptr };
    QUuid otherEntityID;
    glm::vec3 pointInA;
    glm::vec3 axisInA;
    glm::vec3 pointInB;
    glm::vec3 axisInB;

    withReadLock([&]{
        constraint = static_cast<btSliderConstraint*>(_constraint);
        pointInA = _pointInA;
        axisInA = _axisInA;
        otherEntityID = _otherID;
        pointInB = _pointInB;
        axisInB = _axisInB;
    });
    if (constraint) {
        return constraint;
    }

    static int repeatMessageID = LogHandler::getInstance().newRepeatedMessageID();

    btRigidBody* rigidBodyA = getRigidBody();
    if (!rigidBodyA) {
        HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintSlider::getConstraint -- no rigidBodyA");
        return nullptr;
    }

    if (glm::length(axisInA) < FLT_EPSILON) {
        qCWarning(physics) << "slider axis cannot be a zero vector";
        axisInA = DEFAULT_SLIDER_AXIS;
    } else {
        axisInA = glm::normalize(axisInA);
    }

    if (!otherEntityID.isNull()) {
        // This slider is between two entities... find the other rigid body.

        if (glm::length(axisInB) < FLT_EPSILON) {
            qCWarning(physics) << "slider axis cannot be a zero vector";
            axisInB = DEFAULT_SLIDER_AXIS;
        } else {
            axisInB = glm::normalize(axisInB);
        }

        glm::quat rotA = glm::rotation(DEFAULT_SLIDER_AXIS, axisInA);
        glm::quat rotB = glm::rotation(DEFAULT_SLIDER_AXIS, axisInB);

        btTransform frameInA(glmToBullet(rotA), glmToBullet(pointInA));
        btTransform frameInB(glmToBullet(rotB), glmToBullet(pointInB));

        btRigidBody* rigidBodyB = getOtherRigidBody(otherEntityID);
        if (!rigidBodyB) {
            HIFI_FCDEBUG_ID(physics(), repeatMessageID, "ObjectConstraintSlider::getConstraint -- no rigidBodyB");
            return nullptr;
        }

        constraint = new btSliderConstraint(*rigidBodyA, *rigidBodyB, frameInA, frameInB, true);
    } else {
        // This slider is between an entity and the world-frame.

        glm::quat rot = glm::rotation(DEFAULT_SLIDER_AXIS, axisInA);

        btTransform frameInA(glmToBullet(rot), glmToBullet(pointInA));

        constraint = new btSliderConstraint(*rigidBodyA, frameInA, true);
    }

    withWriteLock([&]{
        _constraint = constraint;
    });

    // if we don't wake up rigidBodyA, we may not send the dynamicData property over the network
    forceBodyNonStatic();
    activateBody();

    updateSlider();

    return constraint;
}
Ejemplo n.º 5
0
void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) {
    auto ownerEntity = _ownerEntity.lock();
    if (!ownerEntity) {
        qDebug() << "AvatarActionHold::doKinematicUpdate -- no owning entity";
        return;
    }
    if (ownerEntity->getParentID() != QUuid()) {
        // if the held entity has been given a parent, stop acting on it.
        return;
    }

    void* physicsInfo = ownerEntity->getPhysicsInfo();
    if (!physicsInfo) {
        qDebug() << "AvatarActionHold::doKinematicUpdate -- no owning physics info";
        return;
    }
    ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
    btRigidBody* rigidBody = motionState ? motionState->getRigidBody() : nullptr;
    if (!rigidBody) {
        qDebug() << "AvatarActionHold::doKinematicUpdate -- no rigidBody";
        return;
    }

    withWriteLock([&]{
        if (_previousSet &&
            _positionalTarget != _previousPositionalTarget) { // don't average in a zero velocity if we get the same data
            glm::vec3 oneFrameVelocity = (_positionalTarget - _previousPositionalTarget) / deltaTimeStep;

            _measuredLinearVelocities[_measuredLinearVelocitiesIndex++] = oneFrameVelocity;
            if (_measuredLinearVelocitiesIndex >= AvatarActionHold::velocitySmoothFrames) {
                _measuredLinearVelocitiesIndex = 0;
            }
        }

        glm::vec3 measuredLinearVelocity;
        for (int i = 0; i < AvatarActionHold::velocitySmoothFrames; i++) {
            // there is a bit of lag between when someone releases the trigger and when the software reacts to
            // the release.  we calculate the velocity from previous frames but we don't include several
            // of the most recent.
            //
            // if _measuredLinearVelocitiesIndex is
            //     0 -- ignore i of 3 4 5
            //     1 -- ignore i of 4 5 0
            //     2 -- ignore i of 5 0 1
            //     3 -- ignore i of 0 1 2
            //     4 -- ignore i of 1 2 3
            //     5 -- ignore i of 2 3 4

            // This code is now disabled, but I'm leaving it commented-out because I suspect it will come back.
            // if ((i + 1) % AvatarActionHold::velocitySmoothFrames == _measuredLinearVelocitiesIndex ||
            //     (i + 2) % AvatarActionHold::velocitySmoothFrames == _measuredLinearVelocitiesIndex ||
            //     (i + 3) % AvatarActionHold::velocitySmoothFrames == _measuredLinearVelocitiesIndex) {
            //     continue;
            // }

            measuredLinearVelocity += _measuredLinearVelocities[i];
        }
        measuredLinearVelocity /= (float)(AvatarActionHold::velocitySmoothFrames
                                          // - 3  // 3 because of the 3 we skipped, above
                                          );

        if (_kinematicSetVelocity) {
            rigidBody->setLinearVelocity(glmToBullet(measuredLinearVelocity));
            rigidBody->setAngularVelocity(glmToBullet(_angularVelocityTarget));
        }

        btTransform worldTrans = rigidBody->getWorldTransform();
        worldTrans.setOrigin(glmToBullet(_positionalTarget));
        worldTrans.setRotation(glmToBullet(_rotationalTarget));
        rigidBody->setWorldTransform(worldTrans);

        motionState->dirtyInternalKinematicChanges();

        _previousPositionalTarget = _positionalTarget;
        _previousRotationalTarget = _rotationalTarget;
        _previousDeltaTimeStep = deltaTimeStep;
        _previousSet = true;
    });

    forceBodyNonStatic();
    activateBody(true);
}