limit MyAvatar scale to limits from domain settings

This commit is contained in:
Stephen Birarda 2016-11-10 13:27:13 -08:00
parent 563322d08d
commit 77ede81fc9
6 changed files with 92 additions and 19 deletions

View file

@ -17,7 +17,7 @@
#include <AvatarData.h>
#include <ScriptEngine.h>
class ScriptableAvatar : public AvatarData, public Dependency{
class ScriptableAvatar : public AvatarData, public Dependency {
Q_OBJECT
public:
@ -39,4 +39,4 @@ private:
std::shared_ptr<AnimSkeleton> _animSkeleton;
};
#endif // hifi_ScriptableAvatar_h
#endif // hifi_ScriptableAvatar_h

View file

@ -874,17 +874,17 @@
"name": "min_avatar_scale",
"type": "double",
"label": "Minimum Avatar Scale (meters)",
"help": "Limits the scale of avatars in your domain",
"placeholder": 0.01,
"default": 0.01
"help": "Limits the scale of avatars in your domain. Must be at least than 0.005.",
"placeholder": 0.25,
"default": 0.25
},
{
"name": "max_avatar_scale",
"type": "double",
"label": "Maximum Avatar Scale (meters)",
"help": "Limits the scale of avatars in your domain",
"placeholder": 4.0,
"default": 4.0
"help": "Limits the scale of avatars in your domain. Cannot be greater than 1000.",
"placeholder": 3.0,
"default": 3.0
}
]
},

View file

@ -130,6 +130,15 @@ MyAvatar::MyAvatar(RigPointer rig) :
connect(DependencyManager::get<AddressManager>().data(), &AddressManager::locationChangeRequired,
this, static_cast<SlotType>(&MyAvatar::goToLocation));
// handle scale constraints imposed on us by the domain-server
auto& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
// when we connect to a domain and retrieve its settings, we restrict our max/min scale based on those settings
connect(&domainHandler, &DomainHandler::settingsReceived, this, &MyAvatar::restrictScaleFromDomainSettings);
// when we leave a domain we lift whatever restrictions that domain may have placed on our scale
connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, &MyAvatar::clearScaleRestriction);
_characterController.setEnabled(true);
_bodySensorMatrix = deriveBodyFromHMDSensor();
@ -1824,24 +1833,79 @@ bool findAvatarAvatarPenetration(const glm::vec3 positionA, float radiusA, float
}
void MyAvatar::increaseSize() {
if ((1.0f + SCALING_RATIO) * _targetScale < MAX_AVATAR_SCALE) {
_targetScale *= (1.0f + SCALING_RATIO);
qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale);
// clamp the target scale to the maximum allowable scale in the domain
float updatedTargetScale = _targetScale * (1.0f + SCALING_RATIO);
if (updatedTargetScale > _domainMaximumScale) {
qCDebug(interfaceapp, "Forced scale to %f since %f would be larger than allowed maximum",
_domainMaximumScale, updatedTargetScale);
updatedTargetScale = _domainMaximumScale;
}
setTargetScale(updatedTargetScale);
qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale);
}
void MyAvatar::decreaseSize() {
if (MIN_AVATAR_SCALE < (1.0f - SCALING_RATIO) * _targetScale) {
_targetScale *= (1.0f - SCALING_RATIO);
qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale);
// clamp the target scale to the minimum allowable scale in the domain
float updatedTargetScale = _targetScale * (1.0f - SCALING_RATIO);
if (updatedTargetScale < _domainMinimumScale) {
qCDebug(interfaceapp, "Forced scale to %f since %f would be smaller than allowed minimum",
_domainMinimumScale, updatedTargetScale);
updatedTargetScale = _domainMinimumScale;
}
setTargetScale(updatedTargetScale);
qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale);
}
void MyAvatar::resetSize() {
_targetScale = 1.0f;
// if the default
const float DEFAULT_AVATAR_SCALE = 1.0f;
float allowedDefaultScale = glm::clamp(DEFAULT_AVATAR_SCALE, _domainMinimumScale, _domainMaximumScale);
if (allowedDefaultScale != DEFAULT_AVATAR_SCALE) {
qCDebug(interfaceapp, "Forcing scale to %f since %f is not an allowed avatar scale by the domain",
allowedDefaultScale, DEFAULT_AVATAR_SCALE);
}
setTargetScale(allowedDefaultScale);
qCDebug(interfaceapp, "Reset scale to %f", (double)_targetScale);
}
void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettingsObject) {
// pull out the minimum and maximum scale and set them to restrict our scale
static const QString AVATAR_SETTINGS_KEY = "avatars";
auto avatarsObject = domainSettingsObject[AVATAR_SETTINGS_KEY].toObject();
static const QString MIN_SCALE_OPTION = "min_avatar_scale";
float settingMinScale = avatarsObject[MIN_SCALE_OPTION].toDouble(MIN_AVATAR_SCALE);
setDomainMinimumScale(settingMinScale);
static const QString MAX_SCALE_OPTION = "max_avatar_scale";
float settingMaxScale = avatarsObject[MAX_SCALE_OPTION].toDouble(MAX_AVATAR_SCALE);
setDomainMaximumScale(settingMaxScale);
// debug to log if this avatar's scale in this domain will be clamped
auto clampedScale = glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale);
if (_targetScale != clampedScale) {
qCDebug(interfaceapp, "Avatar scale will be clamped to %f because %f is not allowed by current domain",
clampedScale, _targetScale);
}
}
void MyAvatar::clearScaleRestriction() {
_domainMinimumScale = MIN_AVATAR_SCALE;
_domainMaximumScale = MAX_AVATAR_SCALE;
}
void MyAvatar::goToLocation(const QVariant& propertiesVar) {
qCDebug(interfaceapp, "MyAvatar QML goToLocation");

View file

@ -292,6 +292,9 @@ public slots:
bool shouldFaceLocation = false);
void goToLocation(const QVariant& properties);
void restrictScaleFromDomainSettings(const QJsonObject& domainSettingsObject);
void clearScaleRestriction();
// Set/Get update the thrust that will move the avatar around
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
glm::vec3 getThrust() { return _thrust; };

