tunepunk

I had some fun trying my hand at implementing some of that stuff. My events are mostly clean and as readable as possible, although it's at the point where a lot of it needs to be refactored and cleaned up. It is mostly organized so maybe you'll find it useful.

What it does is fairly straight forward.

1

The object file is loaded so we have a list of 3d points and a list of faces which list indices of the points.

2

The points are moved around, or in the capx rotated around in 3d.

**Rotation**

The rotation math to rotate on the xy plane is this:

newx = x*cos(ang)-y*sin(ang)

newy = y*cos(ang)+x*sin(ang)

It's basically the same for xz or yz rotations. Just change the x,y variables.

Changing the amount of rotation every frame can be used for animation.

**Translation**

Next after rotating the points around we need to move the points away from 0,0,0 which is the viewer position. So for example we want the object center to be five units in front of the viewer you could do this:

newz = z+5

This is important to do before the perspective transform because things get distorted near 0 and we shouldn't be able to see points with z<0 or behind the camera.

**Perspective**

Perspective is really simple, it's just multiplying x,y by a scale number and dividing by z:

perspectiveX= x*scale/z

perspectiveY= y*scale/z

**final transformation to screen position**

This is basically changing the center from 0,0 to the center of the screen.

screenx = x+320

screeny = y+240

3

Now that the points are transformed we next want to draw points and lines and perhaps polygons. There are a few ways that come to mind.

**Using sprites**

Sprites could be created at the transformed xy position and lines could be done by stretching sprites from one point to another. Polygons could be done with some madness with triangle sprites but that's not straightforward.

**Using the canvas plugin**

You can plot points, draw lines and draw polygons fairly easy. The antialiased lines may not be what you want. Also the paster plugin can be used for textured polygons but that's a different topic.

**Using a tilemap**

The tilemap can be thought of as an array and it removes the step needed to convert the array to something visual. One color is simple but if you look at the capx it shows a way to do a spectrum of colors, well 4096 to be exact. It takes red,green and blue components in the range of 0 to 15 and converts it to a tile number.

**Line drawing**

This is done by lerping from the one point to the other and drawing the inbetween points. Look the "plot line" function in the capx, it's fairly simple.

**polygon drawing**

This took me a bit to wrap my head around. I tried two methods to draw triangles.

The first one is fairly simple to understand. First you find the bounding box that contains the all three points of the triangle, then you loop over every pixel in that bounding box and see if that pixel is inside the polygon. Unfortunately the math looks a bit hairy.

The second method is a scanline method which is faster. It involves sorting the three points by y and then lerping along the edges to get the x positions at every y. It has less hairy math but isn't the simplest to understand either.

Performance on the monkey model is about 4-6 fps and I don't think a whole lot of extra performance for this can be squeezed out of the events. This sort of thing is always pretty slow which is why the rasterization is usually all done by the gpu. It can be made faster if most of it was done in javascript, and the events were only used to issue commands. 60fps should be possible with the events ported directly over, but js isn't pleasant to work with imo.