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) { if (_previousSet) { glm::vec3 positionalVelocity = (_positionalTarget - _previousPositionalTarget) / deltaTimeStep; rigidBody->setLinearVelocity(glmToBullet(positionalVelocity)); } } btTransform worldTrans = rigidBody->getWorldTransform(); worldTrans.setOrigin(glmToBullet(_positionalTarget)); worldTrans.setRotation(glmToBullet(_rotationalTarget)); rigidBody->setWorldTransform(worldTrans); motionState->dirtyInternalKinematicChanges(); _previousPositionalTarget = _positionalTarget; _previousRotationalTarget = _rotationalTarget; _previousSet = true; }); activateBody(); }
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); }