16 #include <glm/glm.hpp>
17 #include <glm/gtc/quaternion.hpp>
22 #include <QtCore/QUuid>
24 #include <AvatarData.h>
25 #include <ShapeInfo.h>
26 #include <render/Scene.h>
27 #include <graphics-scripting/Forward.h>
28 #include <GLMHelpers.h>
29 #include <EntityItem.h>
32 #include <ThreadSafeValueCache.h>
35 #include "SkeletonModel.h"
38 #include "MetaModelPayload.h"
39 #include "MultiSphereShape.h"
42 template <>
const ItemKey payloadGetKey(
const AvatarSharedPointer& avatar);
43 template <>
const Item::Bound payloadGetBound(
const AvatarSharedPointer& avatar, RenderArgs* args);
44 template <>
void payloadRender(
const AvatarSharedPointer& avatar, RenderArgs* args);
45 template <> uint32_t metaFetchMetaSubItems(
const AvatarSharedPointer& avatar, ItemIDs& subItems);
48 static const float SCALING_RATIO = .05f;
50 extern const float CHAT_MESSAGE_SCALE;
51 extern const float CHAT_MESSAGE_HEIGHT;
53 enum ScreenTintLayer {
54 SCREEN_TINT_BEFORE_LANDSCAPE = 0,
55 SCREEN_TINT_BEFORE_AVATARS,
56 SCREEN_TINT_BEFORE_MY_AVATAR,
57 SCREEN_TINT_AFTER_AVATARS,
58 NUM_SCREEN_TINT_LAYERS
84 struct TransitConfig {
86 int _totalFrames { 0 };
87 float _framesPerMeter { 0.0f };
88 bool _isDistanceBased {
false };
89 float _minTriggerDistance { 0.0f };
90 float _maxTriggerDistance { 0.0f };
91 float _abortDistance{ 0.0f };
92 EaseType _easeType { EaseType::EASE_OUT };
96 Status update(
float deltaTime,
const glm::vec3& avatarPosition,
const TransitConfig& config);
97 void slamPosition(
const glm::vec3& avatarPosition);
98 Status getStatus() {
return _status; }
99 bool isActive() {
return _isActive; }
100 glm::vec3 getCurrentPosition() {
return _currentPosition; }
101 glm::vec3 getEndPosition() {
return _endPosition; }
102 void setScale(
float scale) { _scale = scale; }
106 Status updatePosition(
float deltaTime);
107 void start(
float deltaTime,
const glm::vec3& startPosition,
const glm::vec3& endPosition,
const TransitConfig& config);
108 float getEaseValue(AvatarTransit::EaseType type,
float value);
109 bool _isActive {
false };
111 glm::vec3 _startPosition;
112 glm::vec3 _endPosition;
113 glm::vec3 _currentPosition;
115 glm::vec3 _lastPosition;
117 glm::vec3 _transitLine;
118 float _totalDistance { 0.0f };
119 float _preTransitTime { 0.0f };
120 float _totalTime { 0.0f };
121 float _transitTime { 0.0f };
122 float _postTransitTime { 0.0f };
123 float _currentTime { 0.0f };
124 EaseType _easeType { EaseType::EASE_OUT };
125 Status _status { Status::IDLE };
126 float _scale { 1.0f };
129 class Avatar :
public AvatarData,
public scriptable::ModelProvider,
public MetaModelPayload {
138 Q_PROPERTY(glm::vec3 skeletonOffset READ getSkeletonOffset WRITE setSkeletonOffset)
141 static void setShowAvatars(
bool render);
142 static void setShowReceiveStats(
bool receiveStats);
143 static void setShowMyLookAtVectors(
bool showMine);
144 static void setShowMyLookAtTarget(
bool showMine);
145 static void setShowOtherLookAtVectors(
bool showOthers);
146 static void setShowOtherLookAtTarget(
bool showOthers);
147 static void setShowCollisionShapes(
bool render);
148 static void setShowNamesAboveHeads(
bool show);
150 explicit Avatar(QThread* thread);
153 virtual void instantiableAvatar() = 0;
155 typedef render::Payload<AvatarData> Payload;
158 void removeAvatarEntitiesFromTree();
159 virtual void simulate(
float deltaTime,
bool inView) = 0;
160 virtual void simulateAttachments(
float deltaTime);
162 virtual void render(RenderArgs* renderArgs);
164 void addToScene(AvatarSharedPointer
self,
const render::ScenePointer& scene,
165 render::Transaction& transaction);
167 void removeFromScene(AvatarSharedPointer
self,
const render::ScenePointer& scene,
168 render::Transaction& transaction);
170 void updateRenderItem(render::Transaction& transaction);
172 virtual void postUpdate(
float deltaTime,
const render::ScenePointer& scene);
175 bool isInitialized()
const {
return _initialized; }
176 SkeletonModelPointer getSkeletonModel() {
return _skeletonModel; }
177 const SkeletonModelPointer getSkeletonModel()
const {
return _skeletonModel; }
178 glm::vec3 getChestPosition()
const;
179 const Head* getHead()
const {
return static_cast<const Head*
>(_headData); }
180 Head* getHead() {
return static_cast<Head*
>(_headData); }
182 AABox getBounds()
const;
185 float getLODDistance()
const;
187 virtual void createOrb() { }
189 enum class LoadingStatus {
195 virtual void indicateLoadingStatus(LoadingStatus loadingStatus) { _loadingStatus = loadingStatus; }
197 virtual QVector<glm::quat> getJointRotations()
const override;
198 using AvatarData::getJointRotation;
199 virtual glm::quat getJointRotation(
int index)
const override;
200 virtual QVector<glm::vec3> getJointTranslations()
const override;
201 using AvatarData::getJointTranslation;
202 virtual glm::vec3 getJointTranslation(
int index)
const override;
203 virtual int getJointIndex(
const QString& name)
const override;
204 virtual QStringList getJointNames()
const override;
206 std::vector<AvatarSkeletonTrait::UnpackedJointData> getSkeletonDefaultData();
216 Q_INVOKABLE
virtual glm::quat getDefaultJointRotation(
int index)
const;
228 Q_INVOKABLE
virtual glm::vec3 getDefaultJointTranslation(
int index)
const;
242 Q_INVOKABLE
virtual glm::quat getAbsoluteDefaultJointRotationInObjectFrame(
int index)
const;
256 Q_INVOKABLE
virtual glm::vec3 getAbsoluteDefaultJointTranslationInObjectFrame(
int index)
const;
259 virtual glm::vec3 getAbsoluteJointScaleInObjectFrame(
int index)
const override;
260 virtual glm::quat getAbsoluteJointRotationInObjectFrame(
int index)
const override;
261 virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(
int index)
const override;
271 virtual bool setAbsoluteJointRotationInObjectFrame(
int index,
const glm::quat& rotation)
override {
return false; }
281 virtual bool setAbsoluteJointTranslationInObjectFrame(
int index,
const glm::vec3& translation)
override {
return false; }
282 virtual glm::vec3 getSpine2SplineOffset()
const {
return _spine2SplineOffset; }
283 virtual float getSpine2SplineRatio()
const {
return _spine2SplineRatio; }
294 Q_INVOKABLE glm::vec3 worldToJointPoint(
const glm::vec3& position,
const int jointIndex = -1)
const;
304 Q_INVOKABLE glm::vec3 worldToJointDirection(
const glm::vec3& direction,
const int jointIndex = -1)
const;
314 Q_INVOKABLE glm::quat worldToJointRotation(
const glm::quat& rotation,
const int jointIndex = -1)
const;
324 Q_INVOKABLE glm::vec3 jointToWorldPoint(
const glm::vec3& position,
const int jointIndex = -1)
const;
334 Q_INVOKABLE glm::vec3 jointToWorldDirection(
const glm::vec3& direction,
const int jointIndex = -1)
const;
344 Q_INVOKABLE glm::quat jointToWorldRotation(
const glm::quat& rotation,
const int jointIndex = -1)
const;
346 Q_INVOKABLE
virtual void setSkeletonModelURL(
const QUrl& skeletonModelURL)
override;
347 virtual void setAttachmentData(
const QVector<AttachmentData>& attachmentData)
override;
349 void updateDisplayNameAlpha(
bool showDisplayName);
350 virtual void setSessionDisplayName(
const QString& sessionDisplayName)
override { };
352 virtual int parseDataFromBuffer(
const QByteArray& buffer)
override;
368 Q_INVOKABLE
void setSkeletonOffset(
const glm::vec3& offset);
378 Q_INVOKABLE glm::vec3 getSkeletonOffset() {
return _skeletonOffset; }
380 virtual glm::vec3 getSkeletonPosition()
const;
388 Q_INVOKABLE glm::vec3 getJointPosition(
int index)
const;
398 Q_INVOKABLE glm::vec3 getJointPosition(
const QString& name)
const;
407 Q_INVOKABLE glm::vec3 getNeckPosition()
const;
414 Q_INVOKABLE glm::vec3 getAcceleration()
const {
return _acceleration; }
418 void scaleVectorRelativeToPosition(glm::vec3& positionToScale)
const;
420 void slamPosition(
const glm::vec3& position);
421 virtual void updateAttitude(
const glm::quat& orientation)
override;
426 void applyPositionDelta(
const glm::vec3& delta);
428 virtual void rebuildCollisionShape() = 0;
430 virtual void computeShapeInfo(ShapeInfo& shapeInfo);
431 virtual void computeDetailedShapeInfo(ShapeInfo& shapeInfo,
int jointIndex);
433 void getCapsule(glm::vec3& start, glm::vec3& end,
float& radius);
440 Q_INVOKABLE glm::vec3 getWorldFeetPosition();
442 void setPositionViaScript(
const glm::vec3& position)
override;
443 void setOrientationViaScript(
const glm::quat& orientation)
override;
451 Q_INVOKABLE
virtual const QUuid getParentID()
const override {
return SpatiallyNestable::getParentID(); }
460 Q_INVOKABLE
virtual void setParentID(
const QUuid& parentID)
override;
469 Q_INVOKABLE
virtual quint16 getParentJointIndex()
const override {
return SpatiallyNestable::getParentJointIndex(); }
479 Q_INVOKABLE
virtual void setParentJointIndex(quint16 parentJointIndex)
override;
486 Q_INVOKABLE QList<QVariant> getSkeleton();
489 glm::vec3 getUncachedLeftPalmPosition()
const;
490 glm::quat getUncachedLeftPalmRotation()
const;
491 glm::vec3 getUncachedRightPalmPosition()
const;
492 glm::quat getUncachedRightPalmRotation()
const;
494 uint64_t getLastRenderUpdateTime()
const {
return _lastRenderUpdateTime; }
495 void setLastRenderUpdateTime(uint64_t time) { _lastRenderUpdateTime = time; }
497 void animateScaleChanges(
float deltaTime);
498 void setTargetScale(
float targetScale)
override;
499 float getTargetScale()
const {
return _targetScale; }
507 Q_INVOKABLE
float getSimulationRate(
const QString& rateName = QString(
""))
const;
509 bool hasNewJointData()
const {
return _hasNewJointData; }
511 float getBoundingRadius()
const;
512 AABox getRenderBounds()
const;
513 AABox getFitBounds()
const {
return _fitBoundingBox; }
515 void addToScene(AvatarSharedPointer
self,
const render::ScenePointer& scene);
516 void ensureInScene(AvatarSharedPointer
self,
const render::ScenePointer& scene);
517 bool isInScene()
const {
return render::Item::isValidID(_renderItemID); }
518 render::ItemID getRenderItemID() {
return _renderItemID; }
519 bool isMoving()
const {
return _moving; }
521 void fadeIn(render::ScenePointer scene);
522 void fadeOut(render::Transaction& transaction, KillAvatarReason reason);
523 render::Transition::Type getLastFadeRequested()
const;
526 Q_INVOKABLE
virtual float getEyeHeight()
const override;
530 virtual float getUnscaledEyeHeight()
const override;
534 virtual bool canMeasureEyeHeight()
const override {
return true; }
536 virtual float getModelScale()
const {
return _modelScale; }
537 virtual void setModelScale(
float scale) { _modelScale = scale; }
538 virtual glm::vec3 scaleForChildren()
const override {
return glm::vec3(getModelScale()); }
541 virtual void setEnableMeshVisible(
bool isEnabled);
542 virtual bool getEnableMeshVisible()
const;
544 void addMaterial(graphics::MaterialLayer material,
const std::string& parentMaterialName);
545 void removeMaterial(graphics::MaterialPointer material,
const std::string& parentMaterialName);
547 virtual scriptable::ScriptableModelBase getScriptableModel()
override;
549 std::shared_ptr<AvatarTransit> getTransit() {
return std::make_shared<AvatarTransit>(_transit); };
550 AvatarTransit::Status updateTransit(
float deltaTime,
const glm::vec3& avatarPosition,
float avatarScale,
const AvatarTransit::TransitConfig& config);
552 void accumulateGrabPositions(std::map<QUuid, GrabLocationAccumulator>& grabAccumulators);
554 const std::vector<MultiSphereShape>& getMultiSphereShapes()
const {
return _multiSphereShapes; }
555 void tearDownGrabs();
557 uint32_t appendSubMetaItems(render::ItemIDs& subItems);
567 void targetScaleChanged(
float targetScale);
581 glm::vec3 getLeftPalmPosition()
const;
590 glm::quat getLeftPalmRotation()
const;
599 glm::vec3 getRightPalmPosition()
const;
608 glm::quat getRightPalmRotation()
const;
616 void setModelURLFinished(
bool success);
633 float getUnscaledEyeHeightFromSkeleton()
const;
634 void buildUnscaledEyeHeightCache();
635 void buildSpine2SplineRatioCache();
636 void clearUnscaledEyeHeightCache();
637 void clearSpine2SplineRatioCache();
638 virtual const QString& getSessionDisplayNameForTransport()
const override {
return _empty; }
640 virtual void maybeUpdateSessionDisplayNameFromTransport(
const QString& sessionDisplayName)
override { _sessionDisplayName = sessionDisplayName; }
641 void computeMultiSphereShapes();
642 void updateFitBoundingBox();
644 SkeletonModelPointer _skeletonModel;
646 void invalidateJointIndicesCache()
const;
647 void withValidJointIndicesCache(std::function<
void()>
const& worker)
const;
648 mutable QHash<QString, int> _modelJointIndicesCache;
649 mutable QReadWriteLock _modelJointIndicesCacheLock;
650 mutable bool _modelJointsCached {
false };
652 glm::vec3 _skeletonOffset;
653 std::vector<std::shared_ptr<Model>> _attachmentModels;
654 std::vector<bool> _attachmentModelsTexturesLoaded;
655 std::vector<std::shared_ptr<Model>> _attachmentsToRemove;
656 std::vector<std::shared_ptr<Model>> _attachmentsToDelete;
658 float _bodyYawDelta { 0.0f };
659 float _seatedBodyYawDelta{ 0.0f };
667 glm::vec3 _positionDeltaAccumulator;
668 glm::vec3 _lastVelocity;
669 glm::vec3 _acceleration;
670 glm::vec3 _angularVelocity;
671 glm::vec3 _lastAngularVelocity;
672 glm::vec3 _angularAcceleration;
673 glm::quat _lastOrientation;
674 glm::vec3 _worldUpDirection { Vectors::UP };
675 bool _moving {
false };
678 bool isLookingAtMe(AvatarSharedPointer avatar)
const;
679 virtual void sendPacket(
const QUuid& entityID)
const { }
680 bool applyGrabChanges();
681 void relayJointDataToChildren();
683 void fade(render::Transaction& transaction, render::Transition::Type type);
685 glm::vec3 getBodyRightDirection()
const {
return getWorldOrientation() * IDENTITY_RIGHT; }
686 glm::vec3 getBodyUpDirection()
const {
return getWorldOrientation() * IDENTITY_UP; }
687 void measureMotionDerivatives(
float deltaTime);
688 bool getCollideWithOtherAvatars()
const {
return _collideWithOtherAvatars; }
690 float getSkeletonHeight()
const;
691 float getHeadHeight()
const;
692 float getPelvisFloatingHeight()
const;
693 glm::vec3 getDisplayNamePosition()
const;
695 Transform calculateDisplayNameTransform(
const ViewFrustum& view,
const glm::vec3& textPosition)
const;
696 void renderDisplayName(gpu::Batch& batch,
const ViewFrustum& view,
const glm::vec3& textPosition,
bool forward)
const;
697 virtual bool shouldRenderHead(
const RenderArgs* renderArgs)
const;
698 virtual void fixupModelsInScene(
const render::ScenePointer& scene);
700 virtual void updatePalms();
702 render::ItemID _renderItemID{ render::Item::INVALID_ITEM_ID };
703 render::Transition::Type _lastFadeRequested { render::Transition::Type::NONE };
705 ThreadSafeValueCache<glm::vec3> _leftPalmPositionCache { glm::vec3() };
706 ThreadSafeValueCache<glm::quat> _leftPalmRotationCache { glm::quat() };
707 ThreadSafeValueCache<glm::vec3> _rightPalmPositionCache { glm::vec3() };
708 ThreadSafeValueCache<glm::quat> _rightPalmRotationCache { glm::quat() };
711 RateCounter<> _simulationRate;
712 RateCounter<> _simulationInViewRate;
713 RateCounter<> _skeletonModelSimulationRate;
714 RateCounter<> _jointDataSimulationRate;
716 class AvatarEntityDataHash {
718 AvatarEntityDataHash(uint32_t h) : hash(h) {};
720 bool success {
false };
723 uint64_t _lastRenderUpdateTime { 0 };
724 int _leftPointerGeometryID { 0 };
725 int _rightPointerGeometryID { 0 };
726 int _nameRectGeometryID { 0 };
727 bool _initialized {
false };
728 bool _isAnimatingScale {
false };
729 bool _mustFadeIn {
false };
730 bool _reconstructSoftEntitiesJointMap {
false };
731 float _modelScale { 1.0f };
733 AvatarTransit _transit;
734 std::mutex _transitLock;
738 float _displayNameTargetAlpha { 1.0f };
739 float _displayNameAlpha { 1.0f };
741 ThreadSafeValueCache<float> _unscaledEyeHeightCache { DEFAULT_AVATAR_EYE_HEIGHT };
742 float _spine2SplineRatio { DEFAULT_SPINE2_SPLINE_PROPORTION };
743 glm::vec3 _spine2SplineOffset;
745 std::unordered_map<std::string, graphics::MultiMaterial> _materials;
746 std::mutex _materialsLock;
748 void processMaterials();
751 bool _isMeshVisible{
true };
752 bool _needMeshVisibleSwitch{
true };
754 static const float MYAVATAR_LOADING_PRIORITY;
755 static const float OTHERAVATAR_LOADING_PRIORITY;
756 static const float ATTACHMENT_LOADING_PRIORITY;
758 LoadingStatus _loadingStatus { LoadingStatus::NoModel };
760 static void metaBlendshapeOperator(render::ItemID renderItemID,
int blendshapeNumber,
const QVector<BlendshapeOffset>& blendshapeOffsets,
761 const QVector<int>& blendedMeshSizes,
const render::ItemIDs& subItemIDs);
763 std::vector<MultiSphereShape> _multiSphereShapes;
764 AABox _fitBoundingBox;
765 void clearAvatarGrabData(
const QUuid& grabID)
override;
767 using SetOfIDs = std::set<QUuid>;
768 using VectorOfIDs = std::vector<QUuid>;
769 using MapOfGrabs = std::map<QUuid, GrabPointer>;
771 MapOfGrabs _avatarGrabs;
772 SetOfIDs _grabsToChange;
773 VectorOfIDs _grabsToDelete;
775 ReadWriteLockable _subItemLock;
776 void updateAttachmentRenderIDs();
777 render::ItemIDs _attachmentRenderIDs;
778 void updateDescendantRenderIDs();
779 render::ItemIDs _descendantRenderIDs;
780 std::unordered_set<EntityItemID> _renderingDescendantEntityIDs;
781 uint32_t _lastAncestorChainRenderableVersion { 0 };
A simple object wrapper for an OpenGL texture.
Definition: material-networking/src/material-networking/TextureCache.h:39