Archive for August, 2024

Homogeneous Coordinates Make for Easy Rays

Monday, August 26th, 2024

This is a bit of a basic observation, but I figured I’d write it down nonetheless.

Suppose you have a transformation matrix in the usual 4×4 form. You transform a point by multiplying the matrix with the vector (in whatever order is conventional for you). Before doing this, you need to convert your point into homogeneous coordinates by adding an extra “1” to the end as the W coordinate. This works great.

But sometimes you need to be able to manipulate pure directions. For example, you’re transforming normal vectors. In this case, you care about rotation and the sign of the scale, but don’t care about the magnitude of the scale, and translation must be excluded. You could do this by first removing the translation from the transformation matrix by changing the last column back to (0, 0, 0, 1)… or, you could do it instead by using 0 as the W coordinate when converting to homogeneous coordinates.

This may seem like a hack, but it’s well-grounded and anything but a hack. 0 as the W coordinate turns the vector into an “infinite-length” vector pointed in a certain direction. Rotations will surely change the direction, as will negative scaling. But scaling infinity by a positive constant still yields infinity, and trying to add any finite value to infinity will be insignificant compared to the infinity, so translations and useless scales naturally fall out.

Fun fact: While projective spaces are quite natural in 3D graphics, I first encountered them when studying elliptic curves. When used in cryptography, there is only one point at infinity, and it functions as the identity element when the curve is interpreted as a group.

OOPs! No Tree Shaking!

Monday, August 19th, 2024

It’s good practice to validate data coming into your program, whether that be from a user, the network, disk, or anywhere else. It’s a first line of defense to prevent bad data from getting into your program and causing problems later, and provides early signals of mismatched expectations or changes in the data format over time.

From JavaScript, JSON is one of the more convenient data serialization formats. Consequently, you need a way to validate that data as well. There are many ways to do this, both declarative and imperative. Declarative, mostly in the form of JSON Schema, holds a lot of appeal to me, but it has some drawbacks of its own.

For my use case, I care a lot about code size. As much as possible, if I am using a library and it has functionality I am not using, I would like that code stripped out of my program by the bundler.

(more…)

Tracking Down a macOS OpenGL Texture Error

Monday, August 12th, 2024

While working on my game, I received this cryptic error, along with no textures visible:

UNSUPPORTED (log once): POSSIBLE ISSUE: unit 0 GLD_TEXTURE_INDEX_2D is unloadable and bound to sampler type (Float) – using zero texture because texture unloadable

There are various mentions of this error around the web. Most of them are random peoples’ bug reports that end up being closed without resolution, but there were a few useful resources I came across.

(more…)

How does Glamorous Toolkit’s PythonBridge Work?

Monday, August 5th, 2024

Glamorous Toolkit offers Python interoperability functionality. It allows mixing Python and Smalltalk more-or-less seamlessly in a Lepiter playground. How does that work? Brace yourselves, it’s boutta get ugly.

The main entry point, from the Smalltalk side, into the integration is PBApplication. There are multiple references to PBApplication start as the way to get it going. PBApplication is a part of PythonBridge, forked by Feenk. PythonBridge is based on the general “LanguageLink” abstraction from PharoLink. In any case, through various abstractions, it uses pipenv to create a virtual environment in the PythonBridgeRuntime subdirectory of the Glamorous Toolkit installation directory. Into this virtual environment, the gtoolkit_bridge package is installed (source in PyPI directory of Feenk’s PythonBridge fork).

The LanguageLink abstraction and gtoolkit_bridge have a protocol for exchanging messages. It can go over one of two transports:

(more…)