Skip to content

Instantly share code, notes, and snippets.

@gfreivasc
Created August 17, 2016 13:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gfreivasc/1a2699613038330d8d324ba2b297e4ba to your computer and use it in GitHub Desktop.
Save gfreivasc/1a2699613038330d8d324ba2b297e4ba to your computer and use it in GitHub Desktop.
WorldToScreen 16:9
/**********************************
Credits to OGC for world2screen
**********************************/
inline float VectorAngle(const vec3_t a, const vec3_t b)
{
float length_a = VectorLength(a);
float length_b = VectorLength(b);
float length_ab = length_a*length_b;
if (length_ab == 0.0) { return 0.0; }
else { return (float)(acos(DotProduct(a, b) / length_ab) * (180.f / M_PI)); }
}
void MakeVector(const vec3_t ain, vec3_t vout)
{
float pitch;
float yaw;
float tmp;
pitch = (float)(ain[0] * M_PI / 180);
yaw = (float)(ain[1] * M_PI / 180);
tmp = (float)cos(pitch);
vout[0] = (float)(-tmp * -cos(yaw));
vout[1] = (float)(sin(yaw)*tmp);
vout[2] = (float)-sin(pitch);
}
void VectorRotateX(const vec3_t in, float angle, vec3_t out)
{
float a, c, s;
a = (float)(angle * M_PI / 180);
c = (float)cos(a);
s = (float)sin(a);
out[0] = in[0];
out[1] = c*in[1] - s*in[2];
out[2] = s*in[1] + c*in[2];
}
void VectorRotateY(const vec3_t in, float angle, vec3_t out)
{
float a, c, s;
a = (float)(angle * M_PI / 180);
c = (float)cos(a);
s = (float)sin(a);
out[0] = c*in[0] + s*in[2];
out[1] = in[1];
out[2] = -s*in[0] + c*in[2];
}
void VectorRotateZ(const vec3_t in, float angle, vec3_t out)
{
float a, c, s;
a = (float)(angle * M_PI / 180);
c = (float)cos(a);
s = (float)sin(a);
out[0] = c*in[0] - s*in[1];
out[1] = s*in[0] + c*in[1];
out[2] = in[2];
}
bool CDraw::worldToScreen(vec3_t w, int *x, int *y) {
vec3_t aim;
vec3_t newaim;
vec3_t view;
vec3_t tmp;
float num, fov;
VectorCopy(sky.cgame.refdef->vieworg, tmp);
VectorSubtract(w, tmp, aim);
MakeVector(sky.cgame.refdefViewAngles, view);
fov = sky.cgame.refdef->fov_x;
fov += (9.f / 40.f) * fov + (3.f / 4.f) + 1.f; // Ignoring 16:10 as for now
if (VectorAngle(view, aim) > (fov / 1.8))
return false;
VectorRotateZ(aim, -sky.cgame.refdefViewAngles[YAW], newaim);
VectorRotateY(newaim, -sky.cgame.refdefViewAngles[PITCH], tmp);
VectorRotateX(tmp, -sky.cgame.refdefViewAngles[ROLL], newaim);
if (newaim[0] <= 0)
return false;
num = (float)((640.0f / newaim[0]) * (120.0 / fov - 1.0 / 3.0));
*x = (int)(640 - num * newaim[1]);
*y = (int)(360 - num * newaim[2]);
BOUND_VALUE(*x, 0, 1280);
BOUND_VALUE(*y, 0, 720);
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment