avatar fading

This commit is contained in:
danteruiz 2019-03-27 16:42:34 -07:00
parent 6956d01099
commit 40d424a01d
9 changed files with 76 additions and 17 deletions

View file

@ -0,0 +1 @@
Dante@DESKTOP-TUOA3HH.30568:1553633650

View file

@ -210,7 +210,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
{ {
// lock the hash for read to check the size // lock the hash for read to check the size
QReadLocker lock(&_hashLock); QReadLocker lock(&_hashLock);
if (_avatarHash.size() < 2 && _avatarsToFadeOut.isEmpty()) { if (_avatarHash.size() < 2 && _avatarsToFadeOut.empty()) {
return; return;
} }
} }
@ -386,8 +386,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
_numAvatarsNotUpdated = numAvatarsNotUpdated; _numAvatarsNotUpdated = numAvatarsNotUpdated;
_numHeroAvatarsUpdated = numHerosUpdated; _numHeroAvatarsUpdated = numHerosUpdated;
simulateAvatarFades(deltaTime); removeFadedAvatars();
_avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC; _avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC;
} }
@ -400,18 +399,17 @@ void AvatarManager::postUpdate(float deltaTime, const render::ScenePointer& scen
} }
} }
void AvatarManager::simulateAvatarFades(float deltaTime) { void AvatarManager::removeFadedAvatars() {
if (_avatarsToFadeOut.empty()) { if (_avatarsToFadeOut.empty()) {
return; return;
} }
QReadLocker locker(&_hashLock); QReadLocker locker(&_hashLock);
QVector<AvatarSharedPointer>::iterator avatarItr = _avatarsToFadeOut.begin(); auto avatarItr = _avatarsToFadeOut.begin();
const render::ScenePointer& scene = qApp->getMain3DScene(); const render::ScenePointer& scene = qApp->getMain3DScene();
render::Transaction transaction; render::Transaction transaction;
while (avatarItr != _avatarsToFadeOut.end()) { while (avatarItr != _avatarsToFadeOut.end()) {
auto avatar = std::static_pointer_cast<Avatar>(*avatarItr); auto avatar = std::static_pointer_cast<Avatar>(*avatarItr);
avatar->updateFadingStatus();
if (!avatar->isFading()) { if (!avatar->isFading()) {
// fading to zero is such a rare event we push a unique transaction for each // fading to zero is such a rare event we push a unique transaction for each
if (avatar->isInScene()) { if (avatar->isInScene()) {
@ -452,7 +450,6 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact
transaction.objectsToRemove.push_back(mState); transaction.objectsToRemove.push_back(mState);
} }
avatar->resetDetailedMotionStates(); avatar->resetDetailedMotionStates();
} else { } else {
if (avatar->getDetailedMotionStates().size() == 0) { if (avatar->getDetailedMotionStates().size() == 0) {
avatar->createDetailedMotionStates(avatar); avatar->createDetailedMotionStates(avatar);
@ -541,8 +538,21 @@ void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar
// remove from node sets, if present // remove from node sets, if present
DependencyManager::get<NodeList>()->removeFromIgnoreMuteSets(avatar->getSessionUUID()); DependencyManager::get<NodeList>()->removeFromIgnoreMuteSets(avatar->getSessionUUID());
DependencyManager::get<UsersScriptingInterface>()->avatarDisconnected(avatar->getSessionUUID()); DependencyManager::get<UsersScriptingInterface>()->avatarDisconnected(avatar->getSessionUUID());
avatar->fadeOut(qApp->getMain3DScene(), removalReason); render::Transaction transaction;
auto scene = qApp->getMain3DScene();
avatar->fadeOut(scene, removalReason);
AvatarData* avatarData = removedAvatar.get();
transaction.transitionFinishedOperator(avatar->getRenderItemID(), [avatarDataWeakPtr]() {
auto avatarDataPtr = avatarDataWeakPtr.lock();
if (avatarDataPtr) {
auto avatar = std::static_pointer_cast<Avatar>(avatarDataPtr);
avatar->setIsFading(false);
}
});
} }
_avatarsToFadeOut.push_back(removedAvatar); _avatarsToFadeOut.push_back(removedAvatar);
} }

View file

@ -220,10 +220,10 @@ private:
explicit AvatarManager(QObject* parent = 0); explicit AvatarManager(QObject* parent = 0);
explicit AvatarManager(const AvatarManager& other); explicit AvatarManager(const AvatarManager& other);
void simulateAvatarFades(float deltaTime);
AvatarSharedPointer newSharedAvatar(const QUuid& sessionUUID) override; AvatarSharedPointer newSharedAvatar(const QUuid& sessionUUID) override;
void removeFadedAvatars();
// called only from the AvatarHashMap thread - cannot be called while this thread holds the // called only from the AvatarHashMap thread - cannot be called while this thread holds the
// hash lock, since handleRemovedAvatar needs a write lock on the entity tree and the entity tree // hash lock, since handleRemovedAvatar needs a write lock on the entity tree and the entity tree
// frequently grabs a read lock on the hash to get a given avatar by ID // frequently grabs a read lock on the hash to get a given avatar by ID
@ -231,8 +231,7 @@ private:
KillAvatarReason removalReason = KillAvatarReason::NoReason) override; KillAvatarReason removalReason = KillAvatarReason::NoReason) override;
void handleTransitAnimations(AvatarTransit::Status status); void handleTransitAnimations(AvatarTransit::Status status);
QVector<AvatarSharedPointer> _avatarsToFadeOut; std::vector<AvatarSharedPointer> _avatarsToFadeOut;
using SetOfOtherAvatars = std::set<OtherAvatarPointer>; using SetOfOtherAvatars = std::set<OtherAvatarPointer>;
SetOfOtherAvatars _avatarsToChangeInPhysics; SetOfOtherAvatars _avatarsToChangeInPhysics;

View file

@ -50,6 +50,7 @@ OtherAvatar::OtherAvatar(QThread* thread) : Avatar(thread) {
} }
OtherAvatar::~OtherAvatar() { OtherAvatar::~OtherAvatar() {
qDebug() << "-------->";
removeOrb(); removeOrb();
} }

View file

@ -463,6 +463,7 @@ public:
void fadeIn(render::ScenePointer scene); void fadeIn(render::ScenePointer scene);
void fadeOut(render::ScenePointer scene, KillAvatarReason reason); void fadeOut(render::ScenePointer scene, KillAvatarReason reason);
bool isFading() const { return _isFading; } bool isFading() const { return _isFading; }
void setIsFading(bool isFading) { _isFading = isFading; }
void updateFadingStatus(); void updateFadingStatus();
// JSDoc is in AvatarData.h. // JSDoc is in AvatarData.h.

View file

@ -132,6 +132,7 @@ AvatarData::AvatarData() :
} }
AvatarData::~AvatarData() { AvatarData::~AvatarData() {
qDebug() << "AvatarData::~AvatarData()";
delete _headData; delete _headData;
} }

View file

@ -47,6 +47,10 @@ void Transaction::queryTransitionOnItem(ItemID id, TransitionQueryFunc func) {
_queriedTransitions.emplace_back(id, func); _queriedTransitions.emplace_back(id, func);
} }
void Transaction::transitionFinishedOperator(ItemID id, TransitionFinishedFunc func) {
_transitionFinishedOperators.emplace_back(id, func);
}
void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) { void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) {
_updatedItems.emplace_back(id, functor); _updatedItems.emplace_back(id, functor);
} }
@ -75,6 +79,7 @@ void Transaction::reserve(const std::vector<Transaction>& transactionContainer)
size_t addedTransitionsCount = 0; size_t addedTransitionsCount = 0;
size_t queriedTransitionsCount = 0; size_t queriedTransitionsCount = 0;
size_t reAppliedTransitionsCount = 0; size_t reAppliedTransitionsCount = 0;
size_t transitionFinishedOperatorsCount = 0;
size_t highlightResetsCount = 0; size_t highlightResetsCount = 0;
size_t highlightRemovesCount = 0; size_t highlightRemovesCount = 0;
size_t highlightQueriesCount = 0; size_t highlightQueriesCount = 0;
@ -85,6 +90,7 @@ void Transaction::reserve(const std::vector<Transaction>& transactionContainer)
updatedItemsCount += transaction._updatedItems.size(); updatedItemsCount += transaction._updatedItems.size();
resetSelectionsCount += transaction._resetSelections.size(); resetSelectionsCount += transaction._resetSelections.size();
addedTransitionsCount += transaction._addedTransitions.size(); addedTransitionsCount += transaction._addedTransitions.size();
transitionFinishedOperatorsCount += transaction._transitionFinishedOperators.size();
queriedTransitionsCount += transaction._queriedTransitions.size(); queriedTransitionsCount += transaction._queriedTransitions.size();
reAppliedTransitionsCount += transaction._reAppliedTransitions.size(); reAppliedTransitionsCount += transaction._reAppliedTransitions.size();
highlightResetsCount += transaction._highlightResets.size(); highlightResetsCount += transaction._highlightResets.size();
@ -99,6 +105,7 @@ void Transaction::reserve(const std::vector<Transaction>& transactionContainer)
_addedTransitions.reserve(addedTransitionsCount); _addedTransitions.reserve(addedTransitionsCount);
_queriedTransitions.reserve(queriedTransitionsCount); _queriedTransitions.reserve(queriedTransitionsCount);
_reAppliedTransitions.reserve(reAppliedTransitionsCount); _reAppliedTransitions.reserve(reAppliedTransitionsCount);
_transitionFinishedOperators.reserve(transitionFinishedOperatorsCount);
_highlightResets.reserve(highlightResetsCount); _highlightResets.reserve(highlightResetsCount);
_highlightRemoves.reserve(highlightRemovesCount); _highlightRemoves.reserve(highlightRemovesCount);
_highlightQueries.reserve(highlightQueriesCount); _highlightQueries.reserve(highlightQueriesCount);
@ -142,6 +149,7 @@ void Transaction::merge(Transaction&& transaction) {
moveElements(_resetSelections, transaction._resetSelections); moveElements(_resetSelections, transaction._resetSelections);
moveElements(_addedTransitions, transaction._addedTransitions); moveElements(_addedTransitions, transaction._addedTransitions);
moveElements(_queriedTransitions, transaction._queriedTransitions); moveElements(_queriedTransitions, transaction._queriedTransitions);
moveElements(_transitionFinishedOperators, transaction._transitionFinishedOperators);
moveElements(_reAppliedTransitions, transaction._reAppliedTransitions); moveElements(_reAppliedTransitions, transaction._reAppliedTransitions);
moveElements(_highlightResets, transaction._highlightResets); moveElements(_highlightResets, transaction._highlightResets);
moveElements(_highlightRemoves, transaction._highlightRemoves); moveElements(_highlightRemoves, transaction._highlightRemoves);
@ -156,6 +164,7 @@ void Transaction::merge(const Transaction& transaction) {
copyElements(_addedTransitions, transaction._addedTransitions); copyElements(_addedTransitions, transaction._addedTransitions);
copyElements(_queriedTransitions, transaction._queriedTransitions); copyElements(_queriedTransitions, transaction._queriedTransitions);
copyElements(_reAppliedTransitions, transaction._reAppliedTransitions); copyElements(_reAppliedTransitions, transaction._reAppliedTransitions);
copyElements(_transitionFinishedOperators, transaction._transitionFinishedOperators);
copyElements(_highlightResets, transaction._highlightResets); copyElements(_highlightResets, transaction._highlightResets);
copyElements(_highlightRemoves, transaction._highlightRemoves); copyElements(_highlightRemoves, transaction._highlightRemoves);
copyElements(_highlightQueries, transaction._highlightQueries); copyElements(_highlightQueries, transaction._highlightQueries);
@ -168,6 +177,7 @@ void Transaction::clear() {
_resetSelections.clear(); _resetSelections.clear();
_addedTransitions.clear(); _addedTransitions.clear();
_queriedTransitions.clear(); _queriedTransitions.clear();
_transitionFinishedOperators.clear();
_reAppliedTransitions.clear(); _reAppliedTransitions.clear();
_highlightResets.clear(); _highlightResets.clear();
_highlightRemoves.clear(); _highlightRemoves.clear();
@ -261,6 +271,10 @@ void Scene::processTransactionFrame(const Transaction& transaction) {
// Update the numItemsAtomic counter AFTER the reset changes went through // Update the numItemsAtomic counter AFTER the reset changes went through
_numAllocatedItems.exchange(maxID); _numAllocatedItems.exchange(maxID);
// reset transition finished operator
resetTransitionFinishedOperator(transaction._transitionFinishedOperators);
// updates // updates
updateItems(transaction._updatedItems); updateItems(transaction._updatedItems);
@ -440,6 +454,18 @@ void Scene::queryTransitionItems(const Transaction::TransitionQueries& transacti
} }
} }
void Scene::resetTransitionFinishedOperator(const Transaction::TransitionFinishedOperators& transactions) {
for (auto& finishedOperator : transactions) {
auto itemId = std::get<0>(finishedOperator);
const auto& item = _items[itemId];
auto func = std::get<1>(finishedOperator);
if (item.exist() && func != nullptr) {
_transitionFinishedOperatorMap[itemId] = func;
}
}
}
void Scene::resetHighlights(const Transaction::HighlightResets& transactions) { void Scene::resetHighlights(const Transaction::HighlightResets& transactions) {
auto outlineStage = getStage<HighlightStage>(HighlightStage::getName()); auto outlineStage = getStage<HighlightStage>(HighlightStage::getName());
if (outlineStage) { if (outlineStage) {
@ -528,8 +554,18 @@ void Scene::resetItemTransition(ItemID itemId) {
auto& item = _items[itemId]; auto& item = _items[itemId];
if (!render::TransitionStage::isIndexInvalid(item.getTransitionId())) { if (!render::TransitionStage::isIndexInvalid(item.getTransitionId())) {
auto transitionStage = getStage<TransitionStage>(TransitionStage::getName()); auto transitionStage = getStage<TransitionStage>(TransitionStage::getName());
transitionStage->removeTransition(item.getTransitionId()); auto transitionItemId = transitionStage->getTransition(item.getTransitionId()).itemId;
setItemTransition(itemId, render::TransitionStage::INVALID_INDEX);
if (transitionItemId == itemId) {
auto transitionFinishedOperator = _transitionFinishedOperatorMap[transitionItemId];
if (transitionFinishedOperator) {
transitionFinishedOperator();
_transitionFinishedOperatorMap[transitionItemId] = nullptr;
}
transitionStage->removeTransition(item.getTransitionId());
setItemTransition(itemId, render::TransitionStage::INVALID_INDEX);
}
} }
} }
@ -587,4 +623,4 @@ void Scene::resetStage(const Stage::Name& name, const StagePointer& stage) {
} else { } else {
(*found).second = stage; (*found).second = stage;
} }
} }

View file

@ -32,12 +32,14 @@ class Scene;
// These changes must be expressed through the corresponding command from the Transaction // These changes must be expressed through the corresponding command from the Transaction
// THe Transaction is then queued on the Scene so all the pending transactions can be consolidated and processed at the time // THe Transaction is then queued on the Scene so all the pending transactions can be consolidated and processed at the time
// of updating the scene before it s rendered. // of updating the scene before it s rendered.
// //
class Transaction { class Transaction {
friend class Scene; friend class Scene;
public: public:
typedef std::function<void(ItemID, const Transition*)> TransitionQueryFunc; typedef std::function<void(ItemID, const Transition*)> TransitionQueryFunc;
typedef std::function<void()> TransitionFinishedFunc;
typedef std::function<void(HighlightStyle const*)> SelectionHighlightQueryFunc; typedef std::function<void(HighlightStyle const*)> SelectionHighlightQueryFunc;
Transaction() {} Transaction() {}
@ -52,6 +54,7 @@ public:
void removeTransitionFromItem(ItemID id); void removeTransitionFromItem(ItemID id);
void reApplyTransitionToItem(ItemID id); void reApplyTransitionToItem(ItemID id);
void queryTransitionOnItem(ItemID id, TransitionQueryFunc func); void queryTransitionOnItem(ItemID id, TransitionQueryFunc func);
void transitionFinishedOperator(ItemID id, TransitionFinishedFunc func);
template <class T> void updateItem(ItemID id, std::function<void(T&)> func) { template <class T> void updateItem(ItemID id, std::function<void(T&)> func) {
updateItem(id, std::make_shared<UpdateFunctor<T>>(func)); updateItem(id, std::make_shared<UpdateFunctor<T>>(func));
@ -84,6 +87,7 @@ protected:
using Update = std::tuple<ItemID, UpdateFunctorPointer>; using Update = std::tuple<ItemID, UpdateFunctorPointer>;
using TransitionAdd = std::tuple<ItemID, Transition::Type, ItemID>; using TransitionAdd = std::tuple<ItemID, Transition::Type, ItemID>;
using TransitionQuery = std::tuple<ItemID, TransitionQueryFunc>; using TransitionQuery = std::tuple<ItemID, TransitionQueryFunc>;
using TransitionFinishedOperator = std::tuple<ItemID, TransitionFinishedFunc>;
using TransitionReApply = ItemID; using TransitionReApply = ItemID;
using SelectionReset = Selection; using SelectionReset = Selection;
using HighlightReset = std::tuple<std::string, HighlightStyle>; using HighlightReset = std::tuple<std::string, HighlightStyle>;
@ -95,6 +99,7 @@ protected:
using Updates = std::vector<Update>; using Updates = std::vector<Update>;
using TransitionAdds = std::vector<TransitionAdd>; using TransitionAdds = std::vector<TransitionAdd>;
using TransitionQueries = std::vector<TransitionQuery>; using TransitionQueries = std::vector<TransitionQuery>;
using TransitionFinishedOperators = std::vector<TransitionFinishedOperator>;
using TransitionReApplies = std::vector<TransitionReApply>; using TransitionReApplies = std::vector<TransitionReApply>;
using SelectionResets = std::vector<SelectionReset>; using SelectionResets = std::vector<SelectionReset>;
using HighlightResets = std::vector<HighlightReset>; using HighlightResets = std::vector<HighlightReset>;
@ -107,6 +112,7 @@ protected:
TransitionAdds _addedTransitions; TransitionAdds _addedTransitions;
TransitionQueries _queriedTransitions; TransitionQueries _queriedTransitions;
TransitionReApplies _reAppliedTransitions; TransitionReApplies _reAppliedTransitions;
TransitionFinishedOperators _transitionFinishedOperators;
SelectionResets _resetSelections; SelectionResets _resetSelections;
HighlightResets _highlightResets; HighlightResets _highlightResets;
HighlightRemoves _highlightRemoves; HighlightRemoves _highlightRemoves;
@ -208,6 +214,7 @@ protected:
ItemIDSet _masterNonspatialSet; ItemIDSet _masterNonspatialSet;
void resetItems(const Transaction::Resets& transactions); void resetItems(const Transaction::Resets& transactions);
void resetTransitionFinishedOperator(const Transaction::TransitionFinishedOperators& transactions);
void removeItems(const Transaction::Removes& transactions); void removeItems(const Transaction::Removes& transactions);
void updateItems(const Transaction::Updates& transactions); void updateItems(const Transaction::Updates& transactions);
void transitionItems(const Transaction::TransitionAdds& transactions); void transitionItems(const Transaction::TransitionAdds& transactions);
@ -223,6 +230,9 @@ protected:
mutable std::mutex _selectionsMutex; // mutable so it can be used in the thread safe getSelection const method mutable std::mutex _selectionsMutex; // mutable so it can be used in the thread safe getSelection const method
SelectionMap _selections; SelectionMap _selections;
mutable std::mutex _transitionFinishedOperatorMapMutex;
std::unordered_map<ItemID, Transaction::TransitionFinishedFunc> _transitionFinishedOperatorMap;
void resetSelections(const Transaction::SelectionResets& transactions); void resetSelections(const Transaction::SelectionResets& transactions);
// More actions coming to selections soon: // More actions coming to selections soon:
// void removeFromSelection(const Selection& selection); // void removeFromSelection(const Selection& selection);

View file

@ -50,4 +50,4 @@ namespace render {
typedef std::vector<Transition::Type> TransitionTypes; typedef std::vector<Transition::Type> TransitionTypes;
} }
#endif // hifi_render_Transition_h #endif // hifi_render_Transition_h