From f94ca28dbe9e1727776a7ab259e5bac30d656120 Mon Sep 17 00:00:00 2001
From: psi29a <psi29a@gmail.com>
Date: Thu, 18 Jun 2020 17:23:16 +0000
Subject: [PATCH] #5463: Optimizer fix, problem was indeed related to tangents
 not being transformd properly.

---
 components/sceneutil/optimizer.cpp | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/components/sceneutil/optimizer.cpp b/components/sceneutil/optimizer.cpp
index e8a9451143..b9da2d1c8d 100644
--- a/components/sceneutil/optimizer.cpp
+++ b/components/sceneutil/optimizer.cpp
@@ -358,6 +358,21 @@ void CollectLowestTransformsVisitor::doTransform(osg::Object* obj,osg::Matrix& m
     {
         osgUtil::TransformAttributeFunctor tf(matrix);
         drawable->accept(tf);
+
+        osg::Geometry *geom = drawable->asGeometry();
+        osg::Vec4Array* tangents = geom ? dynamic_cast<osg::Vec4Array*>(geom->getTexCoordArray(7)) : nullptr;
+        if (tangents)
+        {
+            for (unsigned int i=0; i<tangents->size(); ++i)
+            {
+                osg::Vec4f& itr = (*tangents)[i];
+                osg::Vec3f vec3 (itr.x(), itr.y(), itr.z());
+                vec3 = osg::Matrix::transform3x3(tf._im, vec3);
+                vec3.normalize();
+                itr = osg::Vec4f(vec3.x(), vec3.y(), vec3.z(), itr.w());
+            }
+        }
+
         drawable->dirtyBound();
         drawable->dirtyDisplayList();
 
@@ -614,12 +629,12 @@ void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Drawable& drawable)
     if((geometry) && (isOperationPermissibleForObject(&drawable)))
     {
         osg::VertexBufferObject* vbo = nullptr;
-        if(geometry->getVertexArray() && geometry->getVertexArray()->referenceCount() > 1) {
+        if(geometry->getVertexArray() && geometry->getVertexArray()->referenceCount() > 1)
             geometry->setVertexArray(cloneArray(geometry->getVertexArray(), vbo, geometry));
-        }
-        if(geometry->getNormalArray() && geometry->getNormalArray()->referenceCount() > 1) {
+        if(geometry->getNormalArray() && geometry->getNormalArray()->referenceCount() > 1)
             geometry->setNormalArray(cloneArray(geometry->getNormalArray(), vbo, geometry));
-        }
+        if(geometry->getTexCoordArray(7) && geometry->getTexCoordArray(7)->referenceCount() > 1) // tangents
+            geometry->setTexCoordArray(7, cloneArray(geometry->getTexCoordArray(7), vbo, geometry));
     }
     _drawableSet.insert(&drawable);
 }