I was getting an exception saying that I can't use a normal map without having tangent vectors, and I found some discussion about that in the long "moving Stunt Rally" thread. So I wrote some code that tries to detect when tangent vectors are missing, and build them if needed, but it doesn't seem to work...
Code: Select all
static Ogre::VertexArrayObject* GetFirstVAO( Ogre::MeshPtr inMesh )
{
Ogre::VertexArrayObject* resultVAO = nullptr;
if (inMesh->getNumSubMeshes() > 0)
{
Ogre::SubMesh* firstSub = inMesh->getSubMesh( 0 );
Ogre::VertexArrayObjectArray& vaos( firstSub->mVao[ Ogre::VpNormal ] );
if (not vaos.empty())
{
resultVAO = vaos[0];
}
}
return resultVAO;
}
static bool HasTangents( Ogre::VertexArrayObject* inVAO )
{
bool haveTangents = true;
size_t ignoredIndex, ignoredOffset;
if ( (inVAO != nullptr) and
(nullptr == inVAO->findBySemantic( Ogre::VES_TANGENT,
ignoredIndex, ignoredOffset )) )
{
haveTangents = false;
}
return haveTangents;
}
static bool CanBuildTangents( Ogre::VertexArrayObject* inVAO )
{
size_t ignoredIndex, ignoredOffset;
const Ogre::VertexElement2* norm = inVAO->findBySemantic( Ogre::VES_NORMAL,
ignoredIndex, ignoredOffset );
const Ogre::VertexElement2* uv = inVAO->findBySemantic( Ogre::VES_TEXTURE_COORDINATES,
ignoredIndex, ignoredOffset );
return (norm != nullptr) and (uv != nullptr);
}
static void AddTangentVectors( Ogre::MeshPtr inMesh )
{
// Inconveniently, we must convert to a temporary v1 mesh in order
// to create tangents.
Ogre::v1::MeshPtr m1 = Ogre::v1::MeshManager::getSingleton().create(
"TempV1ForTangents", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
JWAssert( m1.get() != nullptr );
m1->setVertexBufferPolicy( Ogre::v1::HardwareBuffer::HBU_STATIC, false );
m1->setIndexBufferPolicy( Ogre::v1::HardwareBuffer::HBU_STATIC, false );
m1->importV2( inMesh.get() );
m1->buildTangentVectors();
inMesh->importV1( m1.get(), false, false, false );
Ogre::v1::MeshManager::getSingleton().remove( "TempV1ForTangents" );
}
That is, if HasTangents( GetFirstVAO( mesh ) )
returns false and CanBuildTangents( GetFirstVAO( mesh ) )
returns true, I call AddTangentVectors( mesh )
. And in that case, I then call HasTangents( GetFirstVAO( mesh ) )
again as a check, and it STILL returns false. Anyone see what I'm doing wrong?