all boils down to (4x4) * (4x1)
multiplication where some elements are known so it can be done with 4 * 4D
dot products in full but sometimes its enough just 3 * 3D
dots and single 3D addition ... For more info see
with fixed point and 4bit digit long multiplication + LUT is the multiplication not that slow ... Anyway asm was pretty fast and capable of doing this easily ... remember there where not many objects in Elite around.
However at the time of Elite was common to use quaternions instead of transform matrices which required much less operations for rotation So Elite most likely used those.
[Edit1]
Thanks to Mick Waites I found this:
which is reverse engineered BBC Elite source code in C. However from a quick look at the alg_gfx.c
its clear it uses different gfx engine at low level as some of the stuff did not exist at the time. Its something between BGI,3Dfx and SW. But it might be just resolution and gfx API handling for different platforms.
in elite.h
the player is defined as:
struct player_ship
{
int max_speed;
int max_roll;
int max_climb;
int max_fuel;
int altitude;
int cabtemp;
};
extern int flight_speed;
extern int flight_roll;
extern int flight_climb;
which implies something like Euler Angles (but just 2 instead of 3 probably to avoid gimbal locks).
in vector.h
there is:
struct vector
{
double x;
double y;
double z;
};
typedef struct vector Matrix[3];
typedef struct vector Vector;
void mult_matrix (struct vector *first, struct vector *second);
void mult_vector (struct vector *vec, struct vector *mat);
double vector_dot_product (struct vector *first, struct vector *second);
struct vector unit_vector (struct vector *vec);
void set_init_matrix (struct vector *mat);
void tidy_matrix (struct vector *mat);
Which implies 3x3
rotational matrix usage (so not uniform 4x4 !!!). It looks like the transformations are done in space.c
:
void move_univ_object (struct univ_object *obj)
{
double x,y,z;
double k2;
double alpha;
double beta;
int rotx,rotz;
double speed;
alpha = flight_roll / 256.0;
beta = flight_climb / 256.0;
x = obj->location.x;
y = obj->location.y;
z = obj->location.z;
if (!(obj->flags & FLG_DEAD))
{
if (obj->velocity != 0)
{
speed = obj->velocity;
speed *= 1.5;
x += obj->rotmat[2].x * speed;
y += obj->rotmat[2].y * speed;
z += obj->rotmat[2].z * speed;
}
if (obj->acceleration != 0)
{
obj->velocity += obj->acceleration;
obj->acceleration = 0;
if (obj->velocity > ship_list[obj->type]->velocity)
obj->velocity = ship_list[obj->type]->velocity;
if (obj->velocity <= 0)
obj->velocity = 1;
}
}
k2 = y - alpha * x;
z = z + beta * k2;
y = k2 - z * beta;
x = x + alpha * y;
z = z - flight_speed;
obj->location.x = x;
obj->location.y = y;
obj->location.z = z;
obj->distance = sqrt (x*x + y*y + z*z);
if (obj->type == SHIP_PLANET)
beta = 0.0;
rotate_vec (&obj->rotmat[2], alpha, beta);
rotate_vec (&obj->rotmat[1], alpha, beta);
rotate_vec (&obj->rotmat[0], alpha, beta);
if (obj->flags & FLG_DEAD)
return;
rotx = obj->rotx;
rotz = obj->rotz;
/* If necessary rotate the object around the X axis... */
if (rotx != 0)
{
rotate_x_first (&obj->rotmat[2].x, &obj->rotmat[1].x, rotx);
rotate_x_first (&obj->rotmat[2].y, &obj->rotmat[1].y, rotx);
rotate_x_first (&obj->rotmat[2].z, &obj->rotmat[1].z, rotx);
if ((rotx != 127) && (rotx != -127))
obj->rotx -= (rotx < 0) ? -1 : 1;
}
/* If necessary rotate the object around the Z axis... */
if (rotz != 0)
{
rotate_x_first (&obj->rotmat[0].x, &obj->rotmat[1].x, rotz);
rotate_x_first (&obj->rotmat[0].y, &obj->rotmat[1].y, rotz);
rotate_x_first (&obj->rotmat[0].z, &obj->rotmat[1].z, rotz);
if ((rotz != 127) && (rotz != -127))
obj->rotz -= (rotz < 0) ? -1 : 1;
}
/* Orthonormalize the rotation matrix... */
tidy_matrix (obj->rotmat);
}
So if I see it right the rendering uses 3x3 rotation matrix + 3D translation vector (I commonly use that too in the 8bit past) and to compute the translation there is a strange formula:
k2 = y - alpha * x;
z = z + beta * k2;
y = k2 - z * beta;
x = x + alpha * y;
z = z - flight_speed;
That looks something between quaternion, Euler angles and 2D rotation... To sumarize the math is mostly:
- 3x3 rotation transform matrtix
- 3D translation
- 2 Euler angles