mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-28 17:38:46 +02:00
Merge pull request #13332 from hyperlogic/bug-fix/large-avatar-little-domain-rc68
Large avatars should instantly shrink when entering small height domains
This commit is contained in:
commit
027c4f6b9e
3 changed files with 26 additions and 7 deletions
|
@ -5446,7 +5446,7 @@ void Application::update(float deltaTime) {
|
||||||
// process octree stats packets are sent in between full sends of a scene (this isn't currently true).
|
// process octree stats packets are sent in between full sends of a scene (this isn't currently true).
|
||||||
// We keep physics disabled until we've received a full scene and everything near the avatar in that
|
// We keep physics disabled until we've received a full scene and everything near the avatar in that
|
||||||
// scene is ready to compute its collision shape.
|
// scene is ready to compute its collision shape.
|
||||||
if (nearbyEntitiesAreReadyForPhysics()) {
|
if (nearbyEntitiesAreReadyForPhysics() && getMyAvatar()->isReadyForPhysics()) {
|
||||||
_physicsEnabled = true;
|
_physicsEnabled = true;
|
||||||
getMyAvatar()->updateMotionBehaviorFromMenu();
|
getMyAvatar()->updateMotionBehaviorFromMenu();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2430,11 +2430,16 @@ void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettings
|
||||||
if (_domainMinimumHeight > _domainMaximumHeight) {
|
if (_domainMinimumHeight > _domainMaximumHeight) {
|
||||||
std::swap(_domainMinimumHeight, _domainMaximumHeight);
|
std::swap(_domainMinimumHeight, _domainMaximumHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set avatar current scale
|
// Set avatar current scale
|
||||||
Settings settings;
|
Settings settings;
|
||||||
settings.beginGroup("Avatar");
|
settings.beginGroup("Avatar");
|
||||||
_targetScale = loadSetting(settings, "scale", 1.0f);
|
_targetScale = loadSetting(settings, "scale", 1.0f);
|
||||||
|
|
||||||
|
// clamp the desired _targetScale by the domain limits NOW, don't try to gracefully animate. Because
|
||||||
|
// this might cause our avatar to become embedded in the terrain.
|
||||||
|
_targetScale = getDomainLimitedScale();
|
||||||
|
|
||||||
qCDebug(interfaceapp) << "This domain requires a minimum avatar scale of " << _domainMinimumHeight
|
qCDebug(interfaceapp) << "This domain requires a minimum avatar scale of " << _domainMinimumHeight
|
||||||
<< " and a maximum avatar scale of " << _domainMaximumHeight;
|
<< " and a maximum avatar scale of " << _domainMaximumHeight;
|
||||||
|
|
||||||
|
@ -2443,6 +2448,8 @@ void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettings
|
||||||
setModelScale(_targetScale);
|
setModelScale(_targetScale);
|
||||||
rebuildCollisionShape();
|
rebuildCollisionShape();
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
|
_haveReceivedHeightLimitsFromDomain = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::leaveDomain() {
|
void MyAvatar::leaveDomain() {
|
||||||
|
@ -2460,6 +2467,7 @@ void MyAvatar::saveAvatarScale() {
|
||||||
void MyAvatar::clearScaleRestriction() {
|
void MyAvatar::clearScaleRestriction() {
|
||||||
_domainMinimumHeight = MIN_AVATAR_HEIGHT;
|
_domainMinimumHeight = MIN_AVATAR_HEIGHT;
|
||||||
_domainMaximumHeight = MAX_AVATAR_HEIGHT;
|
_domainMaximumHeight = MAX_AVATAR_HEIGHT;
|
||||||
|
_haveReceivedHeightLimitsFromDomain = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::goToLocation(const QVariant& propertiesVar) {
|
void MyAvatar::goToLocation(const QVariant& propertiesVar) {
|
||||||
|
@ -2577,8 +2585,12 @@ bool MyAvatar::safeLanding(const glm::vec3& position) {
|
||||||
|
|
||||||
// If position is not reliably safe from being stuck by physics, answer true and place a candidate better position in betterPositionOut.
|
// If position is not reliably safe from being stuck by physics, answer true and place a candidate better position in betterPositionOut.
|
||||||
bool MyAvatar::requiresSafeLanding(const glm::vec3& positionIn, glm::vec3& betterPositionOut) {
|
bool MyAvatar::requiresSafeLanding(const glm::vec3& positionIn, glm::vec3& betterPositionOut) {
|
||||||
|
|
||||||
// We begin with utilities and tests. The Algorithm in four parts is below.
|
// We begin with utilities and tests. The Algorithm in four parts is below.
|
||||||
auto halfHeight = _characterController.getCapsuleHalfHeight() + _characterController.getCapsuleRadius();
|
// NOTE: we use estimated avatar height here instead of the bullet capsule halfHeight, because
|
||||||
|
// the domain avatar height limiting might not have taken effect yet on the actual bullet shape.
|
||||||
|
auto halfHeight = 0.5f * getHeight();
|
||||||
|
|
||||||
if (halfHeight == 0) {
|
if (halfHeight == 0) {
|
||||||
return false; // zero height avatar
|
return false; // zero height avatar
|
||||||
}
|
}
|
||||||
|
@ -2587,14 +2599,13 @@ bool MyAvatar::requiresSafeLanding(const glm::vec3& positionIn, glm::vec3& bette
|
||||||
return false; // no entity tree
|
return false; // no entity tree
|
||||||
}
|
}
|
||||||
// More utilities.
|
// More utilities.
|
||||||
const auto offset = getWorldOrientation() *_characterController.getCapsuleLocalOffset();
|
const auto capsuleCenter = positionIn;
|
||||||
const auto capsuleCenter = positionIn + offset;
|
|
||||||
const auto up = _worldUpDirection, down = -up;
|
const auto up = _worldUpDirection, down = -up;
|
||||||
glm::vec3 upperIntersection, upperNormal, lowerIntersection, lowerNormal;
|
glm::vec3 upperIntersection, upperNormal, lowerIntersection, lowerNormal;
|
||||||
EntityItemID upperId, lowerId;
|
EntityItemID upperId, lowerId;
|
||||||
QVector<EntityItemID> include{}, ignore{};
|
QVector<EntityItemID> include{}, ignore{};
|
||||||
auto mustMove = [&] { // Place bottom of capsule at the upperIntersection, and check again based on the capsule center.
|
auto mustMove = [&] { // Place bottom of capsule at the upperIntersection, and check again based on the capsule center.
|
||||||
betterPositionOut = upperIntersection + (up * halfHeight) - offset;
|
betterPositionOut = upperIntersection + (up * halfHeight);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
auto findIntersection = [&](const glm::vec3& startPointIn, const glm::vec3& directionIn, glm::vec3& intersectionOut, EntityItemID& entityIdOut, glm::vec3& normalOut) {
|
auto findIntersection = [&](const glm::vec3& startPointIn, const glm::vec3& directionIn, glm::vec3& intersectionOut, EntityItemID& entityIdOut, glm::vec3& normalOut) {
|
||||||
|
@ -2614,7 +2625,7 @@ bool MyAvatar::requiresSafeLanding(const glm::vec3& positionIn, glm::vec3& bette
|
||||||
EntityItemID entityID = entityTree->findRayIntersection(startPointIn, directionIn, include, ignore, visibleOnly, collidableOnly, precisionPicking,
|
EntityItemID entityID = entityTree->findRayIntersection(startPointIn, directionIn, include, ignore, visibleOnly, collidableOnly, precisionPicking,
|
||||||
element, distance, face, normalOut, extraInfo, lockType, accurateResult);
|
element, distance, face, normalOut, extraInfo, lockType, accurateResult);
|
||||||
if (entityID.isNull()) {
|
if (entityID.isNull()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
intersectionOut = startPointIn + (directionIn * distance);
|
intersectionOut = startPointIn + (directionIn * distance);
|
||||||
entityIdOut = entityID;
|
entityIdOut = entityID;
|
||||||
|
@ -2640,7 +2651,7 @@ bool MyAvatar::requiresSafeLanding(const glm::vec3& positionIn, glm::vec3& bette
|
||||||
// I.e., we are in a clearing between two objects.
|
// I.e., we are in a clearing between two objects.
|
||||||
if (isDown(upperNormal) && isUp(lowerNormal)) {
|
if (isDown(upperNormal) && isUp(lowerNormal)) {
|
||||||
auto spaceBetween = glm::distance(upperIntersection, lowerIntersection);
|
auto spaceBetween = glm::distance(upperIntersection, lowerIntersection);
|
||||||
const float halfHeightFactor = 2.5f; // Until case 5003 is fixed (and maybe after?), we need a fudge factor. Also account for content modelers not being precise.
|
const float halfHeightFactor = 2.25f; // Until case 5003 is fixed (and maybe after?), we need a fudge factor. Also account for content modelers not being precise.
|
||||||
if (spaceBetween > (halfHeightFactor * halfHeight)) {
|
if (spaceBetween > (halfHeightFactor * halfHeight)) {
|
||||||
// There is room for us to fit in that clearing. If there wasn't, physics would oscilate us between the objects above and below.
|
// There is room for us to fit in that clearing. If there wasn't, physics would oscilate us between the objects above and below.
|
||||||
// We're now going to iterate upwards through successive upperIntersections, testing to see if we're contained within the top surface of some entity.
|
// We're now going to iterate upwards through successive upperIntersections, testing to see if we're contained within the top surface of some entity.
|
||||||
|
@ -3090,6 +3101,10 @@ float MyAvatar::getWalkSpeed() const {
|
||||||
return _walkSpeed.get() * _walkSpeedScalar;
|
return _walkSpeed.get() * _walkSpeedScalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MyAvatar::isReadyForPhysics() const {
|
||||||
|
return qApp->isServerlessMode() || _haveReceivedHeightLimitsFromDomain;
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::setSprintMode(bool sprint) {
|
void MyAvatar::setSprintMode(bool sprint) {
|
||||||
_walkSpeedScalar = sprint ? AVATAR_SPRINT_SPEED_SCALAR : AVATAR_WALK_SPEED_SCALAR;
|
_walkSpeedScalar = sprint ? AVATAR_SPRINT_SPEED_SCALAR : AVATAR_WALK_SPEED_SCALAR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1015,6 +1015,8 @@ public:
|
||||||
|
|
||||||
QVector<QString> getScriptUrls();
|
QVector<QString> getScriptUrls();
|
||||||
|
|
||||||
|
bool isReadyForPhysics() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -1610,6 +1612,8 @@ private:
|
||||||
|
|
||||||
// load avatar scripts once when rig is ready
|
// load avatar scripts once when rig is ready
|
||||||
bool _shouldLoadScripts { false };
|
bool _shouldLoadScripts { false };
|
||||||
|
|
||||||
|
bool _haveReceivedHeightLimitsFromDomain = { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);
|
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);
|
||||||
|
|
Loading…
Reference in a new issue