Game Development Community

dev|Pro Game Development Curriculum

WorldEditor move on XY plane with terrain

by Nathan Bowhay - ESAL · 11/13/2006 (4:43 pm) · 2 comments

First we must open the correct files:
Open WorldEditor.h and WorldEditor.cc

Then we need to put in a function to find the terrain height (There may already be a function that does this in terrData.cc, but I am not sure).

In WorldEditor.h go to the spot just above the comment
// EditTSCtrl
and place
//Get the Terrain Height
	  static F32 getTerrainHeight(Point2F position);
After that find "static void updateClientTransforms(Selection &)"
and bellow it place:
static void XYupdateClientTransforms(Selection &);

Then, in WorldEditor.cc search for the function "WorldEditor::updateClientTransforms" and place this function before it:
//------------------------------------------------------------------------------
// Get Terrain Height given an x, y position (return a float or F32 that is the z)
//------------------------------------------------------------------------------

F32 WorldEditor::getTerrainHeight(Point2F position)
{
   F32 height = 0.0;
   TerrainBlock* terrain = NULL;
   
   for (SimSetIterator obj(Sim::getRootGroup()); *obj; ++obj) {
	   if ((*obj)->getType() & TerrainObjectType) {
		   terrain = static_cast<TerrainBlock*>(*obj);
		   // This is assuming there is only one TerrainBlock.
		   break;
	   }
   }

   if(terrain)
   {
	  if(terrain->isServerObject())
	  {
		 Point3F offset;
		 terrain->getTransform().getColumn(3, &offset);

		 position -= Point2F(offset.x, offset.y);
		 terrain->getHeight(position, &height);
	  }
   }

   return height;
}

Then find the function "WorldEditor::updateClientTransforms" right before that function put this:
void WorldEditor::XYupdateClientTransforms(Selection & sel)
{
   for(U32 i = 0; i < sel.size(); i++)
   {
      SceneObject * clientObj = getClientObj(sel[i]);
      if(!clientObj)
         continue;

      // If it's an interior we're going to need to relight the scene
      // since we've moved it, so notify script of this. Don't bother
      // ourselves with dynamic lit interiors, of course.
      InteriorInstance  *ii = dynamic_cast<InteriorInstance*>(clientObj);
      if(ii != NULL && ii->mUseGLLighting == false)
      {
         // Set it to be dynamically lit as well.
         ii->mDoSimpleDynamicRender = true;
         Con::executef( 1, "onNeedRelight" );
      }

	  //nbowhay - Change to terrain z - 10/27/06
	  Point2F passed(sel[i]->getPosition().x,sel[i]->getPosition().y);
	  F32 z = getTerrainHeight(passed);
	  Point3F newPos(sel[i]->getPosition().x,sel[i]->getPosition().y,z);
	  sel[i]->setPosition(newPos);

      clientObj->setTransform(sel[i]->getTransform());
      clientObj->setScale(sel[i]->getScale());
   }
}

Then find the comment "// move on XY plane" and find, below that, the first call of "updateClientTransforms" and change it to "XYupdateClientTransforms".

Re-compile and it will work.

#1
11/13/2006 (10:18 pm)
Very Nice Work. Great Resource.
#2
11/14/2006 (8:06 am)
Nice