Game Development Community

T3D 1.2 FootStepSounds Issue has occurred again - LOGGED (THREED-3144)

by John "Mythic" Henry · in Torque 3D Professional · 12/28/2011 (1:40 pm) · 14 replies

I was setting up some of my custom sounds and noticed the Terrain Sounds were not occurring correctly.
I tested this further and ran in Debug mode onyl to find it is returning ONLY the first terrain material
in the list of used materials. I verified this by testing in the clean 1.2 Fps Example without changes
except the following:
Basic Room / Remove Ground Plane / Add New Flat Terrain using existing Terrain materials with sounds mapped
correctly / Set down 4 Areas (Paint em) / then do some treading.. (After Adding the Triggers to soldier.dae)

Here is the sound setup:

//Default Sounds
singleton Material( TerrainSoft )
{
   FootstepSoundId = 0;       // Soft footstep sound defined on player datablock.
   //ImpactSoundId = 0;         // Soft impact sound.
   ShowDust = false;          // No dust particles (footpuffs, hover trails, etc.)
   ShowFootprints = true;     // Show footprints.
};
singleton Material( TerrainHard )
{
   FootstepSoundId = 1;       // Hard footstep sound defined on player datablock.
   //ImpactSoundId = 1;         // Hard impact sound.
   ShowDust = true;           // Show dust particles.
   ShowFootprints = true;     // Show footprints.
};
singleton Material( Ter_desert_sand_03 : TerrainSoft)
{
   mapTo = "desert_sand_03_base";
   diffuseMap[0] = "art/terrains/desert_sand_03/desert_sand_03_base";
   //customFootstepSound = FootSandStepSound;
   materialTag0 = "RoadAndPath";
};
new TerrainMaterial()
{
   internalName = "desert_sand_03";
   diffuseMap = "art/terrains/desert_sand_03/desert_sand_03_base";
   detailMap = "art/terrains/desert_sand_03/desert_sand_03_detail";
   detailSize = "10";
   isManaged = "1";
   detailBrightness = "1";
   Enabled = "1";
   diffuseSize = "250";
   normalMap = "art/terrains/desert_sand_03/desert_sand_03_nrm";
   detailDistance = "350";
};
singleton Material( Ter_rocktest : TerrainHard)
{
   mapTo = "rocktest";
   diffuseMap[0] = "art/terrains/Test/rocktest";
   //customFootstepSound = FootSandStepSound;
   materialTag0 = "RoadAndPath";
};
new TerrainMaterial()
{
   internalName = "rocktest";
   diffuseMap = "art/terrains/Test/rocktest";
   detailMap = "art/terrains/Test/rocktest_d";
   detailSize = "10";
   detailDistance = "100";
   isManaged = "1";
   detailBrightness = "1";
   Enabled = "1";
   diffuseSize = "400";
};
....
(trimmed to get it all posted)
....

This simple test allows you to place the Single Hard Terrain sound at the top of list
Then swap it with any of the Soft Terrains.. Requires a Restart of the Game to take effect
and it will only use the First Material Sound..

Easy way to hear the change without using the true subtle sounds
datablock SFXProfile(FootLightSoftSound)
{
   //filename    = "art/sound/lgtstep_mono_01";
   filename    = "art/sound/orc_pain";
   description = AudioClosest3d;
   preload = true;
};
datablock SFXProfile(FootLightHardSound)
{
   //filename    = "art/sound/hvystep_ mono_01";
   filename    = "art/sound/testing";
   description = AudioClose3d;
   preload = true;
};
It looks like this bug occurred at 1.1 and continued into 1.2
I will be looking at the changes between them shortly

#1
12/28/2011 (1:46 pm)
Better explanation:

