Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A rounded box primitive would be a nice thing #41

Open
jonathanhogg opened this issue Feb 14, 2024 · 2 comments
Open

A rounded box primitive would be a nice thing #41

jonathanhogg opened this issue Feb 14, 2024 · 2 comments
Assignees
Labels
🚀 enhancement New feature or request 🎨 render Anything to do with rendering (windows, physics, etc.)

Comments

@jonathanhogg
Copy link
Owner

jonathanhogg commented Feb 14, 2024

Here's a functional implementation of what I mean:

func rbox(_, position=0, size=1, rotation=null, radius=null, segments=null)
    let radius=clamp(radius/size if radius != null else 0.25, 0;0;0, 0.5)
        inner=1-radius*2
        segments=max(1, segments//8)*8 if segments != null
    !union position=position size=size rotation=rotation
        if inner[1] and inner[2]
            !box size=1;inner[1];inner[2]
        if inner[0] and inner[1]
            !box size=inner[0];1;inner[2]
        if inner[0] and inner[1]
            !box size=inner[0];inner[1];1
        if radius[0] and radius[1] and radius[2]
            for x in (-1;1)*inner[0]/2
                for y in (-1;1)*inner[1]/2
                    for z in (-1;1)*inner[2]/2
                        !sphere segments=segments position=x;y;z size=radius
        if radius[0] and radius[1] and inner[2]
            for x in (-1;1)*inner[0]/2
                for y in (-1;1)*inner[1]/2
                    !transform translate=x;y;0 scale=radius[0];radius[1];inner[2]
                        !cylinder segments=segments
        if radius[0] and inner[1] and radius[2]
            for x in (-1;1)*inner[0]/2
                for z in (-1;1)*inner[2]/2
                    !transform translate=x;0;z scale=radius[0];inner[1];radius[2]
                        !cylinder segments=segments rotation=0.25;0;0
        if inner[0] and radius[1] and radius[2]
            for y in (-1;1)*inner[1]/2
                for z in (-1;1)*inner[2]/2
                    !transform translate=0;y;z scale=inner[0];radius[1];radius[2]
                        !cylinder segments=segments rotation=0;0.25;0

A rounded box primitive would also generalise !box, !cylinder and !sphere in that:

  • @rbox radius=0 is a !box
  • @rbox size=2;2;1 radius=1;1;0 is a !cylinder
  • @rbox size=2 radius=1 is a !sphere

The difference would come down to how the texture UV coordinates work.

Ideally an !rbox would use a box model of UV coordinates and carefully wrap each side 1/4th around the cylinders at the edges and over 1/8th "corners" of the spheres. This ought to take into account the relative area of the flat side vs the curved parts so that the texture isn't weirdly stretched or compressed. To keep the mapping correct, there would need to be seams around each of the 6 "faces" of the !rbox. I guess this also then means that segments must be a multiple of 8.

@jonathanhogg
Copy link
Owner Author

jonathanhogg commented Feb 14, 2024

Note that I've specified radius here such that it is divided by size to get the actual model radii, with the model standardised at unit size and then scaled – which is what happens with every other mesh model. I feel that specifying the standardised radii would be really confusing for the user, e.g.:

!rbox size=100;100;50 radius=0.1;0.1;0

This would intuitively look like a tiny corner radius instead of the 10 unit radius it actually works out to be once the model is scaled, and even harder to make sense of if the side lengths don't match but a single radius is desired around the edges/corners.

Scaling the underlying models means that they can be more easily shared, since:

!rbox size=100
!rbox size=1000

can both use the same underlying model – though, arguably, this is rarely going to happen.

@jonathanhogg
Copy link
Owner Author

It also occurs to me now that:

@rbox size=2;1;1 radius=0.5

is a capsule!

@jonathanhogg jonathanhogg self-assigned this Feb 14, 2024
@jonathanhogg jonathanhogg added 🚀 enhancement New feature or request 🎨 render Anything to do with rendering (windows, physics, etc.) labels Feb 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🚀 enhancement New feature or request 🎨 render Anything to do with rendering (windows, physics, etc.)
Projects
None yet
Development

No branches or pull requests

1 participant