[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions.php on line 5150: file_get_contents(https://freedomsponsors.org/api/project/294): failed to open stream: HTTP request failed! HTTP/1.1 502 Bad Gateway
[C++]Bullet decals disappear if the base is destroyed - Forums | Torque 3D

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

Scripts and code that enhance the gameplay functionality of the engine.
10 posts Page 1 of 1
irei1as
Posts: 66
Joined: Fri Feb 27, 2015 5:13 pm
by irei1as » Wed Jul 27, 2016 1:28 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 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:
Image

With this code change the decals without base disappear:
Image

(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
Last edited by irei1as on Fri Jul 29, 2016 12:05 pm, edited 3 times in total.
rlranft
Posts: 298
Joined: Thu Feb 05, 2015 3:11 pm
 
by rlranft » Wed Jul 27, 2016 5:10 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>
Azaezel
Posts: 368
Joined: Tue Feb 03, 2015 9:50 pm
 
by Azaezel » Thu Jul 28, 2016 1:50 am
flysouth
Posts: 105
Joined: Sun May 15, 2016 10:16 am
by flysouth » Thu Jul 28, 2016 2:53 pm
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?
Azaezel
Posts: 368
Joined: Tue Feb 03, 2015 9:50 pm
 
by Azaezel » Thu Jul 28, 2016 2:57 pm
already in. that was pointing at the area where client replication occurs.
irei1as
Posts: 66
Joined: Fri Feb 27, 2015 5:13 pm
by irei1as » Fri Jul 29, 2016 12:00 pm
flysouth wrote:Do fixes like this automatically get put in to future engine releases?

The fix @
User avatar
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.
Azaezel
Posts: 368
Joined: Tue Feb 03, 2015 9:50 pm
 
by Azaezel » Fri Jul 29, 2016 4:22 pm
@
User avatar
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.
flysouth
Posts: 105
Joined: Sun May 15, 2016 10:16 am
by flysouth » Fri Jul 29, 2016 11:55 pm
@
User avatar
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?
marauder2k9
Posts: 138
Joined: Wed Feb 18, 2015 7:36 am
by marauder2k9 » Sun Mar 19, 2017 11:52 pm
do u think this could be modified to have a decal follow the movement of an object?
irei1as
Posts: 66
Joined: Fri Feb 27, 2015 5:13 pm
by irei1as » Tue Mar 21, 2017 5:39 pm
marauder2k9 wrote: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); 
         
10 posts Page 1 of 1

Who is online

Users browsing this forum: Google [Bot] and 1 guest