Game Development Community

CollisionGroups/Layers and Config Datablocks

by Julien Jassaud · in Torque Game Builder · 05/07/2009 (1:36 am) · 7 replies

Hi,

I am making a simple shooting game. My enemy ships can fire several kinds of projectiles which characteristics I define in Config Datablocks I dynamically assign with setConfigDatablock. Everything works quiet fine except for the CollisionGroups and CollisionLayers fields which are always set to zero whatever value I set them in the datablock. I tried two syntaxes :

datablock t2dSceneObjectDatablock(bulletBlueConfig) {
...
CollisionGroups				= 1 SPC 2 SPC 3 SPC 30;
...
};

or

datablock t2dSceneObjectDatablock(bulletBlueConfig) {
...
CollisionGroups				= "1 2 3 30";
...
};

Neither works. The work around was to call setCollisionGroups() and setCollisionLayers() after setConfigDatablock(). It works fine but I'd really like to know why I can't set those fields in the Config Datablock.

Thanks,
Julien

#1
05/16/2009 (7:36 pm)
Julien,

Did you ever find a resolution for this? I am having the dame issue.

Thanks,

Steve
#2
05/18/2009 (5:05 am)
Steve,

No. I didn't find anything, nor did I get any answer.Strange, because it looks like a pretty big problem to me.

Julien
#3
05/23/2009 (2:26 pm)
The reason for this is as follows:

The actual collision layer and collision group variables are stored as one single number, and each layer or group is represented by one bit. So the actual CollisionLayers variable will never contain something like "1 2 3".

Here's an example, using some binary calculations:

Say you want to turn on collisions with layers 1 and 2. Then you will have:
CollisionLayers = "6".
Why "6"? Well, it breaks down as follows:
Layer 0 = bit 1, so either 0 or 1 (0 = off, 1 = on)
Layer 1 = bit 2, so either 0 or 1, representing 0 or 2
Layer 2 = bit 3, so either 0 or 1, representing 0 or 4
Layer 3 = bit 4, so either 0 or 1, representing 0 or 8
Layer 4 = bit 5, so either 0 or 1, representing 0 or 16
etc. up to:
Layer 31 = bit 32, so either 0 or 1, representing a big number! :)

So to figure out what CollisionLayers will be equal to, you simply add up the values listed above for each layer you turned collisions on for:
So for the above example, for layers 1 and 2, you would add 2 + 4 = 6.

Does that make sense? It's often referred to as using bit flags, and it's a great way to save on space. It allows you to store 32 on/off values in one variable, instead of having 32 separate variables.

The simple way to look at it is by figuring out how binary values are stored, here's a great explanation: www.johnleenwuk.uklinux.net/southport/articles/motherboard/binary.htm

Now you can likely understand why the helper functions like setCollisionGroups() exist, to save you from calculating these values on your own.

In your situation though, an easy way to set things up in the datablocks (and the method I use), is to simply create a dummy t2dSceneObject in the level editor, and use the GUI to turn on/off all the collision groups/layers that you want, and then save the level, and take a peek inside the level file for that t2dSceneObject, and it will have "CollisionLayers = "2048"" or whatever value, and you can simply copy that to your datablock. This is how I create all my datablocks, instead of manually typing in all the fields.

Hope that made some sense, feel free to ask for clarification! :)

EDIT: by the way, in your example, for wanting collisions turned on with 1, 2, 3, and 30, it would be:
CollisionLayers = "1073741838";

:)
#4
05/23/2009 (9:06 pm)
Mark,

Thank you very much ! It all makes sense now ! I think I'll make myself a little ruby tool that will compute everything from an integer list.

Thanks again,
Julien
#5
05/24/2009 (12:36 pm)
Heh. Ruby scripts are a bit overkill ;)

Just use bit math. If you want to set the 1st and 4th layer, you could use this:
%layers = 1 + (1<<3);

Just shift the bits of the number 1 left (number of layer - 1) times to get the layer number.
#6
05/24/2009 (5:26 pm)
The alternative is the BIT function

%layer = BIT(1) + BIT(2) + BIT(9);
#7
05/24/2009 (11:02 pm)
Ronny, Marc,

Thanks for your answers. Neither solutions seems to work when used when declaring a datablock, though.

I was happy with my little ruby script, computing the mask values until this morning I moved some elements from a group to another. Now I have to re-compute everything from scratch. Shifting bits or the BIT() function would make for a much easier editable code, but I really can't seem to have them work inside datablocks...

Thanks