Game Development Community

OffsetNonConst in 1.5.2

by Daniel Buckmaster · in Torque Game Engine · 07/24/2011 (11:41 pm) · 6 replies

I'm trying to doa nifty trick using the MaterialPropertyMap's material types to define decals and particles for a ProjectileData block. I want to be able to do this in script:
//
	hitPuffEmitter[Hard] = SparkEmitter;
	hitPuffEmitter[Soft] = PuffEmitter;
	hitPuffEmitter[Snow] = SnowEmitter;
And have the entries map to the right entry in the ProjectileData::hitPuffEmitter array. To do this, I've written this in ProjectileData::initPersistFields:
//
	char field[128];
	for(U32 i = 0; i < NumDecals; i++)
	{
		dSprintf(field, 128, "hitPuffEmitter[%s]", MaterialPropertyMap::getTypeNameFromIndex(i));
		addField(field, TypeParticleEmitterDataPtr, OffsetNonConst(hitPuffEmitter[i], ProjectileData));
	}
The static function called just gets the ith material type as a string.

The problem is, after doing this, all the entries for hitPuffEmitter[Thing] map to hitPuffEmitter[0], as if I'm using a constant offset. Is the OffsetNonConst macro broken in 1.5.2? I notice it's not being actually used anywhere.

About the author

Studying mechatronic engineering and computer science at the University of Sydney. Game development is probably my most time-consuming hobby!


#1
07/25/2011 (4:40 am)
That does not read right to me. Are you using the material property mapping solely for the puff emitters? If not, are you certain the puff emitters are always going to be the first entries, up to whatever you have set NumDecals to, in the map entry list?
#2
07/25/2011 (6:17 am)
Sorry, I should have been clearer with my custom code ;P. NumDecals is a holdover from when Projectile specified the value itself; it is now initialised to the size of the MPM's types list. Materials also cover hit decals. I do it this way because I'd like to be able to change the material types enum without having to search all over the code and replace/rename entries.

The basic way it works is-

MaterialPropertyMap has an enum of material types. This is matched by an EnumTable which converts these values to strings; MaterialPropertyMap::getTypeNameFromIndex gets the string rep of a type based on its index value in the enum. The last entry in the enum is NUMTYPES, just for convenience.

ProjectileData sets its NumDecals to MaterialPropertyMap::NUMTYPES. Both the decal array and hit puff array are initialised to this size, and NumDecals is used in all iterations and stuff (I might go through and change this, for clarity if nothing else).

The code above maps hitPuffEmitter[name] to the entry in the hitPuffEmitter array which corresponds to the index of 'name' in the material types array.

It's a little convoluted, but I suspect I'll be changing up the material types array a bit while I'm developing - and apart from anything else I'd just like to make it an easily-extendable system. I also want to extend this same system to other uses of the MPM - such as player footsteps (so, in a datablock, you'd be setting footstepSound[Hard] = ... instead of the current big array of sounds).

(And cheers for the speedy reply!)
#3
07/25/2011 (10:51 am)
Looking at the code, Offset() and OffsetNonConst() both point to the same define, _Offset_Normal(), (or at least for non-gcc) so I'm not sure how they are meant to act differently. However, comparing the code between the three engines (TGE, TGEA and T3D) the latter two have the same slightly different code than TGE for _Offset_Normal() so you may want to look at that.
#4
07/25/2011 (4:17 pm)
I saw that - it looks like OffsetNonConst points to a different macro in other build environments though (_Offset_Variant_1), but changing to that didn't seem to help.

I'm actually having a go at writing my own variant of Offset... we'll see how that turns out.

Reference.

Also, I should note that neither TGEA nor T3D actually use their OffsetNonConst macros. Maybe the whole thing is depreciated :P.

More reference. So it's possible to get into arrays - or should be. But those indices were constants.

EDIT: I'm going through and trying to understand how it works at the moment to use addField with an enum. Or even with an array.
#5
07/28/2011 (7:00 am)
So that turned out to be unproductive. I've decided instead to use arrays in the normal sense, but expose named variables to the console. So the datablock now looks like:
//
   hitPuffEmitter[$Material::Snow] = ...;
   hitPuffEmitter[$Material::Crunchy] = ...;
Still, OffsetNonConst is conceptually way better, if it would only work.
#6
07/28/2011 (9:39 am)
I just ran a test and I did manage to get OffsetNC to work... In my engine which is a branch off of Torque 1.3... on Linux. So that probably doesn't help much in and of itself. :P

What I did discover though is that the array bracket syntax (hitPuffEmitter[%s]) will NOT work. If you use hitPuffEmitter[%s] you will see hitPuffEmitter[whatever] in a dump() of the object, but you cannot access it since Torque will attempt to resolve "whatever" to a number and fail before it ever tries to match it to an existing field name. However, you CAN use "hitPuffEmitter_%s". That works fine. At least for me it did.