Game Development Community

getting Terrain Material Name

by Vincent BILLET · in Torque 3D Professional · 01/15/2010 (8:18 am) · 10 replies

I would like, in my game, to avoid player create buildings onto some terrain materials (e.g player can't build on road material). But I can't find how to get material/Texture Name.

AnyOne have an idea?

#1
01/15/2010 (1:32 pm)
Notice in Player::updateActionThread() how the ray cast hits the terrain and pulls some material information.
Then you can use material->getName() ...
#2
01/15/2010 (4:10 pm)
Thanks for your answer, It's a good idea, unfortunately, When I cast a ray on a terrain, it seems that material is always "WarnMaterial"...

So It doesn't work.

in sceneObject.cpp (ConsoleFunction( containerRayCast, const char*, 4, 5, "( Point3F start, Point3F end, bitset mask, SceneObject exempt=NULL )" )

I update the code as follow :
// add the hit position and normal?
   if(ret)
   {
	  Material* material = ( rinfo.material ? dynamic_cast< Material* >( rinfo.material->getMaterial() ) : 0 );
	  if (material==0)
	  {
		dSprintf(returnBuffer, 256, "%d %g %g %g %g %g %g",
               ret, rinfo.point.x, rinfo.point.y, rinfo.point.z,
               rinfo.normal.x, rinfo.normal.y, rinfo.normal.z);
	  } else
	  {
		dSprintf(returnBuffer, 256, "%d %g %g %g %g %g %g %s",
               ret, rinfo.point.x, rinfo.point.y, rinfo.point.z,
			   rinfo.normal.x, rinfo.normal.y, rinfo.normal.z, material->getName());
	  }
   }

Always WarnMaterial... So I thought your solution was the one... But it doesn't work
#3
01/15/2010 (4:32 pm)
Hmmm..
May be you should cast to TerrainMaterial ..
try also getInternalName()
#4
01/15/2010 (9:32 pm)
Tried TerrainMaterial, it seems cast doesn't work at all (null object)...

Tried getInternalName() it always writes "(null)".

I expected somebody had a solution...
#5
01/15/2010 (10:55 pm)
Don't know if this is useful but ...
Wasn't there a real old TGE/A resource for only allowing the player to move over certain terrain materials? That would neccessitate returning the terrain texture. Perhaps search resource.

Also I remember Konrad Kiss posting a resource which created one type of terrain material as impassible during the T3D betas.
#6
01/16/2010 (6:14 am)
Finally, after a good night of search, I found a solution, It doesn't give the material's name but the layer number.

To get it work, you have to update SceneObject.cpp

First, Add these includes :
#include "terrain/terrCollision.h"
#include "terrain/terrData.h"

Second, Add this console function :
ConsoleFunction( getTerrainLayer, const char*, 3, 3, "( Point3F start, Point3F end )"
                "Cast a ray from start to end, checking for collision against Terrain.nn"
                "@returns A string containing either null, if nothing was struck, or these fields:n"
                "            - The ID of the object that was struck.n"
                "            - The x, y, z position that it was struck.n"
                "            - The x, y, z of the normal of the face that was struck."
		"            - The Material Layer number (0 for the first terrain's material).")
{
   char *returnBuffer = Con::getReturnBuffer(256);
   Point3F start, end;
   dSscanf(argv[1], "%g %g %g", &start.x, &start.y, &start.z);
   dSscanf(argv[2], "%g %g %g", &end.x,   &end.y,   &end.z);
   U32 mask = TerrainObjectType;

   RayInfo rinfo;
   S32 ret = 0;
   if (gServerContainer.castRay(start, end, mask, &rinfo) == true)
      ret = rinfo.object->getId();

   // add the hit position and normal?
   if(ret)
   {
	   TerrainBlock* TB = dynamic_cast< TerrainBlock* > ( rinfo.object );
	   Point2I gridPos = TB->getGridPos( rinfo.point );
	   U8 layer = TB->getFile()->getLayerIndex( gridPos.x, gridPos.y );
       dSprintf(returnBuffer, 256, "%d %g %g %g %g %g %g %d",
               ret, rinfo.point.x, rinfo.point.y, rinfo.point.z,
			   rinfo.normal.x, rinfo.normal.y, rinfo.normal.z, layer);
   }
   else
   {
      returnBuffer[0] = '0';
      returnBuffer[1] = '';
   }

   return(returnBuffer);
}

Finally you can use it in any script like this one :
function PlayGui::onMouseDown(%this, %pos, %start, %ray)
{
   // find end of search vector
   %ray = VectorScale(%ray, 2000);
   %end = VectorAdd(%start, %ray);
   
   // search!
   %scanTarg = getTerrainLayer( %start, %end );
   
   // If the terrain object was found in the scan
   if( %scanTarg )
   {
           // Check the Terrain Layer (0=Sand, 1=Grass, 2= Rock,...)
	   if (getWord(%scanTarg,7)==1)
	   {
                   //launch a build function at specified position
		   Build(getWords(%scanTarg,1,3));
	   }
   }
}

Ah ! Torque And Terrains.... Lot, Lot, Lot of time spent !
#7
01/16/2010 (12:34 pm)
Quote:
Ah ! Torque And Terrains.... Lot, Lot, Lot of time spent !
But good for you getting a solution to your problem!
#8
01/16/2010 (2:20 pm)
@Steve :
Unfortunately, since 2005, I almost spend 4 entire months on terrain problems with Torque... This stuff has, along time, too much changes.
#9
01/27/2010 (12:15 pm)
@Vincent...all of the technicals aside...your players are able to build in the world? How did you accomplish that?
What kind of building exactly? I was really hoping to have this ability in my game but assumed it wasn't an option.
#10
01/27/2010 (4:40 pm)
@Scot :
all of the technicals aside,
your players are able to build in the world? Yes
How did you accomplish that ? Click Build button, click Terrain (and check material), and launch building animation... (Hope it answers)
What kind of building exactly? Depending on project.
...But assumed it wasn't an option => everything is possible with Torque. But sometimes, it's more difficult than some other time.