Search In
• More options...
Find results that contain...
Find results in...

# How can 1 segment in SSECTORS be used to create a convex subsector?

## Recommended Posts

I'm working on a program that's helping me learn how doom works. I started with making a 2d automap renderer to see if I could dissect the engine and grab the data that I want.

Thus far it was a success and I was able to map out all the things, lines, segs...etc

But I was interested in how the subsectors are formed. Sometimes I get segs that are separated, I assumed you just connect the dots... but you can't in a certain amount of them. Whats even more confusing is how you go about drawing a subsector when you only have one line. I've been reading the doom wiki for days and I'm stuck on how to render a 2D birds eye view of a subsector.

Therefore: How (using Doom in Hexen lumps and the latest ZDBSP on zdoom.org) can I figure out the edges of the polygon from the wad files given to me from the lumps inside a map file?

Quick ninja question: For segs, what is the point of
8-9 Signed short Direction
10-11 Signed short Offset
Direction is the angle between the first and second vertex?
Offset has to do with the texture that's on it?

EDIT: Please bear with me, first time I've took on a project like this.

Chrispaks said:

Therefore: How (using Doom in Hexen lumps and the latest ZDBSP on zdoom.org) can I figure out the edges of the polygon from the wad files given to me from the lumps inside a map file?

You have to look through nodes, which are explained here. The fields important there are: x, y, dx, dy, right child, left child. Ignore the bounding boxes, they mean nothing for you.

Go to the root node, which is the last in the NODES list. Its x, y, dx, dy fields define a line that slices the entire level in two. Its right child and left child are indices of other NODES entries which also slice their parts in two. This process repeats until one of the children only contains a convex set of linedef segments, which will generate SEGS and a SSECTORS entry. From the subsector SEGS and the node lines drawn so far and trimmed you get the convex shape. You can exercise it by printing the map and tracing with the pencil each node line, until you hit what looks like a subsector

Quick ninja question: For segs, what is the point of
8-9 Signed short Direction
10-11 Signed short Offset
Direction is the angle between the first and second vertex?
Offset has to do with the texture that's on it?

Direction is not the angle, it's a 0/1 value which specifies which side of the linedef the seg is overlaid on. It's kinda similar to how sidedefs are on a side or another. There's also Angle (bytes 4-5) but it seems to be irrelevant to Doom's code, at least in the Eternity port, so ignore it. Offset is simply the distance from linedef's start vertex to seg's start vertex. Do note that segments secretly add more vertices to your map, but the editors know how to ignore them.

printz said:

You have to look through nodes, which are explained here. The fields important there are: x, y, dx, dy, right child, left child. Ignore the bounding boxes, they mean nothing for you.

Go to the root node, which is the last in the NODES list. Its x, y, dx, dy fields define a line that slices the entire level in two. Its right child and left child are indices of other NODES entries which also slice their parts in two. This process repeats until one of the children only contains a convex set of linedef segments, which will generate SEGS and a SSECTORS entry. From the subsector SEGS and the node lines drawn so far and trimmed you get the convex shape. You can exercise it by printing the map and tracing with the pencil each node line, until you hit what looks like a subsector

I went through and wrote everything out for the nodes, and got this data printed out:

(x = 160, y = 160, changex = 0, changey = -64, rightChild = 0 [subsector], leftChild = 1 [subsector]),
(x = 96, y = 160, changex = 64, changey = 0, rightChild = 0, leftChild = 2 [subsector]),
(x = 160, y = 96, changex = -64, changey = 0, rightChild = 1, leftChild = 3 [subsector]),
(x = 96, y = 96, changex = 0, changey = 64, rightChild = 2, leftChild = 4 [subsector])

Nodes have brackets (0..n), subsectors are just the number

(3)
/ \
4  (2)
/ \
3  (1)
/ \
2  (0)
/ \
1   0

