1 /* $Id: points.c,v 1.5 2002-10-28 19:49:15 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
16 * Routines for point definition, rotation, etc.
20 * Revision 1.3 1995/09/21 17:29:40 allender
21 * changed project_point to overflow if z <= 0
23 * Revision 1.2 1995/09/13 11:31:28 allender
24 * removed checkmuldiv from g3_project_point
26 * Revision 1.1 1995/05/05 08:52:35 allender
29 * Revision 1.1 1995/04/17 04:32:25 matt
40 static char rcsid[] = "$Id: points.c,v 1.5 2002-10-28 19:49:15 btb Exp $";
47 //code a point. fills in the p3_codes field of the point, and returns the codes
48 ubyte g3_code_point(g3s_point *p)
52 if (p->p3_x > p->p3_z)
55 if (p->p3_y > p->p3_z)
58 if (p->p3_x < -p->p3_z)
61 if (p->p3_y < -p->p3_z)
67 return p->p3_codes = cc;
71 //rotates a point. returns codes. does not check if already rotated
72 ubyte g3_rotate_point(g3s_point *dest,vms_vector *src)
80 vm_vec_sub(&tempv,src,&View_position);
82 vm_vec_rotate(&dest->p3_vec,&tempv,&View_matrix);
84 dest->p3_flags = 0; //no projected
86 return g3_code_point(dest);
90 //checks for overflow & divides if ok, fillig in r
91 //returns true if div is ok, else false
92 int checkmuldiv(fix *r,fix a,fix b,fix c)
110 *r = fixdivquadlong(q.low,q.high,c);
116 void g3_project_point(g3s_point *p)
121 if (p->p3_flags & PF_PROJECTED || p->p3_codes & CC_BEHIND)
124 if (checkmuldiv(&tx,p->p3_x,Canv_w2,p->p3_z) && checkmuldiv(&ty,p->p3_y,Canv_h2,p->p3_z)) {
125 p->p3_sx = Canv_w2 + tx;
126 p->p3_sy = Canv_h2 - ty;
127 p->p3_flags |= PF_PROJECTED;
130 p->p3_flags |= PF_OVERFLOW;
134 if ((p->p3_flags & PF_PROJECTED) || (p->p3_codes & CC_BEHIND))
137 if ( p->p3_z <= 0 ) {
138 p->p3_flags |= PF_OVERFLOW;
143 p->p3_sx = fl2f(fCanv_w2 + (f2fl(p->p3_x)*fCanv_w2 / fz));
144 p->p3_sy = fl2f(fCanv_h2 - (f2fl(p->p3_y)*fCanv_h2 / fz));
146 p->p3_flags |= PF_PROJECTED;
150 //from a 2d point, compute the vector through that point
151 void g3_point_2_vec(vms_vector *v,short sx,short sy)
156 tempv.x = fixmuldiv(fixdiv((sx<<16) - Canv_w2,Canv_w2),Matrix_scale.z,Matrix_scale.x);
157 tempv.y = -fixmuldiv(fixdiv((sy<<16) - Canv_h2,Canv_h2),Matrix_scale.z,Matrix_scale.y);
160 vm_vec_normalize(&tempv);
162 vm_copy_transpose_matrix(&tempm,&Unscaled_matrix);
164 vm_vec_rotate(v,&tempv,&tempm);
168 //delta rotation functions
169 vms_vector *g3_rotate_delta_x(vms_vector *dest,fix dx)
171 dest->x = fixmul(View_matrix.rvec.x,dx);
172 dest->y = fixmul(View_matrix.uvec.x,dx);
173 dest->z = fixmul(View_matrix.fvec.x,dx);
178 vms_vector *g3_rotate_delta_y(vms_vector *dest,fix dy)
180 dest->x = fixmul(View_matrix.rvec.y,dy);
181 dest->y = fixmul(View_matrix.uvec.y,dy);
182 dest->z = fixmul(View_matrix.fvec.y,dy);
187 vms_vector *g3_rotate_delta_z(vms_vector *dest,fix dz)
189 dest->x = fixmul(View_matrix.rvec.z,dz);
190 dest->y = fixmul(View_matrix.uvec.z,dz);
191 dest->z = fixmul(View_matrix.fvec.z,dz);
197 vms_vector *g3_rotate_delta_vec(vms_vector *dest,vms_vector *src)
199 return vm_vec_rotate(dest,src,&View_matrix);
202 ubyte g3_add_delta_vec(g3s_point *dest,g3s_point *src,vms_vector *deltav)
204 vm_vec_add(&dest->p3_vec,&src->p3_vec,deltav);
206 dest->p3_flags = 0; //not projected
208 return g3_code_point(dest);
211 //calculate the depth of a point - returns the z coord of the rotated point
212 fix g3_calc_point_depth(vms_vector *pnt)
217 fixmulaccum(&q,(pnt->x - View_position.x),View_matrix.fvec.x);
218 fixmulaccum(&q,(pnt->y - View_position.y),View_matrix.fvec.y);
219 fixmulaccum(&q,(pnt->z - View_position.z),View_matrix.fvec.z);
221 return fixquadadjust(&q);