Jump to content

Material Defined Decals


marauder2k9

Recommended Posts

ive been trying to create a resource that specifies a decal for any material, similar to the way that a footstepsound is set by the material. code changes are as follows.


in materialDefinition.h


Includes

#include "T3D/decal/decalManager.h"
#include "T3D/decal/decalData.h"

below the classes added

 

class DecalData;

 

below SFXTrack* mImpactSoundCustom;

 

DecalData *mDecal;

 

in materialDefinition.cpp

set the default of mDecal to null

 

   mFootstepSoundId = -1;     mImpactSoundId = -1;
  mFootstepSoundCustom = 0;  mImpactSoundCustom = 0;
  mDecal = NULL;

 

then added a custom field

	  ///add field for the decal
     addField( "customDecal", TYPEID< DecalData >(), Offset(mDecal, Material),
	  "The Decal to display when a projectile impacts on the surface. If no decal is defined it will revert to the default decal for that projectile");

 

in projectile.h

added

class Material;

 

changed the virtual void of explode

   virtual void explode(const Point3F& p, const Point3F& n, const U32 collideType, Material *contactMaterial );

 

then in projectile.cpp


included

 

#include "materials/baseMatInstance.h"

 

updated the explode function

 

void Projectile::explode( const Point3F &p, const Point3F &n, const U32 collideType, Material *contactMaterial )
{
  // Make sure we don't explode twice...
  if ( mHasExploded )
     return;

  mHasExploded = true;

  // Move the explosion point slightly off the surface to avoid problems with radius damage
  Point3F explodePos = p + n * 0.001f;

  if ( isServerObject() )
  {
     // Do what the server needs to do, damage the surrounding objects, etc.
     mExplosionPosition = explodePos;
     mExplosionNormal = n;
     mCollideHitType  = collideType;

   mDataBlock->onExplode_callback( this, mExplosionPosition, mFadeValue );

     setMaskBits(ExplosionMask);

     // Just wait till the timeout to self delete. This 
     // gives server object time to get ghosted to the client.
  } 
  else 
  {
     // Client just plays the explosion at the right place...
     //       
     Explosion* pExplosion = NULL;

     if (mDataBlock->waterExplosion && pointInWater(p))
     {
        pExplosion = new Explosion;
        pExplosion->onNewDataBlock(mDataBlock->waterExplosion, false);
     }
     else
     if (mDataBlock->explosion)
     {
        pExplosion = new Explosion;
        pExplosion->onNewDataBlock(mDataBlock->explosion, false);
     }

     if( pExplosion )
     {
        MatrixF xform(true);
        xform.setPosition(explodePos);
        pExplosion->setTransform(xform);
        pExplosion->setInitialState(explodePos, 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 (contactMaterial && contactMaterial->mDecal)
  {
	  gDecalManager->addDecal(p, n, 0.0f, contactMaterial->mDecal);
  }
	// Client (impact) decal.
  else 
  if(mDataBlock->decal)
  {
	  gDecalManager->addDecal(p, n, 0.0f, mDataBlock->decal);
  }
     // Client object
     updateSound();
  }

  /*
  // Client and Server both should apply forces to PhysicsWorld objects
  // within the explosion. 
  if ( false && mPhysicsWorld )
  {
     F32 force = 200.0f;
     mPhysicsWorld->explosion( p, 15.0f, force );
  }
  */
}

 


in projectile::simulate


i added these lines after the RayInfo

Material* material = (rInfo.material ? dynamic_cast< Material* >(rInfo.material->getMaterial()) : 0);

 

then changed the explode to have the material

 

// Next order of business: do we explode on this hit?
     if ( mCurrTick > mDataBlock->armingDelay || mDataBlock->armingDelay == 0 )
     {
        mCurrVelocity    = Point3F::Zero;
        explode( rInfo.point, rInfo.normal, objectType, material);
     }

 

then in the material definition i added

 

customDecal = "ScorchBigDecal"; 

 

but it only uses the default decal set by the projectile. Need a fresh set of eyes to look on this and tell me where i am being so stupid lol

Link to comment
Share on other sites

ill be honest i prefer using explosions than just editing the decal lol good thinking. Would those changes work with stock 3.10 ?


i was thinking the reason mine wouldn't work was because i wasn't adding a decal id in materialDefinition which i think would be why this

if (contactMaterial && contactMaterial->mDecal)
    {
       gDecalManager->addDecal(p, n, 0.0f, contactMaterial->mDecal);
    }

 

was always returning false.


Im gonna revert these files back to stock and use ur resource with explosions instead

Link to comment
Share on other sites

Yes, as mentioned http://forums.torque3d.org/viewtopic.php?f=40&t=964 the eventual intent is to squeeze out a wholistic, straightforward, generic approach to interaction effects.



EDIT: special note, for material detection using raycasts, do have to flip that on: https://github.com/Azaezel/Torque3D/commit/49ef12e452a30389f3dc3ce692bd0e2dbf26241d#diff-2b3d6c759a85a94f0264e8c70c70ebdcR1144

Link to comment
Share on other sites

thats definitely a better idea lol i was going to attempt rolling everything into the material definition separately, using an explosion is definitely the better way to go good job. Do u know of any way to get decals to stick to a moving object?


I was thinking of trying to add a type to the decal class

Static or attached


static works the way the default one does, attached will move with an object.


Finding the objects position on one tick then on the next tick finding out the difference in its xyz on its next tick and applying the difference to the decals xyz.


Do u think something like that would work?


reason for the two different types is because i think such a thing would be quite expensive maybe so wouldnt want too many of those flying around

Link to comment
Share on other sites

browsing over az's code it shouldnt be too hard to implement a decal, it has all the required info, position and normal from the raycast, just needs a section for decal data like the projectile does, i want to be able to make decals stick to a moving object would definitely make things a bit better for my game. Have a character coming running over with burn marks on his head from plasma blast as he called his enemy players mother a spawn of satan!!!!!....... no seriously i wanna see the damage i do to people :)

Link to comment
Share on other sites

fars the sticking to players bit off the top of my head, would try doin it in 3 phases:


1-

a) hack into the decal manager and tie individual decals to objectIDs

b) toss a check into the lifetime code round about https://github.com/GarageGames/Torque3D/blob/55b7a8431cf68fb3b88e7c4b19a2513ec447bb81/Engine/source/T3D/decal/decalManager.cpp#L1090-L1098 and kill em if they don't exist


