Commander Map
by Kyle Carter · 03/01/2004 (10:52 am) · 155 comments
Download Code File
To use this resource:
1. Copy guiCommanderHud.cc to your engine/gui subfolder.
2. Open your IDE of choice (or a text editor if that's what you like).
3. Add the source file to your project so it will be compiled into Torque.
4. Do a clean rebuild.
5. Go to the GUI of your choice and add a GuiCommanderHud to it. Poof, instant GUI!
Security and Scoping Issues:
The HUD is designed to prevent people from abusing it in-game. It does not change how anything is scoped, so people will only see what the net code would have previously allowed them to see. If you want to have a special "commander map" behavior that shows all active objects you will need to add it either via server side scripting or in GameConnection::doneScopingScene(). Remember, the best way to prevent cheating and improve net performance on your game is to only scope what people need to see.
If you're particularly paranoid, you may want to remove the ConsoleMethods at the end of the file and control the commander map with events; this is probably unnecessary in most cases, as the commander map reveals no more information than the player could get by opening a map in single player mode or a dedicated server and flying/walking around.
Panning and Zooming:
There are three useful actions you can do via scripting with the GuiCommanderHud. First, you can zoom. This basically consists of changing the FOV of the overhead camera that the view is being rendered from (see GuiCommanderHud::processCameraQuery()), so you want to stick to values between 0 and one half pi. Larger values can give "interesting" results though no value should crash the engine. The available script methods for this are zoom() to instantly set the zoom level and zoomTo() to smoothly interpolate to the requested zoom level.
pan() and panTo() let you set the x,y co-ordinates of the overhead camera - essentially setting where the center of the map is. If you wish to pan onto an object, get the first two words of its position and pass them to pan() or panTo().
There are also two exposed fields, panSpeed and zoomSpeed, which let you tweak how quickly panning and zooming occurs. Negative values for these will give catastrophic results!
Performance:
On a 1.8Ghz P4 with 512mb of RAM and a GeForce 4 440 Go (equivalent to a fast GeForce 2), I get 70fps in the test FPS level without the map on screen, and 40fps with it on the screen (in addition to the normal FPS view). Suggested usage is to run the GuiCommanderHud in its own GUI, so that you don't have the overhead of the PlayGUI and its view of the world.
The GuiCommanderHud only renders interior, terrain, water, and environmental objects. You can easily change the mask it uses for rendering the scene by editing GuiCommanderHud::renderWorld() - there is a comment to guide you. Re-enabling all DTS shapes will bring a significant performance hit, since you'll be rendering potentially all the objects in the game world!
Extensions:
There are three major areas in which the GuiCommanderHud could be extended for your game.
First, you may want to render an overlay or icons indicating where objectives/players are. There is a comment located where you would want to render these objects, in GuiCommanderHud::onRender(). Using standard DGL calls will give good results.
Second, you may want to have the control handle mouse input. Looking at EditTSCtrl (located in engine/editor/editTSCtrl.*) will be an excellent guide for this process. You could either inherit from EditTSCtrl, or copy its mouse handling code to the GuiCommanderHud. The project() and unproject() functions that GuiCommmanderHud inherits from GuiTSCtrl may also be useful here.
Finally, you may wish to optimize rendering speed by caching output to a texture, rendering only the texture, and updating the texture as needed when the map needs to change its view. (You could even render to a large texture and simply pan it around, though this would kill the neat parallaxing and depth buffering effects that you could gain from actually rendering the world into the GuiCommanderHud.) This would be a bit tricky, but GuiCommanderHud::onRender would be your starting point. Look at TSShapeInstance::snapshot() for guidance on how to implement this sort of functionality in OpenGL - beware that the DirectX layer may not place nice with this.
Usage Restrictions:
None. Knock yourself out! :) I would ask that you put my name in your credits somewhere and send me a free copy of your game if this resource is a major piece of functionality for your project, but you are by no means required to do so. I'd also appreciate it if, if you found bugs or made enhancements for the code, if you'd send me your change(s) so I can merge them back into this resource. Many eyes find more bugs. ;)
Addendums:
Neat bit of code to try from the console(replace 1494 with the SimObject you want to track). Notice my commander hud is named commHud.
To use this resource:
1. Copy guiCommanderHud.cc to your engine/gui subfolder.
2. Open your IDE of choice (or a text editor if that's what you like).
3. Add the source file to your project so it will be compiled into Torque.
4. Do a clean rebuild.
5. Go to the GUI of your choice and add a GuiCommanderHud to it. Poof, instant GUI!
Security and Scoping Issues:
The HUD is designed to prevent people from abusing it in-game. It does not change how anything is scoped, so people will only see what the net code would have previously allowed them to see. If you want to have a special "commander map" behavior that shows all active objects you will need to add it either via server side scripting or in GameConnection::doneScopingScene(). Remember, the best way to prevent cheating and improve net performance on your game is to only scope what people need to see.
If you're particularly paranoid, you may want to remove the ConsoleMethods at the end of the file and control the commander map with events; this is probably unnecessary in most cases, as the commander map reveals no more information than the player could get by opening a map in single player mode or a dedicated server and flying/walking around.
Panning and Zooming:
There are three useful actions you can do via scripting with the GuiCommanderHud. First, you can zoom. This basically consists of changing the FOV of the overhead camera that the view is being rendered from (see GuiCommanderHud::processCameraQuery()), so you want to stick to values between 0 and one half pi. Larger values can give "interesting" results though no value should crash the engine. The available script methods for this are zoom() to instantly set the zoom level and zoomTo() to smoothly interpolate to the requested zoom level.
pan() and panTo() let you set the x,y co-ordinates of the overhead camera - essentially setting where the center of the map is. If you wish to pan onto an object, get the first two words of its position and pass them to pan() or panTo().
There are also two exposed fields, panSpeed and zoomSpeed, which let you tweak how quickly panning and zooming occurs. Negative values for these will give catastrophic results!
Performance:
On a 1.8Ghz P4 with 512mb of RAM and a GeForce 4 440 Go (equivalent to a fast GeForce 2), I get 70fps in the test FPS level without the map on screen, and 40fps with it on the screen (in addition to the normal FPS view). Suggested usage is to run the GuiCommanderHud in its own GUI, so that you don't have the overhead of the PlayGUI and its view of the world.
The GuiCommanderHud only renders interior, terrain, water, and environmental objects. You can easily change the mask it uses for rendering the scene by editing GuiCommanderHud::renderWorld() - there is a comment to guide you. Re-enabling all DTS shapes will bring a significant performance hit, since you'll be rendering potentially all the objects in the game world!
Extensions:
There are three major areas in which the GuiCommanderHud could be extended for your game.
First, you may want to render an overlay or icons indicating where objectives/players are. There is a comment located where you would want to render these objects, in GuiCommanderHud::onRender(). Using standard DGL calls will give good results.
Second, you may want to have the control handle mouse input. Looking at EditTSCtrl (located in engine/editor/editTSCtrl.*) will be an excellent guide for this process. You could either inherit from EditTSCtrl, or copy its mouse handling code to the GuiCommanderHud. The project() and unproject() functions that GuiCommmanderHud inherits from GuiTSCtrl may also be useful here.
Finally, you may wish to optimize rendering speed by caching output to a texture, rendering only the texture, and updating the texture as needed when the map needs to change its view. (You could even render to a large texture and simply pan it around, though this would kill the neat parallaxing and depth buffering effects that you could gain from actually rendering the world into the GuiCommanderHud.) This would be a bit tricky, but GuiCommanderHud::onRender would be your starting point. Look at TSShapeInstance::snapshot() for guidance on how to implement this sort of functionality in OpenGL - beware that the DirectX layer may not place nice with this.
Usage Restrictions:
None. Knock yourself out! :) I would ask that you put my name in your credits somewhere and send me a free copy of your game if this resource is a major piece of functionality for your project, but you are by no means required to do so. I'd also appreciate it if, if you found bugs or made enhancements for the code, if you'd send me your change(s) so I can merge them back into this resource. Many eyes find more bugs. ;)
Addendums:
Neat bit of code to try from the console(replace 1494 with the SimObject you want to track). Notice my commander hud is named commHud.
commHud.zoomTo(0.02);
function panPlayer() { commHud.panTo(getWord(1494.getPosition(), 0), getWord(1494.getPosition(), 1)); schedule(100, 0, panPlayer); }
panPlayer();
#42
good...
the code works, i have to press f11 then f10, create the map, then f10 again to close the gui editor, then i move the cursor over the map, and i can zoom in and out,
but the map is only there when i press f11, its not there during game play,
is there any way to get this to work while playing the game and get the wheel to zoom in and out instead of , lets say waepon change..?
i can set up the zaxis to preform a function when the wheel is turned , i just dont know what function to call in the guicommandermap to zoom in/out
heres the modifaction to perform a function on mouse wheel
moveMap.bind(mouse0, "zaxis", handleMouseWheel);
to your \fps\client\config.cs file. I added it under the 2 other mouse axes (x and y).
The function does indeed work! so open fps/client/scripts/default.bind.cs and add the following code to it
//------------------------------------------------------------------------------
// Mouse Wheel
//------------------------------------------------------------------------------
function handleMouseWheel(%val)
{
// Check if the wheel scrolled up or down
if( %val > 0 )
{
//zoom function here
}
else
{
//zoom function here
}
}
moveMap.bind( mouse, zaxis, handleMouseWheel );
thanks to Micha
01/10/2006 (11:53 am)
ok good news and bad newsgood...
the code works, i have to press f11 then f10, create the map, then f10 again to close the gui editor, then i move the cursor over the map, and i can zoom in and out,
but the map is only there when i press f11, its not there during game play,
is there any way to get this to work while playing the game and get the wheel to zoom in and out instead of , lets say waepon change..?
i can set up the zaxis to preform a function when the wheel is turned , i just dont know what function to call in the guicommandermap to zoom in/out
heres the modifaction to perform a function on mouse wheel
moveMap.bind(mouse0, "zaxis", handleMouseWheel);
to your \fps\client\config.cs file. I added it under the 2 other mouse axes (x and y).
The function does indeed work! so open fps/client/scripts/default.bind.cs and add the following code to it
//------------------------------------------------------------------------------
// Mouse Wheel
//------------------------------------------------------------------------------
function handleMouseWheel(%val)
{
// Check if the wheel scrolled up or down
if( %val > 0 )
{
//zoom function here
}
else
{
//zoom function here
}
}
moveMap.bind( mouse, zaxis, handleMouseWheel );
thanks to Micha
#43
This assumes two things:
1) You have named the commander map GUI control "CommanderMap".
2) If you manually tell the commander map to zoom in/out from OUTSIDE the handleMouseWheel function, then you need to modify the $CommanderMapZoom variable above to match the new zoom value. A better option would be to add a new console method to CommanderMap.cc to retrieve the mZoomGoal variable, and automatically retrieve that instead of relying on $CommanderMapZoom. But the above code is a script only solution and should work for you.
01/10/2006 (3:10 pm)
Stephen, you can basically put the zoom code directly in your handleMouseWheel script function, and it should work OK. Try adding this to your default.bind.cs:$CommanderMapZoom = 3.14159/2;
//------------------------------------------------------------------------------
// Mouse Wheel
//------------------------------------------------------------------------------
function handleMouseWheel(%val)
{
if (!isObject(CommanderMap))
return;
%delta = ($CommanderMapZoom / 16) * CommanderMap.zoomSpeed;
// Check if the wheel scrolled up or down
if( %val > 0 )
{
if ($CommanderMapZoom - %delta >= 0.08)
$CommanderMapZoom -= %delta;
}
else
{
if ($CommanderMapZoom + %delta <= 1.75)
$CommanderMapZoom += %delta;
}
CommanderMap.ZoomTo($CommanderMapZoom);
}This assumes two things:
1) You have named the commander map GUI control "CommanderMap".
2) If you manually tell the commander map to zoom in/out from OUTSIDE the handleMouseWheel function, then you need to modify the $CommanderMapZoom variable above to match the new zoom value. A better option would be to add a new console method to CommanderMap.cc to retrieve the mZoomGoal variable, and automatically retrieve that instead of relying on $CommanderMapZoom. But the above code is a script only solution and should work for you.
#44
Thanks
Rob =)
you know your stuff =)
01/10/2006 (5:17 pm)
the code updated the numbers for the fov perfectly but the commandmap just wont update the fov?? i'll try a few thingsThanks
Rob =)
you know your stuff =)
#45
01/10/2006 (5:21 pm)
got it , just deleted my old commandermap and created an new commandermap and it worked...strange but true.
#46
dont know how to grab player cord.
01/10/2006 (5:40 pm)
any ideas on how to get the map to follow the player? commandHud.panTo(...)dont know how to grab player cord.
#47
01/10/2006 (5:43 pm)
Look at the Addendums section at the bottom of the resource article, Ben explains how to do just that.
#48
01/10/2006 (6:01 pm)
were can i place that code so that it will run only when the player has been dropped int othe level?
#49
in the client\scripts\serverConnection.cs
function GameConnection::initialControlSet(%this)
{
echo ("*** Initial Control Object");
panPlayer();
01/11/2006 (4:39 am)
i found that putting it here, gets the best resultsin the client\scripts\serverConnection.cs
function GameConnection::initialControlSet(%this)
{
echo ("*** Initial Control Object");
panPlayer();
#50
01/11/2006 (4:41 am)
how would i go about adding bitmaps for players on the map?
#52
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=2270
01/12/2006 (6:45 am)
Off hand I don't know how to do this, Stephen, but it looks like this resource below does something very similar. Maybe you can look through the source code to see how they're doing it:http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=2270
#53
here is what i have on the PanTo function. i'm trying to get the location of the player on the client. but for somw reason the getposition() is not returning the position of the player.... any ideas
01/17/2006 (3:42 am)
trying to get this to work client sidehere is what i have on the PanTo function. i'm trying to get the location of the player on the client. but for somw reason the getposition() is not returning the position of the player.... any ideas
Quote:
ConsoleMethod(GuiCommanderHud, panTo, void, 4, 4, "(x, y) Smoothly pan to a location.")
{
//-------------------------------------------------------------------------------------------------------
GameConnection* conn = GameConnection::getServerConnection();
if (!conn) return;
// Must have controlled object
ShapeBase* control = conn->getControlObject();
if (!control) return;
for (SimSetIterator itr(conn); *itr; ++itr)
{
// Make sure that the object is a shapebase object
if ((*itr)->getType() & ShapeBaseObjectType)
{
ShapeBase* shape = static_cast(*itr);
// Make sure that the object is the client
if (shape == control && shape->getShapeName())
{
// Make sure the shapebase object is a player
if (shape->getType() & PlayerObjectType)
{
Point3F newCoord;
// Get coords of player object
newCoord = shape->getPosition();
object->mPanGoal.set((newCoord,0), (newCoord,1));
}
}
}
}
}
#54
01/17/2006 (4:07 am)
never mind got itQuote:
Point3F newCoord;
// Get coords of player object
newCoord = shape->getPosition();
object->mPanGoal.set((0,newCoord.x), (1,newCoord.y));
#55
01/17/2006 (7:11 am)
is it just me or does the pan speed not work???
#56
01/17/2006 (7:17 am)
It doesn't. Replace this line in OnRender:mCurPan += (mPanGoal - mCurPan) * (F32)dt/1000.f;with this:
mCurPan += (mPanGoal - mCurPan) * ((F32)(dt/1000.f) * mPanSpeed);and that should enable pan speed.
#57
01/17/2006 (7:24 am)
i take it i'll have change mPanSpeed to a "F32" instead of a Point3F
#58
01/17/2006 (7:25 am)
Ah, yes, forgot about that. Yeah, I did change it to a F32 instead of a Point3F. Good catch.
#59
What is the best way to implement this for multiple users? I generally want it to only track the particular user not the first person that connects to the hosted game or the person that happens to have the particular object ID.
Currently I add the above code mods to the mission file, depending on the mission the map or nav computer would be avaliable for them to use.
Is it possible to have it check for the particular local client at the start of the mission file with out having to manually input the ID through the console? Thanks in advance.
02/18/2006 (8:00 am)
This is a great resource!!! I am working on a rally race style game and I have run into a problem. When I have it implemented in a multipler environment it tends to jump to the center of the scene because the object ID has changed depending on the particular person that connects to the host computer/server. What is the best way to implement this for multiple users? I generally want it to only track the particular user not the first person that connects to the hosted game or the person that happens to have the particular object ID.
Currently I add the above code mods to the mission file, depending on the mission the map or nav computer would be avaliable for them to use.
Is it possible to have it check for the particular local client at the start of the mission file with out having to manually input the ID through the console? Thanks in advance.
#60
02/25/2006 (5:17 pm)
Here is the code ported to 1.4//-----------------------------------------------------------------------------
//Edited by Dreamer
// This started life as CommanderMapHud by Ben Garney
// It has been ported to TGE 1.4 and had several community mods introduced
//
//-----------------------------------------------------------------------------
// Commander Map HUD
//
// Portions Copyright (c) GarageGames.Com
// Copyright (c) Ben Garney
//-----------------------------------------------------------------------------
// These includes are probably overkill -- BJG
#include "platform/platform.h"
#include "platform/platformVideo.h"
#include "platform/platformAudio.h"
#include "platform/platformInput.h"
#include "core/findMatch.h"
#include "dgl/dgl.h"
#include "game/game.h"
#include "math/mMath.h"
#include "console/simBase.h"
#include "console/console.h"
#include "terrain/terrData.h"
#include "terrain/terrRender.h"
#include "terrain/waterBlock.h"
#include "game/collisionTest.h"
#include "game/showTSShape.h"
#include "sceneGraph/sceneGraph.h"
#include "gui/core/guiTSControl.h"
#include "game/moveManager.h"
#include "console/consoleTypes.h"
#include "game/shapeBase.h"
#include "core/dnet.h"
#include "game/gameConnection.h"
#include "core/fileStream.h"
#include "gui/core/guiCanvas.h"
#include "dgl/gTexManager.h"
#include "sceneGraph/sceneLighting.h"
#include "terrain/sky.h"
#include "game/ambientAudioManager.h"
#include "core/frameAllocator.h"
#include "sceneGraph/detailManager.h"
#include "gui/controls/guiMLTextCtrl.h"
#include "platform/profiler.h"
#include "game/fx/underLava.h"
//-----------------------------------------------------------------------------
class GuiMapHud : public GuiTSCtrl
{
private:
typedef GuiTSCtrl Parent;
F32 mPanSpeed;
F32 mZoomSpeed;
S32 mLastRenderTime;
public:
Point2F mPanGoal, mCurPan;
F32 mZoomGoal, mCurZoom;
GuiMapHud();
bool processCameraQuery(CameraQuery *query);
void renderWorld(const RectI &updateRect);
void onRender( Point2I, const RectI &);
static void initPersistFields();
bool onMouseWheelUp(const GuiEvent &event);
bool onMouseWheelDown(const GuiEvent &event);
DECLARE_CONOBJECT( GuiMapHud );
};
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT( GuiMapHud );
GuiMapHud::GuiMapHud()
: mPanSpeed(2.5), mZoomSpeed(1), mCurPan(0,0), mCurZoom(M_PI_F/2),
mPanGoal(0,0), mZoomGoal(M_PI_F/2), mLastRenderTime(0)
{
}
void GuiMapHud::initPersistFields()
{
Parent::initPersistFields();
addField("panSpeed", TypeF32, Offset(mPanSpeed, GuiMapHud), "Set the speed we pan to our goal.");
addField("zoomSpeed", TypeF32, Offset(mZoomSpeed, GuiMapHud), "Set the speed we zoom with to our goal.");
}
bool GuiMapHud::processCameraQuery(CameraQuery *q)
{
// Scale ranges based on the highest/lowest point in the terrain
F32 maxHi = gClientSceneGraph->getCurrentTerrain()->findSquare(8, 0,0)->maxHeight / 10;
F32 minHi = gClientSceneGraph->getCurrentTerrain()->findSquare(8, 0,0)->minHeight / 10;
q->object = NULL;
q->nearPlane = 1;
q->farPlane = mFabs(maxHi) + mFabs(minHi);
q->fov = mCurZoom;
GameConnection* conn;
conn = GameConnection::getConnectionToServer();
if (!conn)
return false;
MatrixF playercam, mat1, mat2;
conn->getControlCameraTransform(0, &playercam); // store camera information
// Get camera angle
AngAxisF aa(playercam);
aa.axis.x = 0.0f;
aa.axis.y = 0.0f;
aa.setMatrix(&mat1);
// Create angle to look straight down
aa.axis.x = 1.0f;
aa.axis.y = 0.0f;
aa.axis.z = 0.0f;
aa.angle = 3.14/2;
aa.setMatrix(&mat2);
// Combine the camera angles
mat1.mul(mat2);
// Make sure we're high enough that we we won't clip
mat1.setColumn(3, Point3F(mCurPan.x, mCurPan.y, maxHi + 100));
q->cameraMatrix = mat1;
return true;
}
void GuiMapHud::renderWorld(const RectI &updateRect)
{
// Set up state
TerrainRender::mRenderingCommander = true;
F32 oldVisDist = gClientSceneGraph->getVisibleDistance();
gClientSceneGraph->setVisibleDistance(2000);
F32 oldFogDist = gClientSceneGraph->getFogDistance();
gClientSceneGraph->setFogDistance(2000);
// set up the camera and viewport stuff:
// Render (stolen from GameRenderWorld)
PROFILE_START(GameRenderCommanderWorld);
FrameAllocator::setWaterMark(0);
#if defined(GATHER_METRICS) && GATHER_METRICS > 1
TextureManager::smTextureCacheMisses = 0;
#endif
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClear(GL_DEPTH_BUFFER_BIT);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_MODELVIEW);
dglSetCanonicalState();
// If you want to render other things, change this mask.
gClientSceneGraph->renderScene( EnvironmentObjectType | TerrainObjectType | InteriorObjectType | WaterObjectType | PlayerObjectType);
glDisable(GL_DEPTH_TEST);
#if defined(GATHER_METRICS) && GATHER_METRICS > 1
Con::setFloatVariable("Video::texResidentPercentage",
TextureManager::getResidentFraction());
Con::setIntVariable("Video::textureCacheMisses",
TextureManager::smTextureCacheMisses);
#endif
AssertFatal(FrameAllocator::getWaterMark() == 0, "Error, someone didn't reset the water mark on the frame allocator!");
FrameAllocator::setWaterMark(0);
PROFILE_END();
// Restore state
gClientSceneGraph->setVisibleDistance(oldVisDist);
gClientSceneGraph->setFogDistance (oldFogDist);
TerrainRender::mRenderingCommander = false;
dglSetClipRect(updateRect);
}
void GuiMapHud::onRender(Point2I offset, const RectI &updateRect)
{
// Update pan/zoom
S32 time = Platform::getVirtualMilliseconds();
S32 dt = time - mLastRenderTime;
mLastRenderTime = time;
mCurPan += (mPanGoal - mCurPan) * (F32)dt/1000.f;
mCurZoom += (mZoomGoal - mCurZoom) * ((F32)(dt/1000.f) * mZoomSpeed);
// Render the world...
Parent::onRender(offset, updateRect);
// If you wanted to render custom GUI elements, like a sensor map, icons for
// players/vehicles/objectives, you would do it here by calling project()
// for all their positions and drawing bitmaps at the appropriate locations.
}
bool GuiMapHud::onMouseWheelUp(const GuiEvent &event)
{
F32 delta = (mZoomGoal/16) * mZoomSpeed;
// Don't let the player zoom so far in that they can't
// tell what's they are looking at.
if (mZoomGoal - delta >= 0.08)
mZoomGoal -= delta;
return( true );
}
bool GuiMapHud::onMouseWheelDown(const GuiEvent &event)
{
F32 delta = (mZoomGoal/16) * mZoomSpeed;
// Don't let the player zoom so far out that the land doesn't
// fill the whole commander map
if (mZoomGoal + delta <= 1.75)
mZoomGoal += delta;
return( true );
}
ConsoleMethod(GuiMapHud, pan, void, 4, 4, "(x, y) Cut to a location.")
{
object->mPanGoal.set(dAtof(argv[2]), dAtof(argv[3]));
object->mCurPan.set (dAtof(argv[2]), dAtof(argv[3]));
}
ConsoleMethod(GuiMapHud, panTo, void, 4, 4, "(x, y) Smoothly pan to a location.")
{
object->mPanGoal.set(dAtof(argv[2]), dAtof(argv[3]));
}
ConsoleMethod(GuiMapHud, zoom, void, 3, 3, "(val) Zoom to a specified level.")
{
object->mZoomGoal = dAtof(argv[2]);
object->mCurZoom = dAtof(argv[2]);
}
ConsoleMethod(GuiMapHud, zoomTo, void, 3, 3, "(val) Smoothly zoom to a specified level.")
{
object->mZoomGoal = dAtof(argv[2]);
}
ConsoleMethod(GuiMapHud, zoomToArea, void, 6, 7, "(top, left, right, bottom, bool cut) Smoothly zoom to view the specified area. If cut is set, we jump there.")
{
// Parse arguments
F32 top, left, right, bottom;
top = dAtof(argv[2]);
left = dAtof(argv[3]);
right = dAtof(argv[4]);
bottom = dAtof(argv[5]);
// Figure out the center of the area
Point2F center;
center.x = (left + right) * 0.5f;
center.y = (top + bottom) * 0.5f;
object->mZoomGoal = mFabs(left - right) / 200; // Cheesy scaling fakery.
// And set our motion
object->mPanGoal = center;
// Cut if requested
if(argc > 6)
if(dAtob(argv[6]))
{
object->mCurPan = object->mPanGoal;
object->mCurZoom = object->mZoomGoal;
}
} 
Torque Owner Stephen Walsh