[racket] Crowdsourcing Pict3D's design

From: Neil Toronto (neil.toronto at gmail.com)
Date: Sat Mar 14 23:51:12 EDT 2015

On 03/14/2015 10:27 PM, Alexander D. Knauth wrote:
> On Mar 8, 2015, at 10:53 PM, Neil Toronto <neil.toronto at gmail.com> wrote:
>> If you've ever had the slightest hankering to do some real 3D but avoided it because of the pain that usually goes with it, try Pict3D. (If it fails to work, please submit a bug report on the GitHub page.) Got a visualization project? Try Pict3D. Want to make a game? Try Pict3D's version of Big Bang. Want to just fool around in 3D space for a bit? Try Pict3D, and report back on how it goes.
> I made a version of the game unpossible using pict3d:
> https://github.com/AlexKnauth/my-unpossible
> It’s a bit slow and jerky, but that’s probably entirely because I didn’t try too hard to make my end of it fast.
> If you have any suggestions that would be great.

Very cool!

Let's be fair to you: it's not obvious how to make it fast. I'd love to 
make the API so that it *is* obvious, or so that the techniques to make 
it fast are done automatically.

Here's an indication about what's going on. Try these in the REPL:

   (time (void (get-tube+obstacles (make-world-stream) +x 40)))
   (time (void (combine (get-tube+obstacles (make-world-stream) +x 40))))

(Using `void` just keeps the Pict3Ds from getting rendered.) For both, I 
get 75-125ms, so the culprit isn't `combine` - it's `get-tube+obstacles`.

But the `get-tube+obstacles` code isn't doing anything in a particularly 
slow way. It's just that making shapes is slow. As evidence, the game 
goes at a good clip, though the tube looks terrible, if I add 
"#:segments 8" to the call to `parametric-cylinder`.

(I could probably speed `parametric-cylinder` way up by writing it using 
a lower-level interface to the 3D engine, but this would eventually come 
up again.)

What you need is to 1) create and combine the necessary Pict3Ds as much 
as possible before the game starts; and 2) reuse them as much as 
possible during the game.

You can even make the reused Pict3Ds fairly large if you freeze them. 
Any modern 3D card won't have any problem with this, for example:

   (freeze (combine (get-tube+obstacles (make-world-stream) +x 1000)))

Freezing takes a while, though, and has this annoying property that it 
takes the most time the first time the frozen Pict3D is rendered. (The 
actual freezing has to be done with an active OpenGL context.) I'm not 
sure what to do about the latter problem.

If you don't mind, I have a couple of questions.

1. What was the most annoying surprise?

2. What was the most pleasant one?

Again, very cool!

Neil ⊥

Posted on the users mailing list.