From 9cf963b75193d8962234b7375aead6eca7a72d11 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 22 Mar 2016 22:13:41 +0100 Subject: [PATCH] Animate tangents in RigGeometry --- components/sceneutil/riggeometry.cpp | 19 +++++++++++++++++++ components/sceneutil/riggeometry.hpp | 1 + 2 files changed, 20 insertions(+) diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index edbb6371e..c1f5fda15 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -84,12 +84,14 @@ RigGeometry::RigGeometry(const RigGeometry ©, const osg::CopyOp ©op) { mSourceVertices = copy.mSourceVertices; mSourceNormals = copy.mSourceNormals; + mSourceTangents = copy.mSourceTangents; } void RigGeometry::setSourceGeometry(osg::ref_ptr sourceGeometry) { mSourceVertices = static_cast(sourceGeometry->getVertexArray()); mSourceNormals = static_cast(sourceGeometry->getNormalArray()); + mSourceTangents = static_cast(sourceGeometry->getTexCoordArray(7)); osg::Geometry& from = *sourceGeometry; @@ -227,9 +229,18 @@ void RigGeometry::update(osg::NodeVisitor* nv) // skinning osg::Vec3Array* positionSrc = mSourceVertices; osg::Vec3Array* normalSrc = mSourceNormals; + osg::Vec4Array* tangentSrc = mSourceTangents; osg::Vec3Array* positionDst = static_cast(getVertexArray()); osg::Vec3Array* normalDst = static_cast(getNormalArray()); + osg::Vec4Array* tangentDst = static_cast(getTexCoordArray(7)); + + if (tangentDst && !tangentSrc) + { + // tangents may be set by the ShaderVisitor so may not have existed yet at the time the source geometry was set + tangentSrc = osg::clone(tangentDst, osg::CopyOp::DEEP_COPY_ALL); + mSourceTangents = tangentSrc; + } for (Bone2VertexMap::const_iterator it = mBone2VertexMap.begin(); it != mBone2VertexMap.end(); ++it) { @@ -253,11 +264,19 @@ void RigGeometry::update(osg::NodeVisitor* nv) unsigned short vertex = *vertexIt; (*positionDst)[vertex] = resultMat.preMult((*positionSrc)[vertex]); (*normalDst)[vertex] = osg::Matrix::transform3x3((*normalSrc)[vertex], resultMat); + if (tangentDst) + { + osg::Vec4f srcTangent = (*tangentSrc)[vertex]; + osg::Vec3f transformedTangent = osg::Matrix::transform3x3(osg::Vec3f(srcTangent.x(), srcTangent.y(), srcTangent.z()), resultMat); + (*tangentDst)[vertex] = osg::Vec4f(transformedTangent, srcTangent.w()); + } } } positionDst->dirty(); normalDst->dirty(); + if (tangentDst) + tangentDst->dirty(); } void RigGeometry::updateBounds(osg::NodeVisitor *nv) diff --git a/components/sceneutil/riggeometry.hpp b/components/sceneutil/riggeometry.hpp index fb4b914a0..b6d39a63a 100644 --- a/components/sceneutil/riggeometry.hpp +++ b/components/sceneutil/riggeometry.hpp @@ -53,6 +53,7 @@ namespace SceneUtil private: osg::ref_ptr mSourceVertices; osg::ref_ptr mSourceNormals; + osg::ref_ptr mSourceTangents; Skeleton* mSkeleton; osg::NodePath mSkelToGeomPath;