mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-11 00:44:33 +00:00
Add special handling of RigGeometry tangents in ShaderVisitor
This commit is contained in:
parent
95e80e7eff
commit
d1f6169889
@ -99,6 +99,13 @@ void RigGeometry::setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeometry)
|
|||||||
setColorArray(from.getColorArray());
|
setColorArray(from.getColorArray());
|
||||||
setSecondaryColorArray(from.getSecondaryColorArray());
|
setSecondaryColorArray(from.getSecondaryColorArray());
|
||||||
setFogCoordArray(from.getFogCoordArray());
|
setFogCoordArray(from.getFogCoordArray());
|
||||||
|
|
||||||
|
// need to copy over texcoord list manually due to a missing null pointer check in setTexCoordArrayList(), this has been fixed in OSG 3.5
|
||||||
|
osg::Geometry::ArrayList& texCoordList = from.getTexCoordArrayList();
|
||||||
|
for (unsigned int i=0; i<texCoordList.size(); ++i)
|
||||||
|
if (texCoordList[i])
|
||||||
|
setTexCoordArray(i, texCoordList[i], osg::Array::BIND_PER_VERTEX);
|
||||||
|
|
||||||
setTexCoordArrayList(from.getTexCoordArrayList());
|
setTexCoordArrayList(from.getTexCoordArrayList());
|
||||||
setVertexAttribArrayList(from.getVertexAttribArrayList());
|
setVertexAttribArrayList(from.getVertexAttribArrayList());
|
||||||
|
|
||||||
@ -120,6 +127,19 @@ void RigGeometry::setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeometry)
|
|||||||
normalArray->setVertexBufferObject(vbo);
|
normalArray->setVertexBufferObject(vbo);
|
||||||
setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX);
|
setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (from.getTexCoordArray(7) && dynamic_cast<osg::Vec4Array*>(from.getTexCoordArray(7)))
|
||||||
|
{
|
||||||
|
// tangents
|
||||||
|
osg::ref_ptr<osg::Array> tangentArray = osg::clone(from.getTexCoordArray(7), osg::CopyOp::DEEP_COPY_ALL);
|
||||||
|
tangentArray->setVertexBufferObject(vbo);
|
||||||
|
setTexCoordArray(7, tangentArray, osg::Array::BIND_PER_VERTEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> RigGeometry::getSourceGeometry()
|
||||||
|
{
|
||||||
|
return mSourceGeometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv)
|
bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv)
|
||||||
@ -225,9 +245,11 @@ void RigGeometry::update(osg::NodeVisitor* nv)
|
|||||||
// skinning
|
// skinning
|
||||||
osg::Vec3Array* positionSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getVertexArray());
|
osg::Vec3Array* positionSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getVertexArray());
|
||||||
osg::Vec3Array* normalSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getNormalArray());
|
osg::Vec3Array* normalSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getNormalArray());
|
||||||
|
osg::Vec4Array* tangentSrc = static_cast<osg::Vec4Array*>(mSourceGeometry->getTexCoordArray(7));
|
||||||
|
|
||||||
osg::Vec3Array* positionDst = static_cast<osg::Vec3Array*>(getVertexArray());
|
osg::Vec3Array* positionDst = static_cast<osg::Vec3Array*>(getVertexArray());
|
||||||
osg::Vec3Array* normalDst = static_cast<osg::Vec3Array*>(getNormalArray());
|
osg::Vec3Array* normalDst = static_cast<osg::Vec3Array*>(getNormalArray());
|
||||||
|
osg::Vec4Array* tangentDst = static_cast<osg::Vec4Array*>(getTexCoordArray(7));
|
||||||
|
|
||||||
for (Bone2VertexMap::const_iterator it = mBone2VertexMap.begin(); it != mBone2VertexMap.end(); ++it)
|
for (Bone2VertexMap::const_iterator it = mBone2VertexMap.begin(); it != mBone2VertexMap.end(); ++it)
|
||||||
{
|
{
|
||||||
@ -251,11 +273,19 @@ void RigGeometry::update(osg::NodeVisitor* nv)
|
|||||||
unsigned short vertex = *vertexIt;
|
unsigned short vertex = *vertexIt;
|
||||||
(*positionDst)[vertex] = resultMat.preMult((*positionSrc)[vertex]);
|
(*positionDst)[vertex] = resultMat.preMult((*positionSrc)[vertex]);
|
||||||
(*normalDst)[vertex] = osg::Matrix::transform3x3((*normalSrc)[vertex], resultMat);
|
(*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();
|
positionDst->dirty();
|
||||||
normalDst->dirty();
|
normalDst->dirty();
|
||||||
|
if (tangentDst)
|
||||||
|
tangentDst->dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigGeometry::updateBounds(osg::NodeVisitor *nv)
|
void RigGeometry::updateBounds(osg::NodeVisitor *nv)
|
||||||
|
@ -43,6 +43,8 @@ namespace SceneUtil
|
|||||||
/// @note The source geometry will not be modified.
|
/// @note The source geometry will not be modified.
|
||||||
void setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeom);
|
void setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeom);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> getSourceGeometry();
|
||||||
|
|
||||||
// Called automatically by our CullCallback
|
// Called automatically by our CullCallback
|
||||||
void update(osg::NodeVisitor* nv);
|
void update(osg::NodeVisitor* nv);
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <components/resource/imagemanager.hpp>
|
#include <components/resource/imagemanager.hpp>
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
|
#include <components/sceneutil/riggeometry.hpp>
|
||||||
|
|
||||||
#include "shadermanager.hpp"
|
#include "shadermanager.hpp"
|
||||||
|
|
||||||
@ -313,24 +314,32 @@ namespace Shader
|
|||||||
{
|
{
|
||||||
const ShaderRequirements& reqs = mRequirements.back();
|
const ShaderRequirements& reqs = mRequirements.back();
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> sourceGeometry = &geometry;
|
||||||
|
SceneUtil::RigGeometry* rig = dynamic_cast<SceneUtil::RigGeometry*>(&geometry);
|
||||||
|
if (rig)
|
||||||
|
sourceGeometry = rig->getSourceGeometry();
|
||||||
|
|
||||||
if (mAllowedToModifyStateSets)
|
if (mAllowedToModifyStateSets)
|
||||||
{
|
{
|
||||||
// make sure that all UV sets are there
|
// make sure that all UV sets are there
|
||||||
for (std::map<int, std::string>::const_iterator it = reqs.mTextures.begin(); it != reqs.mTextures.end(); ++it)
|
for (std::map<int, std::string>::const_iterator it = reqs.mTextures.begin(); it != reqs.mTextures.end(); ++it)
|
||||||
{
|
{
|
||||||
if (geometry.getTexCoordArray(it->first) == NULL)
|
if (sourceGeometry->getTexCoordArray(it->first) == NULL)
|
||||||
geometry.setTexCoordArray(it->first, geometry.getTexCoordArray(0));
|
sourceGeometry->setTexCoordArray(it->first, sourceGeometry->getTexCoordArray(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reqs.mTexStageRequiringTangents != -1 && mAllowedToModifyStateSets)
|
if (reqs.mTexStageRequiringTangents != -1 && mAllowedToModifyStateSets)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osgUtil::TangentSpaceGenerator> generator (new osgUtil::TangentSpaceGenerator);
|
osg::ref_ptr<osgUtil::TangentSpaceGenerator> generator (new osgUtil::TangentSpaceGenerator);
|
||||||
generator->generate(&geometry, reqs.mTexStageRequiringTangents);
|
generator->generate(sourceGeometry, reqs.mTexStageRequiringTangents);
|
||||||
|
|
||||||
geometry.setTexCoordArray(7, generator->getTangentArray(), osg::Array::BIND_PER_VERTEX);
|
sourceGeometry->setTexCoordArray(7, generator->getTangentArray(), osg::Array::BIND_PER_VERTEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rig)
|
||||||
|
rig->setSourceGeometry(sourceGeometry);
|
||||||
|
|
||||||
// TODO: find a better place for the stateset
|
// TODO: find a better place for the stateset
|
||||||
if (reqs.mShaderRequired || mForceShaders)
|
if (reqs.mShaderRequired || mForceShaders)
|
||||||
createProgram(reqs, geometry);
|
createProgram(reqs, geometry);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user