Super Mario 64 Source
A Super Mario 64 decompilation, brought to you by a bunch of clever folks.
Macros | Functions | Variables
math_util.c File Reference
#include <ultra64.h>
#include "sm64.h"
#include "engine/graph_node.h"
#include "math_util.h"
#include "surface_collision.h"

Macros

#define CURVE_BEGIN_1   1
 
#define CURVE_BEGIN_2   2
 
#define CURVE_MIDDLE   3
 
#define CURVE_END_1   4
 
#define CURVE_END_2   5
 

Functions

voidvec3f_copy (Vec3f dest, Vec3f src)
 Copy vector 'src' to 'dest'. More...
 
voidvec3f_set (Vec3f dest, f32 x, f32 y, f32 z)
 Set vector 'dest' to (x, y, z) More...
 
voidvec3f_add (Vec3f dest, Vec3f a)
 Add vector 'a' to 'dest'. More...
 
voidvec3f_sum (Vec3f dest, Vec3f a, Vec3f b)
 Make 'dest' the sum of vectors a and b. More...
 
voidvec3s_copy (Vec3s dest, Vec3s src)
 Copy vector src to dest. More...
 
voidvec3s_set (Vec3s dest, s16 x, s16 y, s16 z)
 Set vector 'dest' to (x, y, z) More...
 
voidvec3s_add (Vec3s dest, Vec3s a)
 Add vector a to 'dest'. More...
 
voidvec3s_sum (Vec3s dest, Vec3s a, Vec3s b)
 Make 'dest' the sum of vectors a and b. More...
 
voidvec3s_sub (Vec3s dest, Vec3s a)
 Subtract vector a from 'dest'. More...
 
voidvec3s_to_vec3f (Vec3f dest, Vec3s a)
 Convert short vector a to float vector 'dest'. More...
 
voidvec3f_to_vec3s (Vec3s dest, Vec3f a)
 Convert float vector a to a short vector 'dest' by rounding the components to the nearest integer. More...
 
voidfind_vector_perpendicular_to_plane (Vec3f dest, Vec3f a, Vec3f b, Vec3f c)
 Set 'dest' the normal vector of a triangle with vertices a, b and c. More...
 
voidvec3f_cross (Vec3f dest, Vec3f a, Vec3f b)
 Make vector 'dest' the cross product of vectors a and b. More...
 
voidvec3f_normalize (Vec3f dest)
 Scale vector 'dest' so it has length 1. More...
 
void mtxf_copy (Mat4 dest, Mat4 src)
 Copy matrix 'src' to 'dest'. More...
 
void mtxf_identity (Mat4 mtx)
 Set mtx to the identity matrix. More...
 
void mtxf_translate (Mat4 dest, Vec3f b)
 Set dest to a translation matrix of vector b. More...
 
void mtxf_lookat (Mat4 mtx, Vec3f from, Vec3f to, s16 roll)
 Set mtx to a look-at matrix for the camera. More...
 
void mtxf_rotate_zxy_and_translate (Mat4 dest, Vec3f translate, Vec3s rotate)
 Build a matrix that rotates around the z axis, then the x axis, then the y axis, and then translates. More...
 
void mtxf_rotate_xyz_and_translate (Mat4 dest, Vec3f b, Vec3s c)
 Build a matrix that rotates around the x axis, then the y axis, then the z axis, and then translates. More...
 
void mtxf_billboard (Mat4 dest, Mat4 mtx, Vec3f position, s16 angle)
 Set 'dest' to a transformation matrix that turns an object to face the camera. More...
 
void mtxf_align_terrain_normal (Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw)
 Set 'dest' to a transformation matrix that aligns an object with the terrain based on the normal. More...
 
void mtxf_align_terrain_triangle (Mat4 mtx, Vec3f pos, s16 yaw, f32 radius)
 Set 'mtx' to a transformation matrix that aligns an object with the terrain based on 3 height samples in an equilateral triangle around the object. More...
 
void mtxf_mul (Mat4 dest, Mat4 a, Mat4 b)
 Sets matrix 'dest' to the matrix product b * a assuming they are both transformation matrices with a w-component of 1. More...
 
void mtxf_scale_vec3f (Mat4 dest, Mat4 mtx, Vec3f s)
 Set matrix 'dest' to 'mtx' scaled by vector s. More...
 
void mtxf_mul_vec3s (Mat4 mtx, Vec3s b)
 Multiply a vector with a transformation matrix, which applies the transformation to the point. More...
 
void mtxf_to_mtx (Mtx *dest, Mat4 src)
 Convert float matrix 'src' to fixed point matrix 'dest'. More...
 
