dxx-rebirth/common/3d/points.cpp

150 lines
3.2 KiB
C++
Raw Normal View History

2006-03-20 17:12:09 +00:00
/*
* This file is part of the DXX-Rebirth project <http://www.dxx-rebirth.com/>.
* It is copyright by its individual contributors, as recorded in the
* project's Git history. See COPYING.txt at the top level for license
* terms and a link to the Git history.
*/
2006-03-20 17:12:09 +00:00
/*
*
* Routines for point definition, rotation, etc.
*
*/
#include "3d.h"
#include "globvars.h"
2015-12-13 18:00:49 +00:00
namespace dcx {
2006-03-20 17:12:09 +00:00
//code a point. fills in the p3_codes field of the point, and returns the codes
2014-11-13 03:16:17 +00:00
ubyte g3_code_point(g3s_point &p)
2006-03-20 17:12:09 +00:00
{
ubyte cc=0;
2014-11-13 03:16:17 +00:00
if (p.p3_x > p.p3_z)
2006-03-20 17:12:09 +00:00
cc |= CC_OFF_RIGHT;
2014-11-13 03:16:17 +00:00
if (p.p3_y > p.p3_z)
2006-03-20 17:12:09 +00:00
cc |= CC_OFF_TOP;
2014-11-13 03:16:17 +00:00
if (p.p3_x < -p.p3_z)
2006-03-20 17:12:09 +00:00
cc |= CC_OFF_LEFT;
2014-11-13 03:16:17 +00:00
if (p.p3_y < -p.p3_z)
2006-03-20 17:12:09 +00:00
cc |= CC_OFF_BOT;
2014-11-13 03:16:17 +00:00
if (p.p3_z < 0)
2006-03-20 17:12:09 +00:00
cc |= CC_BEHIND;
2014-11-13 03:16:17 +00:00
return p.p3_codes = cc;
2006-03-20 17:12:09 +00:00
}
//rotates a point. returns codes. does not check if already rotated
2014-10-02 03:02:35 +00:00
ubyte g3_rotate_point(g3s_point &dest,const vms_vector &src)
2006-03-20 17:12:09 +00:00
{
2014-10-29 03:24:31 +00:00
const auto tempv = vm_vec_sub(src,View_position);
2014-10-02 03:02:35 +00:00
vm_vec_rotate(dest.p3_vec,tempv,View_matrix);
dest.p3_flags = 0; //no projected
2014-11-13 03:16:17 +00:00
return g3_code_point(dest);
2006-03-20 17:12:09 +00:00
}
//checks for overflow & divides if ok, fillig in r
//returns true if div is ok, else false
int checkmuldiv(fix *r,fix a,fix b,fix c)
{
quadint q,qt;
2014-08-16 17:42:34 +00:00
q.q = 0;
2006-03-20 17:12:09 +00:00
fixmulaccum(&q,a,b);
qt = q;
if (qt.high < 0)
fixquadnegate(&qt);
qt.high *= 2;
if (qt.low > 0x7fff)
qt.high++;
if (qt.high >= c)
return 0;
else {
2014-08-16 17:42:34 +00:00
*r = static_cast<int32_t>(q.q / static_cast<int64_t>(c));
2006-03-20 17:12:09 +00:00
return 1;
}
}
//projects a point
2014-11-13 03:21:33 +00:00
void g3_project_point(g3s_point &p)
2006-03-20 17:12:09 +00:00
{
#ifndef __powerc
fix tx,ty;
2014-11-13 03:21:33 +00:00
if ((p.p3_flags & PF_PROJECTED) || (p.p3_codes & CC_BEHIND))
2006-03-20 17:12:09 +00:00
return;
2014-11-13 03:21:33 +00:00
if (checkmuldiv(&tx,p.p3_x,Canv_w2,p.p3_z) && checkmuldiv(&ty,p.p3_y,Canv_h2,p.p3_z)) {
p.p3_sx = Canv_w2 + tx;
p.p3_sy = Canv_h2 - ty;
p.p3_flags |= PF_PROJECTED;
2006-03-20 17:12:09 +00:00
}
else
2014-11-13 03:21:33 +00:00
p.p3_flags |= PF_OVERFLOW;
2006-03-20 17:12:09 +00:00
#else
double fz;
2014-11-13 03:21:33 +00:00
if ((p.p3_flags & PF_PROJECTED) || (p.p3_codes & CC_BEHIND))
2006-03-20 17:12:09 +00:00
return;
2014-11-13 03:21:33 +00:00
if ( p.p3_z <= 0 ) {
p.p3_flags |= PF_OVERFLOW;
2006-03-20 17:12:09 +00:00
return;
}
2014-11-13 03:21:33 +00:00
fz = f2fl(p.p3_z);
p.p3_sx = fl2f(fCanv_w2 + (f2fl(p.p3_x)*fCanv_w2 / fz));
p.p3_sy = fl2f(fCanv_h2 - (f2fl(p.p3_y)*fCanv_h2 / fz));
2006-03-20 17:12:09 +00:00
2014-11-13 03:21:33 +00:00
p.p3_flags |= PF_PROJECTED;
2006-03-20 17:12:09 +00:00
#endif
}
//from a 2d point, compute the vector through that point
2014-10-02 03:02:36 +00:00
void g3_point_2_vec(vms_vector &v,short sx,short sy)
2006-03-20 17:12:09 +00:00
{
vms_vector tempv;
vms_matrix tempm;
tempv.x = fixmuldiv(fixdiv((sx<<16) - Canv_w2,Canv_w2),Matrix_scale.z,Matrix_scale.x);
tempv.y = -fixmuldiv(fixdiv((sy<<16) - Canv_h2,Canv_h2),Matrix_scale.z,Matrix_scale.y);
tempv.z = f1_0;
2014-09-28 21:11:03 +00:00
vm_vec_normalize(tempv);
tempm = vm_transposed_matrix(Unscaled_matrix);
2014-10-02 03:02:36 +00:00
vm_vec_rotate(v,tempv,tempm);
2006-03-20 17:12:09 +00:00
}
void g3_rotate_delta_vec(vms_vector &dest,const vms_vector &src)
2006-03-20 17:12:09 +00:00
{
vm_vec_rotate(dest,src,View_matrix);
2006-03-20 17:12:09 +00:00
}
2014-10-02 03:02:36 +00:00
ubyte g3_add_delta_vec(g3s_point &dest,const g3s_point &src,const vms_vector &deltav)
2006-03-20 17:12:09 +00:00
{
2014-10-02 03:02:36 +00:00
vm_vec_add(dest.p3_vec,src.p3_vec,deltav);
dest.p3_flags = 0; //not projected
2014-11-13 03:16:17 +00:00
return g3_code_point(dest);
2006-03-20 17:12:09 +00:00
}
//calculate the depth of a point - returns the z coord of the rotated point
2014-10-26 22:01:04 +00:00
fix g3_calc_point_depth(const vms_vector &pnt)
2006-03-20 17:12:09 +00:00
{
quadint q;
2014-08-16 17:42:34 +00:00
q.q = 0;
2014-10-26 22:01:04 +00:00
fixmulaccum(&q,(pnt.x - View_position.x),View_matrix.fvec.x);
fixmulaccum(&q,(pnt.y - View_position.y),View_matrix.fvec.y);
fixmulaccum(&q,(pnt.z - View_position.z),View_matrix.fvec.z);
2006-03-20 17:12:09 +00:00
return fixquadadjust(&q);
}
2015-12-05 22:57:24 +00:00
}