fxGuiSnooper
by Melv May · 03/04/2002 (10:03 am) · 39 comments
Download Code File
Ok, here it is.
Allows you to show the scene from any named objects' viewpoint. You can setup automatic sweeping (like a security camera) in all axis as well as put a bitmap/colour overlay for the finishing effect.
Before I get started I would just like to point out that this control will seriously affect your framerate as you are effectively rendering another view so you could see your framerate drop by half in some circumstances. Saying that, if you use it like a security camera / monitoring device then you can place it on a seperate GUI screen so that you maintain your FPS.
Add the file "fxGuiSnooper.cc" to your engine code, compile and you should have a new control named "fxGuiSnooper" in the controls list within the GUI editor.
The "camera.png" can be used as an example for the bitmap overlay (not a very good one I might add) but is not needed otherwise.
The properties explained are:-
(All angles are in degrees)
"ViewRotation" - Sets an initial rotation to the view.
"ViewOffset" - Sets an initial translation to the view.
"FOV" - Sets the Field-of-view. (Hmmm!)
"SweepAmplitude" - Sets the magnitude to which the view will automatically sweep. You can individually select each axis XYZ. The sweep will be centered around the initial rotation e.g 60 = (-30)->(+30).
"SweepTime" - Sets the time constants for the sweep to complete. Again, you can individually select the time for each axis. The time is in mS e.g. 1000mS = 1 Sec. Sweeping will continue for an infinite period.
"AttachedObject" - Sets the object to which the view will be attached. Essentially, the view will use the objects' position as a bsae for snooping. If you move the object, then the view should move with it. Try naming a tree or building as a test.
"OverlayBitmap" - Sets the bitmap which will be overlayed ontop of the view. This allows you to blend/obscure the view for screen effects such as interlacing/moire fringing etc.
"OverlayTile" - Sets the bitmap tile mode. When on, the bitmap will be tessellated over the view.
"OverlayColour" - Sets the overlay colour mode. When on, the overlay colour/mask settings are used to colourise the view so you can do green-screens etc. (See my fxGuiFilter control).
"BitmapOverlay" - Selects the bitmap filename to use for the overlay. Using "fps/client/ui/" is a good idea.
"ColourOverlay" - Selects the RGB colours used for the colourisation effect.
"Red/Green/BlueMask" - Selects the masking effect used for the colourisation effect. A tick indicates that that colour channel can be written to using the ColourOverlay.
------------------------------------------
[EDIT] - MY POST FROM FORUM REGARDING GETTING ONLY THE SNOOPER OBJECT RENDERING IN ANOTHER GUI VIEW TO STOP FPS REDUCTION.
------------------------------------------
Ok, here goes then ...
(So as there is no confusion at all I will give you a step by step guide)
- Run up the Demo App and start-up good ol' "Scorched Planet".
- Goto the Gui editor (F10) and create a new GUI by selected "New" (above "Save"). In the dialog enter "SnooperCam" as the GUI name and select "fxGuiSnooper" from the class list. OK.
- Edit the fxGuiSnooper object e.g. select a named world object like a pyramid or something (you may have to edit these in the world editor if you haven't already done so). Set the Z sweep time to something like 2000mS, apply and save the gui to "fps/client/ui".
- Goto the SCRIPT file "fps/client/init.cs" and insert the line 'exec("./ui/SnooperCamGui.gui");' in the "Load up the Game GUIs" block @ line 48.
- Select the "PlayGui" gui screen. Quit and restart.
Go into "Scorched Planet" again, drop down the console and type 'Canvas.setContent("SnooperCam");' to bring up your SnooperCam and 'Canvas.setContent("PlayGui");' to restore the 'normal' game screen.
Dependent on how your gui works you may want to modify this example.
Hope this helps someone, somewhere. :)
------------------------------------------
I hope you enjoy. If there is a better way of doing what I'm doing here then please let me know. I post this stuff in the hope that I might get helpful advice regarding the details of the engine.
Melv. 3/3/2002.
Ok, here it is.
Allows you to show the scene from any named objects' viewpoint. You can setup automatic sweeping (like a security camera) in all axis as well as put a bitmap/colour overlay for the finishing effect.
Before I get started I would just like to point out that this control will seriously affect your framerate as you are effectively rendering another view so you could see your framerate drop by half in some circumstances. Saying that, if you use it like a security camera / monitoring device then you can place it on a seperate GUI screen so that you maintain your FPS.
Add the file "fxGuiSnooper.cc" to your engine code, compile and you should have a new control named "fxGuiSnooper" in the controls list within the GUI editor.
The "camera.png" can be used as an example for the bitmap overlay (not a very good one I might add) but is not needed otherwise.
The properties explained are:-
(All angles are in degrees)
"ViewRotation" - Sets an initial rotation to the view.
"ViewOffset" - Sets an initial translation to the view.
"FOV" - Sets the Field-of-view. (Hmmm!)
"SweepAmplitude" - Sets the magnitude to which the view will automatically sweep. You can individually select each axis XYZ. The sweep will be centered around the initial rotation e.g 60 = (-30)->(+30).
"SweepTime" - Sets the time constants for the sweep to complete. Again, you can individually select the time for each axis. The time is in mS e.g. 1000mS = 1 Sec. Sweeping will continue for an infinite period.
"AttachedObject" - Sets the object to which the view will be attached. Essentially, the view will use the objects' position as a bsae for snooping. If you move the object, then the view should move with it. Try naming a tree or building as a test.
"OverlayBitmap" - Sets the bitmap which will be overlayed ontop of the view. This allows you to blend/obscure the view for screen effects such as interlacing/moire fringing etc.
"OverlayTile" - Sets the bitmap tile mode. When on, the bitmap will be tessellated over the view.
"OverlayColour" - Sets the overlay colour mode. When on, the overlay colour/mask settings are used to colourise the view so you can do green-screens etc. (See my fxGuiFilter control).
"BitmapOverlay" - Selects the bitmap filename to use for the overlay. Using "fps/client/ui/
"ColourOverlay" - Selects the RGB colours used for the colourisation effect.
"Red/Green/BlueMask" - Selects the masking effect used for the colourisation effect. A tick indicates that that colour channel can be written to using the ColourOverlay.
------------------------------------------
[EDIT] - MY POST FROM FORUM REGARDING GETTING ONLY THE SNOOPER OBJECT RENDERING IN ANOTHER GUI VIEW TO STOP FPS REDUCTION.
------------------------------------------
Ok, here goes then ...
(So as there is no confusion at all I will give you a step by step guide)
- Run up the Demo App and start-up good ol' "Scorched Planet".
- Goto the Gui editor (F10) and create a new GUI by selected "New" (above "Save"). In the dialog enter "SnooperCam" as the GUI name and select "fxGuiSnooper" from the class list. OK.
- Edit the fxGuiSnooper object e.g. select a named world object like a pyramid or something (you may have to edit these in the world editor if you haven't already done so). Set the Z sweep time to something like 2000mS, apply and save the gui to "fps/client/ui".
- Goto the SCRIPT file "fps/client/init.cs" and insert the line 'exec("./ui/SnooperCamGui.gui");' in the "Load up the Game GUIs" block @ line 48.
- Select the "PlayGui" gui screen. Quit and restart.
Go into "Scorched Planet" again, drop down the console and type 'Canvas.setContent("SnooperCam");' to bring up your SnooperCam and 'Canvas.setContent("PlayGui");' to restore the 'normal' game screen.
Dependent on how your gui works you may want to modify this example.
Hope this helps someone, somewhere. :)
------------------------------------------
I hope you enjoy. If there is a better way of doing what I'm doing here then please let me know. I post this stuff in the hope that I might get helpful advice regarding the details of the engine.
Melv. 3/3/2002.
About the author
#2
- Melv.
07/08/2002 (3:53 am)
Yeah I still get messages from this but unfortunately I've not got itme to look at it. If you buzz me in a week or two then I will definately sort it for you. 8)- Melv.
#3
10/03/2002 (4:22 am)
I have yet to install this but will be soon... was this problem fixed Melv?
#4
It doesn't deal with the clients correctly but will work on a local connection. The modification is fairly minor but I've not got my laptop at home tonight. I will put a sticky-note on my board to fix this tomorrow night.
- Melv.
10/03/2002 (8:55 am)
To be honest, I did this before I really understood the networking code.It doesn't deal with the clients correctly but will work on a local connection. The modification is fairly minor but I've not got my laptop at home tonight. I will put a sticky-note on my board to fix this tomorrow night.
- Melv.
#5
01/22/2003 (6:24 pm)
Melv, knowing you're pretty busy I hate to ask ;) Did you ever find a multi-player work around for this, seem like a awesome feature to add.
#6
02/12/2003 (9:44 pm)
Yes, if you get the time Melv, I too would be interested to learn how you would fix this. I've been looking at it, but i'm just too new at this to really have a clue what I'm doing let along dipping into the network code.
#7
im getting "object not selected" during runtime.
im new to gaming(torque)
06/13/2003 (3:37 pm)
not working for me.im getting "object not selected" during runtime.
im new to gaming(torque)
#8
10/01/2003 (3:39 am)
Is it possible to make this vieport to be main play scene view.So the player will be able to control it's movement through this view? Because it was impossible when I made 'Canvas.setContent("SnooperCam");' call .
#9
10/16/2003 (7:42 am)
what is that path for the file name that it asks for for the attached object? ive tried everything and nothing works. thanks
#10
thnks
12/04/2003 (9:51 pm)
Any body still using the thread I need someone to please aw the multi-player q'sthnks
#11
thanks !
03/02/2006 (1:03 pm)
I've followed the instruction but am getting the red screen with " Object not selected". Any help would be greatly appreciated. thanks !
#12
ThanKs in Advance
04/05/2006 (8:43 am)
Hey...I have followed the Instuctions. But whenever I try to Use that control..the it gives me some (Matrix F Inverse Error..) can U help me with It.ThanKs in Advance
#13
04/09/2006 (7:57 am)
@Danny-you should give a name to the object you want to attach the "camera" to, and enter the name in the appropriate field of the fxSnooper
#14
04/09/2006 (8:00 am)
Can I attach this camera to the player?
#15
In gameConnection.h under SimObjectPtr mControlObject add:
In fxguisnooper.cc, first include gameconnection.h. Then comment out the setViewObject() declaration and definition. At the beginning of onRender() and processCameraQuery() add this line:
Finally, make sure that in your script functions where you intend to set the snooper object, you do so with a call like:
I know I've left out a lot of the specifics, and I very well may have forgotten something, but this should be a good start. Let me know if you get stuck.
04/17/2006 (12:45 pm)
I believe I've fixed the multiplayer issues. I got my inspiration by looking at the gameTScontrol used to render the game normally. They use mControlObject in the client connection to determine where to render the world from. So I made it so that the fxguisnooper would do the same thing. Here's the gist of the code to accomplish that. In gameConnection.h under SimObjectPtr
SimObjectPtr<GameBase> mSnooperObject;Make sure to initialize it to NULL in the constructor. Then make your public accessors (ex. getSnooper and setSnooper) functions and expose them to the console via the ConsoleMethod macro. Hint: look at how this is done for mControlObject. You might also want to expose getLocalClientConnection() to the console as well. That should take care of gameconnection.h.
In fxguisnooper.cc, first include gameconnection.h. Then comment out the setViewObject() declaration and definition. At the beginning of onRender() and processCameraQuery() add this line:
mAttachedObject = GameConnection::getLocalClientConnection()->getSnooper();This makes it so that your view object will only be changed if you change your locally assigned snooper object.
Finally, make sure that in your script functions where you intend to set the snooper object, you do so with a call like:
%client.setSnooper(%newSnooperObj);If you exposed getLocalClientConnection() to script you can use that if you have no variable with the client.
I know I've left out a lot of the specifics, and I very well may have forgotten something, but this should be a good start. Let me know if you get stuck.
#16
Instead of getLocalClientConnection(), you need to use getServerConnection().
Where you set your object, instead of calling something like
05/03/2006 (11:04 am)
Well, I'd never tried the above from an actual client (wasn't aware how to run a client and a server on the same comp until recently). The above does not work :( I did get it to work, but not well enough for my own need. If you're needs are not extremely time sensitive, then here's what I did.Instead of getLocalClientConnection(), you need to use getServerConnection().
Where you set your object, instead of calling something like
%client.setSnooper(%objID);You need to make sure object is ghosted and do a commandToClient function, something like this:
//if the object is not already scoped %objID.scopeToClient(%client); %ghostObjID = %client.getGhostID(%objID); commandToClient(%client, 'setSnooper', %ghostObjID);And you need to have a ClientCmd that looks something like this:
function ClientCmdSetSnooper(%ghostID)
{
%client = getServerConnection();
%objID= %client.resolveGhostID(%ghostID);
%client.setSplatter(%ghostID);
}There are a couple more considerations. Most of my knowledge comes from this resource. As mentioned there, ghosting doesn't happen instantly, on my LAN connection it looks like it takes about 300ms for resolveGhostID() to actually return an ID. So you may need to schedule your commandToClient to occur at some point in the future. Like I say, this "works", but it didn't work sufficiently well for me to use it. When I figure out a better solution I'll post it here.
#17
Any suggestions.
07/17/2006 (3:58 am)
Has anyone gotten this to work for non-static objects. It seems to only work with static objects and not RTS units.Any suggestions.
#18
07/17/2006 (9:16 am)
If you can accept a delay of .5-1.5 seconds before the camera attaches to your unit then the changes I made above will work. Also, look in the function that sets the view obect and make sure it's not filtering out any masks that you want to be able to attach to. I vaguely recall that I might have had to remove a few type masks to accomplish that.
#19
open: ...\engine\gui\fxGuiSnooper.cc
replace line 45:
original: void setViewObject(const char* ObjectName);
new: void setViewObject(const char* ObjectId);
replace line 158 to 194 (setViewObject()):
original:
void fxGuiSnooper::setViewObject(const char* ObjectName)
{
// Get Root Group.
SimGroup* SG = Sim::getRootGroup();
// Interate Sim Group.
for (SimSetIterator itr(SG); *itr; ++itr)
{
// Is this our Type?
if ((*itr)->getType())// & STATIC_COLLISION_MASK)
{
// Yes, so cast our Object.
SceneObject* SceneObj = static_cast(*itr);
// Check that it's a Server Object.
if (SceneObj->isServerObject())
{
const char* getName;
getName = SceneObj->getName();
// Yes, so is this our Object?
if (getName && dStrcmp(getName, ObjectName) == 0)
{
// Store Scene Object.
mAttachedObject = SceneObj;
// Return OK.
return;
}
}
}
}
// Reset Object.
mAttachedObject = NULL;
}
new:
void fxGuiSnooper::setViewObject(const char* ObjectId)
{
// Var for the unit the camera will be attached to
SimObject* unit = NULL;
// Use Id to find it and assign it
unit = Sim::findObject(ObjectId);
if(unit){
mAttachedObject = static_cast(unit);
}
else{
// Reset Object.
mAttachedObject = NULL;
}
}
Works fast and great!
07/28/2006 (5:22 pm)
Here is a simple way to use the id of any object instead of just static:open: ...\engine\gui\fxGuiSnooper.cc
replace line 45:
original: void setViewObject(const char* ObjectName);
new: void setViewObject(const char* ObjectId);
replace line 158 to 194 (setViewObject()):
original:
void fxGuiSnooper::setViewObject(const char* ObjectName)
{
// Get Root Group.
SimGroup* SG = Sim::getRootGroup();
// Interate Sim Group.
for (SimSetIterator itr(SG); *itr; ++itr)
{
// Is this our Type?
if ((*itr)->getType())// & STATIC_COLLISION_MASK)
{
// Yes, so cast our Object.
SceneObject* SceneObj = static_cast
// Check that it's a Server Object.
if (SceneObj->isServerObject())
{
const char* getName;
getName = SceneObj->getName();
// Yes, so is this our Object?
if (getName && dStrcmp(getName, ObjectName) == 0)
{
// Store Scene Object.
mAttachedObject = SceneObj;
// Return OK.
return;
}
}
}
}
// Reset Object.
mAttachedObject = NULL;
}
new:
void fxGuiSnooper::setViewObject(const char* ObjectId)
{
// Var for the unit the camera will be attached to
SimObject* unit = NULL;
// Use Id to find it and assign it
unit = Sim::findObject(ObjectId);
if(unit){
mAttachedObject = static_cast
}
else{
// Reset Object.
mAttachedObject = NULL;
}
}
Works fast and great!
#20
10/09/2006 (7:36 am)
the camera only point to one direction only, or did i miss something. I need it to work like normal camera 
Associate Stefan Beffy Moises
if (SceneObj->isServerObject())
...
out to see if that's the problem, but that didn't change anything... And it works fine in singleplayer... (and for the host in MP)
And I think I toggle it as all the other GUIs, too... (but those don't attach to server objects directly I think...)
maybe it's a problem that the script lies on the client side (/client/ui/mapGui.gui) and therefore can't access the server objects?
Or maybe you can only attach ONE snooper to each object?
Do you have an idea what might be wrong?
Thanks a lot!
(but please don't let you stop from finishing the water improvements by this little prob, hehe... ;-))