diff --git a/interface/src/avatar/CauterizedModel.cpp b/interface/src/avatar/CauterizedModel.cpp
index 843779dd3b..0c3d863649 100644
--- a/interface/src/avatar/CauterizedModel.cpp
+++ b/interface/src/avatar/CauterizedModel.cpp
@@ -95,12 +95,6 @@ void CauterizedModel::createCollisionRenderItemSet() {
 	Model::createCollisionRenderItemSet();
 }
 
-// Called within Model::simulate call, below.
-void CauterizedModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
-    Model::updateRig(deltaTime, parentTransform);
-    _needsUpdateClusterMatrices = true;
-}
-
 void CauterizedModel::updateClusterMatrices() {
     PerformanceTimer perfTimer("CauterizedModel::updateClusterMatrices");
 
diff --git a/interface/src/avatar/CauterizedModel.h b/interface/src/avatar/CauterizedModel.h
index 01e0b13650..ba12aee32b 100644
--- a/interface/src/avatar/CauterizedModel.h
+++ b/interface/src/avatar/CauterizedModel.h
@@ -37,7 +37,6 @@ public:
 	void createVisibleRenderItemSet() override;
     void createCollisionRenderItemSet() override;
 
-    virtual void updateRig(float deltaTime, glm::mat4 parentTransform) override;
     virtual void updateClusterMatrices() override;
     void updateRenderItems() override;
 
diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp
index 4b77323bba..476abf8d4b 100644
--- a/interface/src/avatar/SkeletonModel.cpp
+++ b/interface/src/avatar/SkeletonModel.cpp
@@ -166,7 +166,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
         _rig->computeMotionAnimationState(deltaTime, position, velocity, orientation, ccState);
 
         // evaluate AnimGraph animation and update jointStates.
-        CauterizedModel::updateRig(deltaTime, parentTransform);
+        Model::updateRig(deltaTime, parentTransform);
 
         Rig::EyeParameters eyeParams;
         eyeParams.worldHeadOrientation = headParams.worldHeadOrientation;
@@ -179,7 +179,9 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
 
         _rig->updateFromEyeParameters(eyeParams);
     } else {
-        CauterizedModel::updateRig(deltaTime, parentTransform);
+        // no need to call Model::updateRig() because otherAvatars get their joint state
+        // copied directly from AvtarData::_jointData (there are no Rig animations to blend)
+        _needsUpdateClusterMatrices = true;
 
         // This is a little more work than we really want.
         //
diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp
index 07462e9878..fa5d2fc9f1 100644
--- a/libraries/animation/src/Rig.cpp
+++ b/libraries/animation/src/Rig.cpp
@@ -1274,39 +1274,50 @@ void Rig::copyJointsIntoJointData(QVector<JointData>& jointDataVec) const {
 void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
     PerformanceTimer perfTimer("copyJoints");
     PROFILE_RANGE(simulation_animation_detail, "copyJoints");
-    if (_animSkeleton && jointDataVec.size() == (int)_internalPoseSet._relativePoses.size()) {
-        // make a vector of rotations in absolute-geometry-frame
-        const AnimPoseVec& absoluteDefaultPoses = _animSkeleton->getAbsoluteDefaultPoses();
-        std::vector<glm::quat> rotations;
-        rotations.reserve(absoluteDefaultPoses.size());
-        const glm::quat rigToGeometryRot(glmExtractRotation(_rigToGeometryTransform));
-        for (int i = 0; i < jointDataVec.size(); i++) {
-            const JointData& data = jointDataVec.at(i);
-            if (data.rotationSet) {
-                // JointData rotations are in absolute rig-frame so we rotate them to absolute geometry-frame
-                rotations.push_back(rigToGeometryRot * data.rotation);
-            } else {
-                rotations.push_back(absoluteDefaultPoses[i].rot());
-            }
-        }
+    if (!_animSkeleton) {
+        return;
+    }
+    if (jointDataVec.size() != (int)_internalPoseSet._relativePoses.size()) {
+        // animations haven't fully loaded yet.
+        _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses();
+    }
 
-        // convert rotations from absolute to parent relative.
-        _animSkeleton->convertAbsoluteRotationsToRelative(rotations);
-
-        // store new relative poses
-        const AnimPoseVec& relativeDefaultPoses = _animSkeleton->getRelativeDefaultPoses();
-        for (int i = 0; i < jointDataVec.size(); i++) {
-            const JointData& data = jointDataVec.at(i);
-            _internalPoseSet._relativePoses[i].scale() = Vectors::ONE;
-            _internalPoseSet._relativePoses[i].rot() = rotations[i];
-            if (data.translationSet) {
-                // JointData translations are in scaled relative-frame so we scale back to regular relative-frame
-                _internalPoseSet._relativePoses[i].trans() = _invGeometryOffset.scale() * data.translation;
-            } else {
-                _internalPoseSet._relativePoses[i].trans() = relativeDefaultPoses[i].trans();
-            }
+    // make a vector of rotations in absolute-geometry-frame
+    const AnimPoseVec& absoluteDefaultPoses = _animSkeleton->getAbsoluteDefaultPoses();
+    std::vector<glm::quat> rotations;
+    rotations.reserve(absoluteDefaultPoses.size());
+    const glm::quat rigToGeometryRot(glmExtractRotation(_rigToGeometryTransform));
+    for (int i = 0; i < jointDataVec.size(); i++) {
+        const JointData& data = jointDataVec.at(i);
+        if (data.rotationSet) {
+            // JointData rotations are in absolute rig-frame so we rotate them to absolute geometry-frame
+            rotations.push_back(rigToGeometryRot * data.rotation);
+        } else {
+            rotations.push_back(absoluteDefaultPoses[i].rot());
         }
     }
+
+    // convert rotations from absolute to parent relative.
+    _animSkeleton->convertAbsoluteRotationsToRelative(rotations);
+
+    // store new relative poses
+    const AnimPoseVec& relativeDefaultPoses = _animSkeleton->getRelativeDefaultPoses();
+    for (int i = 0; i < jointDataVec.size(); i++) {
+        const JointData& data = jointDataVec.at(i);
+        _internalPoseSet._relativePoses[i].scale() = Vectors::ONE;
+        _internalPoseSet._relativePoses[i].rot() = rotations[i];
+        if (data.translationSet) {
+            // JointData translations are in scaled relative-frame so we scale back to regular relative-frame
+            _internalPoseSet._relativePoses[i].trans() = _invGeometryOffset.scale() * data.translation;
+        } else {
+            _internalPoseSet._relativePoses[i].trans() = relativeDefaultPoses[i].trans();
+        }
+    }
+
+    // build absolute poses and copy to externalPoseSet
+    buildAbsoluteRigPoses(_internalPoseSet._relativePoses, _internalPoseSet._absolutePoses);
+    QWriteLocker writeLock(&_externalPoseSetLock);
+    _externalPoseSet = _internalPoseSet;
 }
 
 void Rig::computeAvatarBoundingCapsule(