Skip to content

A rounded box primitive would be a nice thing #41

@jonathanhogg

Description

@jonathanhogg

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.

Metadata

Metadata

Assignees

Labels

🎨 renderAnything to do with rendering (windows, physics, etc.)🚀 enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions