Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Drawing Flats from SSECTORS?

Recommended Posts

Posted (edited)



I am currently having a go at making a project which displays DOOM maps in Unity, just for fun. It can render uppers, lowers, and walls just fine, since they were quite easy to figure out, but it's come to the time where I need to figure out how to draw ceilings and floors, basically to turn the points that make up sections of the floor into points in 3d space.


After hours of trying, I came up with the current solution which is to use the SSECTORS lump and go through all of the Segs, connecting the points of vertex1 -> vertex2 -> next seg's vertex 1 etc. This works fine for some subsectors, and parts of the floor are appearing, but not others. I think there's probably something more I'm missing, but documentation on SSECTORS and SEGS seems sparse. Here, the image caption says "E1M1 Hangar with both segs and implicit edges shown". I'm not sure what an implicit edge is and my code doesn't take this into account, nor does it take into account the 'offset' value on the SEG definition, which seems important.


Does anyone know how to use the wad to generate a group of points that make up the floor for that subsector?

I am hoping this can be done without diving into too much about the BSP + Nodes system, as I haven't yet had to touch that for walls, uppers or lowers.






Share this post

Link to post
Posted (edited)

you need gl nodes for that. vanilla subsectors are not necessarily convex polys (vanilla engine does flat rendering with screen-space floodfill algo). gl nodes were created exactly to solve this problem. of course, iwad levels doesn't have gl nodes built, so you have to call external nodebuilder (ajbsp, glbsp, zdbsp) somehow, and tell it to write generated gl nodes into separate wad, so you can read it. or port some node builder to c#, and do it on level loading (gzdoom, k8vavoom, 3dge, etc. are creating gl nodes on map loading, if map doesn't have one).


sure, you can try to reconstruct convex polys from subsectors, but it can be tricky. some subsecors can have one sseg attached. it is impossible to reconstruct triangle from one sseg. ;-) you can also use sectors themselves to create polygons, and then use some algorithm to subdivide concave polygons to convex, but... some sectors even in vanilla maps are not closed contours. yeah, vanilla maps are buggy. ;-)


so the best way is to use gl nodes built by some gl node builder.

Share this post

Link to post

It seems like you already know how the grab the explicit ones (via the seg numbers and their corresponding coordinates derived from the SEGS lump). You can get the implicit ones by identifying segments of bsp lines that intersect with the explicitly-defined segs you already have. BSP lines are defined via the first 8 bytes in each NODE entry. An example from another renderer project can be found here (lines 659+).


Another approach that has been taken (by jmickle for this project) was to bypass subsectors entirely, and directly triangulate the arbitrary shape defined by each linedef that references a particular sector. This is rather non-trivial and needs to account for lots of strange cases, relevant algorithms are defined here.


(edit: or use gl nodes as described above)

Share this post

Link to post
Posted (edited)

Using the bsp lines like in cristicbz/rust-doom sounds like a good idea, however, I am a bit confused about lines 686 to 688 since I've never read Rust before.

He's doing something in order to later determine the inside_bsp_and_segs boolean, but I can't figure out what they're determined from, since the l and d variables appear to come out of nowhere with a strange syntax on 686 and 687?


Other than that, the approach seems quite good and not hugely complicated.

Do you know what these within_bsp and within_seg flags mean in the code example you gave?


EDIT: Nvm, I found it. That syntax with || characters is quite hard to search for, since search engines filter special characters, but it's a Rust feature called Closures, which is equivalent to lambda functions. The code makes a lot more sense now.

Edited by Adybo123

Share this post

Link to post

Thank you, @Ribbiks ! I am now so much closer to the desired effect!

I'm using cristicbz's approach of using the BSP nodes in the wad.

However, there are still a few small holes in the floor, and my code reports many subsectors with fewer than 2 sides (about 40 in MAP01), so I think I'm missing a few BSP lines. I noticed there are the flags "bsp tolerance" and "seg tolerance" used in comparisons in the Rust code, which I copied over with the same values & comparisons, but I'm not certain what they are for. I experimented with changing these values and it didn't seem to do much.z


The only thing I can think of is that my BSP node lines aren't ordered since I didn't want to have to walk the tree, every line just checks for an intercept with every other line and then does the tolerance comparison.


Could that maybe be why I'm not picking up some subsector points?





Share this post

Link to post

Hi Adybo123, I'm `cristicbz`, I wrote the rust renderer. Don't know if you're still interested but I think the tolerances are your problem, the coordinate system I use in rust-doom is kinda weird---I take the 16-bit wad coordinates and convert them to floats, dividing them by 100.0 . If you don't do the same thing, your tolerances may be out by a factor of 100 (i.e you may need to multiply the tolerances in your code by 100.0). That's the only I idea I've got right now; lemme know if that fixes it.

Share this post

Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now