Make an Irregular Stairway Slope Smoothly?

Ask about mapping, UDMF, using DoomBuilder/editor of choice, etc, here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
User avatar
Enjay
 
 
Posts: 26517
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Make an Irregular Stairway Slope Smoothly?

Post by Enjay »

Can anyone suggest the best way to take something like this:

Its a twisting stairway (in some cases the steps might be irregular heights) and make it so that the floor and ceiling slope smoothly with no upper/lower sidefes showing between sectors.

Obviously I know that simply using slope lines will not do it:


But what will?

I guess trangular sectors will need to be involved at some point but I just can't wrap my head around how to do it. I can normally get smooth slopes that simply go from one height to another (like was seen many times in KDIZD) but I can't figure out how to do it when there are many steps at different heights all flowing on from each other - much less figure out a quick and easy way to do it.

Any ideas?

Map in the screenshots attached in case the description wasn't clear.
Attachments
SlopeyTwisty.zip
(6.27 KiB) Downloaded 23 times
User avatar
Kappes Buur
 
 
Posts: 4114
Joined: Thu Jul 17, 2003 12:19 am
Graphics Processor: nVidia (Legacy GZDoom)
Location: British Columbia, Canada
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by Kappes Buur »

All I can think of is curving the sectors with Ctrl+C, creating a lot of sectors



and raising the stairs by a wee amount, 1 or 2 mu, to mitigate jagged edges and leaving out the linedef texture to make it appear continuous.





Although for a considerable height difference it needs a lot of sectors. It's a bit tedious.

I tried the Stairbuilder Mode Auto Curve, yet for me it did not show correctly, always showing a black 'shadow' on upper steps, on going up. And the step textures are not as smooth. I don't know why.

Attachments
MAP01x.zip
perhaps a solution
(11.4 KiB) Downloaded 25 times
User avatar
Caligari87
Admin
Posts: 6174
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by Caligari87 »

Yeah you need to triangulate each step (in this case, just corner-to-corner would work) and then apply separate sloping to the front and back of each step. Basically the idea being that the edge of each step is level, and the diagonal is where the slope meets. It's kinda hard to explain.

I made an old old old tutorial for something similar to this for natural terrain back in 2004. It's a bit trickier to apply to sequential slopes but a similar principle should still work.

viewtopic.php?t=4487

I'll try to demo this when I get home from work later.

8-)
User avatar
Enjay
 
 
Posts: 26517
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by Enjay »

Caligari87 wrote:I'll try to demo this when I get home from work later.
I'd appreciate that. What you describe is pretty much how I figured it would need to be done, but my attempts at actually doing it have been unsuccessful.

I can do the crater (etc) effect in the thread that you linked to easily enough but this continuous slope of several different sectors is eluding me.
User avatar
axredneck
Posts: 354
Joined: Mon Dec 11, 2017 2:09 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): Arch
Graphics Processor: nVidia with Vulkan support
Location: Russia
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by axredneck »

Make triangular sectors instead of quads and then adjust vertices' heights?
User avatar
Enjay
 
 
Posts: 26517
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by Enjay »

Thanks for the suggestion. I thought that might be a solution too - but I was hoping for something that didn't involve editing the height for every single vertex in the construct. I'm a big fan of the old line type 181 so something involving that would be best for me, but I am open to other methods if 181 is not suitable in this case.
boris
Posts: 736
Joined: Tue Jul 15, 2003 3:37 pm

Re: Make an Irregular Stairway Slope Smoothly?

Post by boris »

UDBScript to the rescue!

Video: https://streamable.com/rnc87s

Script:

Code: Select all

`#version 4`;
`#name Triangulate and slope sectors`;
`#description Triangulates sectors and sets the vertex heights of the resulting sectors so that it slopes between the sectors.`;

let sectors = UDB.Map.getSelectedSectors();

if(sectors.length == 0)
    UDB.die('You need to select sectors. Aborting');

// Set the vertex height for the selected sectors
sectors.forEach(s => {
    let sidedefs = s.getSidedefs();

    if(sidedefs.length > 4)
        UDB.die(`This only works with sectors that have 4 sides (${s} has ${sidedefs.length} sides)`);

    // Find the sidedefs that have another selected sector on their other side, and set the vertex height to the heights
    // of that other sector. It doesn't matter that the sectors are not triangulated, yet
    sidedefs.filter(sd => sd.other != null && sectors.includes(sd.sector) && sectors.includes(sd.other.sector)).forEach(sd => {
        sd.line.start.floorZ = sd.other.sector.floorHeight;
        sd.line.end.floorZ = sd.other.sector.floorHeight;
        sd.line.start.ceilingZ = sd.other.sector.ceilingHeight;
        sd.line.end.ceilingZ = sd.other.sector.ceilingHeight;
    });
});

