mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-10 12:41:35 -10:00
There are a lot of changes here that should probably be examined, namely the Debug Console (which had conflicts) and Yarn's "any resolution" mainhalls code (Which also had conflicts) but for the most part this should be fairly clean. git-svn-id: svn://svn.icculus.org/fs2open/branches/antipodes@10912 387891d4-d844-0410-90c0-e4c51a9137d3
288 lines
5.8 KiB
C++
288 lines
5.8 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
#include "graphics/2d.h"
|
|
#include "hud/hud.h" //For HUD_offset_*
|
|
#include "render/3dinternal.h"
|
|
|
|
#define MIN_Z 0.0f
|
|
|
|
/**
|
|
* Codes a vector. Returns the codes of a point.
|
|
*/
|
|
ubyte g3_code_vector(vec3d * p)
|
|
{
|
|
ubyte cc=0;
|
|
|
|
if (p->xyz.x > p->xyz.z)
|
|
cc |= CC_OFF_RIGHT;
|
|
|
|
if (p->xyz.y > p->xyz.z)
|
|
cc |= CC_OFF_TOP;
|
|
|
|
if (p->xyz.x < -p->xyz.z)
|
|
cc |= CC_OFF_LEFT;
|
|
|
|
if (p->xyz.y < -p->xyz.z)
|
|
cc |= CC_OFF_BOT;
|
|
|
|
if (p->xyz.z < MIN_Z )
|
|
cc |= CC_BEHIND;
|
|
|
|
if ( G3_user_clip ) {
|
|
// Check if behind user plane
|
|
if ( g3_point_behind_user_plane(p)) {
|
|
cc |= CC_OFF_USER;
|
|
}
|
|
}
|
|
|
|
return cc;
|
|
}
|
|
|
|
|
|
/**
|
|
* Code a point. fills in the p3_codes field of the point, and returns the codes
|
|
*/
|
|
ubyte g3_code_vertex(vertex *p)
|
|
{
|
|
ubyte cc=0;
|
|
|
|
if (p->world.xyz.x > p->world.xyz.z)
|
|
cc |= CC_OFF_RIGHT;
|
|
|
|
if (p->world.xyz.y > p->world.xyz.z)
|
|
cc |= CC_OFF_TOP;
|
|
|
|
if (p->world.xyz.x < -p->world.xyz.z)
|
|
cc |= CC_OFF_LEFT;
|
|
|
|
if (p->world.xyz.y < -p->world.xyz.z)
|
|
cc |= CC_OFF_BOT;
|
|
|
|
if (p->world.xyz.z < MIN_Z )
|
|
cc |= CC_BEHIND;
|
|
|
|
if ( G3_user_clip ) {
|
|
// Check if behind user plane
|
|
if ( g3_point_behind_user_plane(&p->world)) {
|
|
cc |= CC_OFF_USER;
|
|
}
|
|
}
|
|
|
|
return p->codes = cc;
|
|
|
|
}
|
|
|
|
ubyte g3_transfer_vertex(vertex *dest,vec3d *src)
|
|
{
|
|
dest->world = *src;
|
|
|
|
dest->codes = 0;
|
|
dest->flags = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
MONITOR( NumRotations )
|
|
|
|
ubyte g3_rotate_vertex(vertex *dest,vec3d *src)
|
|
{
|
|
#if 0
|
|
vec3d tempv;
|
|
Assert( G3_count == 1 );
|
|
vm_vec_sub(&tempv,src,&View_position);
|
|
vm_vec_rotate( (vec3d *)&dest->x, &tempv, &View_matrix );
|
|
dest->flags = 0; //not projected
|
|
return g3_code_vertex(dest);
|
|
#else
|
|
float tx, ty, tz, x,y,z;
|
|
ubyte codes;
|
|
|
|
MONITOR_INC( NumRotations, 1 );
|
|
|
|
tx = src->xyz.x - View_position.xyz.x;
|
|
ty = src->xyz.y - View_position.xyz.y;
|
|
tz = src->xyz.z - View_position.xyz.z;
|
|
|
|
x = tx * View_matrix.vec.rvec.xyz.x;
|
|
x += ty * View_matrix.vec.rvec.xyz.y;
|
|
x += tz * View_matrix.vec.rvec.xyz.z;
|
|
|
|
y = tx * View_matrix.vec.uvec.xyz.x;
|
|
y += ty * View_matrix.vec.uvec.xyz.y;
|
|
y += tz * View_matrix.vec.uvec.xyz.z; //-V537
|
|
|
|
z = tx * View_matrix.vec.fvec.xyz.x;
|
|
z += ty * View_matrix.vec.fvec.xyz.y;
|
|
z += tz * View_matrix.vec.fvec.xyz.z;
|
|
|
|
codes = 0;
|
|
|
|
if (x > z) codes |= CC_OFF_RIGHT;
|
|
if (x < -z) codes |= CC_OFF_LEFT;
|
|
if (y > z) codes |= CC_OFF_TOP;
|
|
if (y < -z) codes |= CC_OFF_BOT;
|
|
if (z < MIN_Z ) codes |= CC_BEHIND;
|
|
|
|
dest->world.xyz.x = x;
|
|
dest->world.xyz.y = y;
|
|
dest->world.xyz.z = z;
|
|
|
|
if ( G3_user_clip ) {
|
|
// Check if behind user plane
|
|
if ( g3_point_behind_user_plane(&dest->world)) {
|
|
codes |= CC_OFF_USER;
|
|
}
|
|
}
|
|
|
|
dest->codes = codes;
|
|
|
|
dest->flags = 0; // not projected
|
|
|
|
return codes;
|
|
#endif
|
|
}
|
|
|
|
|
|
ubyte g3_rotate_faraway_vertex(vertex *dest,vec3d *src)
|
|
{
|
|
Assert( G3_count == 1 );
|
|
|
|
MONITOR_INC( NumRotations, 1 );
|
|
|
|
vm_vec_rotate( &dest->world, src, &View_matrix );
|
|
dest->flags = 0; //not projected
|
|
return g3_code_vertex(dest);
|
|
}
|
|
|
|
|
|
/**
|
|
* Rotates a point. returns codes. does not check if already rotated
|
|
*/
|
|
ubyte g3_rotate_vector(vec3d *dest,vec3d *src)
|
|
{
|
|
vec3d tempv;
|
|
|
|
Assert( G3_count == 1 );
|
|
|
|
MONITOR_INC( NumRotations, 1 );
|
|
|
|
vm_vec_sub(&tempv,src,&View_position);
|
|
vm_vec_rotate(dest,&tempv,&View_matrix);
|
|
return g3_code_vector(dest);
|
|
}
|
|
|
|
ubyte g3_project_vector(vec3d *p, float *sx, float *sy )
|
|
{
|
|
float w;
|
|
|
|
Assert( G3_count == 1 );
|
|
|
|
if ( p->xyz.z <= MIN_Z ) return PF_OVERFLOW;
|
|
|
|
w=1.0f / p->xyz.z;
|
|
|
|
*sx = (Canvas_width + (p->xyz.x*Canvas_width*w))*0.5f;
|
|
*sy = (Canvas_height - (p->xyz.y*Canvas_height*w))*0.5f;
|
|
return PF_PROJECTED;
|
|
}
|
|
|
|
/**
|
|
* Projects a point. Checks for overflow.
|
|
*/
|
|
int g3_project_vertex(vertex *p)
|
|
{
|
|
float w;
|
|
|
|
Assert( G3_count == 1 );
|
|
|
|
if ( p->flags & PF_PROJECTED )
|
|
return p->flags;
|
|
|
|
if ( p->world.xyz.z <= MIN_Z ) {
|
|
p->flags |= PF_OVERFLOW;
|
|
} else {
|
|
w = 1.0f / p->world.xyz.z;
|
|
p->screen.xyw.x = (Canvas_width + (p->world.xyz.x*Canvas_width*w))*0.5f;
|
|
p->screen.xyw.y = (Canvas_height - (p->world.xyz.y*Canvas_height*w))*0.5f;
|
|
|
|
if ( w > 1.0f ) w = 1.0f;
|
|
|
|
p->screen.xyw.w = w;
|
|
p->flags |= PF_PROJECTED;
|
|
}
|
|
|
|
return p->flags;
|
|
}
|
|
|
|
|
|
/**
|
|
* From a 2d point, compute the vector through that point
|
|
*/
|
|
void g3_point_to_vec(vec3d *v,int sx,int sy)
|
|
{
|
|
vec3d tempv;
|
|
|
|
Assert( G3_count == 1 );
|
|
|
|
tempv.xyz.x = ((float)sx - Canv_w2) / Canv_w2;
|
|
tempv.xyz.y = -((float)sy - Canv_h2) / Canv_h2;
|
|
tempv.xyz.z = 1.0f;
|
|
|
|
tempv.xyz.x = tempv.xyz.x * Matrix_scale.xyz.z / Matrix_scale.xyz.x;
|
|
tempv.xyz.y = tempv.xyz.y * Matrix_scale.xyz.z / Matrix_scale.xyz.y;
|
|
|
|
vm_vec_normalize(&tempv);
|
|
vm_vec_unrotate(v, &tempv, &Unscaled_matrix);
|
|
}
|
|
|
|
/**
|
|
* From a 2d point, compute the vector through that point.
|
|
*
|
|
* This can be called outside of a g3_start_frame/g3_end_frame
|
|
* pair as long g3_start_frame was previously called.
|
|
*/
|
|
void g3_point_to_vec_delayed(vec3d *v,int sx,int sy)
|
|
{
|
|
vec3d tempv;
|
|
|
|
tempv.xyz.x = ((float)sx - Canv_w2) / Canv_w2;
|
|
tempv.xyz.y = -((float)sy - Canv_h2) / Canv_h2;
|
|
tempv.xyz.z = 1.0f;
|
|
|
|
tempv.xyz.x = tempv.xyz.x * Matrix_scale.xyz.z / Matrix_scale.xyz.x;
|
|
tempv.xyz.y = tempv.xyz.y * Matrix_scale.xyz.z / Matrix_scale.xyz.y;
|
|
|
|
vm_vec_normalize(&tempv);
|
|
vm_vec_unrotate(v, &tempv, &Unscaled_matrix);
|
|
}
|
|
|
|
vec3d *g3_rotate_delta_vec(vec3d *dest,vec3d *src)
|
|
{
|
|
Assert( G3_count == 1 );
|
|
return vm_vec_rotate(dest,src,&View_matrix);
|
|
}
|
|
|
|
/**
|
|
* Calculate the depth of a point - returns the z coord of the rotated point
|
|
*/
|
|
float g3_calc_point_depth(vec3d *pnt)
|
|
{
|
|
float q;
|
|
|
|
q = (pnt->xyz.x - View_position.xyz.x) * View_matrix.vec.fvec.xyz.x;
|
|
q += (pnt->xyz.y - View_position.xyz.y) * View_matrix.vec.fvec.xyz.y;
|
|
q += (pnt->xyz.z - View_position.xyz.z) * View_matrix.vec.fvec.xyz.z;
|
|
|
|
return q;
|
|
}
|