IDTA structure...

For all coding issues - MODers and programmers, HTML and more.

Moderators: Jeff250, fliptw

Post Reply
User avatar
Sirius
DBB Master
DBB Master
Posts: 5616
Joined: Fri May 28, 1999 2:01 am
Location: Bellevue, WA
Contact:

IDTA structure...

Post by Sirius »

Working on a program to deal with polymodels probably in various forms using Java (well, it does seem to be fast for development, even if less efficient than it could be), but there are some things I don't quite 'get' about the polymodel structure D2 uses, even with reference to all the material I've been able to find so far. Might be wishful thinking, but perhaps if I'm lucky there are people out there that know the details...

Okay, firstly, the EOF blocks. What they do is fairly obvious - end a block of some kind or other. But I'm not quite sure what the pattern is; it isn't completely obvious. So far all I've figured out is one after every SORTNORM block and two after every chunk (collection of polygons)... however, I don't know why the two, and I also don't know whether the polymodel dump I'm looking at is representative of most of them. (It -does- only have one submodel...)

I could probably work out the details by examining more polymodels (or even the D2 source if I got desperate, I guess), but if someone else around here has already done the work, that would make things rather a lot easier.

Second thing is, all the pointers in the polymodel. Some of them I've worked out (I hope, or the tool I released a few months ago will produce a lot of non-working garbage), but some kind of confirmation would be nice. :)

Third thing, which may be the second... what on earth do zFront/zBack actually do (SORTNORM block)? I realise they correspond to halves of a BSP tree, but what are the numbers - more pointers? And if so, what do they point to - the start of the block (perhaps delimited by EOF blocks) that the SORTNORM splits off?
User avatar
Ferno
DBB Commie Anarchist Thug
DBB Commie Anarchist Thug
Posts: 15164
Joined: Fri Nov 20, 1998 3:01 am

Post by Ferno »

This is more of a coder's corner topic than an oldskool one.
User avatar
Sirius
DBB Master
DBB Master
Posts: 5616
Joined: Fri May 28, 1999 2:01 am
Location: Bellevue, WA
Contact:

Post by Sirius »

No worries (although I needed to do a search to find it, but hey).
User avatar
Sirius
DBB Master
DBB Master
Posts: 5616
Joined: Fri May 28, 1999 2:01 am
Location: Bellevue, WA
Contact:

Post by Sirius »

I found it slightly disturbing that the Descent source code made the whole deal much easier to understand than any other tools I looked at - but I suppose considering the data format was probably optimised (quite well thank you very much) toward reading, as opposed to making it easy to write to, that is expectable.

But, for the few people that want to know anything more about D1/2 polymodels (I realise these are an increasingly rare breed these days), a summary of my findings above and beyond what the Descent Network information will tell you:

How D1/2 process polymodels

Basically, the block data in Descent polymodels are not just sensibly-organised data; it seems quite odd when you look at it that way. It is more closely akin to a very basic scripting language, where each block gives instructions to the renderer, such as draw this or that first, jump to this position in the model data, generate a polygon, or stop reading.

One other important fact is that the renderer is recursive, which explains a lot of the features that seem really odd otherwise.

Block data: EOF
A very simple block, but also quite intriguing because of the patterns it usually turns up in; often there is not just one EOF at a point but several. Took me a while to figure out just how many you needed at each point and what aspect of the structure they are terminating.

Well, it's really quite simple - the EOF block tells the model processor to stop, that's all. And no, this doesn't mean the model stops at the first EOF, since as I said the data processor is recursive; it just means you've reached the end of the current 'node' - but many may be open at once.

Block data: DEFPOINTS
We know that this is rarely ever used, but not why it exists at all, it seems.
Easy explanation is that it's redundant, and superceded. A quick examination of Mike Menefee's IDTA specs will show you that the formerPts field is missing compared to DEFP_START; the reason this matters is that formerPts tells you what points aren't in the current submodel. Thus DEFPOINTS can only safely be used for the root submodel of the model, and it isn't really needed for that. Hence why no-one uses it.

Block data: SORTNORM
I was (obviously) having trouble with this one also, but it turns out to be probably THE most important block in the model, because it controls the rendering sequence. The point and normal data are used to define the plane as per linear algebra. n_Points is always zero, because planes don't have them; I'm personally not sure why they even bothered to put the field there because the Descent code just ignores it.

zFront and zBack are the fun bit. They are offsets from the start of the current block to wherever the renderer should jump next to process the rest of the model; far from being useless they are actually crucial...

Essentially, the renderer determines what side of the plane the viewer is on, and draws either zFront or zBack first to suit. Then it proceeds with the other, before going onward from the current point in the polymodel. (It can actually do this oddly enough; although no modelling programs that I've seen will let you, there are robots in Descent 2 with polygon data after a SORTNORM. I don't know why they did this, since all it does is to guarantee those polygons are drawn last, no matter which side of the splitting plane they are on; I may be able to figure it out once I get around to checking which polygons received that treatment.)

I should note that I've never seen a negative offset given for either zFront and zBack; while this doesn't guarantee it wouldn't work - I suspect it would - there is no actual reason to do that, as you can always put child data later on unless you have loops in the polymodel, which is obviously a bad idea.

But it looks like you CAN do it. It's just quite stupid and will eventually cause an out of memory crash or something along those lines.

Block data: RODBM
This block draws a bitmap that is always facing you. It is not a conventional polygon, since it only has two points to anchor the top and bottom of the sprite (hence 'rod'); it also has values to change how thick it is at either end.

