Compass
by Neil Marshall · in Torque Game Engine · 12/12/2001 (8:35 am) · 18 replies
I just tried using the (old) compass control I found on this site http://www.iamxp.com/nohbdy/
But when I try to compile torque with it I get an error on the last line of code
renderChildControls(offset, updateRect, firstResponder);
If I comment it out, the program compiles, but when I place a compass control in the ui, I don't get the needle or the background image. Does anyone know how to adjust it so it will work with the latest stable version from the CVS?
Oh, and one more request. If the .gui is set to read only, can torque please generate an error message? I made some changes, saved them, quit and reloaded only to see that they didn't stick.
But when I try to compile torque with it I get an error on the last line of code
renderChildControls(offset, updateRect, firstResponder);
If I comment it out, the program compiles, but when I place a compass control in the ui, I don't get the needle or the background image. Does anyone know how to adjust it so it will work with the latest stable version from the CVS?
Oh, and one more request. If the .gui is set to read only, can torque please generate an error message? I made some changes, saved them, quit and reloaded only to see that they didn't stick.
#2
12/15/2001 (8:45 am)
I "rehacked" this conrol recently and fixed a couple of issues having to do with the control, needle and the direction it points. I'll put up a fixed tutorial today as soon as I can pull the pieces together.
#3
This assumes that you have the torque engine installed according to the standard install instructions on the C: drive of your computer and that you are using Visual C++ 6.0 to modify the code. With appropriate modifications it should work in other environments as well.
The short form.
1. Download the original code from nohbdy
2. unzip the code and add it to your development project
3. modify the code according to the directions below
4. recompile the code.
5. modify the playgui.gui to include the compass in the player's display window
6. test
The long form...
1. Download the original files created by nohbdy
The download is originally referenced here...
http://www.garagegames.com/index.php?sec=mg&mod=forums&page=result.thread&qt=1500
and is downloaded from here...
http://www.iamxp.com/nohbdy/guicompassctrl.zip
2. unzip the code. I used winzip. Place the files guiCompassCtrl.h and guiCompassCtrl.cc into your code. It can be located in the directory torque/engine/gui, or you can create your own subdirectory and place it there. The file compass.png goes in ... torque/example/fps/client/ui
To add the code to you project go to torque/vc6 and double click on the file, "Torque SDK.dsw"
a. select "Torque Demo files" from the FileView tab in the Workspace window in Visual C++ and expand it.
b. Expand the "Source files" and right click on the subdirectory file "gui".
c. Select "Add Files to folder..." from the pop up menu.
d. A dialog box will appear titled "Insert Files into Project".
e. Change the "Files of Type" selection to "All Files".
f. Then using the "Look in:" pulldown locate the gui subdirectory -
e.g. Local disk C: -> torque -> engine -> gui.
Select the gui folder and then locate the two files guiCompassCtrl.h and guiCompassCtrl.cc.
g. Using the Ctrl key and the mouse, click on each one so that they are highlighted blue.
Then select OK. Both files will be added to the project list.
3. modify the code according to the directions below.
a. Bring up the guiCompassCtrl.h file and change the last line of code from...
void onRender(Point2I offset, const RectI &updateRect, GuiControl *firstResponder);
to...
void onRender(Point2I offset, const RectI &updateRect);
Save and close the file.
b. Now bring up the guiCompassCrl.cc file and replace the last routine in the code with this one...
void GuiCompassCtrl::onRender(Point2I offset, const RectI &updateRect)
{
//Render the compass bitmap
if (mTextureHandle)
{
dglClearBitmapModulation();
if(mWrap)
{
TextureObject* texture = (TextureObject *) mTextureHandle;
RectI srcRegion;
RectI dstRegion;
float xdone = ((float)mBounds.extent.x/(float)texture->bitmapWidth)+1;
float ydone = ((float)mBounds.extent.y/(float)texture->bitmapHeight)+1;
int xshift = startPoint.x%texture->bitmapWidth;
int yshift = startPoint.y%texture->bitmapHeight;
for(int y = 0; y < ydone; ++y)
for(int x = 0; x < xdone; ++x)
{
srcRegion.set(0,0,texture->bitmapWidth,texture->bitmapHeight);
dstRegion.set( ((texture->bitmapWidth*x)+offset.x)-xshift,
((texture->bitmapHeight*y)+offset.y)-yshift,
texture->bitmapWidth,
texture->bitmapHeight);
dglDrawBitmapStretchSR(texture,dstRegion, srcRegion, false);
}
}
else
{
RectI rect(offset, mBounds.extent);
// RectI rect = mBounds;
// rect.point += offset;
dglDrawBitmapStretch(mTextureHandle, rect);
}
}
else
{
RectI rect = mBounds;
rect.point += offset;
glColor4f(0, 0, 0, 1);
glBegin(GL_LINE_LOOP);
glVertex2i(rect.point.x, rect.point.y);
glVertex2i(rect.point.x + rect.extent.x - 1, rect.point.y);
glVertex2i(rect.point.x + rect.extent.x - 1, rect.point.y + rect.extent.y - 1);
glVertex2i(rect.point.x, rect.point.y + rect.extent.y - 1);
glEnd();
}
//Find distance from top-left corner to center of compass
Point2F center(mBounds.extent.x / 2,mBounds.extent.y / 2);
//Query the camera and find out which direction we're facing
struct CameraQuery query;
GameProcessCameraQuery(&query);
Point3F cameraRot;
MatrixF matrix = query.cameraMatrix;
matrix.getRow(1,&cameraRot); // get camera rotation
//Find point on compass that translates to our direction
center.x += mBounds.point.x; //now make center the screen coordinate center
center.y += mBounds.point.y;
//--dcd-- This is K. Finney's fix to the control to reverse the compass mapping
// This may need to be removed when the terrain problem is corrected
cameraRot.neg(); // <--- this flips the orientation, caused by the upside down terrains from bitmaps
//--dcd-- end fix
Point2F pointA(cameraRot.x * 40, cameraRot.y * 40);
if (!mIs3d)
{
cameraRot.z = 0;
cameraRot.normalize();
cameraRot *= (center.x * 0.8f);
pointA.x = cameraRot.x;
pointA.y = cameraRot.y;
//Ryan's fix to normalize the length of the compass needle
pointA.normalize();
pointA.x = 18 * pointA.x;
pointA.y = 18 * pointA.y;
//end change
}
F32 red = mProfile->mFillColor.red/255.0f;
F32 green = mProfile->mFillColor.green/255.0f;
F32 blue = mProfile->mFillColor.blue/255.0f;
//Render a pretty Compass Pointer
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_LINES);
glColor4f(red, green, blue, 1.0f);
glVertex2f(center.x, center.y);
glColor4f(red, green, blue, 0.0f);
//--dcd-- rotational fix - change back when compass mapping is fixed
// this version agrees with the new Terrain terraform Editor and the Terrain Texture Editor in the HEAD version of the code.
// it does not agree with the Mission Area Editor.
glVertex2f(center.x + pointA.x, center.y + pointA.y);
// to change it you would need to remove the K. Finney fix above and change the code line to be...
// glVertex2f(center.x + pointA.x, center.y - pointA.y);
// This will make the compass agree with the Mission Editor but break the Terraform and Texture Editors.
// Of course, the correct fix is to change the Mission Area Editor - but that is for later...
// for now we want a compass that points and turns in the correct direction!
glEnd();
glDisable(GL_BLEND);
renderChildControls(offset, updateRect);
}
That's it. Save and close the file.
4. Recompile the code.
Select Build -> Build torqueDemo_Debug.exe or simply hit the F7 key to build the debug version of the code.
Make sure the updated executable is in the example folder.
5. modify the playgui.gui to include the compass in the player's display window
OK, almost done. Now, take out your favorite text editor and go to your playGui.gui file which is located in...
example\fps\client\ui
Go to the end of the file and locate the last bracket/semicolon - it is just before the comment line //--- OBJECT WRITE END ---
Just in front of this bracket we add the following new control...
new GuiCompassCtrl(Compass) {
profile = "GuiDefaultProfile";
horizSizing = "right";
vertSizing = "top";
position = "3 377";
extent = "100 100";
minExtent = "8 8";
visible = "1";
helpTag = "0";
bitmap = "./compass.png";
wrap = "0";
is3d = "0";
};
}; <<< these lines should already be here
//--- OBJECT WRITE END ---
That's about it. Save the file. If you go into your test level you should now see a green compass with arrow in the lower left corner.
12/15/2001 (11:40 am)
As promised...This assumes that you have the torque engine installed according to the standard install instructions on the C: drive of your computer and that you are using Visual C++ 6.0 to modify the code. With appropriate modifications it should work in other environments as well.
The short form.
1. Download the original code from nohbdy
2. unzip the code and add it to your development project
3. modify the code according to the directions below
4. recompile the code.
5. modify the playgui.gui to include the compass in the player's display window
6. test
The long form...
1. Download the original files created by nohbdy
The download is originally referenced here...
http://www.garagegames.com/index.php?sec=mg&mod=forums&page=result.thread&qt=1500
and is downloaded from here...
http://www.iamxp.com/nohbdy/guicompassctrl.zip
2. unzip the code. I used winzip. Place the files guiCompassCtrl.h and guiCompassCtrl.cc into your code. It can be located in the directory torque/engine/gui, or you can create your own subdirectory and place it there. The file compass.png goes in ... torque/example/fps/client/ui
To add the code to you project go to torque/vc6 and double click on the file, "Torque SDK.dsw"
a. select "Torque Demo files" from the FileView tab in the Workspace window in Visual C++ and expand it.
b. Expand the "Source files" and right click on the subdirectory file "gui".
c. Select "Add Files to folder..." from the pop up menu.
d. A dialog box will appear titled "Insert Files into Project".
e. Change the "Files of Type" selection to "All Files".
f. Then using the "Look in:" pulldown locate the gui subdirectory -
e.g. Local disk C: -> torque -> engine -> gui.
Select the gui folder and then locate the two files guiCompassCtrl.h and guiCompassCtrl.cc.
g. Using the Ctrl key and the mouse, click on each one so that they are highlighted blue.
Then select OK. Both files will be added to the project list.
3. modify the code according to the directions below.
a. Bring up the guiCompassCtrl.h file and change the last line of code from...
void onRender(Point2I offset, const RectI &updateRect, GuiControl *firstResponder);
to...
void onRender(Point2I offset, const RectI &updateRect);
Save and close the file.
b. Now bring up the guiCompassCrl.cc file and replace the last routine in the code with this one...
void GuiCompassCtrl::onRender(Point2I offset, const RectI &updateRect)
{
//Render the compass bitmap
if (mTextureHandle)
{
dglClearBitmapModulation();
if(mWrap)
{
TextureObject* texture = (TextureObject *) mTextureHandle;
RectI srcRegion;
RectI dstRegion;
float xdone = ((float)mBounds.extent.x/(float)texture->bitmapWidth)+1;
float ydone = ((float)mBounds.extent.y/(float)texture->bitmapHeight)+1;
int xshift = startPoint.x%texture->bitmapWidth;
int yshift = startPoint.y%texture->bitmapHeight;
for(int y = 0; y < ydone; ++y)
for(int x = 0; x < xdone; ++x)
{
srcRegion.set(0,0,texture->bitmapWidth,texture->bitmapHeight);
dstRegion.set( ((texture->bitmapWidth*x)+offset.x)-xshift,
((texture->bitmapHeight*y)+offset.y)-yshift,
texture->bitmapWidth,
texture->bitmapHeight);
dglDrawBitmapStretchSR(texture,dstRegion, srcRegion, false);
}
}
else
{
RectI rect(offset, mBounds.extent);
// RectI rect = mBounds;
// rect.point += offset;
dglDrawBitmapStretch(mTextureHandle, rect);
}
}
else
{
RectI rect = mBounds;
rect.point += offset;
glColor4f(0, 0, 0, 1);
glBegin(GL_LINE_LOOP);
glVertex2i(rect.point.x, rect.point.y);
glVertex2i(rect.point.x + rect.extent.x - 1, rect.point.y);
glVertex2i(rect.point.x + rect.extent.x - 1, rect.point.y + rect.extent.y - 1);
glVertex2i(rect.point.x, rect.point.y + rect.extent.y - 1);
glEnd();
}
//Find distance from top-left corner to center of compass
Point2F center(mBounds.extent.x / 2,mBounds.extent.y / 2);
//Query the camera and find out which direction we're facing
struct CameraQuery query;
GameProcessCameraQuery(&query);
Point3F cameraRot;
MatrixF matrix = query.cameraMatrix;
matrix.getRow(1,&cameraRot); // get camera rotation
//Find point on compass that translates to our direction
center.x += mBounds.point.x; //now make center the screen coordinate center
center.y += mBounds.point.y;
//--dcd-- This is K. Finney's fix to the control to reverse the compass mapping
// This may need to be removed when the terrain problem is corrected
cameraRot.neg(); // <--- this flips the orientation, caused by the upside down terrains from bitmaps
//--dcd-- end fix
Point2F pointA(cameraRot.x * 40, cameraRot.y * 40);
if (!mIs3d)
{
cameraRot.z = 0;
cameraRot.normalize();
cameraRot *= (center.x * 0.8f);
pointA.x = cameraRot.x;
pointA.y = cameraRot.y;
//Ryan's fix to normalize the length of the compass needle
pointA.normalize();
pointA.x = 18 * pointA.x;
pointA.y = 18 * pointA.y;
//end change
}
F32 red = mProfile->mFillColor.red/255.0f;
F32 green = mProfile->mFillColor.green/255.0f;
F32 blue = mProfile->mFillColor.blue/255.0f;
//Render a pretty Compass Pointer
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_LINES);
glColor4f(red, green, blue, 1.0f);
glVertex2f(center.x, center.y);
glColor4f(red, green, blue, 0.0f);
//--dcd-- rotational fix - change back when compass mapping is fixed
// this version agrees with the new Terrain terraform Editor and the Terrain Texture Editor in the HEAD version of the code.
// it does not agree with the Mission Area Editor.
glVertex2f(center.x + pointA.x, center.y + pointA.y);
// to change it you would need to remove the K. Finney fix above and change the code line to be...
// glVertex2f(center.x + pointA.x, center.y - pointA.y);
// This will make the compass agree with the Mission Editor but break the Terraform and Texture Editors.
// Of course, the correct fix is to change the Mission Area Editor - but that is for later...
// for now we want a compass that points and turns in the correct direction!
glEnd();
glDisable(GL_BLEND);
renderChildControls(offset, updateRect);
}
That's it. Save and close the file.
4. Recompile the code.
Select Build -> Build torqueDemo_Debug.exe or simply hit the F7 key to build the debug version of the code.
Make sure the updated executable is in the example folder.
5. modify the playgui.gui to include the compass in the player's display window
OK, almost done. Now, take out your favorite text editor and go to your playGui.gui file which is located in...
example\fps\client\ui
Go to the end of the file and locate the last bracket/semicolon - it is just before the comment line //--- OBJECT WRITE END ---
Just in front of this bracket we add the following new control...
new GuiCompassCtrl(Compass) {
profile = "GuiDefaultProfile";
horizSizing = "right";
vertSizing = "top";
position = "3 377";
extent = "100 100";
minExtent = "8 8";
visible = "1";
helpTag = "0";
bitmap = "./compass.png";
wrap = "0";
is3d = "0";
};
}; <<< these lines should already be here
//--- OBJECT WRITE END ---
That's about it. Save the file. If you go into your test level you should now see a green compass with arrow in the lower left corner.
#4
Now all it needs is for the needle to stay the same length. I just tried figuring out the math now but my heads not in it. I'll try again later.
12/15/2001 (1:31 pm)
Great it worked! Thanks.Now all it needs is for the needle to stay the same length. I just tried figuring out the math now but my heads not in it. I'll try again later.
#5
When I first tried to add the compass, I got an error stating it couldn't find HudCompassCtrl so I renamed
new HudCompassCtrl(Compass)
to
new GuiCompassCtrl(Compass)
and now it works fine.
Thanks!
12/26/2001 (7:51 am)
FYIWhen I first tried to add the compass, I got an error stating it couldn't find HudCompassCtrl so I renamed
new HudCompassCtrl(Compass)
to
new GuiCompassCtrl(Compass)
and now it works fine.
Thanks!
#6
i dont have my code infront of me, but thats the way to do it... btw the math aint hard ;)
Ryan
12/27/2001 (5:56 pm)
For keeping the length on the compass the same throughout the circle, i changed the onrender function to have the following:Point2F pointA(cameraRot.x * 40, cameraRot.y * 40);
if (!mIs3d)
{
cameraRot.z = 0;
cameraRot.normalize();
cameraRot *= (center.x * 0.8f);
pointA.x = cameraRot.x;
pointA.y = cameraRot.y;
//change here
pointA.normalize();
pointA.x = 18 * pointA.x;
pointA.y = 18 * pointA.y;
//end change
} f32 .....i dont have my code infront of me, but thats the way to do it... btw the math aint hard ;)
Ryan
#7
12/28/2001 (6:41 pm)
Works for me. I added it into the listing above - along with appropriate credit. :)
#8
Ryan
12/28/2001 (10:37 pm)
glad i could help :) something i wanted in game, finnaly got it to work, Thx dave. you should post this as a resource. Might help more people in the long run.Ryan
#9
12/29/2001 (6:10 am)
Good idea. Not to mention that it would demonstrate that I actually do know something about indenting - everything I typed in just went to the left border when I pasted it into the forum window. It's correct - but ugly.
#10
Mea culpa. I have changed it in the example above from HudCompassCtrl to the correct GuiCompassCtrl - Thanks Jeff!!
12/29/2001 (9:42 am)
Jeff was also correct in changing the name - when I originally wrote this my system was designed to have one subdirectory for GUI controls and another for HUD controls. All programs and references within each control set were named Gui or Hud respectively. However when the Torque engine superceded V12 the Hud subdirectory went away and I ported everything over. I accidentally cut this from the original v12 version which is why it is referenced as Hud instead of Gui. Mea culpa. I have changed it in the example above from HudCompassCtrl to the correct GuiCompassCtrl - Thanks Jeff!!
#11
12/29/2001 (12:23 pm)
Hey, no prob! One quick question, how do I change the color of the needle? I made a different metal compass texture and the grey needle gets lost in it.
#12
Since it is a line you can't do much more than color and alpha blend it. If you wanted to you could use a bitmap to make a wider needle, but that would require a bit more coding to adjust for aspect ratio when the needle changes direction.
Also, Ryan's fix uses two hardcoded numbers - both 18 - to set the aspect length of the needle. You can adjust the length of the needle by changing these values. However, keep them the same size or the needle will change shape as it rotates - (unless that's what you want it to do ;)
12/29/2001 (12:38 pm)
The needle portion of the compass is essentially a line that is being drawn. If you look at the compass code in guicompassctrl.cc right after Ryan's fix to normalize the length of the needle you will see three F32 values for Red, Green and Blue. Each is currently 255 - yielding white. You can set these values to change the color of the needle. Since it is a line you can't do much more than color and alpha blend it. If you wanted to you could use a bitmap to make a wider needle, but that would require a bit more coding to adjust for aspect ratio when the needle changes direction.
Also, Ryan's fix uses two hardcoded numbers - both 18 - to set the aspect length of the needle. You can adjust the length of the needle by changing these values. However, keep them the same size or the needle will change shape as it rotates - (unless that's what you want it to do ;)
#13
its ok now I hadn't put a bit in........dumb me lol
sorry
01/21/2002 (1:44 am)
mmm... Its not showing the arrow ...any ideas?its ok now I hadn't put a bit in........dumb me lol
sorry
#14
01/21/2002 (6:51 am)
Can These changes go into the cvs?
#15
Ryan
01/21/2002 (7:46 am)
ill throw together a code snippit, if anyone wants, that summarises everything, and then submit it to GG for inclusion in the engine. interested? let me knowRyan
#16
It wont take you much time
01/21/2002 (8:12 am)
hey ryan, do it, it will sure come in handy to everyone wanting to do a compassIt wont take you much time
#18
I got it working, and it's great, thanks to all who worked on this.
I inserted the guiCompassCtrl.h file and in file view, I found it and dragged it into the GUI folder. After inserting the guiCompassCtrl.cc file, I can't find it anywhere. It compiled fine and it's working, but how can I find a file in a project? I'd like to drag it into the GUI folder also, too keep things neat and tidy.
Thanks
David
02/29/2004 (10:32 am)
Stupid n00b question here, about MSVC++ 6. I got it working, and it's great, thanks to all who worked on this.
I inserted the guiCompassCtrl.h file and in file view, I found it and dragged it into the GUI folder. After inserting the guiCompassCtrl.cc file, I can't find it anywhere. It compiled fine and it's working, but how can I find a file in a project? I'd like to drag it into the GUI folder also, too keep things neat and tidy.
Thanks
David
Torque Owner Ryan Ackley
ryan