In player.cpp
else if( contactMaterial && contactMaterial->mFootstepSoundCustom )
   {
      // Footstep sound defined on material.

      SFX->playOnce( contactMaterial->mFootstepSoundCustom, &footMat );
   }
   else
   {
      // Play default sound.

      S32 sound = -1;
      if( contactMaterial && contactMaterial->mFootstepSoundId != -1 )
         sound = contactMaterial->mFootstepSoundId;
      else if( contactObject && contactObject->getTypeMask() & VehicleObjectType )
         sound = 2;

Both Checks using either the builtin mFootstepSoundId or mFootstepSoundCustom,
raycast always returns the First Terrain material only.
Easiest to set the Hitcount on the Break point giving you time to cross over
into another material..
#2
12/28/2011 (2:04 pm)
There was a post somewhere detailing torques order of things, like initialising audio before some things breaks the audio and so on, I'll see if I can find the post, I think it was Steve who posted it.
#3
12/28/2011 (2:52 pm)
Nope, not it.. Failure to load correctly results in no sounds..

This case: Getting sounds, mapping is occurring, RayCast result that finds
material ONLY returns First terrain material in list as it is displayed in
the Terrain Painter Editor. And if you look at my basic file (material.cs)
for the terrain materials, the sounds are correctly ordered Before the terrain
materials :)
#4
12/28/2011 (3:25 pm)
Just for good measure I just ran the exact same test in 1.1 final Fps Example
Same result, and also setup custom Sounds with the exact same result,
Only the first terrain material is ever being returned in the ray cast for
material collision.
#5
12/28/2011 (3:29 pm)
In earlier tests with 1.2, I did notice it changing over a Large Distance, where it
would sometimes return a different Material, the wrong one.
This occurred on a Terrain I had reset the Squaresize after working on it.
I had thought that might be the cause. I don't think so at this point now.
I've got to dig out the original B3 version and test there next.
#6
12/28/2011 (4:59 pm)
Okay, so either I've missed something really simple (I am not afraid to say that *grin)
or this has been a long standing issue that nobody has noticed since sometime before 1.1B3
I just ran the exact same test with a clean download/install/FpsExample and a new project... (1.1B3)
With exactly the same result using both the base footstepid's and custom ones.
Here is the last test I created for 1.1B3 using the premade empty terrain painting 3 splats...
art/terrains/material.cs
singleton Material( TerrainSoft )
{
   FootstepSoundId = 0;
   ShowDust = false;
   ShowFootprints = true;
};
singleton Material( TerrainHard )
{
   FootstepSoundId = 1;
   ShowDust = true;
   ShowFootprints = true;
};
singleton Material( TerrainSnow )
{
   FootstepSoundId = 3;
   ShowDust = false;
   ShowFootprints = true;
};
singleton SFXProfile(FootGrassStepSound)
{
   filename    = "art/sound/testing";
   description = AudioClose3d;
   preload = true;
};
singleton SFXProfile(FootDirtStepSound)
{
   filename    = "art/sound/orc_pain";
   description = AudioClose3d;
   preload = true;
};
singleton SFXProfile(FootDirtHardStepSound)
{
   filename    = "art/sound/orc_pain";
   description = AudioClose3d;
   preload = true;
};
singleton SFXProfile(FootSandStepSound)
{
   filename    = "art/sound/orc_pain";
   description = AudioClose3d;
   preload = true;
};
singleton Material( Ter_Sand01 )
{
   mapTo = "sand";
   diffuseMap[0] = "art/terrains/Example/sand";
   FootstepSoundId = 1;
   //customFootstepSound = FootSandStepSound;
   ShowDust = true;
   ShowFootprints = true;
   materialTag0 = "RoadAndPath";
};
singleton Material( Ter_Grass01 )
{
   mapTo = "grass1";
   diffuseMap[0] = "art/terrains/Example/grass1";
   FootstepSoundId = 0;
   //customFootstepSound = FootGrassStepSound;
   ShowDust = false;
   ShowFootprints = true;
   materialTag0 = "RoadAndPath";
};
singleton Material( Ter_Grass02 )
{
   mapTo = "grass1-dry";
   diffuseMap[0] = "art/terrains/Example/grass1-dry";
   FootstepSoundId = 1;
   //customFootstepSound = FootGrassStepSound;
   ShowDust = false;
   ShowFootprints = true;
   materialTag0 = "RoadAndPath";
};
singleton Material( Ter_Dirt01 )
{
   mapTo = "dirt_grass";
   diffuseMap[0] = "art/terrains/Example/dirt_grass";
   FootstepSoundId = 1;
   //customFootstepSound = "FootDirtStepSound";
   ShowDust = true;
   ShowFootprints = true;
   materialTag0 = "RoadAndPath";
};
singleton Material( Ter_Rock01 )
{
   mapTo = "rocktest";
   diffuseMap[0] = "art/terrains/Example/rocktest";
   FootstepSoundId = 1;
   //customFootstepSound = FootDirtHardStepSound;
   ShowDust = false;
   ShowFootprints = true;
   materialTag0 = "RoadAndPath";
};
new TerrainMaterial()
{
   internalName = "grass1";
   diffuseMap = "art/terrains/Example/grass1";
   detailMap = "art/terrains/Example/grass1_d";
};
new TerrainMaterial()
{
   internalName = "rocktest";
   diffuseMap = "art/terrains/Example/rocktest";
   detailMap = "art/terrains/Example/rocktest_d";
};
new TerrainMaterial()
{
   internalName = "grass1-dry";
   diffuseMap = "art/terrains/Example/grass1-dry";
   detailMap = "art/terrains/Example/grass1-dry_d";
};
new TerrainMaterial()
{
   internalName = "dirt_grass";
   diffuseMap = "art/terrains/Example/dirt_grass";
   detailMap = "art/terrains/Example/dirt_grass_d";
};
new TerrainMaterial()
{
   internalName = "sand";
   diffuseMap = "art/terrains/Example/sand";
   detailMap = "art/terrains/Example/sand_d";
};
art/datablocks/player.cs
datablock SFXProfile(FootLightSoftSound)
{
   filename    = "art/sound/testing";
   description = AudioClosest3d;
   preload = true;
};
datablock SFXProfile(FootLightHardSound)
{
   fileName = "art/sound/orc_pain";
   description = AudioClose3d;
   preload = true;
};
same exact results...

