Try to make skinned mesh work with normal map
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user