Game Development Community

Simple problem with bullet decals

by Logan Strunk · in Torque Game Engine · 07/23/2006 (10:01 pm) · 5 replies

I followed this reference:

http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=9349

And was easily able to add bullethole decals to my weapon.

EXCEPT.

First, I added the code to my rifle script, with the appropriate changes made. But....nothing happened. I decided before I bothered anyone, I would make sure it would work on the head version.

So I put the code into the crossbow script, and lo and behold, its working.

However...when I make one change.


datablock ProjectileData(CrossbowProjectile)
{
projectileShapeName = "~/data/shapes/crossbow/projectile.dts";
directDamage = 20;
radiusDamage = 20;
damageRadius = 1.5;
areaImpulse = 200;

//explosion = CrossbowExplosion;
waterExplosion = CrossbowWaterExplosion;

particleEmitter = CrossbowBoltEmitter;
particleWaterEmitter= CrossbowBoltBubbleEmitter;

splash = CrossbowSplash;

muzzleVelocity = 100;
velInheritFactor = 0.3;

armingDelay = 0;
lifetime = 5000;
fadeDelay = 5000;
bounceElasticity = 0;
bounceFriction = 0;
isBallistic = false;
gravityMod = 0.80;

hasLight = true;
lightRadius = 4;
lightColor = "0.5 0.5 0.25";

hasWaterLight = true;
waterLightColor = "0 0.5 0.5";

//Decal Data Start
decals[0] = CrossbowDecal1;
decals[1] = CrossbowDecal2;
decals[2] = CrossbowDecal3;
decals[3] = CrossbowDecal4;
decals[4] = CrossbowDecal5;
decals[5] = CrossbowDecal6;
//Decal Data End
};


editing out the crossbowexplosion, the decals stop working.

hmm, ok I say to myself, there must be some code the crossbow explosion function thats important.

So I look, and I see absolutely nohting that looks like it could be important to decals.

could someone please explain to me why it quits working with that edited out?

I'd swear a month or so ago I had it in an old version of what I was working on, and it worked just fine.

#1
07/23/2006 (11:08 pm)
I'm trying now to see if it does the same for me. I'll edit this when I find out.

edit: Yup, same problem here. Perhaps the explosion code is what applies the decal, or the projectile code is not applying the decal because no explosion is specified? I'll look into this, but be forewarned I'm not a very experienced programmer ;)

edit again:

Upon perusal of the source, it appears that the second hypothesis is correct. In projectile.cc, starting at line 682:

if( pExplosion )
      {
         MatrixF xform(true);
         xform.setPosition(p);
         pExplosion->setTransform(xform);
         pExplosion->setInitialState(p, n);
         pExplosion->setCollideType( collideType );
         if (pExplosion->registerObject() == false)
         {
            Con::errorf(ConsoleLogEntry::General, "Projectile(%s)::explode: couldn't register explosion",
                        mDataBlock->getName() );
            delete pExplosion;
            pExplosion = NULL;
         }

         if(mDataBlock->decalCount > 0)
         {
            if(collideType & (TerrainObjectType | InteriorObjectType))
            {
               // randomly choose a decal between 0 and (decal count - 1)
               U32 idx = (U32)(mCeil(mDataBlock->decalCount * Platform::getRandom()) - 1.0f);

               // this should never choose a NULL idx, but check anyway
               if(mDataBlock->decals[idx] != NULL)
               {
                  DecalManager *decalMngr = gClientSceneGraph->getCurrentDecalManager();
                  if(decalMngr)
                     decalMngr->addDecal(p, n, mDataBlock->decals[idx]);
               }
            }
         }
      }

This basically ensures that an explosion MUST be defined or the decal will not be created.
The following codeblock _should_ (I have NOT tested this in any way) work to create the decal
even when no explosion is defined:

if( pExplosion )
      {
         MatrixF xform(true);
         xform.setPosition(p);
         pExplosion->setTransform(xform);
         pExplosion->setInitialState(p, n);
         pExplosion->setCollideType( collideType );
         if (pExplosion->registerObject() == false)
         {
            Con::errorf(ConsoleLogEntry::General, "Projectile(%s)::explode: couldn't register explosion",
                        mDataBlock->getName() );
            delete pExplosion;
            pExplosion = NULL;
         }
      }

      
       if(mDataBlock->decalCount > 0)
       {
            if(collideType & (TerrainObjectType | InteriorObjectType))
            {
               // randomly choose a decal between 0 and (decal count - 1)
               U32 idx = (U32)(mCeil(mDataBlock->decalCount * Platform::getRandom()) - 1.0f);

               // this should never choose a NULL idx, but check anyway
               if(mDataBlock->decals[idx] != NULL)
               {
                  DecalManager *decalMngr = gClientSceneGraph->getCurrentDecalManager();
                  if(decalMngr)
                     decalMngr->addDecal(p, n, mDataBlock->decals[idx]);
               }
            }
         }
#2
07/23/2006 (11:56 pm)
Let me know if this works. I have come across the same problem lately.
#3
07/24/2006 (11:41 am)
Thanks alot man.

Wow, thats crazy. You'd think an explosion would be secondary to the impact. Sounds like somone was smoking a little something while writing that part of the code.

I'm gonna work on it tonight and I'll get back to you.

thanks.
#4
07/24/2006 (11:41 am)
I did think of a simpler solution.

just give the explosion no velocity. Then nothing should happen, right?
I haven't tested that though.
#5
07/24/2006 (6:58 pm)
That modification to projectile.cc did that trick.

Worked like a charm. No errors on compile, and now I get the decals.


Your my hero man.

Thanks.