Material Based Effects - Detection - Legacy Terrain

From TDN

To add to the list of getting materials from different object types, here's somehing for the legacy terrain (at least 1.01). I haven't embedded it in the castRay method since I've put my stuff in a utils class together with some other friction utils... I'll see if I get around to do it.

What we need to do is really to fix the broken terrData.cpp so it works as in TGE 1.5x.

In onAdd() find

   StringTableEntry fn = mMaterialFileName[0];
   if(!dStrncmp(fn, "terrain.", 8))
      fn += 8;

   char nameBuff[512];
   dStrcpy(nameBuff, mTerrFileName);
   char *p = dStrrchr(nameBuff, '/');
   if (p) p++;
   else p = nameBuff;
   dStrcat(p,fn);


and change it to

   MaterialPropertyMap* pMatMap = static_cast<MaterialPropertyMap*>(Sim::findObject("MaterialPropertyMap"));
   for (int i = 0; i < TerrainBlock::MaterialGroups; i++)
   {
      StringTableEntry fn = mMaterialFileName[i];
      if (fn != NULL)
      {
         if(!dStrncmp(fn, "terrain.", 8))
            fn += 8;
   
		char nameBuff[512];
		dStrcpy(nameBuff, fn);
		char *p = dStrrchr(nameBuff, '/');
		if (p) p++;
		else p = nameBuff;
		   mMPMIndex[i] = pMatMap->getIndexFromName(p);
      }
      else 
         mMPMIndex[i] = -1;
   }

You need to include "materials/materialPropertyMap.h" as well. Next we add the method getTerrainMapIndex (also from TGE)

S32 TerrainBlock::getTerrainMapIndex(Point3F& pt)
{	
	U8 alphas[MaterialGroups];	
	int mapIndex= -1;
	const MatrixF & mat = getTransform();	
	Point3F origin;	
	mat.getColumn(3, &origin);	
	F32 squareSize = (F32) getSquareSize();	
	F32 halfSquareSize = squareSize / 2;	
	float x = (pt.x - origin.x + halfSquareSize) / squareSize;	
	float y = (pt.y - origin.y + halfSquareSize) / squareSize;	
	getMaterialAlpha(Point2I(x,y), alphas);	
	MaterialPropertyMap* matMap = static_cast<MaterialPropertyMap*>(Sim::findObject("MaterialPropertyMap"));	
	if (matMap != NULL)	
	{         		
		U8 maxAlpha = alphas[0];         		
		U8 maxAlpha2;         		
		int indexTexture = 0;                  		
		for (int i=1; i<MaterialGroups; i++)		
		{			
			maxAlpha2 = getMax(alphas[i],maxAlpha);			
			if (maxAlpha2 != maxAlpha)			
			{				
				indexTexture = i;				
				maxAlpha = maxAlpha2;			
			} 		
		} 		
		mapIndex = mMPMIndex[indexTexture];	
	} 	
	return mapIndex;
}


And that's all there's to it. This is how I use it:

if (ray.object->getTypeMask() & TerrainObjectType)
{
     TerrainBlock* tBlock = static_cast<TerrainBlock*>(ray.object);
     mapIndex = tBlock->getTerrainMapIndex(ray.point);
}


I'm also implementing a system for modifying friction, top speed, etc for my racing game depending on the material the wheels touches. The current implementation is just a grid of material vs material modifiers. Easy to implement, but a pain to maintain when you add new materials and properties. So I'm thinking of alternative system which would be more modifier based. I.e. you specify properties for the materials in terms of roughness, hardness, and so on, and calculate how the materials would react against each other; slick rubber vs tarmac = good friction, rough rubber vs tarmac = not as good, etc. I don't know how racing games normally do this... Any thoghts anyone?

Thanks, Kristoffer

Backtrace: Material Based Effects Projects