Would it have any actual use? I don't know. Effectively it is the same system as used to render hostages, but attached to a polymodel. There are some interesting things you could do with it such as engine glow (maybe; it'd be distorted from above or below), but most other applications seem too problem-fraught to use. I'm not really sure why the block exists, personally.

Block data: SUBCALL
SUBCALL in nature is similar to SORTNORM except it only jumps to one location, not two; it also does a few other fancy things.

Firstly, the vector vmsStartPoint. This defines the reference point around which any vertices in the submodel are rotated; the actual rotation does not occur until a DEFP_START is read though. I've never seen more than one DEFP_START in a submodel, and there appears to be no reason to do so; but I haven't yet seen any sign that you couldn't theoretically do that - it'd just be inefficient.

The 'offset' field just after that defines the point to which the interpreter should jump for the actual submodel data. Once it is done with that it will continue on in the polymodel, but an EOF block usually follows a SUBCALL anyway.

SUBCALL is not needed for the root segment.

Block data: GLOW
GLOW is a fairly simple little trick; it just tells the renderer to assign a preselected brightness to the following polygon instead of calculating it based on surroundings. This is used in the Pyro-GX's engines, for instance (at least I think it is :)).

Summary of model structure
Effectively, a Descent polymodel is a recursive binary tree, where the interpreter renders one node at a time (where a node consists of any sequence of blocks up until an EOF block). Each node can have 0, 1 or 2 children; it will have 0 if it is a leaf, obviously; it will have 1 child node if it contains a SUBCALL, and it will have two if it contains a SORTNORM.

The renderer starts from the root node and proceeds through the rest of the polymodel in a depth-first manner. When it strikes a node with two children (SORTNORM), the branch it will take depends on the orientation of the normal.

Technically, a 'node' could have more than two children if there were two SORTNORMs not separated by an EOF block, but there is no good reason to do this.



Anyway, that should be enough for now, and perhaps it might be useful... at the very least, it should be usable reference material for later on...
User avatar
DCrazy
DBB Alumni
DBB Alumni
Posts: 8826
Joined: Wed Mar 15, 2000 3:01 am
Location: Seattle

Post by DCrazy »

That RODBM thing still intirgues me... I wonder why they never included it in the level structure, for making exhaust pipes/pillars/etc. Doom did it, why not Descent?
User avatar
fliptw
DBB DemiGod
DBB DemiGod
Posts: 6459
Joined: Sat Oct 24, 1998 2:01 am
Location: Calgary Alberta Canada

Post by fliptw »

DCrazy wrote:Doom did it, why not Descent?
Thats probably enough reason not to use it. you got powerups and hostages as sprites - Parrallax probably was worried about looking too much like Doom/ROTT/Blake Stone.
User avatar
Sirius
DBB Master
DBB Master
Posts: 5616
Joined: Fri May 28, 1999 2:01 am
Location: Bellevue, WA
Contact:

Post by Sirius »

Yeah, I wouldn't know myself. Technically you could achieve the same effect by using say an invulnerable mini-reactor with nothing but the RODBM thing...

...but the hitsphere would still cause you trouble. So, you'd just be out of luck.

I mean... hm, you COULD do hostages standing in a cart like that if you wanted, but you would never be able to pick them up.

Edit: There do seem to be a few artifacts such as this hanging around though. There is also a function to draw a flat-shaded 'rod', but I don't think there is a way to call it from a polymodel. It is possible that that and DEFPOINTS are just hanging around from an earlier stage of development when they weren't sure how the game was going to work, or something; would explain why DEFPOINTS is an earlier block number than DEFP_START. Notably, RODBM shows up before SUBCALL; while this doesn't mean it's an antecedent it may mean it came around before they thought of moving robot parts.

Theoretically additional block types could be added to the IDTA format, if the suitable handlers were there and there was at least some reasonable way to add them. (Which I am working on, actually, but it isn't done yet...) Earlier versions of Descent would just ignore the extra data.

Edit #2: Or not. They would ignore it but would also not alter the file pointer; hence they'd probably lock up on an unrecognised block type...
User avatar
DCrazy
DBB Alumni
DBB Alumni
Posts: 8826
Joined: Wed Mar 15, 2000 3:01 am
Location: Seattle

Post by DCrazy »

I don't think they'd have to worry about it looking like ROTT, because it's based on a modified version of the Duke Nukem 3D engine. :P

Seriously though, attaching rods to polymodels seems worthless. And, looking at the code, it would not be easy to adapt to any sort of level decoration purpose.
User avatar
fliptw
DBB DemiGod
DBB DemiGod
Posts: 6459
Joined: Sat Oct 24, 1998 2:01 am
Location: Calgary Alberta Canada

Post by fliptw »

DCrazy wrote:I don't think they'd have to worry about it looking like ROTT, because it's based on a modified version of the Duke Nukem 3D engine.
ROTT is modified Wolf3d, as is blake stone.
User avatar
Kyouryuu
DBB Alumni
DBB Alumni
Posts: 5775
Joined: Fri Apr 30, 1999 2:01 am
Location: Isla Nublar
Contact:

Post by Kyouryuu »

Do you think RODBM might have to do with weapon trails? Mercury Missiles always leave behind that trail of sprites.

The rods themselves could have been from an early stage of prototyping, to test how different robot behaviors might function without necessarily having artwork for those robots.
User avatar
Sirius
DBB Master
DBB Master
Posts: 5616
Joined: Fri May 28, 1999 2:01 am
Location: Bellevue, WA
Contact:

Post by Sirius »

If Descent generates them on the fly, maybe (I doubt that, but I haven't examined all of the code...). I don't see a RODBM block in the Mercury Missile polymodel though - but it is an interesting idea.

I think a development artifact is probably the most reasonable answer.
Post Reply