### [C++]Bullet decals disappear if the base is destroyed

Scripts and code that enhance the gameplay functionality of the engine.

#### [C++]Bullet decals disappear if the base is destroyed

irei1as
Posts: 76
Joined: Fri Feb 27, 2015 5:13 pm
Small code change to make the decals from bullet shots to dissapear if the object under it dissapears (or moves away or the shape changes and under the shots there is nothing anymore).
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 http://forums.torque3d.org/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--

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

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
Last edited by irei1as on Fri Jul 29, 2016 12:05 pm, edited 3 times in total.

#### Re: [C++]Bullet decals disappear if the base is destroyed

rlranft
Posts: 298
Joined: Thu Feb 05, 2015 3:11 pm

Hmm, that's a good question - I thought these decals were handled client-side, but in source it references gDecalManager so perhaps these are server-side and replicated.... <shrug>

#### Re: [C++]Bullet decals disappear if the base is destroyed

Azaezel
Posts: 395
Joined: Tue Feb 03, 2015 9:50 pm

#### Re: [C++]Bullet decals disappear if the base is destroyed

flysouth
Posts: 105
Joined: Sun May 15, 2016 10:16 am
Thanks for this speedy fix, although I think that it would also be good if ShapeBase also had a decalType like TSStatic so that one could decide a decal type if any. Then if it was set to "none" a decal wou;d never be placed on it.
Do fixes like this automatically get put in to future engine releases?

#### Re: [C++]Bullet decals disappear if the base is destroyed

Azaezel
Posts: 395
Joined: Tue Feb 03, 2015 9:50 pm

already in. that was pointing at the area where client replication occurs.

#### Re: [C++]Bullet decals disappear if the base is destroyed

irei1as
Posts: 76
Joined: Fri Feb 27, 2015 5:13 pm
Do fixes like this automatically get put in to future engine releases?
The fix @ Azaezel points is already in, of course, but if you mean this resource... I don't think it's all-purpose enough to be included, it's kinda heavy with all those castRay and I'm not sure if it's 100% bug-free.
You really should fully test it before you add it (specially multiplayer if you plan to use it with that).

But, hey, if enough people check it and they think it's worth it I'm ok with a pull request to add it to the main code.

As side note, let me add a few images to the first post so it's a bit clearer what the code does.

#### Re: [C++]Bullet decals disappear if the base is destroyed

Azaezel
Posts: 395
Joined: Tue Feb 03, 2015 9:50 pm

@
irei1as
could see at least checking if surfaceObject still exists if you'd wanna throw over a minimalist interpretation without the castrays. you're right about tree-searching for a lot of decals potentially getting a bit hairy, but i'd think a simple 'this still valid' test would be ok preformance wise.

#### Re: [C++]Bullet decals disappear if the base is destroyed

flysouth
Posts: 105
Joined: Sun May 15, 2016 10:16 am
@ Azaezel
already in. that was pointing at the area where client replication occurs.

are you saying the decalType is already in shapebase? if so how do you access it?

#### Re: [C++]Bullet decals disappear if the base is destroyed

marauder2k9
Posts: 162
Joined: Wed Feb 18, 2015 7:36 am
do u think this could be modified to have a decal follow the movement of an object?

#### Re: [C++]Bullet decals disappear if the base is destroyed

irei1as
Posts: 76
Joined: Fri Feb 27, 2015 5:13 pm
do u think this could be modified to have a decal follow the movement of an object?
If the object has no internal animations it's very easy, like a static object moving with a tween.
Add the matrix transform of the parent object (the object receiving the decal) as a variable of the decal. Then if the object position changes (you have the id of the object to check) you make a transform of the decal according to that.

The problem is if the object has animations, like the soldier moving his feet or arms.
That's because it's not easy to know where in the geometry the hit will be in any other frame.
Checking how the nodes moves may be a starting point but that needs a C++ change for the nodes to show the transform in real time.

This is what I have related to this for the 3.8 version. Sadly I can't use the new code for the newest version.

Code: Select all

Inside source/T3D/shapeBase.h add before the end of the definition of class ShapeBase: public: MatrixF getNodeTransformN(const String &nodeName); MatrixF getNodeTransform(const S32 nodeIdx); Inside source/T3D/shapeBase.cpp just at the end: MatrixF ShapeBase::getNodeTransformN(const String &nodeName) { S32 nodeIdx = mShapeInstance->getShape()->findNode(nodeName); return getNodeTransform(nodeIdx); } MatrixF ShapeBase::getNodeTransform(const S32 nodeIdx) { MatrixF returnValue = MatrixF::Identity; if(nodeIdx != -1) { if (isServerObject() && mShapeInstance) mShapeInstance->animateNodeSubtrees(true); returnValue = mShapeInstance->mNodeTransforms[nodeIdx]; } MatrixF objectTransform = getTransform(); Point3F nodeObjPos = returnValue.getPosition(); nodeObjPos.convolve( getScale() ); returnValue.setPosition(nodeObjPos); returnValue.mulL(objectTransform); return returnValue; } DefineEngineMethod( ShapeBase, getNodeTransform, TransformF, (const char* nodeName),, "Get the transform of a named node in the shape.\n" "@param nodeName Name of the node to check.\n" "@return The current transform of the node.\n" ) { return TransformF(object->getNodeTransformN(nodeName)); } --------------------------------------------------------------------------------------------------------------------- In source\T3D\shapeImage.cpp look inside of void ShapeBase::getMountTransform( S32 index, const MatrixF &xfm, MatrixF *outMat ) for MatrixF mountTransform = mShapeInstance->mNodeTransforms[ni]; And add these lines before: if (isServerObject() && mShapeInstance) mShapeInstance->animateNodeSubtrees(true); 

#### Who is online

Users browsing this forum: No registered users and 1 guest