Game Development Community

dev|Pro Game Development Curriculum

Mission Area Bounds

by Robert Blanchet Jr. · 06/12/2002 (9:57 am) · 32 comments

For some games you may wish to display visually to the player where the mission area begins and ends.

home.attbi.com/~xgalaxy/missionarea.jpg
This code snippet will show you how to do exactly that.

EDIT: As of June 15th I've made some major changes to the code necessary for this code to display properly when hosting both dedicated and non-dedicated servers. The code below reflects those changes.

Open up game.h and add the following:
void GameRenderMissionArea(F32 alpha, bool *sides);

Once that is done open up game.cc.
Add the following after all the includes:
#include "game/missionArea.h"

Now scroll down and find the function GameRenderWorld(). After the following lines:
dglSetCanonicalState();
gClientSceneGraph->renderScene();

Add this:
GameConnection* conn = GameConnection::getServerConnection();
MatrixF cam;
Point3F camPos;
conn->getControlCameraTransform(0,&cam);
cam.getColumn(3, &camPos);

const RectI &area = MissionArea::smMissionArea;
Point2F min(area.point.x, area.point.y);
Point2F max(area.point.x + area.extent.x, area.point.y + area.extent.y);

float distances[4];
distances[0] = camPos.x - min.x;
distances[1] = camPos.y - min.y;
distances[2] = max.x - camPos.x;
distances[3] = max.y - camPos.y;

bool renderSide[4] = {false, false, false, false};
float alpha = 0.0f;
float dist = 400.0f;
bool flag = false;
for(int side = 0; side < 4; side++)
{
   if(distances[side] < 0)
   {
      renderSide[0] = true;
      renderSide[1] = true;
      renderSide[2] = true;
      renderSide[3] = true;
      flag = true;
   }
   else if(distances[side] < 400)
   {
      renderSide[side] = true;
      if(distances[side] < dist)
      {
         dist = distances[side] < dist ? distances[side] : dist;
         alpha = 20/dist > 1.0 ? 1.0 : 20/dist;
      }
   }
   if(flag)
      alpha = 1.0f;
   GameRenderMissionArea(alpha, renderSide);

// rest of function

Ok now after that function add this function:
void GameRenderMissionArea(F32 alpha, bool *sides)
{
   TerrainBlock *terrain = gClientSceneGraph->getCurrentTerrain();  

   if(!terrain)
      return;

   GridSquare *gs = terrain->findSquare(TerrainBlock::BlockShift, Point2I(0,0));
   F32 height = F32(gs->maxHeight) * 0.03124f + 10.f;

   const RectI &area = MissionArea::smMissionArea;
   Point2F min(area.point.x, area.point.y);
   Point2F max(area.point.x + area.extent.x, area.point.y + area.extent.y);

   dglClearBitmapModulation();
   TextureHandle bitMap = TextureHandle("common/ui/grid.png", MeshTexture);
   
   glDisable(GL_CULL_FACE);
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glDisable(GL_LIGHTING);
   glColor4f(1.0, 1.0, 1.0, alpha);
   glEnable(GL_TEXTURE_2D);
   TextureObject* texture = (TextureObject*)bitMap;
   glBindTexture(GL_TEXTURE_2D, texture->texGLName);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

   height *= 2;
   if (sides[1])
   {
      glBegin(GL_TRIANGLE_FAN);
      glTexCoord2f(0.0,0.0);
      glVertex3f(min.x, min.y, 0);
      glTexCoord2f((max.x - min.x)/5,0);
      glVertex3f(max.x, min.y, 0);
      glTexCoord2f((max.x - min.x)/5, height/5);
      glVertex3f(max.x, min.y, height);
      glTexCoord2f(0,height/5);
      glVertex3f(min.x, min.y, height);
      glEnd();
   }
   if (sides[3])
   {
      glBegin(GL_TRIANGLE_FAN);
      glTexCoord2f(0,0);
      glVertex3f(min.x, max.y, 0);
      glTexCoord2f((max.x - min.x)/5,0);
      glVertex3f(max.x, max.y, 0);
      glTexCoord2f((max.x - min.x)/5,height/5);
      glVertex3f(max.x, max.y, height);
      glTexCoord2f(0,height/5);
      glVertex3f(min.x, max.y, height);
      glEnd();
   }
   if (sides[0])
   {
      glBegin(GL_TRIANGLE_FAN);
      glTexCoord2f(0,0);
      glVertex3f(min.x, min.y, 0);
      glTexCoord2f((max.y-min.y)/5,0);
      glVertex3f(min.x, max.y, 0);
      glTexCoord2f((max.y-min.y)/5,height/5);
      glVertex3f(min.x, max.y, height);
      glTexCoord2f(0,height/5);
      glVertex3f(min.x, min.y, height);
      glEnd();
   }
   if (sides[2])
   {
      glBegin(GL_TRIANGLE_FAN);
      glTexCoord2f(0,0);
      glVertex3f(max.x, min.y, 0);
      glTexCoord2f((max.y-min.y)/5,0);
      glVertex3f(max.x, max.y, 0);
      glTexCoord2f((max.y-min.y)/5,height/5);
      glVertex3f(max.x, max.y, height);
      glTexCoord2f(0,height/5);
      glVertex3f(max.x, min.y, height);
      glEnd();
   }

   glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);
}