2- track relative position motion for tracked objects and offset decals to suit.


3- figure out how to offset decals for animated meshes so if a player moves it's arm where you shot it, it updates to suit. (maybe the equivalent of mounting a decal to a parent bone with a calculated offset, say?)




I will say for ourselves, we've been cooking with

/
(damage lerp that'll be brought along into the engine with the PBR code, since that's a value already ghosted as-is over the network, which means no additional hit there.) Not exactly the same, admitedly, but hey, if the intent is just to get the point across...
Link to comment
Share on other sites

i will say the damage map looks cool, but if i shoot a person with my shotgun i want to see the big red wounds where i hit them lol ill try what u suggested with the offset due to particular position, as for the animation, do u know of a way to find the nearest node to a raycast?


i was thinking of screenspace decal rendering


something like whats discussed here

Link to comment
Share on other sites

SSDR is a more GPU driven version of what we've got now (currently the cpu essentially breaks decals up into sub-strips and wraps em that way). While I'm aware of at least one person casually looking into that end in their free time, swapping underlying methodologies wouldn't have an effect one way or the other on sticking to a specific face while it moves around.

Link to comment
Share on other sites

  • 4 weeks later...
yea u still need to have an offset based on the object its attached to but i was just thinking that ssdr may have less of a hit on performance when there are a lot of particles maybe

 

Senior moment meant decals here instead of particles.


In your fx github are u going to be adding the ability to have tire smoke and tire decals defined in the material?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...