void mtxf_rotate_xy (Mtx *mtx, s16 angle)
 Set 'mtx' to a transformation matrix that rotates around the z axis. More...
 
void get_pos_from_transform_mtx (Vec3f dest, Mat4 objMtx, Mat4 camMtx)
 Extract a position given an object's transformation matrix and a camera matrix. More...
 
void vec3f_get_dist_and_angle (Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw)
 Take the vector starting at 'from' pointed at 'to' an retrieve the length of that vector, as well as the yaw and pitch angles. More...
 
void vec3f_set_dist_and_angle (Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw)
 Construct the 'to' point which is distance 'dist' away from the 'from' position, and has the angles pitch and yaw. More...
 
s32 approach_s32 (s32 current, s32 target, s32 inc, s32 dec)
 Return the value 'current' after it tries to approach target, going up at most 'inc' and going down at most 'dec'. More...
 
f32 approach_f32 (f32 current, f32 target, f32 inc, f32 dec)
 Return the value 'current' after it tries to approach target, going up at most 'inc' and going down at most 'dec'. More...
 
static u16 atan2_lookup (f32 y, f32 x)
 Helper function for atan2s. More...
 
s16 atan2s (f32 y, f32 x)
 Compute the angle from (0, 0) to (x, y) as a s16. More...
 
f32 atan2f (f32 y, f32 x)
 Compute the atan2 in radians by calling atan2s and converting the result. More...
 
void spline_get_weights (Vec4f result, f32 t, UNUSED s32 c)
 Set 'result' to a 4-vector with weights corresponding to interpolation value t in [0, 1] and gSplineState. More...
 
void anim_spline_init (Vec4s *keyFrames)
 Initialize a spline animation. More...
 
s32 anim_spline_poll (Vec3f result)
 Poll the next point from a spline animation. More...
 

Variables

s16 gArctanTable []
 
Vec4sgSplineKeyframe
 
float gSplineKeyframeFraction
 
int gSplineState
 

Macro Definition Documentation

◆ CURVE_BEGIN_1

#define CURVE_BEGIN_1   1

◆ CURVE_BEGIN_2

#define CURVE_BEGIN_2   2

◆ CURVE_END_1

#define CURVE_END_1   4

◆ CURVE_END_2

#define CURVE_END_2   5

◆ CURVE_MIDDLE

#define CURVE_MIDDLE   3

Function Documentation

◆ anim_spline_init()

void anim_spline_init ( Vec4s keyFrames)

Initialize a spline animation.

'keyframes' should be an array of (s, x, y, z) vectors s: the speed of the keyframe in 1000/frames, e.g. s=100 means the keyframe lasts 10 frames (x, y, z): point in 3D space on the curve The array should end with three entries with s=0 (infinite keyframe duration). That's because the spline has a 3rd degree polynomial, so it looks 3 points ahead.

◆ anim_spline_poll()

s32 anim_spline_poll ( Vec3f  result)

Poll the next point from a spline animation.

anim_spline_init should be called before polling for vectors. Returns TRUE when the last point is reached, FALSE otherwise.

◆ approach_f32()

f32 approach_f32 ( f32  current,
f32  target,
f32  inc,
f32  dec 
)

Return the value 'current' after it tries to approach target, going up at most 'inc' and going down at most 'dec'.

◆ approach_s32()

s32 approach_s32 ( s32  current,
s32  target,
s32  inc,
s32  dec 
)

Return the value 'current' after it tries to approach target, going up at most 'inc' and going down at most 'dec'.

If target is close to the max or min s32, then it's possible to overflow

◆ atan2_lookup()

static u16 atan2_lookup ( f32  y,
f32  x 
)
static

Helper function for atan2s.

Does a look up of the arctangent of y/x assuming the resulting angle is in range 0, 0x2000.

◆ atan2f()

f32 atan2f ( f32  y,
f32  x 
)

Compute the atan2 in radians by calling atan2s and converting the result.

◆ atan2s()

s16 atan2s ( f32  y,
f32  x 
)

Compute the angle from (0, 0) to (x, y) as a s16.

Given that terrain is in the xz-plane, this is commonly called with (z, x) to get a yaw angle.

◆ find_vector_perpendicular_to_plane()

void* find_vector_perpendicular_to_plane ( Vec3f  dest,
Vec3f  a,
Vec3f  b,
Vec3f  c 
)

Set 'dest' the normal vector of a triangle with vertices a, b and c.

It is similar to vec3f_cross, but it calculates the vectors (c-b) and (b-a) at the same time.

warning: function returns address of local variable

◆ get_pos_from_transform_mtx()

void get_pos_from_transform_mtx ( Vec3f  dest,
Mat4  objMtx,
Mat4  camMtx 
)