And there you have it. Just make sure to specify a location of a bitmap otherwise you'll just get the gridlike effect by using the one I gave (which the image doesnt exist I believe).
Page«First 1 2 Next»
#21
06/15/2002 (9:53 pm)
Thanks heaps Robert
I have tested it on a dedicated server / client setup and it is working fine here now :)
Thanks fro supply a really top resource and thanks for supporting it :)
#22
06/16/2002 (6:40 am)
yep works perfect good job
#23
06/26/2002 (8:08 am)
just wanted to comment that the line

MissionArea * obj = dynamic_cast(Sim::findObject("MissionArea"));

does work. I'm using to determine if I should be drawing the mission area or not based on a flag set in the missionarea datablock.

so then I do something like

if (obj && obj->getDisplayMissionArea())
{
//the code from this post thats in game.cc
GameConnection* conn = GameConnection::getServerConnection();
MatrixF cam;
Point3F camPos;
conn->getControlCameraTransform(0,&cam);
cam.getColumn(3, &camPos);

...
}

just add a bool flag to the missionarea and the appropriate initialiazation and initpersistfields and there ya go.
Now you can add or remove it from the editor as well.
#24
06/28/2002 (6:45 pm)
hello everyone, im still learning C++, and I added your code and tried to compile it with the torque engine and the error I get is

C:\torque\engine\game\game.cc(1172) : error C2601: 'GameRenderMissionArea' : local function definitions are illegal
Error executing cl.exe.

Could anyone help me out please? thanks.
#25
06/29/2002 (1:58 am)
you seem to have forgotten a { or }
above the code that complains.

:)
#26
07/17/2002 (9:06 pm)
look what happens when alpha textures on my airplane model blend with the alpha from the grid
http://www.afterschoolcartoons.com/images/screenshot_00003.png
any clues?
#27
08/03/2002 (10:33 pm)
Hey I figured out why I kept(many others it appears) getting this error:
error C2601: 'GameRenderMissionArea' : local function definitions are illegal

The fix/solution is after this line add a } to fix it:
GameRenderMissionArea(alpha, renderSide);

It seems the example code is missing it as well. Welp I hope that helped out guys because it sure did fix my problem. :)
#28
08/03/2002 (10:41 pm)
Ohh great, now whenever I have the show mission area code enabled Win2k complains about a read/write memory error whenever I start my own mission and right when the game is done loading everything to about to play the game. So good thing I #ifdef and #endif all the code provided here just in case I needed to disable all the modifications ;)

Welp I'll leave it disabled for now until someone(or me) can comeup with a solution to fix this problem.
#29
08/05/2002 (7:37 am)
OK I figured out why I got that memory read/write error is because I didn't have the grid.png image file located in the correct directory so I think it's a good idea to make it where the engine checks to see if that file exists if not then complain about it in the console and not process the mission area display code. If it does exist then of course proceed as normal. :)
#30
11/11/2002 (5:15 pm)
Great Resource, Thanks a lot.

Has anyone tried (or even needed) to have the mission area solid, so a player could not run though it.

(I know, with all the posts about making the terrian bigger, I must be nuts. :P)

-- Adrian St. Onge
#31
01/01/2003 (12:43 pm)
Adrian,

In the OnLeaveMissionArea() function in player.cs, add %obj.getTransform() to get the player position, then add %ma = nameToID("MissionArea") to get the mission area. Then you can move the player back to the closest point inside the mission area to where his current location is by calling %obj.setTransform(). You will have to figure out the math but yeah I think you can do this.

Robert
#32
10/19/2003 (7:19 am)
code snippet is gone :(
Page«First 1 2 Next»