mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 19:59:28 +02:00
Merge pull request #14079 from luiscuenca/simpleAvatarTransit
Simple avatar transit
This commit is contained in:
commit
6290b56383
13 changed files with 236 additions and 10 deletions
|
@ -48,6 +48,10 @@ AvatarActionHold::~AvatarActionHold() {
|
||||||
myAvatar->removeHoldAction(this);
|
myAvatar->removeHoldAction(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto ownerEntity = _ownerEntity.lock();
|
||||||
|
if (ownerEntity) {
|
||||||
|
ownerEntity->setTransitingWithAvatar(false);
|
||||||
|
}
|
||||||
|
|
||||||
#if WANT_DEBUG
|
#if WANT_DEBUG
|
||||||
qDebug() << "AvatarActionHold::~AvatarActionHold" << (void*)this;
|
qDebug() << "AvatarActionHold::~AvatarActionHold" << (void*)this;
|
||||||
|
@ -131,6 +135,15 @@ bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::
|
||||||
glm::vec3 palmPosition;
|
glm::vec3 palmPosition;
|
||||||
glm::quat palmRotation;
|
glm::quat palmRotation;
|
||||||
|
|
||||||
|
bool isTransitingWithAvatar = holdingAvatar->getTransit()->isTransiting();
|
||||||
|
if (isTransitingWithAvatar != _isTransitingWithAvatar) {
|
||||||
|
_isTransitingWithAvatar = isTransitingWithAvatar;
|
||||||
|
auto ownerEntity = _ownerEntity.lock();
|
||||||
|
if (ownerEntity) {
|
||||||
|
ownerEntity->setTransitingWithAvatar(_isTransitingWithAvatar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (holdingAvatar->isMyAvatar()) {
|
if (holdingAvatar->isMyAvatar()) {
|
||||||
std::shared_ptr<MyAvatar> myAvatar = avatarManager->getMyAvatar();
|
std::shared_ptr<MyAvatar> myAvatar = avatarManager->getMyAvatar();
|
||||||
|
|
||||||
|
@ -404,11 +417,14 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) {
|
||||||
_kinematicSetVelocity = kinematicSetVelocity;
|
_kinematicSetVelocity = kinematicSetVelocity;
|
||||||
_ignoreIK = ignoreIK;
|
_ignoreIK = ignoreIK;
|
||||||
_active = true;
|
_active = true;
|
||||||
|
|
||||||
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
|
|
||||||
auto ownerEntity = _ownerEntity.lock();
|
auto ownerEntity = _ownerEntity.lock();
|
||||||
if (ownerEntity) {
|
if (ownerEntity) {
|
||||||
ownerEntity->setDynamicDataDirty(true);
|
ownerEntity->setDynamicDataDirty(true);
|
||||||
ownerEntity->setDynamicDataNeedsTransmit(true);
|
ownerEntity->setDynamicDataNeedsTransmit(true);
|
||||||
|
ownerEntity->setTransitingWithAvatar(myAvatar->getTransit()->isTransiting());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ private:
|
||||||
bool _kinematicSetVelocity { false };
|
bool _kinematicSetVelocity { false };
|
||||||
bool _previousSet { false };
|
bool _previousSet { false };
|
||||||
bool _ignoreIK { false };
|
bool _ignoreIK { false };
|
||||||
|
bool _isTransitingWithAvatar { false };
|
||||||
|
|
||||||
glm::vec3 _previousPositionalTarget;
|
glm::vec3 _previousPositionalTarget;
|
||||||
glm::quat _previousRotationalTarget;
|
glm::quat _previousRotationalTarget;
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,15 @@ AvatarManager::AvatarManager(QObject* parent) :
|
||||||
removeAvatar(nodeID, KillAvatarReason::AvatarIgnored);
|
removeAvatar(nodeID, KillAvatarReason::AvatarIgnored);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const float AVATAR_TRANSIT_TRIGGER_DISTANCE = 1.0f;
|
||||||
|
const int AVATAR_TRANSIT_FRAME_COUNT = 11; // Based on testing
|
||||||
|
const int AVATAR_TRANSIT_FRAMES_PER_METER = 1; // Based on testing
|
||||||
|
|
||||||
|
_transitConfig._totalFrames = AVATAR_TRANSIT_FRAME_COUNT;
|
||||||
|
_transitConfig._triggerDistance = AVATAR_TRANSIT_TRIGGER_DISTANCE;
|
||||||
|
_transitConfig._framesPerMeter = AVATAR_TRANSIT_FRAMES_PER_METER;
|
||||||
|
_transitConfig._isDistanceBased = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||||
|
@ -129,6 +138,10 @@ void AvatarManager::updateMyAvatar(float deltaTime) {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "AvatarManager::updateMyAvatar()");
|
PerformanceWarning warn(showWarnings, "AvatarManager::updateMyAvatar()");
|
||||||
|
|
||||||
|
AvatarTransit::Status status = _myAvatar->updateTransit(deltaTime, _myAvatar->getNextPosition(), _transitConfig);
|
||||||
|
bool sendFirstTransitPackage = (status == AvatarTransit::Status::START_TRANSIT);
|
||||||
|
bool blockTransitData = (status == AvatarTransit::Status::TRANSITING);
|
||||||
|
|
||||||
_myAvatar->update(deltaTime);
|
_myAvatar->update(deltaTime);
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
_myAvatar->updateRenderItem(transaction);
|
_myAvatar->updateRenderItem(transaction);
|
||||||
|
@ -137,9 +150,13 @@ void AvatarManager::updateMyAvatar(float deltaTime) {
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
quint64 dt = now - _lastSendAvatarDataTime;
|
quint64 dt = now - _lastSendAvatarDataTime;
|
||||||
|
|
||||||
if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !_myAvatarDataPacketsPaused) {
|
|
||||||
|
if (sendFirstTransitPackage || (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !_myAvatarDataPacketsPaused && !blockTransitData)) {
|
||||||
// send head/hand data to the avatar mixer and voxel server
|
// send head/hand data to the avatar mixer and voxel server
|
||||||
PerformanceTimer perfTimer("send");
|
PerformanceTimer perfTimer("send");
|
||||||
|
if (sendFirstTransitPackage) {
|
||||||
|
_myAvatar->overrideNextPackagePositionData(_myAvatar->getTransit()->getEndPosition());
|
||||||
|
}
|
||||||
_myAvatar->sendAvatarDataPacket();
|
_myAvatar->sendAvatarDataPacket();
|
||||||
_lastSendAvatarDataTime = now;
|
_lastSendAvatarDataTime = now;
|
||||||
_myAvatarSendRate.increment();
|
_myAvatarSendRate.increment();
|
||||||
|
@ -258,6 +275,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
if (inView && avatar->hasNewJointData()) {
|
if (inView && avatar->hasNewJointData()) {
|
||||||
numAvatarsUpdated++;
|
numAvatarsUpdated++;
|
||||||
}
|
}
|
||||||
|
avatar->_transit.update(deltaTime, avatar->_globalPosition, _transitConfig);
|
||||||
avatar->simulate(deltaTime, inView);
|
avatar->simulate(deltaTime, inView);
|
||||||
avatar->updateRenderItem(renderTransaction);
|
avatar->updateRenderItem(renderTransaction);
|
||||||
avatar->updateSpaceProxy(workloadTransaction);
|
avatar->updateSpaceProxy(workloadTransaction);
|
||||||
|
@ -811,7 +829,7 @@ void AvatarManager::setAvatarSortCoefficient(const QString& name, const QScriptV
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap AvatarManager::getPalData(const QList<QString> specificAvatarIdentifiers) {
|
QVariantMap AvatarManager::getPalData(const QList<QString> specificAvatarIdentifiers) {
|
||||||
QJsonArray palData;
|
QJsonArray palData;
|
||||||
|
|
||||||
auto avatarMap = getHashCopy();
|
auto avatarMap = getHashCopy();
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "MyAvatar.h"
|
#include "MyAvatar.h"
|
||||||
#include "OtherAvatar.h"
|
#include "OtherAvatar.h"
|
||||||
|
|
||||||
|
|
||||||
using SortedAvatar = std::pair<float, std::shared_ptr<Avatar>>;
|
using SortedAvatar = std::pair<float, std::shared_ptr<Avatar>>;
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -232,6 +233,8 @@ private:
|
||||||
mutable std::mutex _spaceLock;
|
mutable std::mutex _spaceLock;
|
||||||
workload::SpacePointer _space;
|
workload::SpacePointer _space;
|
||||||
std::vector<int32_t> _spaceProxiesToDelete;
|
std::vector<int32_t> _spaceProxiesToDelete;
|
||||||
|
|
||||||
|
AvatarTransit::TransitConfig _transitConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AvatarManager_h
|
#endif // hifi_AvatarManager_h
|
||||||
|
|
|
@ -638,9 +638,8 @@ void MyAvatar::updateChildCauterization(SpatiallyNestablePointer object, bool ca
|
||||||
|
|
||||||
void MyAvatar::simulate(float deltaTime) {
|
void MyAvatar::simulate(float deltaTime) {
|
||||||
PerformanceTimer perfTimer("simulate");
|
PerformanceTimer perfTimer("simulate");
|
||||||
|
|
||||||
animateScaleChanges(deltaTime);
|
animateScaleChanges(deltaTime);
|
||||||
|
|
||||||
setFlyingEnabled(getFlyingEnabled());
|
setFlyingEnabled(getFlyingEnabled());
|
||||||
|
|
||||||
if (_cauterizationNeedsUpdate) {
|
if (_cauterizationNeedsUpdate) {
|
||||||
|
@ -928,6 +927,7 @@ void MyAvatar::updateSensorToWorldMatrix() {
|
||||||
updateJointFromController(controller::Action::RIGHT_HAND, _controllerRightHandMatrixCache);
|
updateJointFromController(controller::Action::RIGHT_HAND, _controllerRightHandMatrixCache);
|
||||||
|
|
||||||
if (hasSensorToWorldScaleChanged) {
|
if (hasSensorToWorldScaleChanged) {
|
||||||
|
setTransitScale(sensorToWorldScale);
|
||||||
emit sensorToWorldScaleChanged(sensorToWorldScale);
|
emit sensorToWorldScaleChanged(sensorToWorldScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1115,6 +1115,8 @@ public:
|
||||||
virtual QVariantList getAttachmentsVariant() const override;
|
virtual QVariantList getAttachmentsVariant() const override;
|
||||||
virtual void setAttachmentsVariant(const QVariantList& variant) override;
|
virtual void setAttachmentsVariant(const QVariantList& variant) override;
|
||||||
|
|
||||||
|
glm::vec3 getNextPosition() { return _goToPending ? _goToPosition : getWorldPosition(); };
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
|
|
@ -113,6 +113,80 @@ void Avatar::setShowNamesAboveHeads(bool show) {
|
||||||
showNamesAboveHeads = show;
|
showNamesAboveHeads = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& avatarPosition, const AvatarTransit::TransitConfig& config) {
|
||||||
|
glm::vec3 currentPosition = _isTransiting ? _currentPosition : avatarPosition;
|
||||||
|
float oneFrameDistance = glm::length(currentPosition - _lastPosition);
|
||||||
|
const float MAX_TRANSIT_DISTANCE = 30.0f;
|
||||||
|
float scaledMaxTransitDistance = MAX_TRANSIT_DISTANCE * _scale;
|
||||||
|
if (oneFrameDistance > config._triggerDistance && oneFrameDistance < scaledMaxTransitDistance && !_isTransiting) {
|
||||||
|
start(deltaTime, _lastPosition, currentPosition, config);
|
||||||
|
}
|
||||||
|
_lastPosition = currentPosition;
|
||||||
|
_status = updatePosition(deltaTime);
|
||||||
|
return _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarTransit::start(float deltaTime, const glm::vec3& startPosition, const glm::vec3& endPosition, const AvatarTransit::TransitConfig& config) {
|
||||||
|
_startPosition = startPosition;
|
||||||
|
_endPosition = endPosition;
|
||||||
|
|
||||||
|
_transitLine = endPosition - startPosition;
|
||||||
|
_totalDistance = glm::length(_transitLine);
|
||||||
|
_easeType = config._easeType;
|
||||||
|
const float REFERENCE_FRAMES_PER_SECOND = 30.0f;
|
||||||
|
|
||||||
|
int transitFrames = (!config._isDistanceBased) ? config._totalFrames : config._framesPerMeter * _totalDistance;
|
||||||
|
_totalTime = (float)transitFrames / REFERENCE_FRAMES_PER_SECOND;
|
||||||
|
_currentTime = 0.0f;
|
||||||
|
_isTransiting = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AvatarTransit::getEaseValue(AvatarTransit::EaseType type, float value) {
|
||||||
|
switch (type) {
|
||||||
|
case EaseType::NONE:
|
||||||
|
return value;
|
||||||
|
break;
|
||||||
|
case EaseType::EASE_IN:
|
||||||
|
return value * value;
|
||||||
|
break;
|
||||||
|
case EaseType::EASE_OUT:
|
||||||
|
return value * (2.0f - value);
|
||||||
|
break;
|
||||||
|
case EaseType::EASE_IN_OUT:
|
||||||
|
return (value < 0.5f) ? 2.0f * value * value : -1.0f + (4.0f - 2.0f * value) * value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
AvatarTransit::Status AvatarTransit::updatePosition(float deltaTime) {
|
||||||
|
Status status = Status::IDLE;
|
||||||
|
if (_isTransiting) {
|
||||||
|
float nextTime = _currentTime + deltaTime;
|
||||||
|
glm::vec3 newPosition;
|
||||||
|
if (nextTime >= _totalTime) {
|
||||||
|
_currentPosition = _endPosition;
|
||||||
|
_isTransiting = false;
|
||||||
|
status = Status::END_TRANSIT;
|
||||||
|
} else {
|
||||||
|
if (_currentTime == 0) {
|
||||||
|
status = Status::START_TRANSIT;
|
||||||
|
} else {
|
||||||
|
status = Status::TRANSITING;
|
||||||
|
}
|
||||||
|
float percentageIntoTransit = nextTime / _totalTime;
|
||||||
|
_currentPosition = _startPosition + getEaseValue(_easeType, percentageIntoTransit) * _transitLine;
|
||||||
|
}
|
||||||
|
_currentTime = nextTime;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AvatarTransit::getNextPosition(glm::vec3& nextPosition) {
|
||||||
|
nextPosition = _currentPosition;
|
||||||
|
return _isTransiting;
|
||||||
|
}
|
||||||
|
|
||||||
Avatar::Avatar(QThread* thread) :
|
Avatar::Avatar(QThread* thread) :
|
||||||
_voiceSphereID(GeometryCache::UNKNOWN_ID)
|
_voiceSphereID(GeometryCache::UNKNOWN_ID)
|
||||||
{
|
{
|
||||||
|
@ -449,7 +523,18 @@ void Avatar::relayJointDataToChildren() {
|
||||||
|
|
||||||
void Avatar::simulate(float deltaTime, bool inView) {
|
void Avatar::simulate(float deltaTime, bool inView) {
|
||||||
PROFILE_RANGE(simulation, "simulate");
|
PROFILE_RANGE(simulation, "simulate");
|
||||||
|
|
||||||
|
if (_transit.isTransiting()) {
|
||||||
|
glm::vec3 nextPosition;
|
||||||
|
if (_transit.getNextPosition(nextPosition)) {
|
||||||
|
_globalPosition = nextPosition;
|
||||||
|
_globalPositionChanged = usecTimestampNow();
|
||||||
|
if (!hasParent()) {
|
||||||
|
setLocalPosition(nextPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_simulationRate.increment();
|
_simulationRate.increment();
|
||||||
if (inView) {
|
if (inView) {
|
||||||
_simulationInViewRate.increment();
|
_simulationInViewRate.increment();
|
||||||
|
@ -460,7 +545,7 @@ void Avatar::simulate(float deltaTime, bool inView) {
|
||||||
PROFILE_RANGE(simulation, "updateJoints");
|
PROFILE_RANGE(simulation, "updateJoints");
|
||||||
if (inView) {
|
if (inView) {
|
||||||
Head* head = getHead();
|
Head* head = getHead();
|
||||||
if (_hasNewJointData) {
|
if (_hasNewJointData || _transit.isTransiting()) {
|
||||||
_skeletonModel->getRig().copyJointsFromJointData(_jointData);
|
_skeletonModel->getRig().copyJointsFromJointData(_jointData);
|
||||||
glm::mat4 rootTransform = glm::scale(_skeletonModel->getScale()) * glm::translate(_skeletonModel->getOffset());
|
glm::mat4 rootTransform = glm::scale(_skeletonModel->getScale()) * glm::translate(_skeletonModel->getOffset());
|
||||||
_skeletonModel->getRig().computeExternalPoses(rootTransform);
|
_skeletonModel->getRig().computeExternalPoses(rootTransform);
|
||||||
|
@ -1881,6 +1966,22 @@ float Avatar::getUnscaledEyeHeightFromSkeleton() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AvatarTransit::Status Avatar::updateTransit(float deltaTime, const glm::vec3& avatarPosition, const AvatarTransit::TransitConfig& config) {
|
||||||
|
std::lock_guard<std::mutex> lock(_transitLock);
|
||||||
|
return _transit.update(deltaTime, avatarPosition, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Avatar::setTransitScale(float scale) {
|
||||||
|
std::lock_guard<std::mutex> lock(_transitLock);
|
||||||
|
return _transit.setScale(scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Avatar::overrideNextPackagePositionData(const glm::vec3& position) {
|
||||||
|
std::lock_guard<std::mutex> lock(_transitLock);
|
||||||
|
_overrideGlobalPosition = true;
|
||||||
|
_globalPositionOverride = position;
|
||||||
|
}
|
||||||
|
|
||||||
void Avatar::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
void Avatar::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
std::lock_guard<std::mutex> lock(_materialsLock);
|
||||||
_materials[parentMaterialName].push(material);
|
_materials[parentMaterialName].push(material);
|
||||||
|
|
|
@ -50,6 +50,62 @@ enum ScreenTintLayer {
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
|
class AvatarTransit {
|
||||||
|
public:
|
||||||
|
enum Status {
|
||||||
|
IDLE = 0,
|
||||||
|
START_TRANSIT,
|
||||||
|
TRANSITING,
|
||||||
|
END_TRANSIT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EaseType {
|
||||||
|
NONE = 0,
|
||||||
|
EASE_IN,
|
||||||
|
EASE_OUT,
|
||||||
|
EASE_IN_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TransitConfig {
|
||||||
|
TransitConfig() {};
|
||||||
|
int _totalFrames { 0 };
|
||||||
|
int _framesPerMeter { 0 };
|
||||||
|
bool _isDistanceBased { false };
|
||||||
|
float _triggerDistance { 0 };
|
||||||
|
EaseType _easeType { EaseType::EASE_OUT };
|
||||||
|
};
|
||||||
|
|
||||||
|
AvatarTransit() {};
|
||||||
|
Status update(float deltaTime, const glm::vec3& avatarPosition, const TransitConfig& config);
|
||||||
|
Status getStatus() { return _status; }
|
||||||
|
bool isTransiting() { return _isTransiting; }
|
||||||
|
glm::vec3 getCurrentPosition() { return _currentPosition; }
|
||||||
|
bool getNextPosition(glm::vec3& nextPosition);
|
||||||
|
glm::vec3 getEndPosition() { return _endPosition; }
|
||||||
|
float getTransitTime() { return _totalTime; }
|
||||||
|
void setScale(float scale) { _scale = scale; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Status updatePosition(float deltaTime);
|
||||||
|
void start(float deltaTime, const glm::vec3& startPosition, const glm::vec3& endPosition, const TransitConfig& config);
|
||||||
|
float getEaseValue(AvatarTransit::EaseType type, float value);
|
||||||
|
bool _isTransiting { false };
|
||||||
|
|
||||||
|
glm::vec3 _startPosition;
|
||||||
|
glm::vec3 _endPosition;
|
||||||
|
glm::vec3 _currentPosition;
|
||||||
|
|
||||||
|
glm::vec3 _lastPosition;
|
||||||
|
|
||||||
|
glm::vec3 _transitLine;
|
||||||
|
float _totalDistance { 0.0f };
|
||||||
|
float _totalTime { 0.0f };
|
||||||
|
float _currentTime { 0.0f };
|
||||||
|
EaseType _easeType { EaseType::EASE_OUT };
|
||||||
|
Status _status { Status::IDLE };
|
||||||
|
float _scale { 1.0f };
|
||||||
|
};
|
||||||
|
|
||||||
class Avatar : public AvatarData, public scriptable::ModelProvider {
|
class Avatar : public AvatarData, public scriptable::ModelProvider {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -370,6 +426,13 @@ public:
|
||||||
|
|
||||||
virtual scriptable::ScriptableModelBase getScriptableModel() override;
|
virtual scriptable::ScriptableModelBase getScriptableModel() override;
|
||||||
|
|
||||||
|
std::shared_ptr<AvatarTransit> getTransit() { return std::make_shared<AvatarTransit>(_transit); };
|
||||||
|
|
||||||
|
AvatarTransit::Status updateTransit(float deltaTime, const glm::vec3& avatarPosition, const AvatarTransit::TransitConfig& config);
|
||||||
|
void setTransitScale(float scale);
|
||||||
|
|
||||||
|
void overrideNextPackagePositionData(const glm::vec3& position);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void targetScaleChanged(float targetScale);
|
void targetScaleChanged(float targetScale);
|
||||||
|
|
||||||
|
@ -505,6 +568,7 @@ protected:
|
||||||
RateCounter<> _skeletonModelSimulationRate;
|
RateCounter<> _skeletonModelSimulationRate;
|
||||||
RateCounter<> _jointDataSimulationRate;
|
RateCounter<> _jointDataSimulationRate;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class AvatarEntityDataHash {
|
class AvatarEntityDataHash {
|
||||||
public:
|
public:
|
||||||
|
@ -528,6 +592,9 @@ protected:
|
||||||
bool _reconstructSoftEntitiesJointMap { false };
|
bool _reconstructSoftEntitiesJointMap { false };
|
||||||
float _modelScale { 1.0f };
|
float _modelScale { 1.0f };
|
||||||
|
|
||||||
|
AvatarTransit _transit;
|
||||||
|
std::mutex _transitLock;
|
||||||
|
|
||||||
static int _jointConesID;
|
static int _jointConesID;
|
||||||
|
|
||||||
int _voiceSphereID;
|
int _voiceSphereID;
|
||||||
|
|
|
@ -369,7 +369,12 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
|
|
||||||
if (hasAvatarGlobalPosition) {
|
if (hasAvatarGlobalPosition) {
|
||||||
auto startSection = destinationBuffer;
|
auto startSection = destinationBuffer;
|
||||||
AVATAR_MEMCPY(_globalPosition);
|
if (_overrideGlobalPosition) {
|
||||||
|
AVATAR_MEMCPY(_globalPositionOverride);
|
||||||
|
} else {
|
||||||
|
AVATAR_MEMCPY(_globalPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int numBytes = destinationBuffer - startSection;
|
int numBytes = destinationBuffer - startSection;
|
||||||
|
|
||||||
|
@ -2088,6 +2093,10 @@ void AvatarData::sendAvatarDataPacket(bool sendAll) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_overrideGlobalPosition) {
|
||||||
|
_overrideGlobalPosition = false;
|
||||||
|
}
|
||||||
|
|
||||||
doneEncoding(cullSmallData);
|
doneEncoding(cullSmallData);
|
||||||
|
|
||||||
static AvatarDataSequenceNumber sequenceNumber = 0;
|
static AvatarDataSequenceNumber sequenceNumber = 0;
|
||||||
|
|
|
@ -1372,7 +1372,8 @@ protected:
|
||||||
// where Entities are located. This is currently only used by the mixer to decide how often to send
|
// where Entities are located. This is currently only used by the mixer to decide how often to send
|
||||||
// updates about one avatar to another.
|
// updates about one avatar to another.
|
||||||
glm::vec3 _globalPosition { 0, 0, 0 };
|
glm::vec3 _globalPosition { 0, 0, 0 };
|
||||||
|
glm::vec3 _globalPositionOverride { 0, 0, 0 };
|
||||||
|
bool _overrideGlobalPosition { false };
|
||||||
|
|
||||||
quint64 _globalPositionChanged { 0 };
|
quint64 _globalPositionChanged { 0 };
|
||||||
quint64 _avatarBoundingBoxChanged { 0 };
|
quint64 _avatarBoundingBoxChanged { 0 };
|
||||||
|
|
|
@ -266,6 +266,7 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer<ReceivedMessag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// have the matching (or new) avatar parse the data from the packet
|
// have the matching (or new) avatar parse the data from the packet
|
||||||
int bytesRead = avatar->parseDataFromBuffer(byteArray);
|
int bytesRead = avatar->parseDataFromBuffer(byteArray);
|
||||||
message->seek(positionBeforeRead + bytesRead);
|
message->seek(positionBeforeRead + bytesRead);
|
||||||
|
@ -316,7 +317,6 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
|
||||||
// In this case, the "sendingNode" is the Avatar Mixer.
|
// In this case, the "sendingNode" is the Avatar Mixer.
|
||||||
avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged);
|
avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged);
|
||||||
_replicas.processAvatarIdentity(identityUUID, message->getMessage(), identityChanged, displayNameChanged);
|
_replicas.processAvatarIdentity(identityUUID, message->getMessage(), identityChanged, displayNameChanged);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +329,7 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer<ReceivedMessage> mess
|
||||||
// grab the avatar so we can ask it to process trait data
|
// grab the avatar so we can ask it to process trait data
|
||||||
bool isNewAvatar;
|
bool isNewAvatar;
|
||||||
auto avatar = newOrExistingAvatar(avatarID, sendingNode, isNewAvatar);
|
auto avatar = newOrExistingAvatar(avatarID, sendingNode, isNewAvatar);
|
||||||
|
|
||||||
// read the first trait type for this avatar
|
// read the first trait type for this avatar
|
||||||
AvatarTraits::TraitType traitType;
|
AvatarTraits::TraitType traitType;
|
||||||
message->readPrimitive(&traitType);
|
message->readPrimitive(&traitType);
|
||||||
|
|
|
@ -441,6 +441,8 @@ public:
|
||||||
|
|
||||||
void setDynamicDataNeedsTransmit(bool value) const { _dynamicDataNeedsTransmit = value; }
|
void setDynamicDataNeedsTransmit(bool value) const { _dynamicDataNeedsTransmit = value; }
|
||||||
bool dynamicDataNeedsTransmit() const { return _dynamicDataNeedsTransmit; }
|
bool dynamicDataNeedsTransmit() const { return _dynamicDataNeedsTransmit; }
|
||||||
|
void setTransitingWithAvatar(bool value) { _transitingWithAvatar = value; }
|
||||||
|
bool getTransitingWithAvatar() { return _transitingWithAvatar; }
|
||||||
|
|
||||||
bool shouldSuppressLocationEdits() const;
|
bool shouldSuppressLocationEdits() const;
|
||||||
|
|
||||||
|
@ -668,6 +670,7 @@ protected:
|
||||||
QUuid _sourceUUID; /// the server node UUID we came from
|
QUuid _sourceUUID; /// the server node UUID we came from
|
||||||
|
|
||||||
bool _clientOnly { false };
|
bool _clientOnly { false };
|
||||||
|
bool _transitingWithAvatar{ false };
|
||||||
QUuid _owningAvatarID;
|
QUuid _owningAvatarID;
|
||||||
|
|
||||||
// physics related changes from the network to suppress any duplicates and make
|
// physics related changes from the network to suppress any duplicates and make
|
||||||
|
|
|
@ -432,6 +432,9 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep) {
|
||||||
// this case is prevented by setting _ownershipState to UNOWNABLE in EntityMotionState::ctor
|
// this case is prevented by setting _ownershipState to UNOWNABLE in EntityMotionState::ctor
|
||||||
assert(!(_entity->getClientOnly() && _entity->getOwningAvatarID() != Physics::getSessionUUID()));
|
assert(!(_entity->getClientOnly() && _entity->getOwningAvatarID() != Physics::getSessionUUID()));
|
||||||
|
|
||||||
|
if (_entity->getTransitingWithAvatar()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (_entity->dynamicDataNeedsTransmit()) {
|
if (_entity->dynamicDataNeedsTransmit()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue