Scratch Advanced: General Purpose Wireframe 3D Engine

This week in Scratch advanced we took on the ambitious task of writing a general-purpose 3d wireframe engine.  The goal here was to build an engine that we could use to view any structure in 3-dimensions as though we had x-ray vision.   We didn’t really know how it might turn out but were delighted with the results!  If you just want the code, skip to the bottom!

We didn’t quite know how to start this so we Googled 3D and Wireframe, and we found this article on wikipedia that really helped us understand what it was:https://en.wikipedia.org/wiki/Wire-frame_model

wireframe examples

This showed us some models and also gave us a clue on how we might do it – they suggested creating two lists – one of “vertexes” or points and another of “edges” or lines.  They gave an example of the points for a cube so we took their example for our first model and expanded to one of size 50 (so we could see it onscreen).

Vertex X Y Z
1 50 50 50
2 50 -50 50
3 -50 -50 50
4 -50 50 50
5 50 50 -50
6 50 -50 -50
7 -50 -50 -50
8 -50 50 -50

Edge table specifies the start and end vertices for each edge.  This table is all about joining points from the points table.

Edge Start Vertex End Vertex
1 1 2
2 2 3
3 3 4
4 4 1
5 5 6
6 6 7
7 7 8
8 8 5
9 1 5
10 2 6
11 3 7
12 4 8

Step 1: First write the code to build the points and draw the cube:

  1. We created 3 lists to store the points: points_x, points_y, points_z
  2. We created two lists to store the edges: edges_from, edges_to
  3. We first added some custom blocks to add values to the lists, making :
    1. add_point (x, y, z) which adds a point to the points lists
    2. add_edge(from, to) which adds an edge to the edge lists
    3. A clear_shape which clears all of the lists with the shape data
    4. build_cube which called the above blocks to add all the items needed for the table above.
    5. We tested these blocks by running the and making sure that when we started the game we had 8 points in each list and 12 edges in the edge lists.

The code for these blocks is below:

build_shape

Step 2: Write the code to draw the shape

  1. We created a custom block to go to a given point go_to_point(point_number)
    1. initially this just went to the x,y of the point_number in the list
  2. We created a custom block to draw the points.  We made sure that the draw_points had “do not refresh screen” checked so that it would run nice and smooth (we did this on all the “draw blocks”)
    draw_points
  3. We also added a very similar draw_lines block which drew the edges
    draw_edges
  4. The main look looked like the following at this stage.  It was pretty simple, just drawing the points and the lines.main_1
  5. At this stage, when we ran the program, it showed us a square:
    square
  6. The reason it looked like a square is because we didn’t have perspective built in.  We looked at perspective for a few minutes and figured out why eyes that work like ours make things look smaller as they get more distant.  We learned out that how quickly things get smaller as they get more distant is called the “perspective

Step 3: Write the code to add perspective

 

  1. Adding perspective was easy – we revisited our go_to_point block and changed it to the following:
    go_to_point
  2. We realize that things don’t get get smaller quite slowly ass they move away so we set the perspective to a very small number – we played around with it a bit till the cube looked like we expected – the value 0.004 looks quite good:
    perspective_value
  3. Now our cube was starting to take shape!
    cube1

Step 4: Rotation!

  1. We again visited the internet to look for how to rotate points about an axis – x, y, or z.  We googled and came to this page: https://www.siggraph.org/education/materials/HyperGraph/modeling/mod_tran/3drota.htm Which showed how it was done.
  2. A point rotates around the X axis by an angle q, it’s Y and Z values change – the webpage showed us the formulas which could tell you how much:
    newY = y*cos q – z*sin q
    newZ = y*sin q + z*cos qSimilarly it showed the formula for rotating around the Y axis:newZ = z*cos q – x*sin q
    newX = z*sin q + x*cos q
  3. We took those and put them in two custom blocks (actually only got one of them finished in the class, but showing both here.  The web page also shows how to do z-axis rotation so feel free to add that into your version if you like!rotation
  4. The final version of the main loop now looks like:
    main_wireframe
  5. I also added some simple blocks to let you control the rotation with the arrow keys:wireframe_controls

That’s IT – a fully functional wireframe model viewer that lets you model, view and rotate any structure in 3D with full perspective!!  All in scratch!

cube_rotate

Feel free to play with it and build other structures – houses, spaceships, random structures, etc.  It is pretty smooth with thousands of points on my old pc.  For example, I added a cloud to the center of the cube with this code at the end of the cube block:

wireframe_cloud

This makes the cube look full of stars – see what you can come up with!

DOWNLOAD THE FULL CODE HERE

If this opens up in a webpage, click on “view raw” to download it.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s