Extract a position given an object's transformation matrix and a camera matrix.

This is used for determining the world position of the held object: since objMtx inherits the transformation from both the camera and Mario, it calculates this by taking the camera matrix and inverting its transformation by first rotating objMtx back from screen orientation to world orientation, and then subtracting the camera position.

◆ mtxf_align_terrain_normal()

void mtxf_align_terrain_normal ( Mat4  dest,
Vec3f  upDir,
Vec3f  pos,
s16  yaw 
)

Set 'dest' to a transformation matrix that aligns an object with the terrain based on the normal.

Used for enemies. 'upDir' is the terrain normal 'yaw' is the angle which it should face 'pos' is the object's position in the world

◆ mtxf_align_terrain_triangle()

void mtxf_align_terrain_triangle ( Mat4  mtx,
Vec3f  pos,
s16  yaw,
f32  radius 
)

Set 'mtx' to a transformation matrix that aligns an object with the terrain based on 3 height samples in an equilateral triangle around the object.

Used for Mario when crawling or sliding. 'yaw' is the angle which it should face 'pos' is the object's position in the world 'radius' is the distance from each triangle vertex to the center

◆ mtxf_billboard()

void mtxf_billboard ( Mat4  dest,
Mat4  mtx,
Vec3f  position,
s16  angle 
)

Set 'dest' to a transformation matrix that turns an object to face the camera.

'mtx' is the look-at matrix from the camera 'position' is the position of the object in the world 'angle' rotates the object while still facing the camera.

◆ mtxf_copy()

void mtxf_copy ( Mat4  dest,
Mat4  src 
)

Copy matrix 'src' to 'dest'.

◆ mtxf_identity()

void mtxf_identity ( Mat4  mtx)

Set mtx to the identity matrix.

◆ mtxf_lookat()

void mtxf_lookat ( Mat4  mtx,
Vec3f  from,
Vec3f  to,
s16  roll 
)

Set mtx to a look-at matrix for the camera.

The resulting transformation transforms the world as if there exists a camera at position 'from' pointed at the position 'to'. The up-vector is assumed to be (0, 1, 0), but the 'roll' angle allows a bank rotation of the camera.

◆ mtxf_mul()

void mtxf_mul ( Mat4  dest,
Mat4  a,
Mat4  b 
)

Sets matrix 'dest' to the matrix product b * a assuming they are both transformation matrices with a w-component of 1.

Since the bottom row is assumed to equal [0, 0, 0, 1], it saves some multiplications and addition. The resulting matrix represents first applying transformation b and then a.

◆ mtxf_mul_vec3s()

void mtxf_mul_vec3s ( Mat4  mtx,
Vec3s  b 
)

Multiply a vector with a transformation matrix, which applies the transformation to the point.

Note that the bottom row is assumed to be [0, 0, 0, 1], which is true for transformation matrices if the translation has a w component of 1.

◆ mtxf_rotate_xy()

void mtxf_rotate_xy ( Mtx mtx,
s16  angle 
)

Set 'mtx' to a transformation matrix that rotates around the z axis.

◆ mtxf_rotate_xyz_and_translate()

void mtxf_rotate_xyz_and_translate ( Mat4  dest,
Vec3f  b,
Vec3s  c 
)

Build a matrix that rotates around the x axis, then the y axis, then the z axis, and then translates.

◆ mtxf_rotate_zxy_and_translate()

void mtxf_rotate_zxy_and_translate ( Mat4  dest,
Vec3f  translate,
Vec3s  rotate 
)

Build a matrix that rotates around the z axis, then the x axis, then the y axis, and then translates.

◆ mtxf_scale_vec3f()

void mtxf_scale_vec3f ( Mat4  dest,
Mat4  mtx,
Vec3f  s 
)

Set matrix 'dest' to 'mtx' scaled by vector s.

◆ mtxf_to_mtx()

void mtxf_to_mtx ( Mtx dest,
Mat4  src 
)

Convert float matrix 'src' to fixed point matrix 'dest'.

The float matrix may not contain entries larger than 65536 or the console crashes. The fixed point matrix has entries with a 16-bit integer part, so the floating point numbers are multipled by 2^16 before being cast to a s32 integer. If this doesn't fit, the N64 and iQue consoles will throw an exception. On Wii and Wii U Virtual Console the value will simply be clamped and no crashes occur.

float-to-integer conversion responsible for PU crashes

◆ mtxf_translate()

void mtxf_translate ( Mat4  dest,
Vec3f  b 
)

Set dest to a translation matrix of vector b.

◆ spline_get_weights()

