diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index c63095a204..8a25c21946 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -36,13 +36,13 @@ #include #include #include -#include #include #include "Application.h" #include "InterfaceLogging.h" #include "Menu.h" #include "MyAvatar.h" +#include "OtherAvatar.h" #include "SceneScriptingInterface.h" // 50 times per second - target is 45hz, but this helps account for any small deviations @@ -192,6 +192,15 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { while (!sortedAvatars.empty()) { const SortableAvatar& sortData = sortedAvatars.top(); const auto avatar = std::static_pointer_cast(sortData.getAvatar()); + const auto otherAvatar = std::static_pointer_cast(sortData.getAvatar()); + + // if the geometry is loaded then turn off the orb + if (avatar->getSkeletonModel()->isLoaded()) { + // remove the orb if it is there + otherAvatar->removeOrb(); + } else { + otherAvatar->updateOrbPosition(); + } bool ignoring = DependencyManager::get()->isPersonalMutingNode(avatar->getID()); if (ignoring) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 4069b702d6..a3b07d400f 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -250,7 +250,7 @@ public: Q_ENUM(DriveKeys) explicit MyAvatar(QThread* thread); - ~MyAvatar(); + virtual ~MyAvatar(); void instantiableAvatar() override {}; void registerMetaTypes(ScriptEnginePointer engine); diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp new file mode 100644 index 0000000000..5e51658128 --- /dev/null +++ b/interface/src/avatar/OtherAvatar.cpp @@ -0,0 +1,60 @@ +// +// Created by Bradley Austin Davis on 2017/04/27 +// Copyright 2013-2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "OtherAvatar.h" +#include "Application.h" + +OtherAvatar::OtherAvatar(QThread* thread) : Avatar(thread) { + // give the pointer to our head to inherited _headData variable from AvatarData + _headData = new Head(this); + _skeletonModel = std::make_shared(this, nullptr); + _skeletonModel->setLoadingPriority(OTHERAVATAR_LOADING_PRIORITY); + connect(_skeletonModel.get(), &Model::setURLFinished, this, &Avatar::setModelURLFinished); + connect(_skeletonModel.get(), &Model::rigReady, this, &Avatar::rigReady); + connect(_skeletonModel.get(), &Model::rigReset, this, &Avatar::rigReset); + + // add the purple orb + createOrb(); +} + +OtherAvatar::~OtherAvatar() { + removeOrb(); +} + +void OtherAvatar::removeOrb() { + if (qApp->getOverlays().isAddedOverlay(_otherAvatarOrbMeshPlaceholderID)) { + qApp->getOverlays().deleteOverlay(_otherAvatarOrbMeshPlaceholderID); + } +} + +void OtherAvatar::updateOrbPosition() { + if (_otherAvatarOrbMeshPlaceholder != nullptr) { + _otherAvatarOrbMeshPlaceholder->setWorldPosition(getHead()->getPosition()); + } +} + +void OtherAvatar::createOrb() { + if (_otherAvatarOrbMeshPlaceholderID == UNKNOWN_OVERLAY_ID || + !qApp->getOverlays().isAddedOverlay(_otherAvatarOrbMeshPlaceholderID)) { + _otherAvatarOrbMeshPlaceholder = std::make_shared(); + _otherAvatarOrbMeshPlaceholder->setAlpha(1.0f); + _otherAvatarOrbMeshPlaceholder->setColor({ 0xFF, 0x00, 0xFF }); + _otherAvatarOrbMeshPlaceholder->setIsSolid(false); + _otherAvatarOrbMeshPlaceholder->setPulseMin(0.5); + _otherAvatarOrbMeshPlaceholder->setPulseMax(1.0); + _otherAvatarOrbMeshPlaceholder->setColorPulse(1.0); + _otherAvatarOrbMeshPlaceholder->setIgnoreRayIntersection(true); + _otherAvatarOrbMeshPlaceholder->setDrawInFront(false); + _otherAvatarOrbMeshPlaceholderID = qApp->getOverlays().addOverlay(_otherAvatarOrbMeshPlaceholder); + // Position focus + _otherAvatarOrbMeshPlaceholder->setWorldOrientation(glm::quat(0.0f, 0.0f, 0.0f, 1.0)); + _otherAvatarOrbMeshPlaceholder->setWorldPosition(getHead()->getPosition()); + _otherAvatarOrbMeshPlaceholder->setDimensions(glm::vec3(0.5f, 0.5f, 0.5f)); + _otherAvatarOrbMeshPlaceholder->setVisible(true); + } +} diff --git a/interface/src/avatar/OtherAvatar.h b/interface/src/avatar/OtherAvatar.h new file mode 100644 index 0000000000..f33952b78b --- /dev/null +++ b/interface/src/avatar/OtherAvatar.h @@ -0,0 +1,32 @@ +// +// Created by Bradley Austin Davis on 2017/04/27 +// Copyright 2013-2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_OtherAvatar_h +#define hifi_OtherAvatar_h + +#include +#include "ui/overlays/Overlays.h" +#include "ui/overlays/Sphere3DOverlay.h" +#include "InterfaceLogging.h" + +class OtherAvatar : public Avatar { +public: + explicit OtherAvatar(QThread* thread); + virtual ~OtherAvatar(); + + virtual void instantiableAvatar() override { }; + virtual void createOrb() override; + void updateOrbPosition(); + void removeOrb(); + +protected: + std::shared_ptr _otherAvatarOrbMeshPlaceholder { nullptr }; + OverlayID _otherAvatarOrbMeshPlaceholderID { UNKNOWN_OVERLAY_ID }; +}; + +#endif // hifi_OtherAvatar_h diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index a99838d810..843235c0e1 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1338,6 +1338,9 @@ void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const { } void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { + if (!isMyAvatar()) { + createOrb(); + } AvatarData::setSkeletonModelURL(skeletonModelURL); if (QThread::currentThread() == thread()) { _skeletonModel->setURL(_skeletonModelURL); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 98246330c4..bb9d6d8cc9 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -23,7 +23,6 @@ #include #include - #include "Head.h" #include "SkeletonModel.h" #include "Rig.h" @@ -41,7 +40,6 @@ static const float SCALING_RATIO = .05f; extern const float CHAT_MESSAGE_SCALE; extern const float CHAT_MESSAGE_HEIGHT; - enum ScreenTintLayer { SCREEN_TINT_BEFORE_LANDSCAPE = 0, SCREEN_TINT_BEFORE_AVATARS, @@ -69,7 +67,7 @@ public: static void setShowNamesAboveHeads(bool show); explicit Avatar(QThread* thread); - ~Avatar(); + virtual ~Avatar(); virtual void instantiableAvatar() = 0; @@ -109,6 +107,7 @@ public: float getLODDistance() const; virtual bool isMyAvatar() const override { return false; } + virtual void createOrb() { } virtual QVector getJointRotations() const override; using AvatarData::getJointRotation; @@ -167,8 +166,8 @@ public: virtual int parseDataFromBuffer(const QByteArray& buffer) override; - static void renderJointConnectingCone( gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2, - float radius1, float radius2, const glm::vec4& color); + static void renderJointConnectingCone(gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2, + float radius1, float radius2, const glm::vec4& color); virtual void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { } @@ -235,7 +234,7 @@ public: /// Scales a world space position vector relative to the avatar position and scale /// \param vector position to be scaled. Will store the result - void scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const; + void scaleVectorRelativeToPosition(glm::vec3& positionToScale) const; void slamPosition(const glm::vec3& position); virtual void updateAttitude(const glm::quat& orientation) override; @@ -254,7 +253,6 @@ public: void setPositionViaScript(const glm::vec3& position) override; void setOrientationViaScript(const glm::quat& orientation) override; - /**jsdoc * @function MyAvatar.getParentID * @returns {Uuid} @@ -283,7 +281,6 @@ public: // This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript. Q_INVOKABLE virtual void setParentJointIndex(quint16 parentJointIndex) override; - /**jsdoc * Returns an array of joints, where each joint is an object containing name, index, and parentIndex fields. * @function MyAvatar.getSkeleton @@ -349,7 +346,6 @@ public: // not all subclasses of AvatarData have access to this data. virtual bool canMeasureEyeHeight() const override { return true; } - virtual float getModelScale() const { return _modelScale; } virtual void setModelScale(float scale) { _modelScale = scale; } virtual glm::vec3 scaleForChildren() const override { return glm::vec3(getModelScale()); } diff --git a/libraries/avatars-renderer/src/avatars-renderer/OtherAvatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/OtherAvatar.cpp deleted file mode 100644 index 7678c03276..0000000000 --- a/libraries/avatars-renderer/src/avatars-renderer/OtherAvatar.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// -// Created by Bradley Austin Davis on 2017/04/27 -// Copyright 2013-2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "OtherAvatar.h" - -OtherAvatar::OtherAvatar(QThread* thread) : Avatar(thread) { - // give the pointer to our head to inherited _headData variable from AvatarData - _headData = new Head(this); - _skeletonModel = std::make_shared(this, nullptr); - _skeletonModel->setLoadingPriority(OTHERAVATAR_LOADING_PRIORITY); - connect(_skeletonModel.get(), &Model::setURLFinished, this, &Avatar::setModelURLFinished); - connect(_skeletonModel.get(), &Model::rigReady, this, &Avatar::rigReady); - connect(_skeletonModel.get(), &Model::rigReset, this, &Avatar::rigReset); -} diff --git a/libraries/avatars-renderer/src/avatars-renderer/OtherAvatar.h b/libraries/avatars-renderer/src/avatars-renderer/OtherAvatar.h deleted file mode 100644 index df09d7fd99..0000000000 --- a/libraries/avatars-renderer/src/avatars-renderer/OtherAvatar.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// Created by Bradley Austin Davis on 2017/04/27 -// Copyright 2013-2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_OtherAvatar_h -#define hifi_OtherAvatar_h - -#include "Avatar.h" - -class OtherAvatar : public Avatar { -public: - explicit OtherAvatar(QThread* thread); - virtual void instantiableAvatar() override {}; -}; - -#endif // hifi_OtherAvatar_h