Trying to add bounding box toggle to player
by Danner Jones · in Torque Game Engine · 09/02/2006 (12:50 am) · 6 replies
I'm trying to add the ability to toggle drawing the player's bounding box on the fly. I'd like to learn how to add this flag to the engine but I'm having some troubles.
I've added the variable mShowBoundingBox as a bool to Player.h, in a public section (for now).
In Player.cc, in the constructor, I set the value to false initially.
In Player.cc, in renderImage, I've changed my "if" to check the value of mShowBoundingBox.
Also in Player.cc, I've added the following:
There's probably a better way to add this variable, through Con::addVariable or similar, but I can't even get my ConsoleMethod to work.
If I default the value of mShowBoundingBox to true in the ctor then the bounding box draws perfectly.
I'm trying to now call the console method "showBoundingBox" on the player object. My attempt is this:
I'm modifying starter.fps\server\scripts\game.cs, in method GameConnection::createPlayer.
Just after %player is created, I use the following to see its value:
I only use error so it shows up easier.
In my computer, this value is 1491. I then try typing this in the console:
When running in debug mode (MS VC++), I can break into the ConsoleMethod call and see the value updated to true. However, it appears as though the "object" used to set mShowBoundingBox is not the same as the player. At least they're showing different memory addresses in the debugger ("object" shows 0x0736c430 within the console method, setting a breakpoint inside of renderImage shows a different value for "this").
Any ideas on where I can start looking? I'm really trying to learn here, so please don't say I should be using Con::addVariable unless there's just something inately wrong with using ConsoleMethod. If you're kind and have the time, helping me find my errors and providing a better solution would be MUCH appreciated.
Thanks,
ner
I've added the variable mShowBoundingBox as a bool to Player.h, in a public section (for now).
In Player.cc, in the constructor, I set the value to false initially.
In Player.cc, in renderImage, I've changed my "if" to check the value of mShowBoundingBox.
Also in Player.cc, I've added the following:
ConsoleMethod( Player, showBoundingBox, void, 3, 3, "(true or false)")
{
object->mShowBoundingBox = dAtob(argv[2]);
}There's probably a better way to add this variable, through Con::addVariable or similar, but I can't even get my ConsoleMethod to work.
If I default the value of mShowBoundingBox to true in the ctor then the bounding box draws perfectly.
I'm trying to now call the console method "showBoundingBox" on the player object. My attempt is this:
I'm modifying starter.fps\server\scripts\game.cs, in method GameConnection::createPlayer.
Just after %player is created, I use the following to see its value:
error("Player2 = " @ %player);I only use error so it shows up easier.
In my computer, this value is 1491. I then try typing this in the console:
1491.showBoundingBox(1);
When running in debug mode (MS VC++), I can break into the ConsoleMethod call and see the value updated to true. However, it appears as though the "object" used to set mShowBoundingBox is not the same as the player. At least they're showing different memory addresses in the debugger ("object" shows 0x0736c430 within the console method, setting a breakpoint inside of renderImage shows a different value for "this").
Any ideas on where I can start looking? I'm really trying to learn here, so please don't say I should be using Con::addVariable unless there's just something inately wrong with using ConsoleMethod. If you're kind and have the time, helping me find my errors and providing a better solution would be MUCH appreciated.
Thanks,
ner
#2
09/02/2006 (1:16 am)
Just run the above function on the client instead of the server. No need to send flags.
#3
@Stefan: How would I "run the function" on the client? Is there another kind of macro like ConsoleMethod?
I forgot to mention that I originally had code in packUpdate and unpackUpdate to read/write the flag but it didn't seem to do anything. I only put code there because a resource, similar to what I wanted, was using that. I'm getting a better understanding of why but I'm still not clear on the how. :)
Thanks,
ner
09/03/2006 (7:39 am)
It looks like the ConsoleMethod is called on the server while Player::renderImage is called on the client. I verified by calling isClientObject in renderImage and got back true.@Stefan: How would I "run the function" on the client? Is there another kind of macro like ConsoleMethod?
I forgot to mention that I originally had code in packUpdate and unpackUpdate to read/write the flag but it didn't seem to do anything. I only put code there because a resource, similar to what I wanted, was using that. I'm getting a better understanding of why but I'm still not clear on the how. :)
Thanks,
ner
#4
I did not hear back from Stefan on how to set a value on the client directly. Maybe I'll ask again some day.
-ner
09/04/2006 (8:01 am)
This has been resolved. My placement of the code in packUpdate/unpackUpdate was just below a line of code that said, more or less, "nothing past this point is sent to the client". I should have checked the code a little closer.I did not hear back from Stefan on how to set a value on the client directly. Maybe I'll ask again some day.
-ner
#5
First off I want to say that your
You are telling the server that you want to render boundingBoxes. This is bad design. The server has nothing to do with rendering and it is not efficent to send stuff like this across the network and tax your connection with unneeded data. The server never runs renderObject() so it couldnt care less if mShowBoundingBox is enabled or not.
I would add the mShowBoundingBox boolean to shapeBase.h.
Head into shapeBase.cpp at ShapeBase::renderObject(). There is a snippit of code in there that renders the boundingBox. Just add an if statement that checks if mShowBoundingBox is true and you got it!
So how do you trigger it? Just run your function as you did before but on the client. If what you did previously was typing it into the console, then *that* is on the client.
Hope it helps!
09/04/2006 (9:20 am)
Chill :) It has been only one day since!First off I want to say that your
You are telling the server that you want to render boundingBoxes. This is bad design. The server has nothing to do with rendering and it is not efficent to send stuff like this across the network and tax your connection with unneeded data. The server never runs renderObject() so it couldnt care less if mShowBoundingBox is enabled or not.
I would add the mShowBoundingBox boolean to shapeBase.h.
Head into shapeBase.cpp at ShapeBase::renderObject(). There is a snippit of code in there that renders the boundingBox. Just add an if statement that checks if mShowBoundingBox is true and you got it!
So how do you trigger it? Just run your function as you did before but on the client. If what you did previously was typing it into the console, then *that* is on the client.
1491.showBoundingBox ( true );
Hope it helps!
#6
Unfortunately, I'm still not sure how to trigger it just on the client. Your suggestion says that by typing in something in the console it is on the client. I understand that, but I'm not sure how I get the engine code to know that the method call, showBoundingBox, is to be handled by the client. Meaning, I expose that method through the ConsoleMethod macro which appears to be handled by the "server" (all my testing is currently on one machine). It makes sense that the server would have to pass that to the client through the pack/unpackUpdate. It makes sense that I should not be calling showBoundingBox on the server, but on the client - but I don't know how.
Is there a special macro that exposes engine code to the console that affects the client objects? As I understand it, the handle I've printed (1491 in my case above) is valid for both the server and client since this is a ghosted object. I just don't know how to call into the engine as the client.
...
I didn't want to add the code to ShapeBase since I need to draw the bounding box on the player. I'm playing around with new physics for the player which includes new bounding boxes - similar to the hitbox resource that adds bounding boxes per limb. Since this is just test code, I didn't mind encumbering the server with some extra packets that are really just client-side information.
Thanks,
-ner
09/04/2006 (10:36 am)
I'm chilled out - didn't mean to sound short with you. I got things "working" for my tests and didn't want to encumber you with more questions at the moment - I know you're busy working on your own games.Unfortunately, I'm still not sure how to trigger it just on the client. Your suggestion says that by typing in something in the console it is on the client. I understand that, but I'm not sure how I get the engine code to know that the method call, showBoundingBox, is to be handled by the client. Meaning, I expose that method through the ConsoleMethod macro which appears to be handled by the "server" (all my testing is currently on one machine). It makes sense that the server would have to pass that to the client through the pack/unpackUpdate. It makes sense that I should not be calling showBoundingBox on the server, but on the client - but I don't know how.
Is there a special macro that exposes engine code to the console that affects the client objects? As I understand it, the handle I've printed (1491 in my case above) is valid for both the server and client since this is a ghosted object. I just don't know how to call into the engine as the client.
...
I didn't want to add the code to ShapeBase since I need to draw the bounding box on the player. I'm playing around with new physics for the player which includes new bounding boxes - similar to the hitbox resource that adds bounding boxes per limb. Since this is just test code, I didn't mind encumbering the server with some extra packets that are really just client-side information.
Thanks,
-ner
Torque 3D Owner Peter Simard
Default Studio Name
The resolution to this is to transfer the value of the variable to the ghost (client) version. Take a look into the packUpdate and unpackUpdate methods. You need to add a writeFlag and readFlag to those methods to transfer the value to the ghosted player since it is the ghost that is actually rendered.