A three.js voxel digital circuit simulator

Well the university semester’s now over. I never ended up updating about my three.js project much as many of the middle weeks involved researching into improving my program’s performance.

In any case, here’s the final result. It’s not great (memory usage is high) but it works. You can even do stuff like make binary counters!

Actually, this is half the reason I made the JK flip flop a block

Actually, this is half the reason I made the JK flip flop a block

Edit: It’s been over a year now, and recent updates to Chrome have meant that the simulator no longer works with the latest Chrome versions. Darn.

[Week 3] Research into three.js and rendering performance

A slow week with the project, largely due to the performance obstacle that I’ve run into. After last week’s block placement test, I decided to try rendering more and more cubes to see how many cubes my computer could render before it starts lagging.

I created two tests – 10000 cubes and 90000 cubes. My computer could still handle 10000 cubes, but 90000 cubes took ages to load and it was very hard to move in the environment. This is a bit of a problem, because I expect the number of cubes that need to be rendered to possibly be in the several hundred thousands. I made another benchmarking test – it turns out that my computer will drop to a single digit frame rate at about 22500 cubes.

Of course, I haven’t done any optimisations yet. Everything is in a simple array, and every cube is rendered individually. But not being able to handle 90000 cubes even at this stage is a worry. Even though three.js abstracts away all the low-level WebGL, examples like this, this and this make me feel as though that there’s got to be a way around it.

There’s a lot of posts on the internet saying that using shaders can improve performance for WebGL, but there’s a bit of a problem for me – I still don’t get what shaders are. They don’t only “shade”, you see – not nowadays, anyway. Shaders confuse me.

On another note, 0fps has some great tips on building a voxel engine. I’m not sure how easy run-length encoding plus an interval tree would be to implement, but it’s an idea alright. I’m still trying to figure out a good way to store my cubes so that:

  • They don’t take up much space (the world can get large)
  • It’s easy to read/write from the data structure
  • I can get the neighbour of a cube easily

I have to say, optimising performance is one hell of a problem.

… oh and I’ve also figured out how to get textures working.

[Week 2] Block placement

Why the random colours? I was too lazy to do anything else.

Why the random colours? I was too lazy to do anything else.

My project has evolved to the state of “webtoy”!

Here’s the latest demo – it’s a block placement test. Nothing fancy so far, but at least I have some functionality going on.

I have a few notes though:

  • The crosshair may be slightly offcentre. I have yet to figure out how to fix this one properly.
  • Try to use Chrome. The site will load fine in Firefox, but there’s a few bugs and I haven’t actually bothered to try testing in Firefox yet.

If anyone’s interested in how the block detection was done… the magic phrase is “ray casting”. I didn’t implement the ray casting myself though – three.js has a RayCaster class inbuilt. Also, the intersect function that three.js has even detects which face of the cube is selected, so that saved me a lot of work.

The other thing I had to figure out was how to convert from Euler angles to a direction vector. Luckily, StackOverflow is very good at questions like these.

[Week 1] Pointer locks and browser 3D

Cuuuuubes

Cuuuuubes

This week marks the start of a semester long project I’ll be doing as part of a university course. The plan is to *whispers incomprehensibly* requiring WebGL and *whispers incomprehensibly* will probably be familiar to those who play Minecraft.

For now I have a WebGL page up here – initially i was going to make everything using WebGL directly, but after confusing myself with buffers and shaders I resorted to using the three.js library instead. It’s making my life a lot easier.

Here is a summary of my triumphs and failures in this past week:

  • Getting the Pointer Lock API to work in Chrome: Pointer locking is where your cursor is disabled. It allows you to do things like spin around and around without having to worry about your cursor hitting the edge of your window. It took me a while until I realised that Chrome only allows pointer locking after some sort of user input (e.g. mouse click).
  • Researching DartAs good as Dart seems to be as a Javascript alternative, I got utterly confused when trying to work out how to use Javascript libraries from Dart. So I gave up and reverted back to JS.
  • Getting something to actually work: This. So far it only works in Google Chrome though – and the only other browser I’m planning to support is Firefox. That’s because these two browsers are the only ones which support the Pointer Lock API so far. Firefox has this annoying thing where the pointer locking only kicks in for full screen mode though…

So huzzah. I’m off to (some sort of) start.

Graph drawing in LaTeX

Graphs? No, not pie graphs. Not even graphs of functions. THESE graphs.

Yesterday I tried making LaTeX notes for one of my maths courses. Not so much because I needed digital notes (to be honest it would have been much faster on paper), but because I wanted to get some practice at typing up documents in LaTeX.

I aimed to finish the discrete maths half of the course in a day, just to see how quickly I could make the document. After all, LaTeX has a steep learning curve, and some people, like me initially, probably have the impression that LaTeX would be slower than other what-you-see-is-what-you-get word processing software. Well, I met my aim.