void spline_get_weights ( Vec4f  result,
f32  t,
UNUSED s32  c 
)

Set 'result' to a 4-vector with weights corresponding to interpolation value t in [0, 1] and gSplineState.

Given the current control point P, these weights are for P[0], P[1], P[2] and P[3] to obtain an interpolated point. The weights naturally sum to 1, and they are also always in range [0, 1] so the inteprolated point will never overshoot. The curve is guaranteed to go through the first and last point, but not through intermediate points.

gSplineState ensures that the curve is clamped: the first two points and last two points have different weight formulas. These are the weights just before gSplineState transitions: 1: [1, 0, 0, 0] 1->2: [0, 3/12, 7/12, 2/12] 2->3: [0, 1/6, 4/6, 1/6] 3->3: [0, 1/6, 4/6, 1/6] (repeats) 3->4: [0, 1/6, 4/6, 1/6] 4->5: [0, 2/12, 7/12, 3/12] 5: [0, 0, 0, 1]

I suspect that the weight formulas will give a 3rd degree B-spline with the common uniform clamped knot vector, e.g. for n points: [0, 0, 0, 0, 1, 2, ... n-1, n, n, n, n] TODO: verify the classification of the spline / figure out how polynomials were computed

◆ vec3f_add()

void* vec3f_add ( Vec3f  dest,
Vec3f  a 
)

Add vector 'a' to 'dest'.

warning: function returns address of local variable

◆ vec3f_copy()

void* vec3f_copy ( Vec3f  dest,
Vec3f  src 
)

Copy vector 'src' to 'dest'.

warning: function returns address of local variable

◆ vec3f_cross()

void* vec3f_cross ( Vec3f  dest,
Vec3f  a,
Vec3f  b 
)

Make vector 'dest' the cross product of vectors a and b.

warning: function returns address of local variable

◆ vec3f_get_dist_and_angle()

void vec3f_get_dist_and_angle ( Vec3f  from,
Vec3f  to,
f32 dist,
s16 pitch,
s16 yaw 
)

Take the vector starting at 'from' pointed at 'to' an retrieve the length of that vector, as well as the yaw and pitch angles.

◆ vec3f_normalize()

void* vec3f_normalize ( Vec3f  dest)

Scale vector 'dest' so it has length 1.

Possible division by zero

warning: function returns address of local variable

◆ vec3f_set()

void* vec3f_set ( Vec3f  dest,
f32  x,
f32  y,
f32  z 
)

Set vector 'dest' to (x, y, z)

warning: function returns address of local variable

◆ vec3f_set_dist_and_angle()

void vec3f_set_dist_and_angle ( Vec3f  from,
Vec3f  to,
f32  dist,
s16  pitch,
s16  yaw 
)

Construct the 'to' point which is distance 'dist' away from the 'from' position, and has the angles pitch and yaw.

◆ vec3f_sum()

void* vec3f_sum ( Vec3f  dest,
Vec3f  a,
Vec3f  b 
)

Make 'dest' the sum of vectors a and b.

warning: function returns address of local variable

◆ vec3f_to_vec3s()

void* vec3f_to_vec3s ( Vec3s  dest,
Vec3f  a 
)

Convert float vector a to a short vector 'dest' by rounding the components to the nearest integer.

warning: function returns address of local variable

◆ vec3s_add()

void* vec3s_add ( Vec3s  dest,
Vec3s  a 
)

Add vector a to 'dest'.

warning: function returns address of local variable

◆ vec3s_copy()

void* vec3s_copy ( Vec3s  dest,
Vec3s  src 
)

Copy vector src to dest.

warning: function returns address of local variable

◆ vec3s_set()

void* vec3s_set ( Vec3s  dest,
s16  x,
s16  y,
s16  z 
)

Set vector 'dest' to (x, y, z)

warning: function returns address of local variable

◆ vec3s_sub()

void* vec3s_sub ( Vec3s  dest,
Vec3s  a 
)

Subtract vector a from 'dest'.

warning: function returns address of local variable

◆ vec3s_sum()

void* vec3s_sum ( Vec3s  dest,
Vec3s  a,
Vec3s  b 
)

Make 'dest' the sum of vectors a and b.

warning: function returns address of local variable

◆ vec3s_to_vec3f()

void* vec3s_to_vec3f ( Vec3f  dest,
Vec3s  a 
)

Convert short vector a to float vector 'dest'.

warning: function returns address of local variable

Variable Documentation

◆ gArctanTable

s16 gArctanTable[]

◆ gSplineKeyframe

Vec4s* gSplineKeyframe

◆ gSplineKeyframeFraction

float gSplineKeyframeFraction

◆ gSplineState

int gSplineState