diff --git a/AUTHORS.md b/AUTHORS.md
index beb2b490f2..abc3f1a8d1 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -99,6 +99,7 @@ Programmers
     James Stephens (james-h-stephens)
     Jan-Peter Nilsson (peppe)
     Jan Borsodi (am0s)
+    JanuarySnow
     Jason Hooks (jhooks)
     jeaye
     jefetienne
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bc9c79411b..3ad818bd25 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -48,6 +48,7 @@
     Feature #6162: Refactor GUI to use shaders and to be GLES and GL3+ friendly
     Feature #6199: Support FBO Rendering
     Feature #6251: OpenMW-CS: Set instance movement based on camera zoom
+    Task #6264: Remove the old classes in animation.cpp
 
 0.47.0
 ------
diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp
index 591e666d01..a04724c70a 100644
--- a/apps/openmw/mwrender/animation.cpp
+++ b/apps/openmw/mwrender/animation.cpp
@@ -196,32 +196,6 @@ namespace
         return 0.0f;
     }
 
-    /// @brief Base class for visitors that remove nodes from a scene graph.
-    /// Subclasses need to fill the mToRemove vector.
-    /// To use, node->accept(removeVisitor); removeVisitor.remove();
-    class RemoveVisitor : public osg::NodeVisitor
-    {
-    public:
-        RemoveVisitor()
-            : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
-        {
-        }
-
-        void remove()
-        {
-            for (RemoveVec::iterator it = mToRemove.begin(); it != mToRemove.end(); ++it)
-            {
-                if (!it->second->removeChild(it->first))
-                    Log(Debug::Error) << "Error removing " << it->first->getName();
-            }
-        }
-
-    protected:
-        // <node to remove, parent node to remove it from>
-        typedef std::vector<std::pair<osg::Node*, osg::Group*> > RemoveVec;
-        std::vector<std::pair<osg::Node*, osg::Group*> > mToRemove;
-    };
-
     class GetExtendedBonesVisitor : public osg::NodeVisitor
     {
     public:
@@ -244,7 +218,7 @@ namespace
         std::vector<std::pair<osg::Node*, osg::Group*> > mFoundBones;
     };
 
-    class RemoveFinishedCallbackVisitor : public RemoveVisitor
+    class RemoveFinishedCallbackVisitor : public SceneUtil::RemoveVisitor
     {
     public:
         bool mHasMagicEffects;
@@ -289,7 +263,7 @@ namespace
         }
     };
 
-    class RemoveCallbackVisitor : public RemoveVisitor
+    class RemoveCallbackVisitor : public SceneUtil::RemoveVisitor
     {
     public:
         bool mHasMagicEffects;
@@ -397,90 +371,6 @@ namespace
     private:
         int mEffectId;
     };
-
-    // Removes all drawables from a graph.
-    class CleanObjectRootVisitor : public RemoveVisitor
-    {
-    public:
-        void apply(osg::Drawable& drw) override
-        {
-            applyDrawable(drw);
-        }
-
-        void apply(osg::Group& node) override
-        {
-            applyNode(node);
-        }
-        void apply(osg::MatrixTransform& node) override
-        {
-            applyNode(node);
-        }
-        void apply(osg::Node& node) override
-        {
-            applyNode(node);
-        }
-
-        void applyNode(osg::Node& node)
-        {
-            if (node.getStateSet())
-                node.setStateSet(nullptr);
-
-            if (node.getNodeMask() == 0x1 && node.getNumParents() == 1)
-                mToRemove.emplace_back(&node, node.getParent(0));
-            else
-                traverse(node);
-        }
-        void applyDrawable(osg::Node& node)
-        {
-            osg::NodePath::iterator parent = getNodePath().end()-2;
-            // We know that the parent is a Group because only Groups can have children.
-            osg::Group* parentGroup = static_cast<osg::Group*>(*parent);
-
-            // Try to prune nodes that would be empty after the removal
-            if (parent != getNodePath().begin())
-            {
-                // This could be extended to remove the parent's parent, and so on if they are empty as well.
-                // But for NIF files, there won't be a benefit since only TriShapes can be set to STATIC dataVariance.
-                osg::Group* parentParent = static_cast<osg::Group*>(*(parent - 1));
-                if (parentGroup->getNumChildren() == 1 && parentGroup->getDataVariance() == osg::Object::STATIC)
-                {
-                    mToRemove.emplace_back(parentGroup, parentParent);
-                    return;
-                }
-            }
-
-            mToRemove.emplace_back(&node, parentGroup);
-        }
-    };
-
-    class RemoveTriBipVisitor : public RemoveVisitor
-    {
-    public:
-        void apply(osg::Drawable& drw) override
-        {
-            applyImpl(drw);
-        }
-
-        void apply(osg::Group& node) override
-        {
-            traverse(node);
-        }
-        void apply(osg::MatrixTransform& node) override
-        {
-            traverse(node);
-        }
-
-        void applyImpl(osg::Node& node)
-        {
-            const std::string toFind = "tri bip";
-            if (Misc::StringUtils::ciCompareLen(node.getName(), toFind, toFind.size()) == 0)
-            {
-                osg::Group* parent = static_cast<osg::Group*>(*(getNodePath().end()-2));
-                // Not safe to remove in apply(), since the visitor is still iterating the child list
-                mToRemove.emplace_back(&node, parent);
-            }
-        }
-    };
 }
 
 namespace MWRender