Try to make skinned mesh work with normal map

This commit is contained in:
Benau
2016-10-15 00:17:09 +08:00
parent f70a64f61a
commit efb6b7431a
4 changed files with 90 additions and 7 deletions

View File

@@ -28,6 +28,7 @@
#include <irrlicht.h>
#include <IMesh.h>
#include <IMeshBuffer.h>
#include <SSkinMeshBuffer.h>
void MeshTools::minMax3D(scene::IMesh* mesh, Vec3 *min, Vec3 *max) {
@@ -460,11 +461,70 @@ scene::IMesh* MeshTools::createMeshWithTangents(scene::IMesh* mesh,
irr_driver->removeMeshFromCache(mesh);
scene::SAnimatedMesh* amesh = new scene::SAnimatedMesh(clone);
clone->drop();
irr_driver->grabAllTextures(amesh);
meshCache->addMesh(path, amesh);
World::getWorld()->getTrack()->addCachedMesh(amesh);
if (World::getWorld())
{
irr_driver->grabAllTextures(amesh);
World::getWorld()->getTrack()->addCachedMesh(amesh);
return amesh;
}
amesh->drop();
return amesh;
}
}
void MeshTools::createSkinnedMeshWithTangents(scene::ISkinnedMesh* mesh,
bool(*predicate)(scene::IMeshBuffer*))
{
core::array<scene::SSkinMeshBuffer*>& all_mb = mesh->getMeshBuffers();
const int all_mb_size = all_mb.size();
for (int i = 0; i < all_mb_size; i++)
{
scene::SSkinMeshBuffer* mb = all_mb[i];
if (mb && predicate(mb))
{
mb->convertToTangents();
const int index_count = mb->getIndexCount();
uint16_t* idx = mb->getIndices();
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)mb->getVertices();
for (int i = 0; i < index_count; i += 3)
{
calculateTangents(
v[idx[i+0]].Normal,
v[idx[i+0]].Tangent,
v[idx[i+0]].Binormal,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords);
calculateTangents(
v[idx[i+1]].Normal,
v[idx[i+1]].Tangent,
v[idx[i+1]].Binormal,
v[idx[i+1]].Pos,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].TCoords,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords);
calculateTangents(
v[idx[i+2]].Normal,
v[idx[i+2]].Tangent,
v[idx[i+2]].Binormal,
v[idx[i+2]].Pos,
v[idx[i+0]].Pos,
v[idx[i+1]].Pos,
v[idx[i+2]].TCoords,
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
}
}
}
}

View File

@@ -21,7 +21,7 @@
namespace irr
{
namespace scene { class IMesh; class IMeshBuffer; }
namespace scene { class IMesh; class IMeshBuffer; class ISkinnedMesh; }
}
using namespace irr;
@@ -37,8 +37,14 @@ namespace MeshTools
bool isNormalMap(scene::IMeshBuffer* mb);
// Copied from irrlicht
scene::IMesh* createMeshWithTangents(scene::IMesh* mesh, bool(*predicate)(scene::IMeshBuffer*),
bool recalculateNormals = false, bool smooth = false, bool angleWeighted = false, bool calculateTangents = true);
scene::IMesh* createMeshWithTangents(scene::IMesh* mesh,
bool(*predicate)(scene::IMeshBuffer*), bool recalculateNormals = false,
bool smooth = false, bool angleWeighted = false,
bool calculateTangents = true);
void createSkinnedMeshWithTangents(scene::ISkinnedMesh* mesh,
bool(*predicate)(scene::IMeshBuffer*));
} // MeshTools
#endif

View File

@@ -169,7 +169,7 @@ void STKAnimatedMesh::updateNoGL()
}
else
{
Material::ShaderType MatType = material->getShaderType();// getMeshMaterialFromType(type, mb->getVertexType(), material);
Material::ShaderType MatType = getMeshMaterialFromType(type, mb->getVertexType(), material, NULL);
MeshSolidMaterial[MatType].push_back(&mesh);
}
}

View File

@@ -522,6 +522,13 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
full_path.c_str(), kart_properties.getIdent().c_str());
return false;
}
scene::ISkinnedMesh* sm = dynamic_cast<scene::ISkinnedMesh*>(m_mesh);
if (sm)
{
MeshTools::createSkinnedMeshWithTangents(sm, &MeshTools::isNormalMap);
}
m_mesh->grab();
irr_driver->grabAllTextures(m_mesh);
@@ -570,6 +577,14 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
// Grab all textures. This is done for the master only, so
// the destructor will only free the textures if a master
// copy is freed.
scene::ISkinnedMesh* sm =
dynamic_cast<scene::ISkinnedMesh*>(obj.m_model);
if (sm)
{
MeshTools::createSkinnedMeshWithTangents(sm,
&MeshTools::isNormalMap);
}
irr_driver->grabAllTextures(obj.m_model);
// Update min/max
@@ -612,6 +627,8 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
std::string full_wheel =
kart_properties.getKartDir()+m_wheel_filename[i];
m_wheel_model[i] = irr_driver->getMesh(full_wheel);
m_wheel_model[i] = MeshTools::createMeshWithTangents(m_wheel_model[i],
&MeshTools::isNormalMap);
// Grab all textures. This is done for the master only, so
// the destructor will only free the textures if a master
// copy is freed.