Arguments and data types
by Daniel McNeese · in Torque Game Builder · 07/04/2007 (10:26 am) · 5 replies
After searching the docs to find a function that will let me detect objects within a given area I came across the pickRect function: http://tdn.garagegames.com/wiki/TGB/Reference:_t2dSceneGraph
This seems to be what I need, but some of the documentation makes little sense. In particular, the data types for some of the argument fields. %layermask only needs a single Bool to determine which of 32 layers to check? %groupmask requires a "Mask," which isn't even a data type?
Anyway, after giving it some thought I think I understand what to do, but I want to double-check this. For %layermask, %groupmask and %excludeObjects I need to give lists of the data type, correct? So if I want to, say, check only layer 0 while not excluding anything based on %groupmask or %excludeObject, I would:
1) Pass a list of 32 Bools to %layermask, with only the first Bool being true.
2) Pass empty lists for both %groupmask and %excludeObject.
Is this correct?
This seems to be what I need, but some of the documentation makes little sense. In particular, the data types for some of the argument fields. %layermask only needs a single Bool to determine which of 32 layers to check? %groupmask requires a "Mask," which isn't even a data type?
Anyway, after giving it some thought I think I understand what to do, but I want to double-check this. For %layermask, %groupmask and %excludeObjects I need to give lists of the data type, correct? So if I want to, say, check only layer 0 while not excluding anything based on %groupmask or %excludeObject, I would:
1) Pass a list of 32 Bools to %layermask, with only the first Bool being true.
2) Pass empty lists for both %groupmask and %excludeObject.
Is this correct?
About the author
#2
in short ... you would pass an int to both groupmask and layermask according to the engine source, so the reference to 'bool' is just a typo in the docs ... (shame on you Matt :P)
Thats from the pickRect C++ method ... so it converts the argument passed for the group and layer masks to an int using dAtoi() ... for layermask, it adds one to the value, not sure why ... but this should solve the question of what to pass ...
using the addBitToMask functions you can create a mask ...
Now, pretty sure those are the two functions, haha ... still early in the morning and I closed the doc reference page, :)
Anyhow ... you'd want to pass a mask to the pickRect ... you could pass MASK_ALL which is defined as a constant in TorqueScript to map back to T2D_MASK_ALL which is basically a mask that has everything turned on ... which is also the default value if you don't pass the parameter in at all.
07/04/2007 (11:50 am)
Ok - after checking the source to the engine, T2D_MASK_ALL is the only defined constant for possible values, which I believe simply means that a groupmask and layermask are an int, and all 32 bits in the int are the possible layers and groups ... so they are either on or off ...in short ... you would pass an int to both groupmask and layermask according to the engine source, so the reference to 'bool' is just a typo in the docs ... (shame on you Matt :P)
// Calculate Group Mask.
U32 groupMask = T2D_MASK_ALL;
if (argc > firstArg)
groupMask = dAtoi(argv[firstArg]);
// Calculate Group Mask.
U32 layerMask = T2D_MASK_ALL;
if (argc > (firstArg + 1))
layerMask = dAtoi(argv[firstArg + 1]);Thats from the pickRect C++ method ... so it converts the argument passed for the group and layer masks to an int using dAtoi() ... for layermask, it adds one to the value, not sure why ... but this should solve the question of what to pass ...
using the addBitToMask functions you can create a mask ...
%mask = 0; // nothing in this mask addBitToMask(%mask, 4); // 4th bit turned on removeBitFromMask(%mask, 4); // 4th bit turned off
Now, pretty sure those are the two functions, haha ... still early in the morning and I closed the doc reference page, :)
Anyhow ... you'd want to pass a mask to the pickRect ... you could pass MASK_ALL which is defined as a constant in TorqueScript to map back to T2D_MASK_ALL which is basically a mask that has everything turned on ... which is also the default value if you don't pass the parameter in at all.
#3
Anyway, can you give me a couple of concrete examples to help get me started?
1) What would be the command to have pickRect search for anything in a particular layer?
2) What would be the command to have pickRect search all layers for objects of the class "encounter"?
EDIT: Whoops, you posted while I was still typing. I may be able to figure it out myself now based on all that. Thanks.
07/04/2007 (11:54 am)
Argh. When 1.5 comes out, somebody really needs to put some time into making the docs more user-friendly. The community support here is great, but I didn't have to turn to community support anywhere near this frequently with Game Maker.Anyway, can you give me a couple of concrete examples to help get me started?
1) What would be the command to have pickRect search for anything in a particular layer?
2) What would be the command to have pickRect search all layers for objects of the class "encounter"?
EDIT: Whoops, you posted while I was still typing. I may be able to figure it out myself now based on all that. Thanks.
#4
As for getting a list of objects in a layer, you'd create a mask for that layer ... say layer 5, might look like this;
Then you'd pass %layer5 to the pickRect ... you could optionally just pass the value 16 ... as 16 is the value of the 5th bit only ...
1 2 4 8 16 32 64 128 256 512 1024 ....
Your bits are all equal to this ... the first layer is 1, second layer is 2, third layer is 4,
fourth layer is 8 ...
So if you wanted layers 5 and 1 ... you'd pass 17 ... cause thats "1 + 16" ... now, you need to have an understanding of bits and how they work to just pass static values such as 1 and 16 ... otherwise, you could use the helper functions addBitToMask and removeBitFromMask ...
Now, keep in mind, I've not yet had a use for any of these things, so I've not tried any of it ... this is all practical theory for me, hehe ... if I were to attempt what your doing, I'd go about it the way I'm approaching it now ... and I might find a caveat here or there and correct the logic along the way ...
To best understand what exactly is going on, you can look at the pickRect method in t2dSceneGraph.cc and follow it's trail ...
Basically, a 10 second overview is ...
ConsoleMethod(pickRect) -- converts all the TorqueScript parameters to equivalent C++ values and then calls the pickRect method that takes these parameters, t2dSceneGraph::pickRect.
t2dSceneGraph::pickRect then does some extra stuff that can, for the most part, be ignored, and then loops through all the objects in the scenegraph and compares them to the passed values, if they match, it adds them to a stack and returns the size of the stack ... which returns execution back to the consolemethod, which converts the stack into a TorqueScript list of Object ID's ...
t2dSceneGraph::pickRect effectively searches like so;
So ... basically, it just looks to see if there's a collision with the object it's currently looking at and the rectangular area you asked for ... so it's a fairly intense function to call, especially if you have a ton of objects in your scenegraph ...
t2dSceneGraph::pickRect also calls t2dSceneGraph::pickArea to grab all objects within the given area ... which is what it uses to search for all the objects in the rectangle ... this is done at the very top of the pickRect C++ method ... the above loop code is looping through the result of pickArea
pickArea has a ton of code that is executed, which trails through quite a bit of stuff ... I would suggest that, for a complete understanding of it all, you traverse through this code and see what all is being done ...
But to understand that %groupmask and %layermask are just ints, you need only look at the ConsoleMethod definition to determine that ...
So ... in short ... the above %layer5 example is how you'd find all objects in the rectangle on layer 5 (according to my -brief- traversal through the code) ... however, to find all "encounter" objects you'd have to get a list of all objects in all layers (unless encounter was always on a specific layer .. in which case, to reduce code strain, I'd pass that layer in with the mask) ... then you'd have to compare the object's class to "encounter" and decide on your own (in your TorqueScript) whether it qualifies or not.
07/04/2007 (12:10 pm)
Well, I don't believe "pickRect" has the ability to search for all objects of class "encounter" ... so you'd have to basically get a list of objects back from pickRect, then check there class yourself ...As for getting a list of objects in a layer, you'd create a mask for that layer ... say layer 5, might look like this;
%layer5 = 0; addBitToMask(%layer5, 5);
Then you'd pass %layer5 to the pickRect ... you could optionally just pass the value 16 ... as 16 is the value of the 5th bit only ...
1 2 4 8 16 32 64 128 256 512 1024 ....
Your bits are all equal to this ... the first layer is 1, second layer is 2, third layer is 4,
fourth layer is 8 ...
So if you wanted layers 5 and 1 ... you'd pass 17 ... cause thats "1 + 16" ... now, you need to have an understanding of bits and how they work to just pass static values such as 1 and 16 ... otherwise, you could use the helper functions addBitToMask and removeBitFromMask ...
Now, keep in mind, I've not yet had a use for any of these things, so I've not tried any of it ... this is all practical theory for me, hehe ... if I were to attempt what your doing, I'd go about it the way I'm approaching it now ... and I might find a caveat here or there and correct the logic along the way ...
To best understand what exactly is going on, you can look at the pickRect method in t2dSceneGraph.cc and follow it's trail ...
Basically, a 10 second overview is ...
ConsoleMethod(pickRect) -- converts all the TorqueScript parameters to equivalent C++ values and then calls the pickRect method that takes these parameters, t2dSceneGraph::pickRect.
t2dSceneGraph::pickRect then does some extra stuff that can, for the most part, be ignored, and then loops through all the objects in the scenegraph and compares them to the passed values, if they match, it adds them to a stack and returns the size of the stack ... which returns execution back to the consolemethod, which converts the stack into a TorqueScript list of Object ID's ...
t2dSceneGraph::pickRect effectively searches like so;
for(layer = 0; layer < maxSupportedLayers; layer++)
{
foreach(object in layer)
{
if(object in rect) return true;
}
}So ... basically, it just looks to see if there's a collision with the object it's currently looking at and the rectangular area you asked for ... so it's a fairly intense function to call, especially if you have a ton of objects in your scenegraph ...
t2dSceneGraph::pickRect also calls t2dSceneGraph::pickArea to grab all objects within the given area ... which is what it uses to search for all the objects in the rectangle ... this is done at the very top of the pickRect C++ method ... the above loop code is looping through the result of pickArea
pickArea has a ton of code that is executed, which trails through quite a bit of stuff ... I would suggest that, for a complete understanding of it all, you traverse through this code and see what all is being done ...
But to understand that %groupmask and %layermask are just ints, you need only look at the ConsoleMethod definition to determine that ...
So ... in short ... the above %layer5 example is how you'd find all objects in the rectangle on layer 5 (according to my -brief- traversal through the code) ... however, to find all "encounter" objects you'd have to get a list of all objects in all layers (unless encounter was always on a specific layer .. in which case, to reduce code strain, I'd pass that layer in with the mask) ... then you'd have to compare the object's class to "encounter" and decide on your own (in your TorqueScript) whether it qualifies or not.
#5
As for that comment, the docs for TGB are quite extensive and very nice ... your having trouble with one of the more complex areas and the solution to it is really at your fingertips (the C++ source) ... Game Maker does not provide the source to there engine, so the only thing you have is the docs ... TGB provides both a full set of docs for all the relevant things and ... when things are a bit less relevant you have the C++ source ...
With the source, who really needs the docs? Ok ... thats a horrible statement, cause without the docs in TGB I wouldn't be here ... haha ... but seriously, the docs are very well done and more then enough to get you started ... one your going, you have to get your hands dirty to keep going though ...
With Game Maker, which is a bad thing to compare to TGB by the way, you are extremely limited in what you have access too ... this being the docs only ... and, I'm sure that Game Maker has a few typo's in it's docs as well ... and if not, I'm impressed ... but TGB's docs are constantly being updated and modified ... and the docs for 1.5 are about 5x's the size of the docs for 1.1.3 ... largely because of the new doc system ... does this mean there better? possibly ... does it mean theres more info ... yep ... which means the docs are even more confusing ... ;)
07/04/2007 (12:14 pm)
Quote:
Argh. When 1.5 comes out, somebody really needs to put some time into making the docs more user-friendly. The community support here is great, but I didn't have to turn to community support anywhere near this frequently with Game Maker.
As for that comment, the docs for TGB are quite extensive and very nice ... your having trouble with one of the more complex areas and the solution to it is really at your fingertips (the C++ source) ... Game Maker does not provide the source to there engine, so the only thing you have is the docs ... TGB provides both a full set of docs for all the relevant things and ... when things are a bit less relevant you have the C++ source ...
With the source, who really needs the docs? Ok ... thats a horrible statement, cause without the docs in TGB I wouldn't be here ... haha ... but seriously, the docs are very well done and more then enough to get you started ... one your going, you have to get your hands dirty to keep going though ...
With Game Maker, which is a bad thing to compare to TGB by the way, you are extremely limited in what you have access too ... this being the docs only ... and, I'm sure that Game Maker has a few typo's in it's docs as well ... and if not, I'm impressed ... but TGB's docs are constantly being updated and modified ... and the docs for 1.5 are about 5x's the size of the docs for 1.1.3 ... largely because of the new doc system ... does this mean there better? possibly ... does it mean theres more info ... yep ... which means the docs are even more confusing ... ;)
Associate David Higgins
DPHCoders.com
From the documentation ... MASK_ALL is one of the possible values you can pass as a groupmask or layermask value, using the & and | bit-wise operators to put them together. .. I failed to find a quick lookup for all the possible MASK_* values ... but basically, you'd pass a series of mask's in with & or | ...
The layermasks and groupmasks are probably one of the less documented aspects of TGB ... unfortunately.