VERTEXES:
[(64,64),
(64,192),
(192,192),
(192,64),
(96,96),
(96,160),
(160,160),
(160,96),
(96,192),
(96,64),
(192,96),
(192,160)]

SEGS:
[(startVertex = 4, endVertex = 5, angle = 64, linedefNum = 4, direction = 0, offset = 0, ),
(startVertex = 5, endVertex = 6, angle = 0, linedefNum = 5, direction = 0, offset = 0, ),
(startVertex = 6, endVertex = 7, angle = 192, linedefNum = 6, direction = 0, offset = 0, ),
(startVertex = 7, endVertex = 4, angle = 128, linedefNum = 7, direction = 0, offset = 0, ),
(startVertex = 11, endVertex = 10, angle = 192, linedefNum = 2, direction = 0, offset = 32, ),
(startVertex = 7, endVertex = 6, angle = 64, linedefNum = 6, direction = 1, offset = 0, ),
(startVertex = 8, endVertex = 2, angle = 0, linedefNum = 1, direction = 0, offset = 32, ),
(startVertex = 2, endVertex = 11, angle = 192, linedefNum = 2, direction = 0, offset = 0, ),
(startVertex = 6, endVertex = 5, angle = 128, linedefNum = 5, direction = 1, offset = 0, ),
(startVertex = 10, endVertex = 3, angle = 192, linedefNum = 2, direction = 0, offset = 96, ),
(startVertex = 3, endVertex = 9, angle = 128, linedefNum = 3, direction = 0, offset = 0, ),
(startVertex = 4, endVertex = 7, angle = 0, linedefNum = 7, direction = 1, offset = 0, ),
(startVertex = 0, endVertex = 1, angle = 64, linedefNum = 0, direction = 0, offset = 0, ),
(startVertex = 1, endVertex = 8, angle = 0, linedefNum = 1, direction = 0, offset = 0, ),
(startVertex = 9, endVertex = 0, angle = 128, linedefNum = 3, direction = 0, offset = 96, ),
(startVertex = 5, endVertex = 4, angle = 192, linedefNum = 4, direction = 1, offset = 0, )]

SUBSECTORS:
[(4,0),
(2,4),
(3,6),
(3,9),
(4,12)]

NODES (raw signed data, see top of post for unsigned children nodes):
[(x = 160, y = 160, changex = 0, changey = -64, rightChild = -32768, leftChild = -32767),
(x = 96, y = 160, changex = 64, changey = 0, rightChild = 0, leftChild = -32766),
(x = 160, y = 96, changex = -64, changey = 0, rightChild = 1, leftChild = -32765),
(x = 96, y = 96, changex = 0, changey = 64, rightChild = 2, leftChild = -32764)]
Rendered, it shows up how I expect it to show up:

The above image shows the whole map (blue lines = linedefs connected by the white vertices, the yellow lines show all the lines for the specific segment, in this case... subsector 4's four line segments

How do I used the dx and dy again? For example, the root node is 3, and its x/y is (96,96). The changey = 64, so that means I go up 64 units to (96,160). Does that just mean the line that was used to split up the level for the left/right bounding boxes? Or can I use it as an actual line in calculating a polygon?

I'm probably missing something, can you clarify for me what to do to get the sector polygons I need again? Sorry if it's an inconvenience; something isn't clicking with me

BTW: The data values should be right, but if somethings wrong then maybe I messed something up (like if something should be unsigned, then I messed up...); though I was able to render doom2 map29 lines and vertices properly so thus far everything should be working right...

The root node 3 has an endless line that goes along the (96, 96)-(96, 160) linedef. To its left is subsector 4, to its right is node 2. Subsector 4 is made by the yellow lines you drew there AND the segments of the (96, 96)-(96, 160) line that close up that shape.

Node 2 goes from (160, 96)-(96, 96) and to its left sees another subsector (3 segs + extension of that line) and to its right node 1. It only slices through the part of the map at the right of node 3.