View file

@ -210,7 +210,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
packFloatAngleToTwoByte((uint8_t*)(header->localOrientation + 0), bodyEulerAngles.y);
packFloatAngleToTwoByte((uint8_t*)(header->localOrientation + 1), bodyEulerAngles.x);
packFloatAngleToTwoByte((uint8_t*)(header->localOrientation + 2), bodyEulerAngles.z);
packFloatRatioToTwoByte((uint8_t*)(&header->scale), _targetScale);
packFloatRatioToTwoByte((uint8_t*)(&header->scale), getDomainLimitedScale());
header->lookAtPosition[0] = _headData->_lookAtPosition.x;
header->lookAtPosition[1] = _headData->_lookAtPosition.y;
header->lookAtPosition[2] = _headData->_lookAtPosition.z;
@ -516,7 +516,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
}
return buffer.size();
}
_targetScale = std::max(MIN_AVATAR_SCALE, std::min(MAX_AVATAR_SCALE, scale));
setTargetScale(scale);
glm::vec3 lookAt = glm::vec3(header->lookAtPosition[0], header->lookAtPosition[1], header->lookAtPosition[2]);
if (isNaN(lookAt)) {
@ -1439,7 +1439,7 @@ QJsonObject AvatarData::toJson() const {
if (!success) {
qDebug() << "Warning -- AvatarData::toJson couldn't get avatar transform";
}
avatarTransform.setScale(getTargetScale());
avatarTransform.setScale(getDomainLimitedScale());
if (recordingBasis) {
root[JSON_AVATAR_BASIS] = Transform::toJson(*recordingBasis);
// Find the relative transform
@ -1451,7 +1451,7 @@ QJsonObject AvatarData::toJson() const {
root[JSON_AVATAR_RELATIVE] = Transform::toJson(avatarTransform);
}
auto scale = getTargetScale();
auto scale = getDomainLimitedScale();
if (scale != 1.0f) {
root[JSON_AVATAR_SCALE] = scale;
}

View file

@ -243,6 +243,10 @@ public:
void setTargetScale(float targetScale);
void setTargetScaleVerbose(float targetScale);
float getDomainLimitedScale() const { return glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); }
void setDomainMinimumScale(float domainMinimumScale) { _domainMinimumScale = std::max(domainMinimumScale, MIN_AVATAR_SCALE); }
void setDomainMaximumScale(float domainMaximumScale) { _domainMaximumScale = std::min(domainMaximumScale, MAX_AVATAR_SCALE); }
// Hand State
Q_INVOKABLE void setHandState(char s) { _handState = s; }
Q_INVOKABLE char getHandState() const { return _handState; }
@ -377,6 +381,8 @@ protected:
// Body scale
float _targetScale;
float _domainMinimumScale { MIN_AVATAR_SCALE };
float _domainMaximumScale { MAX_AVATAR_SCALE };
// Hand state (are we grabbing something or not)
char _handState;