First terrain material is the only material sound file that activates
Switch the first material with a diffent one or delete and recreate
results in the same thing.
#7
12/28/2011 (5:05 pm)
oh, just so ya know, I painted blocks (square, size 10) pressure 100, smooth 100
Over a good 2-3 squares in a line for each terrain material in all these tests.
It seems to only see the Base Terrain Material that covers everything initially.
#8
12/28/2011 (6:33 pm)
A workaround for the moment...
It turns out this has been seen before:
www.garagegames.com/community/forums/viewthread/109311

My initial workaround:
player.cpp
//Add at top of file
//Mythic DEBUG Begin
#include "terrain/terrCollision.h"  
#include "terrain/terrData.h"
//Mythic DEBUG End
...
...
void Player::updateActionThread()
{
...
...
         if( gClientContainer.castRay( Point3F( pos.x, pos.y, pos.z + 0.01f ),
               Point3F( pos.x, pos.y, pos.z - 2.0f ),
               STATIC_COLLISION_TYPEMASK | VehicleObjectType, &rInfo ) )
         {
                        //Mythic DEBUG Begin
                        //Temp workaround for only getting Terrain Layer 0 on cast ray
			Material* material = NULL;
			TerrainBlock* TB = (rInfo.object ? dynamic_cast< TerrainBlock* > ( rInfo.object ) : NULL);
			if( TB )
			{
				Point2I gridPos = TB->getGridPos( rInfo.point );  
				U32 layer = TB->getFile()->getLayerIndex( gridPos.x, gridPos.y );
				//TerrainMaterial* materialA = TB->getMaterial(layer);
				String TestName = "Ter_";
				TestName += TB->getMaterialName(layer);
				material = (TestName.length() > 4) ? dynamic_cast<Material*>( Sim::findObject(TestName.c_str()) ) : NULL;
			}
			if( material == NULL )
				material = ( rInfo.material ? dynamic_cast< Material* >( rInfo.material->getMaterial() ) : 0 );
                        //Mythic DEBUG End

            // Put footprints on surface, if appropriate for material.

This is just that, a workaround. This needs to be dug further into the actual
Castray function and get the correct material there..

Many ways to deal with this, you could use the getinternalname() as well
I've gone with a Set Naming convention for terrain materials for ease at the moment.

*edit*
Just thought, if its Layer ( 0 ), can skip the rest and use the normal material
returned, reducing calls and such..
#9
01/11/2012 (10:19 am)
Thanks for the bug report John. I've logged this issue under ticket number THREED-3144 for review.
#10
01/20/2012 (4:32 pm)
I hope you guys can get this fixed, having a player that does not make any sound when moving is not very immersive.
#11
01/31/2012 (10:12 am)
The terrain castRay method was not looking up the material correctly.

On engine/source/terrain/terrCollision.cpp add the following to line 602:

getTransform().mulP( info->point );    // transform to world coordinates for getGridPos
#12
01/31/2012 (6:09 pm)
Just make tons of Ninja games - then your player is supposed to be silent!
#13
03/27/2013 (9:14 am)
Still doesn't work; even with getTransform().mulP( info->point ); added to terrCollision.cpp

Problem with the workaround is that one need to change the material names; for existing terrains that's a bit tricky; or is there a solution for this?

Replacing the S32 sound = -1; with S32 sound = 0; in player.cpp will at least give some sound (PlayerData::FootSoft). But having the same sound for different types of terrain...
#14
03/08/2014 (5:51 am)
Any fix for this yet? I need to cast a ray to the terrain to apply this fix http://www.garagegames.com/community/forums/viewthread/121221