Decal System / Manager

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
kinkreet
Posts: 64
Joined: Thu Oct 31, 2013 7:53 pm
Location: Barcelona, Spain

Re: Decal System / Manager

Post by kinkreet »

This is a very good tool :D, 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.

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);
}
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.

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.
Last edited by kinkreet on Mon Jan 19, 2015 7:04 am, edited 1 time in total.
rustyk
Posts: 25
Joined: Sat Jan 10, 2015 4:03 pm

Re: Decal System / Manager

Post by rustyk »

This is awesome, it flat out works and code is clean. Thanks for sharing! :D
Post Reply