However, to be fair, discrete maths only involved a lot of equations, which are easy to type up once you’re used to it. Graph theory, the other half of the course however, would definitely take longer due to the diagrams that had to be drawn. Well I thought it would take a very long time, but that’s because I only started looking into how to draw LaTeX graphs today.

It’s a shame that I only know a few words of French. At least the code’s in English though

I found out, after some research, that there is a tkz-graph package for LaTeX. It makes graph drawing pretty easy. Installing it took some figuring out, but it turned out that MikTeX has an installer for packages inbuilt, which was very useful.

The good thing about tkz-graph is that you can define vertices, and then reference them when creating edges. I haven’t worked out most of the features yet, but I can make some simple graphs now at least.

Simple graphs.

Here’s the code I used to generate the first of the graphs (the other two are similar):

\begin{minipage}[b]{0.3333\linewidth}
\centering
    \begin{tikzpicture}[scale=.5]
        SetGraphUnit{2}
        \GraphInit[vstyle=Classic]
        \tikzset{VertexStyle/.style= {fill=black, inner sep=2pt, shape=circle}}

        \begin{scope}[rotate=135]
        \Vertices[Lpos=135, unit=2, NoLabel]{circle}{A, B, C, D}
        \end{scope}

        \Edges(A, B, C, D)
    \end{tikzpicture}
\end{minipage}

For those interested, here’s a few quick notes about what I know, and don’t know about the above code:

  • The \begin{minipage} is what allows me to show three graphs side by side. Make sure your minipage blocks of code don’t have any empty lines in between them though, or your diagrams will appear under each other as opposed to adjacent (empty lines are like telling LaTeX “I want a new paragraph!”)
  • I’ve got SetGraphUnit{2} there, which refers to how far about everything is. However, I’ve also got unit=2 when defining the vertices – I put that there because for some reason some graphs were turning out smaller than others if I didn’t have it…
  • In the \tikzset command, inner sep=2pt makes the vertices smaller than their usual size.
  • The Lpos=135 argument of the \Vertices command refers to the positioning of the vertex labels in relation to the vertices (135 degrees rotation). I’ve also set labels off with NoLabel though, so it’s not actually doing anything.
  • \Edges draws edges continuously, so \Edges{A, B, C, D} draws the edges AB, BC and CD.  For a single edge, use \Edge(A)(B).

I’m only just starting out though, so this will get interesting when I have to draw more complex graphs. As a forward reference though, here’s some things I’ll be expecting to use:

  • There is a label option for the edges, which will come in handy for weighted graphs.
  • tikz supports a \foreach command, which is like a programming for loop for repetitive tasks. This will probably come in useful for drawing complete graphs.

Too lazy to click links

Quite a lot of files to download and not enough patience in me

Quite a lot of files to download and not enough patience in me

It’s the end of the university semester, and that means downloading-every-available-resource time. For archiving reasons.

Unfortunately, there are a lot of files to be downloaded. For instance, one subject might have  12 weeks of content, each week having a tutorial sheet, a tutorial solution, a practice class sheet and a practice class solution. That’s 48 links already, and that doesn’t even include past exams and other resources yet!

So I started to think, maybe I could use Python and Requests to nab the files I need. First I’d specify a URL, an output folder and the types of files to be downloaded (pdf, tex, etc). Then all I would have to do is run the program and voila! Everything downloaded in a second!

Well, that only worked for my first subject.

Unfortunately, other subjects needed a bit more work to get the files – you had to first log in with your university account. I saw this coming, so I was surprised that my first attempt even worked (maybe the lecturer just couldn’t be bothered).

I didn’t end up figuring my way around this. Requests has a way of submitting forms by using requests.post(url, data), but unfortunately my university used some sort of authentication I couldn’t work out. Other subjects I didn’t even attempt, since they were on a completely different system which also required logging into.

One thing I did learn from this, however, is that you can download files with Requests quite easily. Fetch the file with r = requests.get(url), and the binary data can be found in r.content. Then all you have to do is write to a file using open(filename, “wb”).

What this means is that when I wrote my xkcd comic downloader, I didn’t actually have to use the Python Imaging Library. I could have just written to a file directly using the “wb” mode – and in fact this would also resolve my problem of downloaded GIFs being static

An overview of past projects

High school quality graphics.

Over time you learn new things, and find new ways to apply what you know. Or maybe there’s something you don’t yet know but want to learn, so you decide to look it up and play around with it.

That, in a nutshell, is how my post-primary school life went. I’d (infrequently) embark on new experiments, generally digital ones, and make something small over the course of a few days. Rarely did I ever create a large project which gave off a sense of completion, but nonetheless even the small projects were nice learning experiences.

Here I thought I’d share… quite a lot of these projects. Maybe you’ll find my journey amusing, and consider this a nice read. Or maybe I can somehow motivate you to try things you’ve never done before. Either way, enjoy.

(This is quite a long post, so feel free to skim the page and read the parts that look interesting. My heartfelt thanks goes to you if you end up reading it all though.)

Continue reading