Coordinate systems

From Boktai Hacking Wiki

The game does all game logic and physics calculation in orthogonal 3D space (that is, not isometric). The isometric projection step is only performed during the render phase of the game. The are three coordinate systems in use:

  1. World space: Orthogonal coordinate system. All game logic calculations are performed in this coordinate system.
  2. View space: Isometric coordinate system. Result of running world space coordinates through the isometric projection.
  3. Screen space: Result of translating view space such that the top-left corner of the visible view space has coordinates (0, 0). This is determined by the camera coordinates.

Forward conversion

To go from world space to screen space:

vec3 world_to_view(vec3 world) {
  i32 y_scaled = world.y * 0x18 / 0x100;
  i32 xz = (world.x/2 + world.z/2) * 0x30 / 0x100;
  return {
    (world.x/2 - world.z/2) * 0x30 / 0x100,
    xz - y_scaled,
    xz + y_scaled,
  };
}

const int GBA_SCREEN_WIDTH = 240;
const int GBA_SCREEN_HEIGHT = 160;
vec3 view_to_screen(vec3 view, vec3 camera) {
  return {
    view.x - camera.x + GBA_SCREEN_WIDTH/2,
    view.y - camera.y + GBA_SCREEN_HEIGHT/2,
    view.z - camera.z,
  };
}

Alternatively, replace the world_to_view() function with a multiplication by the following 3x3 matrix:

matrix3x3 worldToView = {
    0.09375, 0, -0.09375,
    0.09375, -0.09375, 0.09375,
    0.09375, 0.09375, 0.09375,
};

Reverse conversion

TODO