diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d9cbdd9b06..901b300277 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2463,7 +2463,7 @@ void Application::paintGL() { PerformanceTimer perfTimer("CameraUpdates"); auto myAvatar = getMyAvatar(); - boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; + boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; // The render mode is default or mirror if the camera is in mirror mode, assigned further below renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; @@ -2516,14 +2516,14 @@ void Application::paintGL() { hmdOffset.x = -hmdOffset.x; _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0) + + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + mirrorBodyOrientation * hmdOffset); } else { _myCamera.setOrientation(myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0) + + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 91af85a108..eca61d95c8 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -558,7 +558,7 @@ void MyAvatar::simulate(float deltaTime) { headPosition = getPosition(); } head->setPosition(headPosition); - head->setScale(getUniformScale()); + head->setScale(getModelScale()); head->simulate(deltaTime); } @@ -1223,7 +1223,7 @@ void MyAvatar::updateLookAtTargetAvatar() { float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition); avatar->setIsLookAtTarget(false); if (!avatar->isMyAvatar() && avatar->isInitialized() && - (distanceTo < GREATEST_LOOKING_AT_DISTANCE * getUniformScale())) { + (distanceTo < GREATEST_LOOKING_AT_DISTANCE * getModelScale())) { float radius = glm::length(avatar->getHead()->getEyePosition() - avatar->getHead()->getRightEyePosition()); float angleTo = coneSphereAngle(getHead()->getEyePosition(), lookForward, avatar->getHead()->getEyePosition(), radius); if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) { @@ -1465,7 +1465,7 @@ glm::vec3 MyAvatar::getSkeletonPosition() const { void MyAvatar::rebuildCollisionShape() { // compute localAABox - float scale = getUniformScale(); + float scale = getModelScale(); float radius = scale * _skeletonModel->getBoundingCapsuleRadius(); float height = scale * _skeletonModel->getBoundingCapsuleHeight() + 2.0f * radius; glm::vec3 corner(-radius, -0.5f * height, -radius); @@ -1896,7 +1896,7 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) { const float RENDER_HEAD_CUTOFF_DISTANCE = 0.3f; bool MyAvatar::cameraInsideHead(const glm::vec3& cameraPosition) const { - return glm::length(cameraPosition - getHeadPosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getUniformScale()); + return glm::length(cameraPosition - getHeadPosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getModelScale()); } bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const { @@ -2251,7 +2251,7 @@ void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettings _targetScale = clampedScale; } - setScale(glm::vec3(_targetScale)); + setModelScale(_targetScale); rebuildCollisionShape(); settings.endGroup(); } @@ -2940,6 +2940,30 @@ glm::mat4 MyAvatar::computeCameraRelativeHandControllerMatrix(const glm::mat4& c return glm::inverse(avatarMatrix) * controllerWorldMatrix; } +glm::vec3 MyAvatar::getAbsoluteJointScaleInObjectFrame(int index) const { + if (index < 0) { + index += numeric_limits::max() + 1; // 65536 + } + + // only sensor to world matrix has non identity scale. + switch (index) { + case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX: { + auto pose = getControllerPoseInSensorFrame(controller::Action::LEFT_HAND); + glm::mat4 controllerSensorMatrix = createMatFromQuatAndPos(pose.rotation, pose.translation); + glm::mat4 result = computeCameraRelativeHandControllerMatrix(controllerSensorMatrix); + return extractScale(result); + } + case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX: { + auto pose = getControllerPoseInSensorFrame(controller::Action::RIGHT_HAND); + glm::mat4 controllerSensorMatrix = createMatFromQuatAndPos(pose.rotation, pose.translation); + glm::mat4 result = computeCameraRelativeHandControllerMatrix(controllerSensorMatrix); + return extractScale(result); + } + default: + return Avatar::getAbsoluteJointScaleInObjectFrame(index); + } +} + glm::quat MyAvatar::getAbsoluteJointRotationInObjectFrame(int index) const { if (index < 0) { index += numeric_limits::max() + 1; // 65536 diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 1c7cd559a6..07ad61b271 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -513,6 +513,7 @@ public: Q_INVOKABLE void setCharacterControllerEnabled(bool enabled); // deprecated Q_INVOKABLE bool getCharacterControllerEnabled(); // deprecated + virtual glm::vec3 getAbsoluteJointScaleInObjectFrame(int index) const override; virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 8f59d46cc8..fb451f6b0e 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -193,8 +193,8 @@ void setupPreferences() { preferences->addPreference(new PrimaryHandPreference(AVATAR_TUNING, "Dominant Hand", getter, setter)); } { - auto getter = [=]()->float { return myAvatar->getUniformScale(); }; - auto setter = [=](float value) { myAvatar->setTargetScale(value); }; + auto getter = [=]()->float { return myAvatar->getModelScale(); }; + auto setter = [=](float value) { myAvatar->setModelScale(value); }; auto preference = new SpinnerSliderPreference(AVATAR_TUNING, "Avatar Scale", getter, setter); preference->setStep(0.05f); preference->setDecimals(2); diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 0bed07891e..c0d352bcae 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -46,13 +46,15 @@ void ModelOverlay::update(float deltatime) { if (_updateModel) { _updateModel = false; _model->setSnapModelToCenter(true); + Transform transform = getTransform(); + transform.setScale(1.0f); // disable inherited scale if (_scaleToFit) { - _model->setScaleToFit(true, getScale() * getDimensions()); + _model->setScaleToFit(true, transform.getScale() * getDimensions()); } else { - _model->setScale(getScale()); + _model->setScale(transform.getScale()); } - _model->setRotation(getRotation()); - _model->setTranslation(getPosition()); + _model->setRotation(transform.getRotation()); + _model->setTranslation(transform.getTranslation()); _model->setURL(_url); _model->simulate(deltatime, true); } else { @@ -93,13 +95,13 @@ void ModelOverlay::setProperties(const QVariantMap& properties) { auto origPosition = getPosition(); auto origRotation = getRotation(); auto origDimensions = getDimensions(); - auto origScale = getScale(); + auto origScale = getSNScale(); Base3DOverlay::setProperties(properties); auto scale = properties["scale"]; if (scale.isValid()) { - setScale(vec3FromVariant(scale)); + setSNScale(vec3FromVariant(scale)); } auto dimensions = properties["dimensions"]; @@ -112,7 +114,7 @@ void ModelOverlay::setProperties(const QVariantMap& properties) { _scaleToFit = false; } - if (origPosition != getPosition() || origRotation != getRotation() || origDimensions != getDimensions() || origScale != getScale()) { + if (origPosition != getPosition() || origRotation != getRotation() || origDimensions != getDimensions() || origScale != getSNScale()) { _updateModel = true; } @@ -194,7 +196,7 @@ QVariant ModelOverlay::getProperty(const QString& property) { return vec3toVariant(getDimensions()); } if (property == "scale") { - return vec3toVariant(getScale()); + return vec3toVariant(getSNScale()); } if (property == "textures") { if (_modelTextures.size() > 0) { diff --git a/interface/src/ui/overlays/OverlaysPayload.cpp b/interface/src/ui/overlays/OverlaysPayload.cpp index f2684a4368..887bf7ff8e 100644 --- a/interface/src/ui/overlays/OverlaysPayload.cpp +++ b/interface/src/ui/overlays/OverlaysPayload.cpp @@ -74,7 +74,7 @@ namespace render { glm::vec3 myAvatarPosition = avatar->getPosition(); float angle = glm::degrees(glm::angle(myAvatarRotation)); glm::vec3 axis = glm::axis(myAvatarRotation); - float myAvatarScale = avatar->getUniformScale(); + float myAvatarScale = avatar->getModelScale(); Transform transform = Transform(); transform.setTranslation(myAvatarPosition); transform.setRotation(glm::angleAxis(angle, axis)); diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 104082dee4..d56a90e8fe 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -199,7 +199,6 @@ QString Web3DOverlay::pickURL() { } } - void Web3DOverlay::loadSourceURL() { if (!_webSurface) { return; @@ -302,19 +301,11 @@ void Web3DOverlay::render(RenderArgs* args) { emit resizeWebSurface(); } - vec2 halfSize = getSize() / 2.0f; vec4 color(toGlm(getColor()), getAlpha()); Transform transform = getTransform(); - - // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. - // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? - /* - applyTransformTo(transform, true); - setTransform(transform); - */ - + transform.setScale(1.0f); // ignore inherited scale factor from parents if (glm::length2(getDimensions()) != 1.0f) { transform.postScale(vec3(getDimensions(), 1.0f)); } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index fc0ee1df7b..4e8f2ad572 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -107,7 +107,7 @@ Avatar::Avatar(QThread* thread) : // we may have been created in the network thread, but we live in the main thread moveToThread(thread); - setScale(glm::vec3(1.0f)); // avatar scale is uniform + setModelScale(1.0f); // avatar scale is uniform auto geometryCache = DependencyManager::get(); _nameRectGeometryID = geometryCache->allocateID(); @@ -156,14 +156,14 @@ glm::vec3 Avatar::getNeckPosition() const { AABox Avatar::getBounds() const { if (!_skeletonModel->isRenderable() || _skeletonModel->needsFixupInScene()) { // approximately 2m tall, scaled to user request. - return AABox(getPosition() - glm::vec3(getUniformScale()), getUniformScale() * 2.0f); + return AABox(getPosition() - glm::vec3(getModelScale()), getModelScale() * 2.0f); } return _skeletonModel->getRenderableMeshBound(); } void Avatar::animateScaleChanges(float deltaTime) { if (_isAnimatingScale) { - float currentScale = getUniformScale(); + float currentScale = getModelScale(); float desiredScale = getDomainLimitedScale(); // use exponential decay toward the domain limit clamped scale @@ -178,7 +178,7 @@ void Avatar::animateScaleChanges(float deltaTime) { animatedScale = desiredScale; _isAnimatingScale = false; } - setScale(glm::vec3(animatedScale)); // avatar scale is uniform + setModelScale(animatedScale); // avatar scale is uniform // flag the joints as having changed for force update to RenderItem _hasNewJointData = true; @@ -365,7 +365,7 @@ void Avatar::simulate(float deltaTime, bool inView) { } head->setPosition(headPosition); } - head->setScale(getUniformScale()); + head->setScale(getModelScale()); head->simulate(deltaTime); } else { // a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated. @@ -423,7 +423,7 @@ bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) const { glm::vec3 theirLookAt = dynamic_pointer_cast(avatar)->getHead()->getLookAtPosition(); glm::vec3 myEyePosition = getHead()->getEyePosition(); - return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getUniformScale()); + return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getModelScale()); } void Avatar::slamPosition(const glm::vec3& newPosition) { @@ -654,7 +654,7 @@ void Avatar::render(RenderArgs* renderArgs) { if (showCollisionShapes && shouldRenderHead(renderArgs) && _skeletonModel->isRenderable()) { PROFILE_RANGE_BATCH(batch, __FUNCTION__":skeletonBoundingCollisionShapes"); const float BOUNDING_SHAPE_ALPHA = 0.7f; - _skeletonModel->renderBoundingCollisionShapes(renderArgs, *renderArgs->_batch, getUniformScale(), BOUNDING_SHAPE_ALPHA); + _skeletonModel->renderBoundingCollisionShapes(renderArgs, *renderArgs->_batch, getModelScale(), BOUNDING_SHAPE_ALPHA); } if (showReceiveStats || showNamesAboveHeads) { @@ -727,9 +727,9 @@ void Avatar::simulateAttachments(float deltaTime) { } else { if (_skeletonModel->getJointPositionInWorldFrame(jointIndex, jointPosition) && _skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRotation)) { - model->setTranslation(jointPosition + jointRotation * attachment.translation * getUniformScale()); + model->setTranslation(jointPosition + jointRotation * attachment.translation * getModelScale()); model->setRotation(jointRotation * attachment.rotation); - float scale = getUniformScale() * attachment.scale; + float scale = getModelScale() * attachment.scale; model->setScaleToFit(true, model->getNaturalDimensions() * scale, true); // hack to force rescale model->setSnapModelToCenter(false); // hack to force resnap model->setSnapModelToCenter(true); @@ -889,7 +889,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const } void Avatar::setSkeletonOffset(const glm::vec3& offset) { - const float MAX_OFFSET_LENGTH = getUniformScale() * 0.5f; + const float MAX_OFFSET_LENGTH = getModelScale() * 0.5f; float offsetLength = glm::length(offset); if (offsetLength > MAX_OFFSET_LENGTH) { _skeletonOffset = (MAX_OFFSET_LENGTH / offsetLength) * offset; @@ -990,11 +990,8 @@ glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const { switch (index) { case SENSOR_TO_WORLD_MATRIX_INDEX: { glm::mat4 sensorToWorldMatrix = getSensorToWorldMatrix(); - bool success; - Transform avatarTransform; - Transform::mult(avatarTransform, getParentTransform(success), getLocalTransform()); - glm::mat4 invAvatarMat = avatarTransform.getInverseMatrix(); - glm::mat4 finalMat = invAvatarMat * sensorToWorldMatrix; + glm::mat4 avatarMatrix = getLocalTransform().getMatrix(); + glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix; return glmExtractRotation(finalMat); } case CONTROLLER_LEFTHAND_INDEX: { @@ -1031,11 +1028,8 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const { switch (index) { case SENSOR_TO_WORLD_MATRIX_INDEX: { glm::mat4 sensorToWorldMatrix = getSensorToWorldMatrix(); - bool success; - Transform avatarTransform; - Transform::mult(avatarTransform, getParentTransform(success), getLocalTransform()); - glm::mat4 invAvatarMat = avatarTransform.getInverseMatrix(); - glm::mat4 finalMat = invAvatarMat * sensorToWorldMatrix; + glm::mat4 avatarMatrix = getLocalTransform().getMatrix(); + glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix; return extractTranslation(finalMat); } case CONTROLLER_LEFTHAND_INDEX: { @@ -1064,7 +1058,6 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const { } } -#ifdef SPATIALLY_NESTABLE_SCALE_SUPPORT glm::vec3 Avatar::getAbsoluteJointScaleInObjectFrame(int index) const { if (index < 0) { index += numeric_limits::max() + 1; // 65536 @@ -1080,7 +1073,6 @@ glm::vec3 Avatar::getAbsoluteJointScaleInObjectFrame(int index) const { return AvatarData::getAbsoluteJointScaleInObjectFrame(index); } } -#endif void Avatar::invalidateJointIndicesCache() const { QWriteLocker writeLock(&_modelJointIndicesCacheLock); @@ -1170,7 +1162,7 @@ glm::vec3 Avatar::getJointPosition(const QString& name) const { void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const { //Scale a world space vector as if it was relative to the position - positionToScale = getPosition() + getUniformScale() * (positionToScale - getPosition()); + positionToScale = getPosition() + getModelScale() * (positionToScale - getPosition()); } void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { @@ -1372,7 +1364,7 @@ void Avatar::updateDisplayNameAlpha(bool showDisplayName) { // virtual void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) { - float uniformScale = getUniformScale(); + float uniformScale = getModelScale(); shapeInfo.setCapsuleY(uniformScale * _skeletonModel->getBoundingCapsuleRadius(), 0.5f * uniformScale * _skeletonModel->getBoundingCapsuleHeight()); shapeInfo.setOffset(uniformScale * _skeletonModel->getBoundingCapsuleOffset()); @@ -1581,7 +1573,7 @@ float Avatar::getEyeHeight() const { // TODO: if performance becomes a concern we can cache this value rather then computing it everytime. // Makes assumption that the y = 0 plane in geometry is the ground plane. // We also make that assumption in Rig::computeAvatarBoundingCapsule() - float avatarScale = getUniformScale(); + float avatarScale = getModelScale(); if (_skeletonModel) { auto& rig = _skeletonModel->getRig(); int headTopJoint = rig.indexOfJoint("HeadTop_End"); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 7b0819655a..75d9afeb90 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -108,7 +108,6 @@ public: SkeletonModelPointer getSkeletonModel() { return _skeletonModel; } const SkeletonModelPointer getSkeletonModel() const { return _skeletonModel; } glm::vec3 getChestPosition() const; - float getUniformScale() const { return getScale().y; } const Head* getHead() const { return static_cast(_headData); } Head* getHead() { return static_cast(_headData); } @@ -151,9 +150,7 @@ public: */ Q_INVOKABLE virtual glm::vec3 getAbsoluteDefaultJointTranslationInObjectFrame(int index) const; -#ifdef SPATIALLY_NESTABLE_SCALE_SUPPORT virtual glm::vec3 getAbsoluteJointScaleInObjectFrame(int index) const override; -#endif virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; } @@ -263,6 +260,9 @@ public: */ Q_INVOKABLE float getEyeHeight() const; + float getModelScale() const { return _modelScale; } + void setModelScale(float scale) { _modelScale = scale; } + public slots: // FIXME - these should be migrated to use Pose data instead @@ -365,6 +365,7 @@ private: bool _isAnimatingScale { false }; bool _mustFadeIn { false }; bool _isFading { false }; + float _modelScale { 1.0f }; static int _jointConesID; diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index c0d5fc07d7..eaa62ecb0a 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -121,7 +121,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { void SkeletonModel::updateAttitude(const glm::quat& orientation) { setTranslation(_owningAvatar->getSkeletonPosition()); setRotation(orientation * Quaternions::Y_180); - setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale()); + setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getModelScale()); } // Called by Avatar::simulate after it has set the joint states (fullUpdate true if changed), @@ -294,7 +294,7 @@ bool SkeletonModel::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& seco } glm::vec3 SkeletonModel::getDefaultEyeModelPosition() const { - return _owningAvatar->getScale() * _defaultEyeModelPosition; + return _owningAvatar->getModelScale() * _defaultEyeModelPosition; } float DENSITY_OF_WATER = 1000.0f; // kg/m^3 @@ -316,7 +316,7 @@ void SkeletonModel::computeBoundingShape() { float radius, height; glm::vec3 offset; _rig.computeAvatarBoundingCapsule(geometry, radius, height, offset); - float invScale = 1.0f / _owningAvatar->getUniformScale(); + float invScale = 1.0f / _owningAvatar->getModelScale(); _boundingCapsuleRadius = invScale * radius; _boundingCapsuleHeight = invScale * height; _boundingCapsuleLocalOffset = invScale * offset; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 0c120d586c..6b57c79713 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -42,7 +42,8 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : setLocalVelocity(ENTITY_ITEM_DEFAULT_VELOCITY); setLocalAngularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY); // explicitly set transform parts to set dirty flags used by batch rendering - setScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); + locationChanged(); + dimensionsChanged(); quint64 now = usecTimestampNow(); _lastSimulated = now; _lastUpdated = now; @@ -1382,7 +1383,11 @@ void EntityItem::setDimensions(const glm::vec3& value) { if (value.x <= 0.0f || value.y <= 0.0f || value.z <= 0.0f) { return; } - setScale(value); + if (_dimensions != value) { + _dimensions = value; + locationChanged(); + dimensionsChanged(); + } } /// The maximum bounding cube for the entity, independent of it's rotation. diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 84742587e9..a95f7ba316 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -179,7 +179,7 @@ public: void setDescription(const QString& value); /// Dimensions in meters (0.0 - TREE_SCALE) - inline const glm::vec3 getDimensions() const { return getScale(); } + inline const glm::vec3 getDimensions() const { return _dimensions; } virtual void setDimensions(const glm::vec3& value); float getLocalRenderAlpha() const; @@ -470,6 +470,7 @@ protected: virtual void dimensionsChanged() override; + glm::vec3 _dimensions { ENTITY_ITEM_DEFAULT_DIMENSIONS }; EntityTypes::EntityType _type { EntityTypes::Unknown }; quint64 _lastSimulated { 0 }; // last time this entity called simulate(), this includes velocity, angular velocity, // and physics changes diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index 23a5c88900..ad9686bdf2 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -176,7 +176,7 @@ void PolyLineEntityItem::calculateScaleAndRegistrationPoint() { } // if Polyline has only one or fewer points, use default dimension settings - SpatiallyNestable::setScale(newScale); + setDimensions(newScale); EntityItem::setRegistrationPoint(newRegistrationPoint); } diff --git a/libraries/entities/src/PolyLineEntityItem.h b/libraries/entities/src/PolyLineEntityItem.h index 4860e3d4a4..9fbc6c60a1 100644 --- a/libraries/entities/src/PolyLineEntityItem.h +++ b/libraries/entities/src/PolyLineEntityItem.h @@ -91,8 +91,6 @@ class PolyLineEntityItem : public EntityItem { // disable these external interfaces as PolyLineEntities caculate their own dimensions based on the points they contain virtual void setRegistrationPoint(const glm::vec3& value) override {}; - virtual void setScale(const glm::vec3& scale) override {}; - virtual void setScale(float value) override {}; virtual void debugDump() const override; static const float DEFAULT_LINE_WIDTH; diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 0bf7a8b95d..c20ce90cd6 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -84,12 +84,7 @@ Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const return result; } if (parent) { -#ifdef SPATIALLY_NESTABLE_SCALE_SUPPORT result = parent->getTransform(_parentJointIndex, success, depth + 1); -#else - Transform parentTransform = parent->getTransform(_parentJointIndex, success, depth + 1); - result = parentTransform.setScale(1.0f); // TODO: scaling -#endif } return result; } @@ -161,7 +156,6 @@ void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) { glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success) { - Transform result; QSharedPointer parentFinder = DependencyManager::get(); if (!parentFinder) { success = false; @@ -185,25 +179,17 @@ glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, if (!success) { return glm::vec3(0.0f); } -#ifndef SPATIALLY_NESTABLE_SCALE_SUPPORT - parentTransform.setScale(1.0f); // TODO: scale -#endif } success = true; - Transform positionTransform; - positionTransform.setTranslation(position); - Transform myWorldTransform; - Transform::mult(myWorldTransform, parentTransform, positionTransform); - myWorldTransform.setTranslation(position); - Transform::inverseMult(result, parentTransform, myWorldTransform); - return result.getTranslation(); + Transform invParentTransform; + parentTransform.evalInverse(invParentTransform); + return invParentTransform.transform(position); } glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success) { - Transform result; QSharedPointer parentFinder = DependencyManager::get(); if (!parentFinder) { success = false; @@ -227,19 +213,11 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, if (!success) { return glm::quat(); } -#ifndef SPATIALLY_NESTABLE_SCALE_SUPPORT - parentTransform.setScale(1.0f); // TODO: scale -#endif } success = true; - Transform orientationTransform; - orientationTransform.setRotation(orientation); - Transform myWorldTransform; - Transform::mult(myWorldTransform, parentTransform, orientationTransform); - myWorldTransform.setRotation(orientation); - Transform::inverseMult(result, parentTransform, myWorldTransform); - return result.getRotation(); + glm::quat invParentOrientation = glm::inverse(parentTransform.getRotation()); + return invParentOrientation * orientation; } glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID, @@ -301,9 +279,6 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, if (!success) { return glm::vec3(0.0f); } -#ifndef SPATIALLY_NESTABLE_SCALE_SUPPORT - parentTransform.setScale(1.0f); // TODO: scale -#endif } success = true; @@ -645,9 +620,6 @@ const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, i } Transform worldTransform = getTransform(success, depth); -#ifndef SPATIALLY_NESTABLE_SCALE_SUPPORT - worldTransform.setScale(1.0f); // TODO: scale -#endif if (!success) { return jointInWorldFrame; } @@ -686,61 +658,51 @@ bool SpatiallyNestable::setTransform(const Transform& transform) { return success; } -glm::vec3 SpatiallyNestable::getScale() const { - // TODO: scale - glm::vec3 result; - _transformLock.withReadLock([&] { - result = _transform.getScale(); - }); +glm::vec3 SpatiallyNestable::getSNScale() const { + bool success; + auto result = getSNScale(success); + #ifdef WANT_DEBUG + if (!success) { + qCDebug(shared) << "Warning -- getScale failed" << getID(); + } + #endif return result; } -glm::vec3 SpatiallyNestable::getScale(int jointIndex) const { - // TODO: scale - return getScale(); +glm::vec3 SpatiallyNestable::getSNScale(bool& success) const { + return getTransform(success).getScale(); } -void SpatiallyNestable::setScale(const glm::vec3& scale) { +glm::vec3 SpatiallyNestable::getSNScale(int jointIndex, bool& success) const { + return getTransform(jointIndex, success).getScale(); +} + +void SpatiallyNestable::setSNScale(const glm::vec3& scale) { + bool success; + setSNScale(scale, success); +} + +void SpatiallyNestable::setSNScale(const glm::vec3& scale, bool& success) { // guard against introducing NaN into the transform if (isNaN(scale)) { - qCDebug(shared) << "SpatiallyNestable::setScale -- scale contains NaN"; + success = false; return; } bool changed = false; - // TODO: scale + Transform parentTransform = getParentTransform(success); + Transform myWorldTransform; _transformLock.withWriteLock([&] { - if (_transform.getScale() != scale) { - _transform.setScale(scale); + Transform::mult(myWorldTransform, parentTransform, _transform); + if (myWorldTransform.getScale() != scale) { changed = true; + myWorldTransform.setScale(scale); + Transform::inverseMult(_transform, parentTransform, myWorldTransform); _scaleChanged = usecTimestampNow(); } }); - if (changed) { - dimensionsChanged(); - } -} - -void SpatiallyNestable::setScale(float value) { - // guard against introducing NaN into the transform - if (value <= 0.0f) { - qCDebug(shared) << "SpatiallyNestable::setScale -- scale is zero or negative value"; - return; - } - - bool changed = false; - // TODO: scale - _transformLock.withWriteLock([&] { - glm::vec3 beforeScale = _transform.getScale(); - _transform.setScale(value); - if (_transform.getScale() != beforeScale) { - changed = true; - _scaleChanged = usecTimestampNow(); - } - }); - - if (changed) { - dimensionsChanged(); + if (success && changed) { + locationChanged(); } } @@ -857,8 +819,7 @@ void SpatiallyNestable::setLocalAngularVelocity(const glm::vec3& angularVelocity }); } -glm::vec3 SpatiallyNestable::getLocalScale() const { - // TODO: scale +glm::vec3 SpatiallyNestable::getLocalSNScale() const { glm::vec3 result; _transformLock.withReadLock([&] { result = _transform.getScale(); @@ -866,7 +827,7 @@ glm::vec3 SpatiallyNestable::getLocalScale() const { return result; } -void SpatiallyNestable::setLocalScale(const glm::vec3& scale) { +void SpatiallyNestable::setLocalSNScale(const glm::vec3& scale) { // guard against introducing NaN into the transform if (isNaN(scale)) { qCDebug(shared) << "SpatiallyNestable::setLocalScale -- scale contains NaN"; @@ -874,7 +835,6 @@ void SpatiallyNestable::setLocalScale(const glm::vec3& scale) { } bool changed = false; - // TODO: scale _transformLock.withWriteLock([&] { if (_transform.getScale() != scale) { _transform.setScale(scale); @@ -918,10 +878,8 @@ const Transform SpatiallyNestable::getAbsoluteJointTransformInObjectFrame(int jo Transform jointTransformInObjectFrame; glm::vec3 position = getAbsoluteJointTranslationInObjectFrame(jointIndex); glm::quat orientation = getAbsoluteJointRotationInObjectFrame(jointIndex); -#ifdef SPATIALLY_NESTABLE_SCALE_SUPPORT glm::vec3 scale = getAbsoluteJointScaleInObjectFrame(jointIndex); jointTransformInObjectFrame.setScale(scale); -#endif jointTransformInObjectFrame.setRotation(orientation); jointTransformInObjectFrame.setTranslation(position); return jointTransformInObjectFrame; @@ -1214,3 +1172,13 @@ QString SpatiallyNestable::nestableTypeToString(NestableType nestableType) { return "unknown"; } } + +void SpatiallyNestable::dump(const QString& prefix) const { + qDebug().noquote() << prefix << "id = " << getID(); + qDebug().noquote() << prefix << "transform = " << _transform; + bool success; + SpatiallyNestablePointer parent = getParentPointer(success); + if (success && parent) { + parent->dump(prefix + " "); + } +} diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index cb3dba754a..4195efc553 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -111,14 +111,15 @@ public: virtual AACube getQueryAACube(bool& success) const; virtual AACube getQueryAACube() const; - virtual glm::vec3 getScale() const; - virtual void setScale(const glm::vec3& scale); - virtual void setScale(float value); + virtual glm::vec3 getSNScale() const; + virtual glm::vec3 getSNScale(bool& success) const; + virtual void setSNScale(const glm::vec3& scale); + virtual void setSNScale(const glm::vec3& scale, bool& success); // get world-frame values for a specific joint virtual const Transform getTransform(int jointIndex, bool& success, int depth = 0) const; virtual glm::vec3 getPosition(int jointIndex, bool& success) const; - virtual glm::vec3 getScale(int jointIndex) const; + virtual glm::vec3 getSNScale(int jointIndex, bool& success) const; // object's parent's frame virtual const Transform getLocalTransform() const; @@ -136,8 +137,8 @@ public: virtual glm::vec3 getLocalAngularVelocity() const; virtual void setLocalAngularVelocity(const glm::vec3& angularVelocity); - virtual glm::vec3 getLocalScale() const; - virtual void setLocalScale(const glm::vec3& scale); + virtual glm::vec3 getLocalSNScale() const; + virtual void setLocalSNScale(const glm::vec3& scale); QList getChildren() const; bool hasChildren() const; @@ -146,9 +147,7 @@ public: // this object's frame virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const; -#ifdef SPATIALLY_NESTABLE_SCALE_SUPPORT virtual glm::vec3 getAbsoluteJointScaleInObjectFrame(int index) const { return glm::vec3(1.0f); } -#endif virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { return glm::quat(); } virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { return glm::vec3(); } virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) { return false; } @@ -193,6 +192,8 @@ public: bool tranlationChangedSince(quint64 time) const { return _translationChanged > time; } bool rotationChangedSince(quint64 time) const { return _rotationChanged > time; } + void dump(const QString& prefix = "") const; + protected: const NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; diff --git a/libraries/shared/src/Transform.cpp b/libraries/shared/src/Transform.cpp index c51b3dae4b..3e29c38add 100644 --- a/libraries/shared/src/Transform.cpp +++ b/libraries/shared/src/Transform.cpp @@ -150,3 +150,10 @@ QJsonObject Transform::toJson(const Transform& transform) { } return result; } + +QDebug& operator<<(QDebug& debug, const Transform& transform) { + debug << "Transform, trans = (" << transform._translation.x << transform._translation.y << transform._translation.z << "), rot = (" + << transform._rotation.x << transform._rotation.y << transform._rotation.z << transform._rotation.w << "), scale = (" + << transform._scale.x << transform._scale.y << transform._scale.z << ")"; + return debug; +} diff --git a/libraries/shared/src/Transform.h b/libraries/shared/src/Transform.h index 38d47695f7..316fcb2f04 100644 --- a/libraries/shared/src/Transform.h +++ b/libraries/shared/src/Transform.h @@ -38,6 +38,7 @@ inline bool isValidScale(float scale) { class Transform { public: + friend QDebug& operator<<(QDebug& debug, const Transform& transform); using Pointer = std::shared_ptr; typedef glm::mat4 Mat4; typedef glm::mat3 Mat3; @@ -170,7 +171,6 @@ protected: }; typedef std::bitset Flags; - // TRS Quat _rotation; Vec3 _scale; @@ -202,6 +202,8 @@ protected: Mat4& getCachedMatrix(Mat4& result) const; }; +QDebug& operator<<(QDebug& debug, const Transform& transform); + inline Transform& Transform::setIdentity() { _translation = Vec3(0.0f); _rotation = Quat(1.0f, 0.0f, 0.0f, 0.0f);