I'm not sure if it works for multiplayer and it may be heavy on resources if there are a lot of decals active.
(Related to viewtopic.php?f=12&t=733 )
Example_ A Red cube becomes a smaller green shape after a few bullets impact.
Before the code change some decals keep hanging:

With this code change the decals without base disappear:

(Note: The decals need to have lifetime. Permanent decals keep hanging.)
--Code changes--
In decalInstance.h add after
Code: Select all
DecalData *mDataBlock;
this line:
Code: Select all
S32 surfaceObject;
Then, also in that file, replace
Code: Select all
DecalInstance() : mId(-1) {}
with
Code: Select all
DecalInstance() : mId(-1), surfaceObject(0) {}
In projectile.cpp find:
Code: Select all
// Client (impact) decal.
if ( mDataBlock->decal )
gDecalManager->addDecal(p, n, 0.0f, mDataBlock->decal);
And replace it with:
Code: Select all
// Client (impact) decal.
DecalInstance * decalReturn = NULL;
if ( mDataBlock->decal )
decalReturn = gDecalManager->addDecal(p, n, 0.0f, mDataBlock->decal);
if(decalReturn)
{
RayInfo rInfo;
Point3F oldPosition = p;
Point3F newPosition = p - (n*0.05);
// Raycast the abstract PhysicsWorld if a PhysicsPlugin exists.
bool hit = false;
//disableCollision();
//let's ignore bullet physics and go the poor castRay
hit = gClientContainer.castRay(oldPosition, newPosition, csmDynamicCollisionMask | csmStaticCollisionMask, &rInfo);
//enableCollision();
//if(rInfo.object has some quality that enables this check) {
if(hit)
decalReturn->surfaceObject = (rInfo.object)->getId(); //else, surfaceObject keeps being 0
//} ----- closing of if(rInfo.object has some quality...)
}
---------------------------------
In decalManager.cpp find:
Code: Select all
if ( dinst->mVisibility <= 0.0f )
{
mDecalQueue.erase_fast( i );
removeDecal( dinst );
i--;
continue;
}
}
And add after that:
Code: Select all
if(dinst->surfaceObject)
{
if(!Sim::findObject(dinst->surfaceObject))
{
//the object that was under the decal does not exist anymore
mDecalQueue.erase_fast( i );
removeDecal( dinst );
i--;
continue;
}
RayInfo rInfo;
Point3F oldPosition = dinst->mPosition;
Point3F newPosition = dinst->mPosition - (dinst->mNormal*0.05);
bool hit = false;
//disableCollision();
//let's ignore bullet physics and go the poor castRay in the client
hit = gClientContainer.castRay(oldPosition, newPosition, (PlayerObjectType | VehicleObjectType) | (TerrainObjectType | StaticShapeObjectType), &rInfo);
//enableCollision();
if(!hit || ((rInfo.object)->getId() != dinst->surfaceObject))
{
//the object that was under the decal moved or transformed and the decal is in the air
mDecalQueue.erase_fast( i );
removeDecal( dinst );
i--;
continue;
}
}
They should end as:
source\T3D\decal\decalInstance.h : http://pastebin.com/43QiN2df
source\T3D\projectile.cpp : http://pastebin.com/B170LDAm
source\T3D\decal\decalManager.cpp : http://pastebin.com/r1U5fJ5F