diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4399d4754f..5bc1040a34 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2287,8 +2287,8 @@ void Application::updateMyAvatarLookAtPosition() { } } else { - AvatarSharedPointer lookingAt = _myAvatar->getLookAtTargetAvatar().toStrongRef(); - if (lookingAt && _myAvatar != lookingAt.data()) { + AvatarSharedPointer lookingAt = _myAvatar->getLookAtTargetAvatar().lock(); + if (lookingAt && _myAvatar != lookingAt.get()) { isLookingAtSomeone = true; // If I am looking at someone else, look directly at one of their eyes @@ -2296,17 +2296,17 @@ void Application::updateMyAvatarLookAtPosition() { // If a face tracker is active, look at the eye for the side my gaze is biased toward if (tracker->getEstimatedEyeYaw() > _myAvatar->getHead()->getFinalYaw()) { // Look at their right eye - lookAtSpot = static_cast(lookingAt.data())->getHead()->getRightEyePosition(); + lookAtSpot = static_cast(lookingAt.get())->getHead()->getRightEyePosition(); } else { // Look at their left eye - lookAtSpot = static_cast(lookingAt.data())->getHead()->getLeftEyePosition(); + lookAtSpot = static_cast(lookingAt.get())->getHead()->getLeftEyePosition(); } } else { // Need to add randomly looking back and forth between left and right eye for case with no tracker if (_myAvatar->isLookingAtLeftEye()) { - lookAtSpot = static_cast(lookingAt.data())->getHead()->getLeftEyePosition(); + lookAtSpot = static_cast(lookingAt.get())->getHead()->getLeftEyePosition(); } else { - lookAtSpot = static_cast(lookingAt.data())->getHead()->getRightEyePosition(); + lookAtSpot = static_cast(lookingAt.get())->getHead()->getRightEyePosition(); } } } else { @@ -3027,11 +3027,6 @@ void Application::updateShadowMap(RenderArgs* renderArgs) { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.1f, 4.0f); // magic numbers courtesy http://www.eecs.berkeley.edu/~ravir/6160/papers/shadowmaps.ppt - { - PerformanceTimer perfTimer("avatarManager"); - DependencyManager::get()->renderAvatars(renderArgs); - } - { PerformanceTimer perfTimer("entities"); _entities.render(renderArgs); @@ -3410,15 +3405,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se DependencyManager::get()->render(); } } - - bool mirrorMode = (theCamera.getMode() == CAMERA_MODE_MIRROR); - - { - PerformanceTimer perfTimer("avatars"); - renderArgs->_renderMode = mirrorMode ? RenderArgs::MIRROR_RENDER_MODE : RenderArgs::NORMAL_RENDER_MODE; - DependencyManager::get()->renderAvatars(renderArgs, false, selfAvatarOnly); - renderArgs->_renderMode = RenderArgs::NORMAL_RENDER_MODE; - } render::Scene::PendingChanges pendingChanges; @@ -3456,13 +3442,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se PerformanceTimer perfTimer("lighting"); DependencyManager::get()->render(); } - - { - PerformanceTimer perfTimer("avatarsPostLighting"); - renderArgs->_renderMode = mirrorMode ? RenderArgs::MIRROR_RENDER_MODE : RenderArgs::NORMAL_RENDER_MODE; - DependencyManager::get()->renderAvatars(renderArgs, true, selfAvatarOnly); - renderArgs->_renderMode = RenderArgs::NORMAL_RENDER_MODE; - } //Render the sixense lasers if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) { diff --git a/interface/src/Application.h b/interface/src/Application.h index fb262ad2aa..2fbf6f3847 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -352,6 +352,8 @@ public: render::ScenePointer getMain3DScene() { return _main3DScene; } render::EnginePointer getRenderEngine() { return _renderEngine; } + render::ScenePointer getMain3DScene() const { return _main3DScene; } + signals: /// Fired when we're simulating; allows external parties to hook in. diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 4d950d4386..65ab6b8d44 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -60,6 +60,25 @@ const float DISPLAYNAME_FADE_FACTOR = pow(0.01f, 1.0f / DISPLAYNAME_FADE_TIME); const float DISPLAYNAME_ALPHA = 0.95f; const float DISPLAYNAME_BACKGROUND_ALPHA = 0.4f; +namespace render { + template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar) { + return ItemKey::Builder::opaqueShape(); + } + template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar) { + return static_cast(avatar.get())->getBounds(); + } + template <> void payloadRender(const AvatarSharedPointer& avatar, RenderArgs* args) { + Avatar* avatarPtr = static_cast(avatar.get()); + bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::RenderLookAtVectors); + avatarPtr->setDisplayingLookatVectors(renderLookAtVectors); + + if (avatarPtr->isInitialized() && args) { + avatarPtr->render(args, Application::getInstance()->getCamera()->getPosition()); + args->_elementsTouched++; + } + } +} + Avatar::Avatar() : AvatarData(), _skeletonModel(this), @@ -116,6 +135,10 @@ glm::quat Avatar::getWorldAlignedOrientation () const { return computeRotationFromBodyToWorldUp() * getOrientation(); } +AABox Avatar::getBounds() const { + return AABox(); +} + float Avatar::getLODDistance() const { return DependencyManager::get()->getAvatarLODDistanceMultiplier() * glm::distance(qApp->getCamera()->getPosition(), _position) / _scale; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index b912a159af..21c269381f 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -20,12 +20,20 @@ #include #include +#include + #include "Hand.h" #include "Head.h" #include "InterfaceConfig.h" #include "SkeletonModel.h" #include "world.h" +namespace render { + template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar); + template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar); + template <> void payloadRender(const AvatarSharedPointer& avatar, RenderArgs* args); +} + static const float SCALING_RATIO = .05f; static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1 static const float RESCALING_TOLERANCE = .02f; @@ -66,6 +74,10 @@ public: Avatar(); ~Avatar(); + typedef render::Payload Payload; + typedef std::shared_ptr PayloadPointer; + typedef Payload::DataPointer Pointer; + void init(); void simulate(float deltaTime); @@ -87,6 +99,8 @@ public: Hand* getHand() { return static_cast(_handData); } glm::quat getWorldAlignedOrientation() const; + AABox getBounds() const; + /// Returns the distance to use as a LOD parameter. float getLODDistance() const; @@ -220,9 +234,10 @@ protected: virtual void renderAttachments(RenderArgs* args); virtual void updateJointMappings(); + + render::ItemID _renderItemID; private: - bool _initialized; NetworkTexturePointer _billboardTexture; bool _shouldRenderBillboard; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 2b3b2f2df0..a4b437c009 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -55,12 +55,22 @@ AvatarManager::AvatarManager(QObject* parent) : _avatarFades() { // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar qRegisterMetaType >("NodeWeakPointer"); - _myAvatar = QSharedPointer(new MyAvatar()); + _myAvatar = std::shared_ptr(new MyAvatar()); } void AvatarManager::init() { _myAvatar->init(); _avatarHash.insert(MY_AVATAR_KEY, _myAvatar); + + render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + auto avatarPayload = new render::Payload(_myAvatar); + auto avatarPayloadPointer = Avatar::PayloadPointer(avatarPayload); + static_cast(_myAvatar.get())->_renderItemID = scene->allocateID(); + + render::Scene::PendingChanges pendingChanges; + pendingChanges.resetItem(static_cast(_myAvatar.get())->_renderItemID, avatarPayloadPointer); + + scene->enqueuePendingChanges(pendingChanges); } void AvatarManager::updateMyAvatar(float deltaTime) { @@ -92,9 +102,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { // simulate avatars AvatarHash::iterator avatarIterator = _avatarHash.begin(); while (avatarIterator != _avatarHash.end()) { - Avatar* avatar = reinterpret_cast(avatarIterator.value().data()); + Avatar* avatar = reinterpret_cast(avatarIterator.value().get()); - if (avatar == _myAvatar || !avatar->isInitialized()) { + if (avatar == _myAvatar.get() || !avatar->isInitialized()) { // DO NOT update _myAvatar! Its update has already been done earlier in the main loop. // DO NOT update or fade out uninitialized Avatars ++avatarIterator; @@ -111,32 +121,6 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { simulateAvatarFades(deltaTime); } -void AvatarManager::renderAvatars(RenderArgs* renderArgs, bool postLighting, bool selfAvatarOnly) { - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::renderAvatars()"); - bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::RenderLookAtVectors); - - glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); - - if (!selfAvatarOnly) { - if (DependencyManager::get()->shouldRenderAvatars()) { - foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) { - Avatar* avatar = static_cast(avatarPointer.data()); - if (!avatar->isInitialized()) { - continue; - } - avatar->render(renderArgs, cameraPosition, postLighting); - avatar->setDisplayingLookatVectors(renderLookAtVectors); - } - renderAvatarFades(renderArgs, cameraPosition); - } - } else { - // just render myAvatar - _myAvatar->render(renderArgs, cameraPosition, postLighting); - _myAvatar->setDisplayingLookatVectors(renderLookAtVectors); - } -} - void AvatarManager::simulateAvatarFades(float deltaTime) { QVector::iterator fadingIterator = _avatarFades.begin(); @@ -144,7 +128,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { const float MIN_FADE_SCALE = 0.001f; while (fadingIterator != _avatarFades.end()) { - Avatar* avatar = static_cast(fadingIterator->data()); + Avatar* avatar = static_cast(fadingIterator->get()); avatar->setTargetScale(avatar->getScale() * SHRINK_RATE, true); if (avatar->getTargetScale() < MIN_FADE_SCALE) { fadingIterator = _avatarFades.erase(fadingIterator); @@ -155,18 +139,6 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { } } -void AvatarManager::renderAvatarFades(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { - // render avatar fades - Glower glower(renderArgs, renderArgs->_renderMode == RenderArgs::NORMAL_RENDER_MODE ? 1.0f : 0.0f); - - foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) { - Avatar* avatar = static_cast(fadingAvatar.data()); - if (avatar != static_cast(_myAvatar.data()) && avatar->isInitialized()) { - avatar->render(renderArgs, cameraPosition); - } - } -} - AvatarSharedPointer AvatarManager::newSharedAvatar() { return AvatarSharedPointer(new Avatar()); } @@ -174,6 +146,17 @@ AvatarSharedPointer AvatarManager::newSharedAvatar() { // virtual AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer) { AvatarSharedPointer avatar = AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer); + + render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + auto avatarPayload = new render::Payload(avatar); + auto avatarPayloadPointer = Avatar::PayloadPointer(avatarPayload); + static_cast(avatar.get())->_renderItemID = scene->allocateID(); + + render::Scene::PendingChanges pendingChanges; + pendingChanges.resetItem(static_cast(avatar.get())->_renderItemID, avatarPayloadPointer); + + scene->enqueuePendingChanges(pendingChanges); + return avatar; } @@ -194,13 +177,18 @@ void AvatarManager::removeAvatarMotionState(Avatar* avatar) { void AvatarManager::removeAvatar(const QUuid& sessionUUID) { AvatarHash::iterator avatarIterator = _avatarHash.find(sessionUUID); if (avatarIterator != _avatarHash.end()) { - Avatar* avatar = reinterpret_cast(avatarIterator.value().data()); - if (avatar != _myAvatar && avatar->isInitialized()) { + Avatar* avatar = reinterpret_cast(avatarIterator.value().get()); + if (avatar != _myAvatar.get() && avatar->isInitialized()) { removeAvatarMotionState(avatar); _avatarFades.push_back(avatarIterator.value()); _avatarHash.erase(avatarIterator); } + + render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::Scene::PendingChanges pendingChanges; + pendingChanges.removeItem(avatar->_renderItemID); + scene->enqueuePendingChanges(pendingChanges); } } @@ -208,8 +196,8 @@ void AvatarManager::clearOtherAvatars() { // clear any avatars that came from an avatar-mixer AvatarHash::iterator avatarIterator = _avatarHash.begin(); while (avatarIterator != _avatarHash.end()) { - Avatar* avatar = reinterpret_cast(avatarIterator.value().data()); - if (avatar == _myAvatar || !avatar->isInitialized()) { + Avatar* avatar = reinterpret_cast(avatarIterator.value().get()); + if (avatar == _myAvatar.get() || !avatar->isInitialized()) { // don't remove myAvatar or uninitialized avatars from the list ++avatarIterator; } else { @@ -276,7 +264,7 @@ void AvatarManager::handleCollisionEvents(CollisionEvents& collisionEvents) { void AvatarManager::updateAvatarPhysicsShape(const QUuid& id) { AvatarHash::iterator avatarItr = _avatarHash.find(id); if (avatarItr != _avatarHash.end()) { - Avatar* avatar = static_cast(avatarItr.value().data()); + Avatar* avatar = static_cast(avatarItr.value().get()); AvatarMotionState* motionState = avatar->_motionState; if (motionState) { motionState->addDirtyFlags(EntityItem::DIRTY_SHAPE); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index bc4f7765d8..b4482c5a34 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -35,11 +35,10 @@ public: void init(); - MyAvatar* getMyAvatar() { return _myAvatar.data(); } + MyAvatar* getMyAvatar() { return _myAvatar.get(); } void updateMyAvatar(float deltaTime); void updateOtherAvatars(float deltaTime); - void renderAvatars(RenderArgs* renderArgs, bool postLighting = false, bool selfAvatarOnly = false); void clearOtherAvatars(); @@ -70,7 +69,6 @@ private: AvatarManager(const AvatarManager& other); void simulateAvatarFades(float deltaTime); - void renderAvatarFades(RenderArgs* renderArgs, const glm::vec3& cameraPosition); // virtual overrides virtual AvatarSharedPointer newSharedAvatar(); @@ -79,7 +77,7 @@ private: virtual void removeAvatar(const QUuid& sessionUUID); QVector _avatarFades; - QSharedPointer _myAvatar; + std::shared_ptr _myAvatar; quint64 _lastSendAvatarDataTime = 0; // Controls MyAvatar send data rate. QVector _localLights; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e1f62f616e..bdf66eb1b5 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -105,7 +105,7 @@ MyAvatar::MyAvatar() : } MyAvatar::~MyAvatar() { - _lookAtTargetAvatar.clear(); + _lookAtTargetAvatar.reset(); } QByteArray MyAvatar::toByteArray() { @@ -335,7 +335,7 @@ void MyAvatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, b } Avatar::render(renderArgs, cameraPosition, postLighting); - + // don't display IK constraints in shadow mode if (Menu::getInstance()->isOptionChecked(MenuOption::ShowIKConstraints) && postLighting) { _skeletonModel.renderIKConstraints(); @@ -856,7 +856,7 @@ void MyAvatar::updateLookAtTargetAvatar() { // // Look at the avatar whose eyes are closest to the ray in direction of my avatar's head // - _lookAtTargetAvatar.clear(); + _lookAtTargetAvatar.reset(); _targetAvatarPosition = glm::vec3(0.0f); glm::vec3 lookForward = getHead()->getFinalOrientationInWorldFrame() * IDENTITY_FRONT; @@ -868,7 +868,7 @@ void MyAvatar::updateLookAtTargetAvatar() { int howManyLookingAtMe = 0; foreach (const AvatarSharedPointer& avatarPointer, DependencyManager::get()->getAvatarHash()) { - Avatar* avatar = static_cast(avatarPointer.data()); + Avatar* avatar = static_cast(avatarPointer.get()); bool isCurrentTarget = avatar->getIsLookAtTarget(); float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition); avatar->setIsLookAtTarget(false); @@ -896,13 +896,14 @@ void MyAvatar::updateLookAtTargetAvatar() { } } } - if (_lookAtTargetAvatar) { - static_cast(_lookAtTargetAvatar.data())->setIsLookAtTarget(true); + auto avatarPointer = _lookAtTargetAvatar.lock(); + if (avatarPointer) { + static_cast(avatarPointer.get())->setIsLookAtTarget(true); } } void MyAvatar::clearLookAtTargetAvatar() { - _lookAtTargetAvatar.clear(); + _lookAtTargetAvatar.reset(); } bool MyAvatar::isLookingAtLeftEye() { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 34264f5808..c8d16e8cb0 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -37,9 +37,9 @@ public: void simulate(float deltaTime); void updateFromTrackers(float deltaTime); - void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting = false); - void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel = 0.0f); - bool shouldRenderHead(const RenderArgs* renderArgs, const glm::vec3& cameraPosition) const override; + virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting = false) override; + virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel = 0.0f) override; + virtual bool shouldRenderHead(const RenderArgs* renderArgs, const glm::vec3& cameraPosition) const override; void renderDebugBodyPoints(); // setters @@ -108,7 +108,7 @@ public: Q_INVOKABLE glm::vec3 getEyePosition() const { return getHead()->getEyePosition(); } Q_INVOKABLE glm::vec3 getTargetAvatarPosition() const { return _targetAvatarPosition; } - QWeakPointer getLookAtTargetAvatar() const { return _lookAtTargetAvatar; } + AvatarWeakPointer getLookAtTargetAvatar() const { return _lookAtTargetAvatar; } void updateLookAtTargetAvatar(); void clearLookAtTargetAvatar(); @@ -226,7 +226,7 @@ private: DynamicCharacterController _characterController; - QWeakPointer _lookAtTargetAvatar; + AvatarWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; bool _shouldRender; bool _billboardValid; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 603b5d76ea..00a970d2b5 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -13,6 +13,7 @@ #define hifi_AvatarData_h #include +#include /* VS2010 defines stdint.h, but not inttypes.h */ #if defined(_MSC_VER) typedef signed char int8_t; @@ -57,6 +58,10 @@ typedef unsigned long long quint64; #include "Recorder.h" #include "Referential.h" +typedef std::shared_ptr AvatarSharedPointer; +typedef std::weak_ptr AvatarWeakPointer; +typedef QHash AvatarHash; + // avatar motion behaviors const quint32 AVATAR_MOTION_KEYBOARD_MOTOR_ENABLED = 1U << 0; const quint32 AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED = 1U << 1; diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 9204826d03..45edbf8d5a 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -16,16 +16,14 @@ #include #include +#include + #include #include #include "AvatarData.h" #include -typedef QSharedPointer AvatarSharedPointer; -typedef QWeakPointer AvatarWeakPointer; -typedef QHash AvatarHash; - class AvatarHashMap : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY