From 69a7b1ef76c4892f7ee28b4080c132f392d074b1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 23 Jan 2017 16:12:47 -0800 Subject: [PATCH] move some stuff out of Avatar::simulate() call it explicity in AvatarManager::updateOtherAvatars() --- interface/src/avatar/Avatar.cpp | 28 +++++++++++++++----------- interface/src/avatar/Avatar.h | 5 +++-- interface/src/avatar/AvatarManager.cpp | 22 ++++++++++++++++++++ interface/src/avatar/AvatarManager.h | 2 +- 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index c5c5dacfc6..208d265dcd 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -188,25 +188,35 @@ AABox Avatar::getBounds() const { } void Avatar::animateScaleChanges(float deltaTime) { - float currentScale = getUniformScale(); - auto desiredScale = getDomainLimitedScale(); - if (currentScale != desiredScale) { + if (_isAnimatingScale) { + float currentScale = getUniformScale(); + float desiredScale = getDomainLimitedScale(); + // use exponential decay toward the domain limit clamped scale const float SCALE_ANIMATION_TIMESCALE = 0.5f; float blendFactor = glm::clamp(deltaTime / SCALE_ANIMATION_TIMESCALE, 0.0f, 1.0f); float animatedScale = (1.0f - blendFactor) * currentScale + blendFactor * desiredScale; // snap to the end when we get close enough - const float MIN_RELATIVE_SCALE_ERROR = 0.03f; - if (fabsf(desiredScale - currentScale) / desiredScale < MIN_RELATIVE_SCALE_ERROR) { + const float MIN_RELATIVE_ERROR = 0.03f; + float relativeError = fabsf(desiredScale - currentScale) / desiredScale; + if (relativeError < MIN_RELATIVE_ERROR) { animatedScale = desiredScale; + _isAnimatingScale = false; } - setScale(glm::vec3(animatedScale)); // avatar scale is uniform + + // TODO: rebuilding the shape constantly is somehwat expensive. + // We should only rebuild after significant change. rebuildCollisionShape(); } } +void Avatar::setTargetScale(float targetScale) { + AvatarData::setTargetScale(targetScale); + _isAnimatingScale = true; +} + void Avatar::updateAvatarEntities() { PerformanceTimer perfTimer("attachments"); // - if queueEditEntityMessage sees clientOnly flag it does _myAvatar->updateAvatarEntity() @@ -311,12 +321,6 @@ bool Avatar::shouldDie() const { void Avatar::simulate(float deltaTime, bool inView) { PROFILE_RANGE(simulation, "simulate"); PerformanceTimer perfTimer("simulate"); - - if (!isDead() && !_motionState) { - DependencyManager::get()->addAvatarToSimulation(this); - } - animateScaleChanges(deltaTime); - { PROFILE_RANGE(simulation, "updateJoints"); uint64_t start = usecTimestampNow(); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index d6f588c47e..a6c5bbf16f 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -181,6 +181,8 @@ public: void setLastRenderUpdateTime(uint64_t time) { _lastRenderUpdateTime = time; } bool shouldDie() const; + void animateScaleChanges(float deltaTime); + void setTargetScale(float targetScale) override; public slots: @@ -231,8 +233,6 @@ protected: // protected methods... bool isLookingAtMe(AvatarSharedPointer avatar) const; - virtual void animateScaleChanges(float deltaTime); - glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; } glm::vec3 getBodyFrontDirection() const { return getOrientation() * IDENTITY_FRONT; } @@ -269,6 +269,7 @@ private: bool _initialized; bool _isLookAtTarget { false }; bool _inScene { false }; + bool _isAnimatingScale { false }; float getBoundingRadius() const; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index e3d3164b68..fa2ee2190c 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -175,6 +175,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { removeAvatar(avatar->getID()); continue; } + if (avatar->isDead()) { + continue; + } // priority = weighted linear combination of: // (a) apparentSize @@ -205,7 +208,24 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { while (!sortedAvatars.empty()) { const AvatarPriority& sortData = sortedAvatars.top(); const auto& avatar = std::static_pointer_cast(sortData.avatar); + + // for ALL avatars... avatar->ensureInScene(avatar); + if (!avatar->getMotionState()) { + ShapeInfo shapeInfo; + avatar->computeShapeInfo(shapeInfo); + btCollisionShape* shape = const_cast(ObjectMotionState::getShapeManager()->getShape(shapeInfo)); + if (shape) { + // don't add to the simulation now, instead put it on a list to be added later + AvatarMotionState* motionState = new AvatarMotionState(avatar.get(), shape); + avatar->setMotionState(motionState); + _motionStatesToAddToPhysics.insert(motionState); + _motionStatesThatMightUpdate.insert(motionState); + } + } + avatar->animateScaleChanges(deltaTime); + + // for avatars in view... const bool inView = sortData.priority > 0.5f * OUT_OF_VIEW_PENALTY; avatar->simulate(deltaTime, inView); if (expiry > usecTimestampNow()) { @@ -429,6 +449,7 @@ void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents } } +/* void AvatarManager::addAvatarToSimulation(Avatar* avatar) { assert(!avatar->getMotionState()); @@ -443,6 +464,7 @@ void AvatarManager::addAvatarToSimulation(Avatar* avatar) { _motionStatesThatMightUpdate.insert(motionState); } } +*/ void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) { if (DependencyManager::get()->shouldRenderAvatars()) { diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index a423e34f8f..efb01e071f 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -69,7 +69,7 @@ public: void handleOutgoingChanges(const VectorOfMotionStates& motionStates); void handleCollisionEvents(const CollisionEvents& collisionEvents); - void addAvatarToSimulation(Avatar* avatar); + //void addAvatarToSimulation(Avatar* avatar); Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersection(const PickRay& ray, const QScriptValue& avatarIdsToInclude = QScriptValue(),