action actCameraCollider () {
proc_mode = PROC_LATE; // execute after player action
my->flags |= INVISIBLE | PASSABLE | FAT | NARROW;
vec_set(&my->max_x, vector(16, 16, 16)); // collision hull
vec_set(&my->min_x, vector(-16, -16, -16));
VECTOR vOffset;
vec_set(&vOffset, vector(0, -7, 35)); // camera rotation center in player space
var nCamDist = 200; // distance to the center
...
vec_set(&my->x, &vOffset); // set the collider position in reference to the player position and orientation
vec_rotate(&my->x, &player->pan);
vec_add(&my->x, &player->x);
VECTOR vDir;
vec_for_angle(&vDir, &camera->pan); // compute the inverse of the view ray; the trace is backwards
vec_scale(&vDir, -nCamDist);
VECTOR vTarget; // compute the target position for c_trace
vec_set(&vTarget, &my->x); // it is also the final camera position when the trace collides nothing
vec_add(&vTarget, &vDir);
you = player;
var nDist = c_trace(&my->x, &vTarget, IGNORE_YOU | IGNORE_PASSABLE | USE_BOX);
if (nDist > 0) { // when it collides
vec_normalize(&vDir, nDist); // enshort the view ray
vec_set(&camera->x, &my->x); // and recompute the position of the camera
vec_add(&camera->x, &vDir);
} else { // when it does not collide
vec_set(&camera->x, &vTarget); // set the already computed position of the camera
}
...