James Randall Musings on software development, business and technology.
Empire of Asphalt: Cameras and Picking

Actually maanged to get a decent amount of time in on personal projects this week. Mostly in the morning before work as my best buddy is injured and on 7 days of vet prescribed rest - so no walks.

I’m missing the walks. Its tough on us both. But we’e done lots of brain training and I’ve got some coding in.

First task for the week was to get the camera working properly on the isometric view. This isn’t particularly difficult - basically you are rotating the direction of the “eye” around the point the camera is looking at. However… with the orthographic projection it is quite easy to make a non-obvious mistake because the camera isn’t necessarily where you think it is. I spent ages eyeballing my rotation code, asking an AI about it, looking at other approaches as it just would not rotate around the looked at position.

Eventually it dawned on me something else might be going on…. what if the issue isn’t my rotation but my translation as I move the camera. With the orthographic projection their is no sense of depth so my camera could be in a different position from where I expect and I wouldn’t know. Yup. I’d been translating it on the Z axis rather than the X and Y for up and down movement.

After fixing this it all worked.

Next job was to let me “pick” a tile from the landscape. The final game will have all sorts of objects on the map and some will be behind others and so I needed a way of being able to really know what the user was clicking on accounting for depth and any other rendering factors.

My solution to this was to render the scene again. Yes - again! However this time rather than using the colours of things and rendering to the screen instead I render to an off screen frame buffer and encode an object ID to a colour - a colour, ultimately, being a vector of 4 components that I can treat as a UInt8Array and pack and unpack the object ID into.

After rendering the scene in this form I have a texture that I can read the colour under the mouse position from and decode it back to an objcet ID.

For the landscape I’m using an object ID constructed from the X and Y co-ordinates of the tile and that works a charm.

To do the actual highlight on screen I simply pass the object ID back in, along with the colour encoded IDs, and I can just turn a tile red when a match is found.

This was really pretty simple to implement - though I lost an hour because my object IDs were coming out with weird values when I read the pixel. Eventually I realised that my main renderer was using colour blending for opacity and that that’s a global setting. I turned that off and it all worked like a charm.

Next up is some basic GUI stuff. The city builder has a lot of UI elements to it and I need a decent way of putting that together. The solution I’m pursuing is to use JSX with a custom engine that renders to WebGL. You can point the TypeScript compiler at a custom factory function. So far so good and hopefully in my next update I can share a good demo.

All the code is in the usual place.