Skip to content

Instantly share code, notes, and snippets.

@ancientstraits
Created March 30, 2026 04:04
Show Gist options
  • Select an option

  • Save ancientstraits/90c07fe22102d1aaefe76f62a5300085 to your computer and use it in GitHub Desktop.

Select an option

Save ancientstraits/90c07fe22102d1aaefe76f62a5300085 to your computer and use it in GitHub Desktop.
Swivel.
// This function, is one of the BIGGEST endeavors I have ever taken on.
// This function is something I have spent DAYS on.
// I think it might have started on Thursday, or even earlier.
// I was able to convert `swivel_vert` to matrix form, with one catch:
// z' = z is not possible. So z' = -zcoord here.
// I wonder if after successfully implementing this function,
// I'll even want to work on the game anymore.
// What if I feel burnt out, before I even started making the game?
// Hopefully that does not happen.
// I want to make a video on this WHOLE thing, so that happening would be an absolute SHAME.
// mid (or (mx, my)): The "vanishing point" for the perspective projection
// angle (radians): The amount to rotate the plane by, on the Y-axis
// pfactor (f): Larger pfactor means more perspective effect. pfactor=0.001 is fine.
// zcoord (K): The transformed z-coordinate will equal -K.
static void swivel_begin(Vector2 mid, float angle, float pfactor, float zcoord) {
// My apologies for these abbreviations.
// I derived my work using math notation (single-letter variables),
// so it's easier for me if I write it this way.
float mx = mid.x, my = mid.y;
float a = angle;
float f = pfactor;
float k = zcoord;
float c = cos(angle);
float s = sin(angle);
Matrix mat;
// TODO should I do a*b*c or a * b * c here?
mat.m0 = c - (f * mx *s);
mat.m1 = -f * my * s;
mat.m2 = k * f * s;
mat.m3 = -f * s;
mat.m4 = 0.0f;
mat.m5 = 1.0f;
mat.m6 = 0.0f;
mat.m7 = 0.0f;
mat.m8 = 0.0f;
mat.m9 = 0.0f;
mat.m10 = 0.0f;
mat.m11 = 0.0f;
mat.m12 = mx * (1 - c + (f * mx * s));
mat.m13 = f * mx * my * s;
mat.m14 = -k * (1 + (f * mx * s));
mat.m15 = 1 + (f * mx * s);
rlPushMatrix();
rlLoadIdentity();
rlMultMatrixm(mat);
}
static void swivel_end() {
rlPopMatrix();
}
// A matrixless solution (I made this before making swivel_begin())
// (this is actually more efficient.
// I think the vertex shader approach to doing this, could be better than using a transformation matrix)
static void swivel_vert(float x, float y, float mx, float my, float angle) {
// Assume middle is z = -1
float xrot = mx + (x - mx) * cos(angle);
float yrot = y; // rotating horizontally, so y is unchanged here
float zrot = -1 + 0.001 * (x - mx) * sin(angle);
float xnew = ((xrot - mx) / -zrot) + mx;
float ynew = ((yrot - my) / -zrot) + my;
rlVertex2f(xnew, ynew);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment