mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 19:59:28 +02:00
Select avatar to look using API. Blink when look at change
This commit is contained in:
parent
68e287628c
commit
fc018257e1
5 changed files with 52 additions and 16 deletions
|
@ -2188,15 +2188,20 @@ void MyAvatar::computeMyLookAtTarget(const AvatarHash& hash) {
|
||||||
foreach (const AvatarSharedPointer& avatarData, hash) {
|
foreach (const AvatarSharedPointer& avatarData, hash) {
|
||||||
std::shared_ptr<Avatar> avatar = std::static_pointer_cast<Avatar>(avatarData);
|
std::shared_ptr<Avatar> avatar = std::static_pointer_cast<Avatar>(avatarData);
|
||||||
if (!avatar->isMyAvatar() && avatar->isInitialized()) {
|
if (!avatar->isMyAvatar() && avatar->isInitialized()) {
|
||||||
glm::vec3 otherForward = avatar->getHead()->getForwardDirection();
|
if (_forceTargetAvatarID.isNull() || avatar->getID() != _forceTargetAvatarID) {
|
||||||
glm::vec3 otherPosition = avatar->getHead()->getEyePosition();
|
glm::vec3 otherForward = avatar->getHead()->getForwardDirection();
|
||||||
const float TIME_WITHOUT_TALKING_THRESHOLD = 1.0f;
|
glm::vec3 otherPosition = avatar->getHead()->getEyePosition();
|
||||||
bool otherIsTalking = avatar->getHead()->getTimeWithoutTalking() <= TIME_WITHOUT_TALKING_THRESHOLD;
|
const float TIME_WITHOUT_TALKING_THRESHOLD = 1.0f;
|
||||||
bool lookingAtOtherAlready = _lookAtTargetAvatar.lock().get() == avatar.get();
|
bool otherIsTalking = avatar->getHead()->getTimeWithoutTalking() <= TIME_WITHOUT_TALKING_THRESHOLD;
|
||||||
float cost = lookAtCostFunction(myForward, myPosition, otherForward, otherPosition, otherIsTalking, lookingAtOtherAlready);
|
bool lookingAtOtherAlready = _lookAtTargetAvatar.lock().get() == avatar.get();
|
||||||
if (cost < bestCost) {
|
float cost = lookAtCostFunction(myForward, myPosition, otherForward, otherPosition, otherIsTalking, lookingAtOtherAlready);
|
||||||
bestCost = cost;
|
if (cost < bestCost) {
|
||||||
|
bestCost = cost;
|
||||||
|
bestAvatar = avatar;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
bestAvatar = avatar;
|
bestAvatar = avatar;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6838,3 +6843,10 @@ void MyAvatar::resetPointAt() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyAvatar::setLookAtAvatarID(const QUuid& avatarID) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
BLOCKING_INVOKE_METHOD(this, "setLookAtAvatarID",
|
||||||
|
Q_ARG(const QUuid&, avatarID));
|
||||||
|
}
|
||||||
|
_forceTargetAvatarID = avatarID;
|
||||||
|
}
|
|
@ -971,6 +971,7 @@ public:
|
||||||
* @param {Uuid} entityID - The entity that the hand touch effect will be enabled for.
|
* @param {Uuid} entityID - The entity that the hand touch effect will be enabled for.
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void enableHandTouchForID(const QUuid& entityID);
|
Q_INVOKABLE void enableHandTouchForID(const QUuid& entityID);
|
||||||
|
Q_INVOKABLE void setLookAtAvatarID(const QUuid& avatarID);
|
||||||
|
|
||||||
bool useAdvancedMovementControls() const { return _useAdvancedMovementControls.get(); }
|
bool useAdvancedMovementControls() const { return _useAdvancedMovementControls.get(); }
|
||||||
void setUseAdvancedMovementControls(bool useAdvancedMovementControls)
|
void setUseAdvancedMovementControls(bool useAdvancedMovementControls)
|
||||||
|
@ -2656,6 +2657,7 @@ private:
|
||||||
|
|
||||||
AvatarWeakPointer _lookAtTargetAvatar;
|
AvatarWeakPointer _lookAtTargetAvatar;
|
||||||
glm::vec3 _targetAvatarPosition;
|
glm::vec3 _targetAvatarPosition;
|
||||||
|
QUuid _forceTargetAvatarID;
|
||||||
bool _shouldRender { true };
|
bool _shouldRender { true };
|
||||||
float _oculusYawOffset;
|
float _oculusYawOffset;
|
||||||
|
|
||||||
|
|
|
@ -96,10 +96,13 @@ void Head::simulate(float deltaTime) {
|
||||||
// no blinking when brows are raised; blink less with increasing loudness
|
// no blinking when brows are raised; blink less with increasing loudness
|
||||||
const float BASE_BLINK_RATE = 15.0f / 60.0f;
|
const float BASE_BLINK_RATE = 15.0f / 60.0f;
|
||||||
const float ROOT_LOUDNESS_TO_BLINK_INTERVAL = 0.25f;
|
const float ROOT_LOUDNESS_TO_BLINK_INTERVAL = 0.25f;
|
||||||
if (forceBlink || (_browAudioLift < EPSILON && shouldDo(glm::max(1.0f, sqrt(fabs(_averageLoudness - _longTermAverageLoudness)) *
|
if (_forceBlink || forceBlink || (_browAudioLift < EPSILON && shouldDo(glm::max(1.0f, sqrt(fabs(_averageLoudness - _longTermAverageLoudness)) *
|
||||||
ROOT_LOUDNESS_TO_BLINK_INTERVAL) / BASE_BLINK_RATE, deltaTime))) {
|
ROOT_LOUDNESS_TO_BLINK_INTERVAL) / BASE_BLINK_RATE, deltaTime))) {
|
||||||
float randSpeedVariability = randFloat();
|
float randSpeedVariability = randFloat();
|
||||||
float eyeBlinkVelocity = BLINK_SPEED + randSpeedVariability * BLINK_SPEED_VARIABILITY;
|
float eyeBlinkVelocity = BLINK_SPEED + randSpeedVariability * BLINK_SPEED_VARIABILITY;
|
||||||
|
if (_forceBlink) {
|
||||||
|
eyeBlinkVelocity = 0.5f * eyeBlinkVelocity;
|
||||||
|
}
|
||||||
_leftEyeBlinkVelocity = eyeBlinkVelocity;
|
_leftEyeBlinkVelocity = eyeBlinkVelocity;
|
||||||
_rightEyeBlinkVelocity = eyeBlinkVelocity;
|
_rightEyeBlinkVelocity = eyeBlinkVelocity;
|
||||||
if (randFloat() < 0.5f) {
|
if (randFloat() < 0.5f) {
|
||||||
|
@ -114,7 +117,7 @@ void Head::simulate(float deltaTime) {
|
||||||
|
|
||||||
if (_leftEyeBlink == FULLY_CLOSED) {
|
if (_leftEyeBlink == FULLY_CLOSED) {
|
||||||
_leftEyeBlinkVelocity = -BLINK_SPEED;
|
_leftEyeBlinkVelocity = -BLINK_SPEED;
|
||||||
|
updateEyeLookAt();
|
||||||
} else if (_leftEyeBlink == FULLY_OPEN) {
|
} else if (_leftEyeBlink == FULLY_OPEN) {
|
||||||
_leftEyeBlinkVelocity = 0.0f;
|
_leftEyeBlinkVelocity = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,3 +233,19 @@ void HeadData::setHasProceduralEyeMovement(bool hasProceduralEyeMovement) {
|
||||||
void HeadData::setFaceTrackerConnected(bool value) {
|
void HeadData::setFaceTrackerConnected(bool value) {
|
||||||
_isFaceTrackerConnected = value;
|
_isFaceTrackerConnected = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HeadData::setLookAtPosition(const glm::vec3& lookAtPosition) {
|
||||||
|
if (_requestLookAtPosition != lookAtPosition) {
|
||||||
|
_lookAtPositionChanged = usecTimestampNow();
|
||||||
|
glm::vec3 oldAvatarLookAtVector = _requestLookAtPosition - _owningAvatar->getWorldPosition();
|
||||||
|
glm::vec3 newAvatarLookAtVector = lookAtPosition - _owningAvatar->getWorldPosition();
|
||||||
|
const float MIN_BLINK_ANGLE = 0.35f; // 20 degrees
|
||||||
|
_forceBlink = angleBetween(oldAvatarLookAtVector, newAvatarLookAtVector) > MIN_BLINK_ANGLE;
|
||||||
|
_lookAtUpdated = false;
|
||||||
|
}
|
||||||
|
_requestLookAtPosition = lookAtPosition;
|
||||||
|
if (_lookAtUpdated) {
|
||||||
|
_forceBlink = false;
|
||||||
|
_lookAtPosition = lookAtPosition;
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,12 +64,7 @@ public:
|
||||||
void setBlendshapeCoefficients(const QVector<float>& blendshapeCoefficients) { _blendshapeCoefficients = blendshapeCoefficients; }
|
void setBlendshapeCoefficients(const QVector<float>& blendshapeCoefficients) { _blendshapeCoefficients = blendshapeCoefficients; }
|
||||||
|
|
||||||
const glm::vec3& getLookAtPosition() const { return _lookAtPosition; }
|
const glm::vec3& getLookAtPosition() const { return _lookAtPosition; }
|
||||||
void setLookAtPosition(const glm::vec3& lookAtPosition) {
|
void setLookAtPosition(const glm::vec3& lookAtPosition);
|
||||||
if (_lookAtPosition != lookAtPosition) {
|
|
||||||
_lookAtPositionChanged = usecTimestampNow();
|
|
||||||
}
|
|
||||||
_lookAtPosition = lookAtPosition;
|
|
||||||
}
|
|
||||||
bool lookAtPositionChangedSince(quint64 time) { return _lookAtPositionChanged >= time; }
|
bool lookAtPositionChangedSince(quint64 time) { return _lookAtPositionChanged >= time; }
|
||||||
|
|
||||||
bool getHasProceduralEyeFaceMovement() const;
|
bool getHasProceduralEyeFaceMovement() const;
|
||||||
|
@ -84,6 +79,11 @@ public:
|
||||||
void setFaceTrackerConnected(bool value);
|
void setFaceTrackerConnected(bool value);
|
||||||
bool getFaceTrackerConnected() const { return _isFaceTrackerConnected; }
|
bool getFaceTrackerConnected() const { return _isFaceTrackerConnected; }
|
||||||
|
|
||||||
|
void updateEyeLookAt() {
|
||||||
|
_lookAtPosition = _requestLookAtPosition;
|
||||||
|
_lookAtUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
friend class AvatarData;
|
friend class AvatarData;
|
||||||
|
|
||||||
QJsonObject toJson() const;
|
QJsonObject toJson() const;
|
||||||
|
@ -95,6 +95,7 @@ protected:
|
||||||
float _basePitch;
|
float _basePitch;
|
||||||
float _baseRoll;
|
float _baseRoll;
|
||||||
|
|
||||||
|
glm::vec3 _requestLookAtPosition;
|
||||||
glm::vec3 _lookAtPosition;
|
glm::vec3 _lookAtPosition;
|
||||||
quint64 _lookAtPositionChanged { 0 };
|
quint64 _lookAtPositionChanged { 0 };
|
||||||
|
|
||||||
|
@ -115,6 +116,8 @@ protected:
|
||||||
QVector<float> _summedBlendshapeCoefficients;
|
QVector<float> _summedBlendshapeCoefficients;
|
||||||
QMap<QString, int> _blendshapeLookupMap;
|
QMap<QString, int> _blendshapeLookupMap;
|
||||||
AvatarData* _owningAvatar;
|
AvatarData* _owningAvatar;
|
||||||
|
bool _forceBlink { false };
|
||||||
|
bool _lookAtUpdated { false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// privatize copy ctor and assignment operator so copies of this object cannot be made
|
// privatize copy ctor and assignment operator so copies of this object cannot be made
|
||||||
|
|
Loading…
Reference in a new issue