// Triangulate the sectors
sectors.forEach(s => {
    let vertices = [];

    // Add the vertices of all the sector's sidedefs to the list
    s.getSidedefs().forEach(sd => {
        if(!vertices.includes(sd.line.start)) vertices.push(sd.line.start);
        if(!vertices.includes(sd.line.end)) vertices.push(sd.line.end);
    });

    // Get the first vertex
    let v1 = vertices[0];

    // Remove all vertices from the list that belong to lines that are connected to our first vertex
    v1.getLinedefs().forEach(ld => vertices = vertices.filter(v => v != ld.start && v != ld.end));

    // There's only one vertex remaining, so take that as the second vertex
    let v2 = vertices[0];

    // Draw the lien that cuts the sector into two triangles
    UDB.Map.drawLines([ v1.position, v2.position ]);
})
P.S.: while creating that script I stumbled into a small bug, so I recommend to run this script using the "Run script" button and not the hotkey, otherwise UDB might crash if the mouse is moved out of the map view while the script is running.
User avatar
Enjay
 
 
Posts: 26517
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by Enjay »

Oh my goodness!

That was so quick and easy. Thank you.

One thing I noticed is that it only works with 4 sided sectors and one of the sectors in my demo file had more than that. Understandable.
A quick reconfigure of the map solved that problem and I can just keep that requirement in mind for actual maps.

Can I ask, what preference setting do I need to set so that I can see the vertex indicators like they are in your video? I can't find the option.
boris
Posts: 736
Joined: Tue Jul 15, 2003 3:37 pm

Re: Make an Irregular Stairway Slope Smoothly?

Post by boris »

Enjay wrote:Can I ask, what preference setting do I need to set so that I can see the vertex indicators like they are in your video? I can't find the option.
It's the "Show editable vertices (visual mode)" button in the tool bar (the one with the dot in the middle and the arrows pointing up and down). The default hotkey to toggle it should be Alt+V.
User avatar
Enjay
 
 
Posts: 26517
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by Enjay »

Got it. Thanks once again. :)
User avatar
ReX
Posts: 1578
Joined: Tue Aug 05, 2003 10:01 am
Location: Quatto's Palace
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by ReX »

I recently dealt with the same exercise. Here is what I did:

1. I created "proper" steps (i.e., trapezoid sectors with the appropriate height)
2. I split each step sector to create 2 triangles
3. I placed a floor vertex height thing (Thing Type 1504) at each corner of each triangle (except all the way at the bottom and all the way at the top of the stairs). [Refer to attached screenshot in map editor.]
4. I gave the [absolute] value of each vertex height thing a height that corresponds to the floor of the step above. Therefore, if the bottom step is at height 0 and the next step is at height of 32, then the thing gets a height of 32. Naturally, you'll have pairs of height things with identical height attributes.

This will give you a smoothly-sloping floor all the way to the top. You can apply the same principle to slope the ceiling.

When I have a chance I'll copy and paste the relevant parts of my map and post it here.
Screenshot of sloped stairs
Screenshot of sloped stairs
User avatar
Enjay
 
 
Posts: 26517
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by Enjay »

I think what you have described is pretty much exactly with the UDB script that boris posted does.

There are two main differences:
a) It sets vertex heights directly on the vertex (a UDMF feature).
b) much of the manual "work" is taken out if it. All you need to do it set up the trapezoid sectors in the way that you described, select them and then run the script. It cuts the sectors into triangles and applies the vertex heights in under a second.

The script does floors and ceilings at the same time but looking at it, it would probably be easy to make a floors only and a ceiling only one (and, usually, simply mass-selecting the vertices and resetting their ceiling/floor heights for whichever plane you don't want to have sloped is pretty easy anyway).

It's always useful to have instructions and an example though. Especially if you did yours in ZDoomHexen mode so that people who don't use UDMF/a UDMF capable editor can see how its done. So please post your one when it's ready. I'd like to see it. :)
User avatar
ReX
Posts: 1578
Joined: Tue Aug 05, 2003 10:01 am
Location: Quatto's Palace
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by ReX »

Enjay wrote:I think what you have described is pretty much exactly with the UDB script that boris posted does.
That's very good to know. When (if?) I graduate to UDMF I'll undoubtedly use Boris' script mercilessly.
It's always useful to have instructions and an example though. Especially if you did yours in ZDoomHexen mode so that people who don't use UDMF/a UDMF capable editor can see how its done. So please post your one when it's ready. I'd like to see it. :)
I'll do that forthwith (heh).

