Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
3
 * It is copyright by its individual contributors, as recorded in the
4
 * project's Git history.  See COPYING.txt at the top level for license
5
 * terms and a link to the Git history.
6
 */
7
/*
8
 *
9
 * Routines for point definition, rotation, etc.
10
 *
11
 */
12
 
13
 
14
#include "3d.h"
15
#include "globvars.h"
16
 
17
namespace dcx {
18
 
19
//code a point.  fills in the p3_codes field of the point, and returns the codes
20
ubyte g3_code_point(g3s_point &p)
21
{
22
        ubyte cc=0;
23
 
24
        if (p.p3_x > p.p3_z)
25
                cc |= CC_OFF_RIGHT;
26
 
27
        if (p.p3_y > p.p3_z)
28
                cc |= CC_OFF_TOP;
29
 
30
        if (p.p3_x < -p.p3_z)
31
                cc |= CC_OFF_LEFT;
32
 
33
        if (p.p3_y < -p.p3_z)
34
                cc |= CC_OFF_BOT;
35
 
36
        if (p.p3_z < 0)
37
                cc |= CC_BEHIND;
38
 
39
        return p.p3_codes = cc;
40
 
41
}
42
 
43
//rotates a point. returns codes.  does not check if already rotated
44
ubyte g3_rotate_point(g3s_point &dest,const vms_vector &src)
45
{
46
        const auto tempv = vm_vec_sub(src,View_position);
47
        vm_vec_rotate(dest.p3_vec,tempv,View_matrix);
48
        dest.p3_flags = 0;      //no projected
49
        return g3_code_point(dest);
50
}
51
 
52
//checks for overflow & divides if ok, fillig in r
53
//returns true if div is ok, else false
54
int checkmuldiv(fix *r,fix a,fix b,fix c)
55
{
56
        quadint q,qt;
57
        q.q = 0;
58
        fixmulaccum(&q,a,b);
59
 
60
        qt = q;
61
        if (qt.high < 0)
62
                fixquadnegate(&qt);
63
 
64
        qt.high *= 2;
65
        if (qt.low > 0x7fff)
66
                qt.high++;
67
 
68
        if (qt.high >= c)
69
                return 0;
70
        else {
71
                *r = static_cast<int32_t>(q.q / static_cast<int64_t>(c));
72
                return 1;
73
        }
74
}
75
 
76
//projects a point
77
void g3_project_point(g3s_point &p)
78
{
79
#ifndef __powerc
80
        fix tx,ty;
81
 
82
        if ((p.p3_flags & PF_PROJECTED) || (p.p3_codes & CC_BEHIND))
83
                return;
84
 
85
        if (checkmuldiv(&tx,p.p3_x,Canv_w2,p.p3_z) && checkmuldiv(&ty,p.p3_y,Canv_h2,p.p3_z)) {
86
                p.p3_sx = Canv_w2 + tx;
87
                p.p3_sy = Canv_h2 - ty;
88
                p.p3_flags |= PF_PROJECTED;
89
        }
90
        else
91
                p.p3_flags |= PF_OVERFLOW;
92
#else
93
        double fz;
94
 
95
        if ((p.p3_flags & PF_PROJECTED) || (p.p3_codes & CC_BEHIND))
96
                return;
97
 
98
        if ( p.p3_z <= 0 )      {
99
                p.p3_flags |= PF_OVERFLOW;
100
                return;
101
        }
102
 
103
        fz = f2fl(p.p3_z);
104
        p.p3_sx = fl2f(fCanv_w2 + (f2fl(p.p3_x)*fCanv_w2 / fz));
105
        p.p3_sy = fl2f(fCanv_h2 - (f2fl(p.p3_y)*fCanv_h2 / fz));
106
 
107
        p.p3_flags |= PF_PROJECTED;
108
#endif
109
}
110
 
111
//from a 2d point, compute the vector through that point
112
void g3_point_2_vec(vms_vector &v,short sx,short sy)
113
{
114
        vms_vector tempv;
115
        vms_matrix tempm;
116
 
117
        tempv.x =  fixmuldiv(fixdiv((sx<<16) - Canv_w2,Canv_w2),Matrix_scale.z,Matrix_scale.x);
118
        tempv.y = -fixmuldiv(fixdiv((sy<<16) - Canv_h2,Canv_h2),Matrix_scale.z,Matrix_scale.y);
119
        tempv.z = f1_0;
120
 
121
        vm_vec_normalize(tempv);
122
        tempm = vm_transposed_matrix(Unscaled_matrix);
123
        vm_vec_rotate(v,tempv,tempm);
124
}
125
 
126
void g3_rotate_delta_vec(vms_vector &dest,const vms_vector &src)
127
{
128
        vm_vec_rotate(dest,src,View_matrix);
129
}
130
 
131
ubyte g3_add_delta_vec(g3s_point &dest,const g3s_point &src,const vms_vector &deltav)
132
{
133
        vm_vec_add(dest.p3_vec,src.p3_vec,deltav);
134
        dest.p3_flags = 0;              //not projected
135
        return g3_code_point(dest);
136
}
137
 
138
//calculate the depth of a point - returns the z coord of the rotated point
139
fix g3_calc_point_depth(const vms_vector &pnt)
140
{
141
        quadint q;
142
        q.q = 0;
143
        fixmulaccum(&q,(pnt.x - View_position.x),View_matrix.fvec.x);
144
        fixmulaccum(&q,(pnt.y - View_position.y),View_matrix.fvec.y);
145
        fixmulaccum(&q,(pnt.z - View_position.z),View_matrix.fvec.z);
146
        return fixquadadjust(&q);
147
}
148
 
149
}