today is sad screensaver day

Two screensaver defeats in two days! First I wrote one that displayed a few side-scrolling views of its own heap (just converting memory values into colors in various simple ways.) It just looked... kinda boring and dumb. I shelved it.

Then, I poked around and found some medical volumetric data and hacked up a screensaver that would display a rotating head, with progressive slices of it removed to expose cross-sections of the skull and brain. But, the first problem is that the data set (109 slices of 256x256 samples) is 7MB; and, even on my pretty fast machine, I find that if I want a frame rate even as high as one a second, I have to scale the mesh down to 100x100x100, which, though it emits 200,000+ polygons, still looks like hell. It also might be that without either raytraced shadows, or coloration of the data, you wouldn't be able to identify features very easily anyway, even at full 256x256x256 resolution.

I keep trying to come up with more opportunities for using my marching cubes code, but I'm just not hitting anything that is both good looking and practical...


Tags: , , ,

6 Responses:

  1. soul4rent says:

    But I see you listen to Emergency Broadcast Network, which makes you the second person I know (besides me) who does. And I wanted to compliment you on your fine taste in music. :)

  2. neschek says:

    Even it it weren't for xscreensaver, I'd be firmly convinced that the man who wrote dadadodo can do no wrong.

  3. nothings says:

    There's an obscure enhancement of marching cubes, the only place I know of that it was published was an aside in the Journal of Graphics Tools, and I can't remember which article, nor am I having any luck searching their abstracts, which doesn't surprise me since I remember it was an aside not implied by the main topic of the article.

    The basic issue is that MC creates lots of little slivers from the isosurface being clipped to all the cubes. A common approach is to apply a polygon simplification algorithm afterwards, but the clever solution here is to observe that there's no reason why the points of the cubes have to be exactly on the grid; there's no particular benefit to them being cube shaped; the basic grid topology gets all the effects that you want. And if you were to magically teleport the cube corner vertices so that they lay on the isosurface everywhere, suddenly you get a lot fewer slivers, since the surface will pass exactly through the corner between two cubes.

    To do this, basically, if I remember correctly (this was like five years ago that I heard this), when you go to determine the intersection along a cube edge, and you eventually determine, ok, it's distance t along the edge from A to B, if that distance is less than 0.5 of the edge, you move point A to the intersection point; otherwise you move point B to it.

    Complications: you can only move a point once, and it has to be consistently used the same for every query after that. I think we kept a cache and probed in all six directions from the point, and picked the nearest point to move it to. Second, if you move a point so it lies "on" the isosurface, you've picked that point "on" the isosurface numerically, so evaluating the function there will only be within some epsilon, and you now have to recognize when a corner is within epsilon of the isosurface and treat it appropriately. Really you just say "hey, this point is displaced, the function at this point must be the isosurface value"; the point is not to just recompute the function at the point and treat it naively.

    I forget how much improvement this gives though.

  4. omni_ferret says:

    Hm. You might look at SliceViewer for a way to get a slice drawn quickly. Am I reading you wrong, or did you just want an animated slice floating in a shell of a head, with parts conveniently disappearing for an animated cutaway view?

  5. robotdevil says:

    Every time this runs on my mac I wonder if it's just reading the whole address space of the screensaver process. Do you specifically read from the heap? I keep thinking maybe it's reading hardware registers that could be mapped to address space (as video drivers are prone to do for GL)

    • jwz says:

      Well, it's weird on MacOS for some reason. It's trying to read from the heap of its own process -- between the result of a very early malloc(), and sbrk() -- but on MacOS, sometimes those values make no sense, pointer-arith-wise. I don't understand how that's possible, since they are both supposedly returning data from malloc()'s data structures. But, it is. (In both X11 and Cocoa builds.) So memscroller does some sanity-checking and if the values seem insane, it either uses a smaller range, or goes into "random" mode. See memscroller.c around line 318.