diff --git a/src/runtimerender/rendererimpl/qssgrendererimpllayerrenderpreparationdata.cpp b/src/runtimerender/rendererimpl/qssgrendererimpllayerrenderpreparationdata.cpp
index 446a543f45d26c0c1d60052edfb5631e87270e48..291f33a578fd899422e8bfd094e636e0a2f3ba3a 100644
--- a/src/runtimerender/rendererimpl/qssgrendererimpllayerrenderpreparationdata.cpp
+++ b/src/runtimerender/rendererimpl/qssgrendererimpllayerrenderpreparationdata.cpp
@@ -657,6 +657,30 @@ bool QSSGLayerRenderPreparationData::prepareModelForRender(QSSGRenderModel &inMo
 
     bool subsetDirty = false;
 
+    // Completely transparent models cannot be pickable.  But models with completely
+    // transparent materials still are.  This allows the artist to control pickability
+    // in a somewhat fine-grained style.
+    const bool canModelBePickable = (inModel.globalOpacity > QSSG_RENDER_MINIMUM_RENDER_OPACITY)
+                                    && (theModelContext.model.flags.testFlag(QSSGRenderModel::Flag::GloballyPickable));
+    if (canModelBePickable) {
+        // Check if there is BVH data, if not generate it
+        if (!theMesh->bvh && !inModel.meshPath.isNull()) {
+            theMesh->bvh = bufferManager->loadMeshBVH(inModel.meshPath);
+            if (theMesh->bvh) {
+                for (int i = 0; i < theMesh->bvh->roots.count(); ++i)
+                    theMesh->subsets[i].bvhRoot = theMesh->bvh->roots.at(i);
+            }
+        }
+    } else {
+        // Check if there is BVH data, if so delete it
+        if (theMesh->bvh) {
+            delete theMesh->bvh;
+            theMesh->bvh = nullptr;
+            for (auto subset : theMesh->subsets)
+                subset.bvhRoot = nullptr;
+        }
+    }
+
     const QSSGScopedLightsListScope lightsScope(globalLights, lightDirections, sourceLightDirections, inScopedLights);
     setShaderFeature(QSSGShaderDefines::asString(QSSGShaderDefines::CgLighting), !globalLights.empty());
     for (int idx = 0; idx < theMesh->subsets.size(); ++idx) {
@@ -672,7 +696,6 @@ bool QSSGLayerRenderPreparationData::prepareModelForRender(QSSGRenderModel &inMo
         {
             QSSGRenderSubset &theSubset(theOuterSubset);
             QSSGRenderableObjectFlags renderableFlags;
-            renderableFlags.setPickable(false);
             float subsetOpacity = inModel.globalOpacity;
             QVector3D theModelCenter(theSubset.bounds.center());
             theModelCenter = mat44::transform(inModel.globalTransform, theModelCenter);
@@ -685,15 +708,6 @@ bool QSSGLayerRenderPreparationData::prepareModelForRender(QSSGRenderModel &inMo
                     subsetOpacity = 0.0f;
             }
 
-            // For now everything is pickable.  Eventually we want to have localPickable and
-            // globalPickable set on the node during
-            // updates and have the runtime tell us what is pickable and what is not pickable.
-            // Completely transparent models cannot be pickable.  But models with completely
-            // transparent materials
-            // still are.  This allows the artist to control pickability in a somewhat
-            // fine-grained style.
-            const bool canModelBePickable = (inModel.globalOpacity > QSSG_RENDER_MINIMUM_RENDER_OPACITY)
-                                            && (theModelContext.model.flags.testFlag(QSSGRenderModel::Flag::GloballyPickable) || renderableFlags.isPickable());
             renderableFlags.setPickable(canModelBePickable);
 
             // Casting and Receiving Shadows
diff --git a/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp b/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp
index 0ad000a84ee137b5aca66d2f974fc4b6f5a37970..d53d2c1d1dffe7743c8eee11b95be5fce84989ec 100644
--- a/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp
+++ b/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp
@@ -496,15 +496,11 @@ QSSGRenderMesh *QSSGBufferManager::createRenderMesh(
         ::memcpy(newJoint.localToGlobalBoneSpace, importJoint.m_localToGlobalBoneSpace, 16 * sizeof(float));
     }
 
-    // Build BVH for Mesh
-    QSSGMeshBVHBuilder meshBVHBuilder(result.m_mesh);
-    newMesh->bvh = meshBVHBuilder.buildTree();
-
     for (quint32 subsetIdx = 0, subsetEnd = result.m_mesh->m_subsets.size(); subsetIdx < subsetEnd; ++subsetIdx) {
         QSSGRenderSubset subset;
         const QSSGMeshUtilities::MeshSubset &source(result.m_mesh->m_subsets.index(baseAddress, subsetIdx));
         subset.bounds = source.m_bounds;
-        subset.bvhRoot = newMesh->bvh->roots.at(subsetIdx);
+        subset.bvhRoot = nullptr;
         subset.count = source.m_count;
         subset.offset = source.m_offset;
         subset.joints = newMesh->joints;
@@ -590,27 +586,7 @@ QSSGRenderMesh *QSSGBufferManager::loadMesh(const QSSGRenderMeshPath &inMeshPath
         return meshItr.value();
 
     // loading new mesh
-    QSSGMeshUtilities::MultiLoadResult result;
-
-    // check to see if this is a primitive mesh
-    if (inMeshPath.path.startsWith('#'))
-        result = loadPrimitive(inMeshPath.path);
-
-    // Attempt a load from the filesystem if this mesh isn't a primitive.
-    if (result.m_mesh == nullptr) {
-        QString pathBuilder = inMeshPath.path;
-        int poundIndex = pathBuilder.lastIndexOf('#');
-        int id = 0;
-        if (poundIndex != -1) {
-            id = pathBuilder.midRef(poundIndex + 1).toInt();
-            pathBuilder = pathBuilder.left(poundIndex);
-        }
-        if (!pathBuilder.isEmpty()) {
-            QSharedPointer<QIODevice> ioStream(inputStreamFactory->getStreamForFile(pathBuilder));
-            if (ioStream)
-                result = QSSGMeshUtilities::Mesh::loadMulti(*ioStream, id);
-        }
-    }
+    QSSGMeshUtilities::MultiLoadResult result = loadMeshData(inMeshPath);
 
     if (result.m_mesh == nullptr) {
         qCWarning(WARNING, "Failed to load mesh: %s", qPrintable(inMeshPath.path));
@@ -642,6 +618,51 @@ QSSGRenderMesh *QSSGBufferManager::loadCustomMesh(const QSSGRenderMeshPath &inSo
     return nullptr;
 }
 
+QSSGMeshBVH *QSSGBufferManager::loadMeshBVH(const QSSGRenderMeshPath &inSourcePath)
+{
+    // loading new mesh
+    QSSGMeshUtilities::MultiLoadResult result = loadMeshData(inSourcePath);
+
+    if (result.m_mesh == nullptr) {
+        qCWarning(WARNING, "Failed to load mesh: %s", qPrintable(inSourcePath.path));
+        return nullptr;
+    }
+
+    // Build BVH for Mesh
+    QSSGMeshBVHBuilder meshBVHBuilder(result.m_mesh);
+    auto bvh = meshBVHBuilder.buildTree();
+
+    ::free(result.m_mesh);
+    return bvh;
+}
+
+QSSGMeshUtilities::MultiLoadResult QSSGBufferManager::loadMeshData(const QSSGRenderMeshPath &inMeshPath) const
+{
+    // loading new mesh
+    QSSGMeshUtilities::MultiLoadResult result;
+
+    // check to see if this is a primitive mesh
+    if (inMeshPath.path.startsWith('#'))
+        result = loadPrimitive(inMeshPath.path);
+
+    // Attempt a load from the filesystem if this mesh isn't a primitive.
+    if (result.m_mesh == nullptr) {
+        QString pathBuilder = inMeshPath.path;
+        int poundIndex = pathBuilder.lastIndexOf('#');
+        int id = 0;
+        if (poundIndex != -1) {
+            id = pathBuilder.midRef(poundIndex + 1).toInt();
+            pathBuilder = pathBuilder.left(poundIndex);
+        }
+        if (!pathBuilder.isEmpty()) {
+            QSharedPointer<QIODevice> ioStream(inputStreamFactory->getStreamForFile(pathBuilder));
+            if (ioStream)
+                result = QSSGMeshUtilities::Mesh::loadMulti(*ioStream, id);
+        }
+    }
+    return result;
+}
+
 QSSGRenderMesh *QSSGBufferManager::createMesh(const QString &inSourcePath, quint8 *inVertData, quint32 inNumVerts, quint32 inVertStride, quint32 *inIndexData, quint32 inIndexCount, QSSGBounds3 inBounds)
 {
     QString sourcePath = inSourcePath;
diff --git a/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h b/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h
index 9fb1ef17dcc05dcb5ab96db0d969ba544c45d2be..8cdc67f2871c8b30985f050117a4148610ab2e1a 100644
--- a/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h
+++ b/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h
@@ -57,6 +57,7 @@ struct QSSGRenderMesh;
 struct QSSGLoadedTexture;
 class QSSGRenderContext;
 class QSSGInputStreamFactory;
+struct QSSGMeshBVH;
 namespace QSSGMeshUtilities {
     struct MultiLoadResult;
 }
@@ -136,6 +137,8 @@ public:
     QSSGRenderMesh *loadCustomMesh(const QSSGRenderMeshPath &inSourcePath,
                                    QSSGMeshUtilities::Mesh *mesh,
                                    bool update = false);
+    QSSGMeshBVH *loadMeshBVH(const QSSGRenderMeshPath &inSourcePath);
+    QSSGMeshUtilities::MultiLoadResult loadMeshData(const QSSGRenderMeshPath &inSourcePath) const;
 
     QSSGRenderMesh *createMesh(const QString &inSourcePath,
                                          quint8 *inVertData,