Game Development Community

dev|Pro Game Development Curriculum

Torque 3D - Render Mission Area bounds

by Andy Rollins · 01/27/2011 (7:17 am) · 9 comments

In Torque3D 1.1 Beta 3 the Mission Area code doesn't include any rendering for the bounds to see where you've placed it, this little resource adds some rendering and allows you to toggle it on and off in the world editor using the usual visibility options.

At the top of editTSCtrl.h around Ln 17
class TerrainBlock;
class MissionArea; // added for MissionArea Rendering
class Gizmo;

Further down around Ln 177
virtual TerrainBlock* getActiveTerrain();
      
      virtual MissionArea* getMissionArea(); // added for MissionArea Rendering

      virtual void calcOrthoCamOffset(F32 mousex, F32 mousey, U8 modifier=0);


Add the following function to editTSCtrl.cpp

MissionArea* EditTSCtrl::getMissionArea()
{
   // Find the mission Area
   SimSet* scopeAlwaysSet = Sim::getGhostAlwaysSet();
   for(SimSet::iterator itr = scopeAlwaysSet->begin(); itr != scopeAlwaysSet->end(); itr++)
   {
      MissionArea* misArea = dynamic_cast<MissionArea*>(*itr);
      if( misArea )
         return misArea;
   }

   return NULL;
}

In editTSCtrl.ccp replace the renderMissionArea() function that is mostly commented out with this version
void EditTSCtrl::renderMissionArea()
{
   MissionArea *obj = getMissionArea();

   if( obj == NULL )
      return;

   F32 minHeight = 0.f;
   F32 maxHeight = 0.f;

   TerrainBlock* activeTerrain = getActiveTerrain();
   if( activeTerrain != NULL )
   {
      activeTerrain->getMinMaxHeight(&minHeight, &maxHeight);
      Point3F pos = activeTerrain->getPosition();
      
      maxHeight += pos.z + 5.0f;
      minHeight += pos.z - 5.0f;
   }

   const RectI &area = obj->getArea();
   Box3F areaBox( area.point.x, 
                  area.point.y, 
                  minHeight, 
                  area.point.x + area.extent.x,
                  area.point.y + area.extent.y,
                  maxHeight );

   GFXDrawUtil *drawer = GFX->getDrawUtil();

   GFXStateBlockDesc desc;
   desc.setZReadWrite( true, false );
   desc.setBlend( true );

   desc.setFillModeSolid();
   drawer->drawCube( desc, areaBox, mMissionAreaFillColor);

   desc.setFillModeWireframe();
   drawer->drawCube( desc, areaBox, mMissionAreaFrameColor );
}


Alter toolsworldEditormain.cs and in the initializeWorldEditor() function add the following line, around Ln 98

EVisibility.addOption( "Render Sound Emitters", "$SFXEmitter::renderEmitters", "" );
EVisibility.addOption( "Render Mission Area", "EworldEditor.renderMissionArea", "" ); // added MissionArea Rendering 
EVisibility.addOption( "Wireframe Mode", "$gfx::wireframe", "" );

There are various Gui that have RenderMission area on by default, we don't want it to render in any of them so change:

renderMissionArea = "1";
to:
renderMissionArea = "0";

In the following places:

tools/convexEditor/convexEditorGui.gui      - Line (25)
tools/decalEditor/decalEditorGui.gui        - Line (25)
tools/forestEditor/forestEditorGui.gui      - Line (3)
tools/meshRoadEditor/meshRoadEditorGui.gui  - Line (25)
tools/riverEditor/RiverEditorGui.gui        - Line (25)
tools/roadEditor/RoadEditorGui.gui          - Line (26)
tools/worldEditor/guiEditorGui.ed.gui       - Line (512)

That's it folks, enjoy!

img268.imageshack.us/img268/299/misfull.jpg

#1
01/27/2011 (7:36 am)
This is really usefull, ty Andy!
#2
01/27/2011 (2:13 pm)
cheers Andy, very useful. It took me a while to test it with a player without bounds (being lazy!) so this will save people some time. Should be in stock :)
#3
01/27/2011 (7:57 pm)
Sweet, thanks!
#4
01/27/2011 (8:36 pm)
Now if they could make placement of the MissionArea object more intuitive and pick a name for it. Level Bounds is displayed in the Library but "MissionArea" is what it says when you mouse over it.
#5
01/28/2011 (4:48 am)
To add the editor back into the game (it's found on the Edit menu) then you can just use this:

In missionAreaEditor.cpp replace createTerrainBitmap() function (that's mostly commented out) with the following:
GBitmap * MissionAreaEditor::createTerrainBitmap()
{
   GBitmap * bitmap = new GBitmap(mTerrainBlock->getBlockSize(), mTerrainBlock->getBlockSize(), false, GFXFormatR8G8B8 );

   if(!bitmap)
      return(0);

   U8 * pBits = bitmap->getAddress(0,0);

   // get the min/max
   F32 min, max;
   mTerrainBlock->getMinMaxHeight(&min, &max);

   Point3F pos = mTerrainBlock->getPosition();
   max += pos.z;
   min += pos.z;   

   F32 diff = max - min;

   // This method allocates it's bitmap above, and does all assignment
   // in the following loop. It is not subject to 24-bit -> 32-bit conversion
   // problems, because the texture handle creation is where the conversion would
   // occur, if it occurs. Since the data in the texture is never read back, and
   // the bitmap is deleted after texture-upload, this is not a problem.
   for(U32 y = 0; y < mTerrainBlock->getBlockSize(); y++)
      for(U32 x = 0; x < mTerrainBlock->getBlockSize(); x++)
      {
         F32 height;
         mTerrainBlock->getHeight(Point2F(x, y),&height);
 
         U8 col = U8((height - min) / diff * 255.f);
         *pBits++ = col;
         *pBits++ = col;
         *pBits++ = col;
      }

   return(bitmap);
}

Then in tools/worldEditor/scripts/menu.ed.cs at around Ln 158 change:
//item[9] = "Mission Area Editor" TAB "" TAB "Canvas.pushDialog(MissionAreaEditorContainer);";
to:
item[17] = "Mission Area Editor" TAB "" TAB "Canvas.pushDialog(MissionAreaEditorContainer);";

Optionally if you really want to change the name of the item from Level Bounds back to mission Area then just change it in tools/worldEditor/scripts/editors/creator.ed.cs and look for:

%this.registerMissionObject( "MissionArea",  "Level Bounds" );

change to:

%this.registerMissionObject( "MissionArea",  "Mission Area" );

It's not perfect for some reason it renders patches of black in some areas which is why that's not part of the original resource but I've not the time to investigate that further.

#6
01/28/2011 (6:34 am)
much thanks :)
#7
01/30/2011 (6:58 pm)
This is a big help, I saw the functions in the player.cs file for when the player goes out of the borders ... now I can actually "see" where these borders are!

I was looking for a way to set the boundaries on where the player could walk with the terrain ... and load the next level when they left that boundary.

Assuming that works, I won't have to use the old trigger hack.
#8
02/01/2011 (1:39 pm)
Sweet, thanks!
#9
02/25/2011 (11:30 pm)
NOTE: to get it to trigger your onEnter/Leave Mission Area() scripts for players, we need to rename the MissionArea to GlobalMissionArea ... seems to be some hard coded carry over from TGE days.