Lots more progress on my web-based parametric modeler for 3d-printable tech panels. I’ve added in two new feature types:
handles: similar to the kind of handles one sees on rack-mounted equipment, including configurable thickness and height from the surface
dials: the kind of indicator you might see on old equipment to provide voltage or other data
I’ve also added in the first steps towards a nicer UI in the right-hand side of the page, including swapping out the parameters based on the selected feature type.
I’m continuing to work on my web-based parametric modeler for 3d-printable tech panels, and I finally solved what will likely be the hardest problem in the whole (pun not intended) project- supporting multiple holes.
At the start, the system creates six quads that can each receive mouse events. When the user holds space and click-drags to specify a new feature’s location, a couple of things happen, namely:
A new hole is added to the existing quad
The existing quad re-generates its faces to fill in everywhere except the hole (or holes)
The new feature is created, with the hole’s points as its basis
The second step above was the doozy. If there’s only a single hole in a quad, it’s very easy to fill in the necessary faces. This is especially true since I’m making sure that quads are always represented with their points in clockwise order starting at the top left.
However, if there are multiple holes, it gets tricky. One solution would be to throw all the points into a collection and create a Deluany triangulation, but I thought I could leverage the constraints built into my system to my advantage and do something a bit simpler.
Ultimately I ended up writing my own algorithm that sweeps across from left to right, adding the vertical edges of the holes one at a time and creating triangles as needed.
The approach is to:
create two vertical edges for each hole
sort all of the edges by X-coord
init a sweep line with the bottom-left and top-left points of the parent quad
for each edge starting with the left-most:
start with the bottom vert
find either the two or three (see below) vertices in the sweep line that are directly above and below the new vert, and connect them to the vert that’s currently being inserted
insert the new vert into the sweep line at the appropriate position
after each edge is inserted, run along the vertices of the sweep line and check for any concavities. If any three vertices form a concave curve, connect the first and last with a triangle to make it convex
once all of that is done, finish off the quad by connecting the top-right and bottom-right vertices of the original quad to the remaining vertices of the sweep line
You might have noticed that nothing about the above mentioned removing vertices from the sweep line. You may have also noticed that I mentioned that we get either two or three vertices when comparing a new vertex to the sweep line. One of those provides the answer to the other.
Since everything, both the parent and the holes, are quads, that means that sometimes we’ll have a new vertex that has exactly the same Y-coord as an existing vertex in the sweep line (since we’re inserting the right-hand edge of a hole that already had its left-hand edge inserted). In that case, we get three vertices:
the vertex in the sweep line that’s below the new vert
the vertex in the sweep line that’s equal to the new vert (in Y-pos)
the vertex in the sweep line that’s above the new vert
In such a case, the algorithm connects the new vert to the middle and either the top or the bottom, whichever one *doesn’t result in the three vertices belonging to the same hole (since that would create a face inside the hole). It then removes the middle vert from the sweep line.
I’ve recently started working on a web-based parametric modeler for making 3d-printable panels full of greebles/nurnies using javascript and Three.JS. The general idea is to have a base shape and allow the user to draw rectangular sections that then get filled in with additional details.
Currently, the system supports beveled extrusions and arrays of buttons, but more feature types are on the way. To see it for yourself, head here: http://adrianherbez.net/greebles/03/
The Roguelike Celebration is an annual mini-conference on roguelike games and procedural content, currently in its fourth year. I’ve gone the past three years and its always wonderful- highly recommended.
This year, I was lucky enough to get to present a short talk on my 3d-printable roguelike, “PLARL” (short of the poly-latcic acid roguelike). The talk (along with all the other, even better talks given by other contributors), is up on youtube and viewable here:
Also also, I have all of the code for both the OpenSCAD model generation and the JS-based maze generation available on github here: https://github.com/aherbez/plarl
I’ve been continuing to work on my 3d-printable roguelike, and in order to do that, I needed a way to generate mazes. OpenSCAD is a bit annoying to work with for general programming, so I instead opted to write the maze generation in javascript and export data into the OpenSCAD file.
The maze generation is based on Jamis Buck’s excellent book, “Mazes for Programmers”. The numbers in the cells are there to indicate the contents of the rooms, which can either be monsters (which deal 1-6 points of damage) or food/potions (which heal 1-6 points of health). I kept it really simple on that front- just using numbers between 11-16 for damage and 21-26 for health regen, since all I needed was an easy way to pass the number and type into the OpenSCAD code.
The end result of the mazegen is a set of integer values representing the exists for each cell (each of the cardinal directions being represented by a unique power of 2 and added together), as well as for the contents. Those arrays are pasted into the OpenSCAD source to actually generate the level
This was a project to generate a 3d printable dungeon using OpenSCAD. To play the game, the player uses a screwdriver or similar to break away parts of the printed model, revealing additional information.
The result has multiple layers stacked on top of each other, with the bottom layer (red) consisting of the maze pattern, the middle layer (green) supporting iconography for things like monsters, and the top layer (blue) being the door. Both the blue and green layers break away.
To see a playthrough of an example level, check out this video:
This was a project to create procedural flowers using pure WebGL. All of the geometry and textures are generated via code, and the only external library used is glMatrix. The flowers are also generated using a seed derived from lat-long coordinates, so specific flowers can be generated for specific locations. To see it in action, head here.
Development Process
Step 1: Flat leaves The project happened over the course of about a week and a half. I started by generating flat, 2d versions of leaves:
I started by implementing Bezier curves, then using two cubic curves to set the shape of the leaf edge and generating faces to fill in the contents. I also set up a simple shader to have the center of the leaf be a bit red, fading to green at the edges. See this version head here: http://www.adrianherbez.net/glflower/01/.
Step 2: 3d Leaves Once I had the basic 2d leaf working, it was time to add additional cubic curves to make it bend backwards along its length as well as to curve gently away from the spine of the leaf.
Step 4: Expanding leaves to petals, normals At this point, it was time to move onto the flower itself. I refactored the code for the leaf to be more general, making it a general class for creating geometry from sets of curves (XY, XZ, and YZ). By changing the curves, it was easy to go from pointy leaves to more bell-like petals.
I also added in proper normal calculations for the faces, which also meant writing a normal shader for easy debugging. All of the geometry is rendered double-sided, with one side rendering with the normal color and the other either red (for petals) or green (for leaves). See this version here: http://www.adrianherbez.net/glflower/04/
Step 5: Lathed Geometry In order to create the central part of the flower, I created a LathedGeometry class that could take a curve and spin it around the Y axis to generate a sealed piece of geometry.
Step 6: Putting it all together Now that I had all of the parts I needed, I put it all together into a full flower, with a stem, leaves, a central element, and petals.
The colors look a bit crazy, but that’s because I was still using the normal shader as a diagnostic. It makes a lot more sense if you see it moving- to do that, head here: http://www.adrianherbez.net/glflower/06/. Moving the mouse in the canvas will change the angle of the flower (added that in to make it easier to see what was going on).
Step 7: Colors! With all of the geometry in, I started working on better colors for the shaders.
Step 8: Lat-long based seed values Now that the flower was close to done, I turned my attention to adding support for a lat/long-derived seed value.
Once set, the same seed is used for all the randomized generation, allowing any place in the world to have its own unique flower. At this point, the colors were still always the same though. See it here: http://www.adrianherbez.net/glflower/08/
Step 9: Finishing Touches I was pretty happy with things at this point, but added a few things here and there to provide some polish, namely: – randomized colors for the petals – modification of the leaf shader to have stripes on the underside – changed the background color to a nice medium gray
I spent some time recently diving into noise generation, which is something I’ve previously taken for granted. As part of that, I ended up putting together a simple 2d noise generator. The code isn’t particularly optimized or well-structured, as this is just a stepping stone on the way to bigger things. I was pretty happy with the results anyways though, so I’ve put the current state up. See if for yourself here.
Lately, I’ve been working on a system to display virtual books in a browser as fully 3d objects using Three.js. While there are still lots of things I want to add, it’s finally at the point where I feel like it’s worth sharing.
The system loads data from archive.org and uses it to create a 3d model of a book. The book can be opened, and pages can be flipped, allowing the user to read the entire contents. The current iteration is hard-coded to load just one book (The Wizard of Oz), but I’ll be expanding it to pull from the rest of the Internet Archive’s extensive collection.
All of the geometry is procedural, allowing for books of any size and proportion. The texture used for the cover is also procedural, allowing for any color of book, and for proper rendering of title and author along the spine.
This was a small, one-night project to explore the procedural creation of snakeskin-like patterns. The main trick is to use overlapping sine waves and a bit of noise to create mirrored, snakeskin patterns, which ended up being both straightforward to implement and fairly effective.