1 ->setVertexColorAlpha(mesh, alpha <= 0 ? 0 : alpha);
Because sometimes the alpha it's < to 0 and breaks the fadeout effect, showing the decal without fadeout.
Code: Select all
void DecalSceneNode::OnAnimate(u32 timeMs) {
if (fadeOut && lifetime > 0) {
// Lifetime done, start fading out
if (difftime(time(NULL), creationTime) > lifetime) {
if (startFadeOutTimeMs > 0) {
const u32 timeDiff = timeMs - startFadeOutTimeMs;
const s32 alpha = 255 - ((timeDiff * 255) / (fadeOutTime * 1000)) ;
SceneManager->getMeshManipulator()->setVertexColorAlpha(mesh, alpha <= 0 ? 0 : alpha);
} else {
material.MaterialType = video::EMT_ONETEXTURE_BLEND;
startFadeOutTimeMs = timeMs;
}
}
}
ISceneNode::OnAnimate(timeMs);
}
Passing the normal vector of the decal is not necesary and fails always and if you use the normal inverted of the camera , the decal looks deformed. You can use the same function that creates the mesh of the decal to obtain the real normal vector of the resultant mesh.
Code: Select all
irr::scene::DecalSceneNode* DecalManager::addDecal(irr::video::ITexture* texture, irr::core::vector3df position, irr::core::vector3df dimension, irr::core::vector3df normal, const irr::f32 textureRotation,
irr::scene::ISceneNode* parent, const irr::f32 lifeTime, const irr::f32 distance, const bool useTerrainOnly) {
// Check if meta selector has any selectors added
if (metaSelector->getTriangleCount() == 0) {
return 0;
}
dimension *= 0.5f;
//////////////////////////////////// REAL NORMAL /////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
irr::core::array<irr::core::vector3df> realnormal;
irr::core::aabbox3df box2 = irr::core::aabbox3df( -dimension, dimension);
box2.MinEdge += position;
box2.MaxEdge += position;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
irr::core::array<irr::core::triangle3df> triangles;
irr::s32 triangleCount = 0;
if (terrain && useTerrainOnly) {
triangles.set_used(terrain->getTriangleSelector()->getTriangleCount());
terrain->getTriangleSelector()->getTriangles(&triangles[0], triangles.size(), triangleCount, box2);
} else {
triangles.set_used(metaSelector->getTriangleCount());
metaSelector->getTriangles(&triangles[0], triangles.size(), triangleCount, box2);
}
for (irr::u32 i = 0; i < (irr::u32)triangleCount; i++) {
bool repeat = false;
irr::core::vector3df triangleNormal = triangles[i].getNormal().normalize();
for (irr::u32 b = 0; b < realnormal.size(); ++b){
if (realnormal[b] == triangleNormal){
repeat = true;
break;
}
}
if (!repeat)
realnormal.push_back(triangleNormal);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create boxes
irr::core::aabbox3df box = irr::core::aabbox3df( -dimension, dimension);
box.MinEdge += position;
box.MaxEdge += position;
// Calculate normal
irr::core::vector3df result = irr::core::vector3df(0,0,0);
for (irr::u32 b = 0; b < realnormal.size(); ++b)
result += realnormal[b];
// Calculate rotation
result = result/realnormal.size();
result.normalize();
result.Y *= -1;
realnormal.clear();
irr::core::quaternion quatDirection;
quatDirection.rotationFromTo(irr::core::vector3df(0, 1, 0), result );
irr::core::vector3df rotation = quatDirection.getMatrix().getRotationDegrees();
rotation.Y += textureRotation;
// Create rotation matrix
irr::core::matrix4 rotationMatrix;
rotationMatrix.setRotationDegrees(rotation);
rotationMatrix.setRotationCenter( irr::core::vector3df(0.5f, 0.5f, 0.5f), irr::core::vector3df(0, 0, 0));
// Create mesh
irr::scene::IMesh* mesh = createMesh(box, rotationMatrix, useTerrainOnly);
// Create decal scene node
if (parent == 0) {
parent = smgr->getRootSceneNode();
}
position -= parent->getAbsolutePosition();
position /= parent->getScale();
irr::scene::DecalSceneNode* decal = new irr::scene::DecalSceneNode(parent, smgr, mesh, texture, position);
decal->setLifetime(lifeTime);
decal->setDistance(distance);
decal->drop();
return decal;
}
This solutions are provisionals, but it works.