-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtransform.c
46 lines (41 loc) · 1.58 KB
/
transform.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "transform.h"
// Matrix update, calculate transform = world * view * projection (matrix multiplication)
void transform_update(transform_t *ts) {
matrix_t m;
matrix_mul(&m, &ts->world, &ts->view);
matrix_mul(&ts->transform, &m, &ts->projection);
}
//Initialize, set the screen length and width and calculate the perspective transformation matrix
void transform_init(transform_t *ts, int width, int height) {
float aspect = (float)width / ((float)height);
matrix_set_identity(&ts->world);
matrix_set_identity(&ts->view);
matrix_set_perspective(&ts->projection, 3.1415926f * 0.5f, aspect, 1.0f, 500.0f);
ts->w = (float)width;
ts->h = (float)height;
transform_update(ts);
}
// Project the vector x to the screen, and the result is stored in y
void transform_apply(const transform_t *ts, vector_t *y, const vector_t *x) {
matrix_apply(y, x, &ts->transform);
}
// Check the boundaries of homogeneous coordinates and cvv for frustum clipping (return 0 if it is in the visible area)
int transform_check_cvv(const vector_t *v) {
float w = v->w;
int check = 0;
if (v->z < 0.0f) check |= 1;
if (v->z > w) check |= 2;
if (v->x < -w) check |= 4;
if (v->x > w) check |= 8;
if (v->y < -w) check |= 16;
if (v->y > w) check |= 32;
return check;
}
//Normalize to get screen coordinates (x, y, z, w) -> (x/w, y/w, z/w, 1)
void transform_homogenize(const transform_t *ts, vector_t *y, const vector_t *x) {
float rhw = 1.0f / x->w;
y->x = (x->x * rhw + 1.0f) * ts->w * 0.5f;
y->y = (1.0f - x->y * rhw) * ts->h * 0.5f;
y->z = x->z * rhw;
y->w = 1.0f;
}