diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h
index 5910b8d312..6e51c413dc 100644
--- a/libraries/fbx/src/FBXReader.h
+++ b/libraries/fbx/src/FBXReader.h
@@ -300,7 +300,7 @@ public:
 
     QHash<QString, FBXMaterial> materials;
 
-    glm::mat4 offset;
+    glm::mat4 offset; // This includes offset, rotation, and scale as specified by the FST file
     
     int leftEyeJointIndex = -1;
     int rightEyeJointIndex = -1;
diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp
index 9dd3563887..d94bb67590 100644
--- a/libraries/render-utils/src/Model.cpp
+++ b/libraries/render-utils/src/Model.cpp
@@ -375,6 +375,14 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
             recalculateMeshBoxes(pickAgainstTriangles);
         }
 
+        glm::mat4 meshToModelMatrix = glm::scale(_scale) * glm::translate(_offset);
+        glm::mat4 meshToWorldMatrix = meshToModelMatrix * glm::translate(_translation) * glm::mat4_cast(_rotation);
+        glm::mat4 worldToMeshMatrix = glm::inverse(meshToWorldMatrix);
+
+        glm::vec3 meshFrameOrigin = glm::vec3(worldToMeshMatrix * glm::vec4(origin, 1.0f));
+        glm::vec3 meshFrameDirection = glm::vec3(worldToMeshMatrix * glm::vec4(direction, 0.0f));
+
+
         for (const auto& subMeshBox : _calculatedMeshBoxes) {
             bool intersectedSubMesh = false;
             float subMeshDistance = std::numeric_limits<float>::max();
@@ -383,19 +391,24 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
                 if (distanceToSubMesh < bestDistance) {
                     if (pickAgainstTriangles) {
 
-                        float subMeshDistance;
+                        float subMeshDistance = 0.0f;
                         glm::vec3 subMeshNormal;
-                        const auto& meshTriangleSet = _meshTriangleSets[subMeshIndex];
-                        bool intersectedMesh = meshTriangleSet.findRayIntersection(origin, direction, subMeshDistance, subMeshNormal);
+                        const auto& meshTriangleSet = _modelSpaceMeshTriangleSets[subMeshIndex];
+                        bool intersectedMesh = meshTriangleSet.findRayIntersection(meshFrameOrigin, meshFrameDirection, subMeshDistance, subMeshNormal);
 
-                        if (intersectedMesh && subMeshDistance < bestDistance) {
-                            bestDistance = subMeshDistance;
-                            intersectedSomething = true;
-                            face = subMeshFace;
-                            surfaceNormal = subMeshNormal;
-                            extraInfo = geometry.getModelNameOfMesh(subMeshIndex);
+                        if (intersectedMesh) {
+                            glm::vec3 meshIntersectionPoint = meshFrameOrigin + (meshFrameDirection * subMeshDistance);
+                            glm::vec3 worldIntersectionPoint = glm::vec3(meshToWorldMatrix * glm::vec4(meshIntersectionPoint, 1.0f));
+                            float worldDistance = glm::distance(origin, worldIntersectionPoint);
+
+                            if (worldDistance < bestDistance) {
+                                bestDistance = subMeshDistance;
+                                intersectedSomething = true;
+                                face = subMeshFace;
+                                surfaceNormal = glm::vec3(meshToWorldMatrix * glm::vec4(subMeshNormal, 0.0f));
+                                extraInfo = geometry.getModelNameOfMesh(subMeshIndex);
+                            }
                         }
-
                     } else {
                         // this is the non-triangle picking case...
                         bestDistance = distanceToSubMesh;
@@ -458,7 +471,13 @@ bool Model::convexHullContains(glm::vec3 point) {
         foreach(const AABox& subMeshBox, _calculatedMeshBoxes) {
             if (subMeshBox.contains(point)) {
 
-                if (_meshTriangleSets[subMeshIndex].convexHullContains(point)) {
+                glm::mat4 meshToModelMatrix = glm::scale(_scale) * glm::translate(_offset);
+                glm::mat4 meshToWorldMatrix = meshToModelMatrix * glm::translate(_translation) * glm::mat4_cast(_rotation);
+                glm::mat4 worldToMeshMatrix = glm::inverse(meshToWorldMatrix);
+
+                glm::vec3 meshFramePoint = glm::vec3(worldToMeshMatrix * glm::vec4(point, 1.0f));
+
+                if (_modelSpaceMeshTriangleSets[subMeshIndex].convexHullContains(meshFramePoint)) {
                     // It's inside this mesh, return true.
                     _mutex.unlock();
                     return true;
@@ -493,8 +512,9 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
         int numberOfMeshes = geometry.meshes.size();
         _calculatedMeshBoxes.resize(numberOfMeshes);
         _calculatedMeshPartBoxes.clear();
-        _meshTriangleSets.clear();
-        _meshTriangleSets.resize(numberOfMeshes);
+
+        _modelSpaceMeshTriangleSets.clear();
+        _modelSpaceMeshTriangleSets.resize(numberOfMeshes);
 
         for (int i = 0; i < numberOfMeshes; i++) {
             const FBXMesh& mesh = geometry.meshes.at(i);
@@ -503,9 +523,7 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
             _calculatedMeshBoxes[i] = AABox(scaledMeshExtents);
 
             if (pickAgainstTriangles) {
-                auto& thisMeshTriangleSet = _meshTriangleSets[i];
 
-                QVector<Triangle> thisMeshTriangles;
                 for (int j = 0; j < mesh.parts.size(); j++) {
                     const FBXMeshPart& part = mesh.parts.at(j);
 
@@ -540,24 +558,21 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
                             thisPartBounds += mv2;
                             thisPartBounds += mv3;
 
-                            glm::vec3 v0 = calculateScaledOffsetPoint(mv0);
-                            glm::vec3 v1 = calculateScaledOffsetPoint(mv1);
-                            glm::vec3 v2 = calculateScaledOffsetPoint(mv2);
-                            glm::vec3 v3 = calculateScaledOffsetPoint(mv3);
+                            // let's also track the model space version... (eventually using only this!)
+                            // these points will be transformed by the FST's offset, which includes the
+                            // scaling, rotation, and translation specified by the FST/FBX, this can't change
+                            // at runtime, so we can safely store these in our TriangleSet
+                            {
+                                glm::vec3 v0 = glm::vec3(getFBXGeometry().offset * glm::vec4(mesh.vertices[i0], 1.0f));
+                                glm::vec3 v1 = glm::vec3(getFBXGeometry().offset * glm::vec4(mesh.vertices[i1], 1.0f));
+                                glm::vec3 v2 = glm::vec3(getFBXGeometry().offset * glm::vec4(mesh.vertices[i2], 1.0f));
+                                glm::vec3 v3 = glm::vec3(getFBXGeometry().offset * glm::vec4(mesh.vertices[i3], 1.0f));
 
-                            // Sam's recommended triangle slices
-                            Triangle tri1 = { v0, v1, v3 };
-                            Triangle tri2 = { v1, v2, v3 };
-
-                            // NOTE: Random guy on the internet's recommended triangle slices
-                            //Triangle tri1 = { v0, v1, v2 };
-                            //Triangle tri2 = { v2, v3, v0 };
-
-                            thisMeshTriangles.push_back(tri1);
-                            thisMeshTriangles.push_back(tri2);
-
-                            thisMeshTriangleSet.insertTriangle(tri1);
-                            thisMeshTriangleSet.insertTriangle(tri2);
+                                Triangle tri1 = { v0, v1, v3 };
+                                Triangle tri2 = { v1, v2, v3 };
+                                _modelSpaceMeshTriangleSets[i].insertTriangle(tri1);
+                                _modelSpaceMeshTriangleSets[i].insertTriangle(tri2);
+                            }
 
                         }
                     }
@@ -584,15 +599,18 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
                             thisPartBounds += mv1;
                             thisPartBounds += mv2;
 
-                            glm::vec3 v0 = calculateScaledOffsetPoint(mv0);
-                            glm::vec3 v1 = calculateScaledOffsetPoint(mv1);
-                            glm::vec3 v2 = calculateScaledOffsetPoint(mv2);
+                            // let's also track the model space version... (eventually using only this!)
+                            // these points will be transformed by the FST's offset, which includes the
+                            // scaling, rotation, and translation specified by the FST/FBX, this can't change
+                            // at runtime, so we can safely store these in our TriangleSet
+                            {
+                                glm::vec3 v0 = glm::vec3(getFBXGeometry().offset * glm::vec4(mesh.vertices[i0], 1.0f));
+                                glm::vec3 v1 = glm::vec3(getFBXGeometry().offset * glm::vec4(mesh.vertices[i1], 1.0f));
+                                glm::vec3 v2 = glm::vec3(getFBXGeometry().offset * glm::vec4(mesh.vertices[i2], 1.0f));
 
-                            Triangle tri = { v0, v1, v2 };
-
-                            thisMeshTriangles.push_back(tri);
-
-                            thisMeshTriangleSet.insertTriangle(tri);
+                                Triangle tri = { v0, v1, v2 };
+                                _modelSpaceMeshTriangleSets[i].insertTriangle(tri);
+                            }
 
                         }
                     }
diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h
index bc3cf0e521..763112cebc 100644
--- a/libraries/render-utils/src/Model.h
+++ b/libraries/render-utils/src/Model.h
@@ -294,10 +294,10 @@ protected:
 
     SpatiallyNestable* _spatiallyNestableOverride;
 
-    glm::vec3 _translation;
+    glm::vec3 _translation; // this is the translation in world coordinates to the model's registration point
     glm::quat _rotation;
     glm::vec3 _scale;
-    glm::vec3 _offset;
+    glm::vec3 _offset; // this is the translation for the minimum extent of the model (in original mesh coordinate space) to the model's registration point
 
     static float FAKE_DIMENSION_PLACEHOLDER;
 
@@ -363,7 +363,7 @@ protected:
     bool _calculatedMeshPartBoxesValid;
     QVector<AABox> _calculatedMeshBoxes; // world coordinate AABoxes for all sub mesh boxes
     bool _calculatedMeshBoxesValid;
-    QVector< TriangleSet > _meshTriangleSets; // world coordinate triangles for all sub meshes
+    QVector<TriangleSet> _modelSpaceMeshTriangleSets; // model space triangles for all sub meshes
 
     bool _calculatedMeshTrianglesValid;
     QMutex _mutex;