Incidentally, as this is one of the projects you and I are working on together, you'll get to see the entire map soon enough.
User avatar
Enjay
 
 
Posts: 26517
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Make an Irregular Stairway Slope Smoothly?

Post by Enjay »

I rather hoped it might be. :D

And if you were really looking hard, you might even notice that the original file that I used as an example might just have been plucked from a certain Star Wars mod that you are more than slightly familiar with. ;)
boris
Posts: 736
Joined: Tue Jul 15, 2003 3:37 pm

Re: Make an Irregular Stairway Slope Smoothly?

Post by boris »

UDBScript of course works in all map formats and not just UDMF. The script obviously has to take the differences into account. Here's a version of the script that also works on Hexen maps (and also lets the user decided if to slope the floor and/or ceiling):

Code: Select all

`#version 4`;
`#name Triangulate and slope sectors`;
`#description Triangulates sectors and sets the vertex heights of the resulting sectors so that it slopes between the sectors.`;
`#scriptoptions
whichsurface
{
    description = "Surface to slope";
    default = 0;
    type = 11;
    enumvalues {
        0 = "Floor and Ceiling";
        1 = "Floor only";
        2 = "Ceiling only";
    }
}
`;

if(UDB.Map.isDoom)
    UDB.die('Map needs to be in Hexen format or UDMF');

let sectors = UDB.Map.getSelectedSectors();

if(sectors.length == 0)
    UDB.die('You need to select sectors. Aborting');

let processedlinedefs = [];

// Set the vertex height for the selected sectors
sectors.forEach(s => {
    let sidedefs = s.getSidedefs();

    if(sidedefs.length > 4)
        UDB.die(`This only works with sectors that have 4 sides (${s} has ${sidedefs.length} sides)`);

    // Find the sidedefs that have another selected sector on their other side, and set the vertex height to the heights
    // of that other sector. It doesn't matter that the sectors are not triangulated, yet
    sidedefs.filter(sd => sd.other != null && sectors.includes(sd.sector) && sectors.includes(sd.other.sector)).forEach(sd => {
        if(processedlinedefs.includes(sd.line))
            return;

        if(UDB.ScriptOptions.whichsurface == 0 || UDB.ScriptOptions.whichsurface == 1)
        {
            if(UDB.Map.isUDMF)
            {
                sd.line.start.floorZ = sd.other.sector.floorHeight;
                sd.line.end.floorZ = sd.other.sector.floorHeight;
            }
            else
            {
                UDB.Map.createThing([ sd.line.start.position.x, sd.line.start.position.y, sd.other.sector.floorHeight ], 1504);
                UDB.Map.createThing([ sd.line.end.position.x, sd.line.end.position.y, sd.other.sector.floorHeight ], 1504);
            }
        }

        if(UDB.ScriptOptions.whichsurface == 0 || UDB.ScriptOptions.whichsurface == 2)
        {
            if(UDB.Map.isUDMF)
            {
                sd.line.start.ceilingZ = sd.other.sector.ceilingHeight;
                sd.line.end.ceilingZ = sd.other.sector.ceilingHeight;
            }
            else
            {
                UDB.Map.createThing([ sd.line.start.position.x, sd.line.start.position.y, sd.other.sector.ceilingHeight ], 1505);
                UDB.Map.createThing([ sd.line.end.position.x, sd.line.end.position.y, sd.other.sector.ceilingHeight ], 1505);
            }
        }

        processedlinedefs.push(sd.line);
    });
});

// Triangulate the sectors
sectors.forEach(s => {
    let vertices = [];

    // Add the vertices of all the sector's sidedefs to the list
    s.getSidedefs().forEach(sd => {
        if(!vertices.includes(sd.line.start)) vertices.push(sd.line.start);
        if(!vertices.includes(sd.line.end)) vertices.push(sd.line.end);
    });

    // Get the first vertex
    let v1 = vertices[0];

    // Remove all vertices from the list that belong to lines that are connected to our first vertex
    v1.getLinedefs().forEach(ld => vertices = vertices.filter(v => v != ld.start && v != ld.end));

    // There's only one vertex remaining, so take that as the second vertex
    let v2 = vertices[0];

    // Draw the lien that cuts the sector into two triangles
    UDB.Map.drawLines([ v1.position, v2.position ]);
})
Post Reply

Return to “Mapping”