Re: Decal System / Manager
Posted: Sat Feb 01, 2014 1:33 pm
This is a very good tool , I made some change in the code:
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.
2n ->
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.
This solutions are provisionals, but it works.
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.