2 * $Logfile: /Freespace2/code/Render/3dMath.cpp $
7 * 3d Math routines used by the Renderer lib
10 * Revision 1.1 2002/05/03 03:28:10 root
14 * 7 7/24/99 4:19p Dave
15 * Fixed dumb code with briefing bitmaps. Made d3d zbuffer work much
16 * better. Made model code use zbuffer more intelligently.
18 * 6 3/19/99 9:51a Dave
19 * Checkin to repair massive source safe crash. Also added support for
20 * pof-style nebulae, and some new weapons code.
22 * 6 3/15/99 6:45p Daveb
23 * Put in rough nebula bitmap support.
25 * 5 1/29/99 12:47a Dave
26 * Put in sounds for beam weapon. A bunch of interface screens (tech
29 * 4 12/07/98 5:51p Dave
30 * Finally got d3d fog working! Now we just need to tweak values.
32 * 3 12/06/98 2:36p Dave
33 * Drastically improved nebula fogging.
35 * 2 10/07/98 10:53a Dave
38 * 1 10/07/98 10:51a Dave
40 * 21 3/16/98 4:51p John
41 * Added low-level code to clip all polygons against an arbritary plane.
42 * Took out all old model_interp_zclip and used this new method instead.
44 * 20 2/05/98 9:21p John
45 * Some new Direct3D code. Added code to monitor a ton of stuff in the
48 * 19 7/28/97 2:21p John
49 * changed vecmat functions to not return src. Started putting in code
50 * for inline vector math. Fixed some bugs with optimizer.
52 * 18 7/03/97 1:32p John
53 * took out wacky warp. Tried to make rotation faster by inlining all its
54 * functions and using temp variables to help the optimizer
56 * 17 4/29/97 12:24p Adam
57 * JAS: Added code for delayed point to vec. Fixed some FRED
58 * sequencing problems with g3_start_frame / g3_end_frame.
60 * 16 4/29/97 9:55a John
62 * 15 3/24/97 3:26p John
63 * Cleaned up and restructured model_collide code and fvi code. In fvi
64 * made code that finds uvs work.. Added bm_get_pixel to BmpMan.
66 * 14 3/06/97 5:36p Mike
67 * Change vec_normalize_safe() back to vec_normalize().
68 * Spruce up docking a bit.
70 * 13 3/06/97 10:56a Mike
71 * Write error checking version of vm_vec_normalize().
72 * Fix resultant problems.
74 * 12 2/17/97 5:18p John
75 * Added a bunch of RCS headers to a bunch of old files that don't have
82 #include "3dinternal.h"
87 //Codes a vector. Returns the codes of a point.
88 ubyte g3_code_vector(vector * p)
107 if ( G3_user_clip ) {
108 // Check if behind user plane
109 if ( g3_point_behind_user_plane(p)) {
118 //code a point. fills in the p3_codes field of the point, and returns the codes
119 ubyte g3_code_vertex(vertex *p)
138 if ( G3_user_clip ) {
139 // Check if behind user plane
140 if ( g3_point_behind_user_plane((vector *)&p->x)) {
145 return p->codes = cc;
149 MONITOR( NumRotations );
151 ubyte g3_rotate_vertex(vertex *dest,vector *src)
155 Assert( G3_count == 1 );
156 vm_vec_sub(&tempv,src,&View_position);
157 vm_vec_rotate( (vector *)&dest->x, &tempv, &View_matrix );
158 dest->flags = 0; //not projected
159 return g3_code_vertex(dest);
161 float tx, ty, tz, x,y,z;
164 MONITOR_INC( NumRotations, 1 );
166 tx = src->x - View_position.x;
167 ty = src->y - View_position.y;
168 tz = src->z - View_position.z;
170 x = tx * View_matrix.rvec.x;
171 x += ty * View_matrix.rvec.y;
172 x += tz * View_matrix.rvec.z;
174 y = tx * View_matrix.uvec.x;
175 y += ty * View_matrix.uvec.y;
176 y += tz * View_matrix.uvec.z;
178 z = tx * View_matrix.fvec.x;
179 z += ty * View_matrix.fvec.y;
180 z += tz * View_matrix.fvec.z;
184 if (x > z) codes |= CC_OFF_RIGHT;
185 if (x < -z) codes |= CC_OFF_LEFT;
186 if (y > z) codes |= CC_OFF_TOP;
187 if (y < -z) codes |= CC_OFF_BOT;
188 if (z < MIN_Z ) codes |= CC_BEHIND;
194 if ( G3_user_clip ) {
195 // Check if behind user plane
196 if ( g3_point_behind_user_plane((vector *)&dest->x)) {
197 codes |= CC_OFF_USER;
203 dest->flags = 0; // not projected
210 ubyte g3_rotate_faraway_vertex(vertex *dest,vector *src)
212 Assert( G3_count == 1 );
214 MONITOR_INC( NumRotations, 1 );
216 vm_vec_rotate( (vector *)&dest->x, src, &View_matrix );
217 dest->flags = 0; //not projected
218 return g3_code_vertex(dest);
222 //rotates a point. returns codes. does not check if already rotated
223 ubyte g3_rotate_vector(vector *dest,vector *src)
227 Assert( G3_count == 1 );
229 MONITOR_INC( NumRotations, 1 );
231 vm_vec_sub(&tempv,src,&View_position);
232 vm_vec_rotate(dest,&tempv,&View_matrix);
233 return g3_code_vector(dest);
236 ubyte g3_project_vector(vector *p, float *sx, float *sy )
240 Assert( G3_count == 1 );
242 if ( p->z <= MIN_Z ) return PF_OVERFLOW;
246 *sx = (Canvas_width + (p->x*Canvas_width*w))*0.5f;
247 *sy = (Canvas_height - (p->y*Canvas_height*w))*0.5f;
251 //projects a point. Checks for overflow.
253 int g3_project_vertex(vertex *p)
257 Assert( G3_count == 1 );
259 if ( p->flags & PF_PROJECTED )
262 //if ( p->z < MIN_Z ) {
263 if ( p->z <= MIN_Z ) {
264 p->flags |= PF_OVERFLOW;
266 // w = (p->z == 0.0f) ? 100.0f : 1.0f / p->z;
268 p->sx = (Canvas_width + (p->x*Canvas_width*w))*0.5f;
269 p->sy = (Canvas_height - (p->y*Canvas_height*w))*0.5f;
271 if(gr_screen.mode == GR_GLIDE){
272 if ( w > 61439.0f ) w = 61439.0f;
274 if ( w > 1.0f ) w = 1.0f;
277 p->flags |= PF_PROJECTED;
284 //from a 2d point, compute the vector through that point
285 void g3_point_to_vec(vector *v,int sx,int sy)
289 Assert( G3_count == 1 );
291 tempv.x = ((float)sx - Canv_w2) / Canv_w2;
292 tempv.y = -((float)sy - Canv_h2) / Canv_h2;
295 tempv.x = tempv.x * Matrix_scale.z / Matrix_scale.x;
296 tempv.y = tempv.y * Matrix_scale.z / Matrix_scale.y;
298 vm_vec_normalize(&tempv);
299 vm_vec_unrotate(v, &tempv, &Unscaled_matrix);
302 //from a 2d point, compute the vector through that point.
303 // This can be called outside of a g3_start_frame/g3_end_frame
304 // pair as long g3_start_frame was previously called.
305 void g3_point_to_vec_delayed(vector *v,int sx,int sy)
309 tempv.x = ((float)sx - Canv_w2) / Canv_w2;
310 tempv.y = -((float)sy - Canv_h2) / Canv_h2;
313 tempv.x = tempv.x * Matrix_scale.z / Matrix_scale.x;
314 tempv.y = tempv.y * Matrix_scale.z / Matrix_scale.y;
316 vm_vec_normalize(&tempv);
317 vm_vec_unrotate(v, &tempv, &Unscaled_matrix);
320 vector *g3_rotate_delta_vec(vector *dest,vector *src)
322 Assert( G3_count == 1 );
323 return vm_vec_rotate(dest,src,&View_matrix);
329 // tempv.x = fixmuldiv(fixdiv((sx<<16) - Canv_w2,Canv_w2),Matrix_scale.z,Matrix_scale.x);
330 // tempv.y = -fixmuldiv(fixdiv((sy<<16) - Canv_h2,Canv_h2),Matrix_scale.z,Matrix_scale.y);
333 // vm_vec_normalize(&tempv);
335 // vm_copy_transpose_matrix(&tempm,&Unscaled_matrix);
337 // vm_vec_rotate(v,&tempv,&tempm);
341 //from a 2d point, compute the vector through that point
342 void g3_point_2_vec(vector *v,int sx,int sy)
347 tempv.x = fixmuldiv(fixdiv((sx<<16) - Canv_w2,Canv_w2),Matrix_scale.z,Matrix_scale.x);
348 tempv.y = -fixmuldiv(fixdiv((sy<<16) - Canv_h2,Canv_h2),Matrix_scale.z,Matrix_scale.y);
351 vm_vec_normalize(&tempv);
353 vm_copy_transpose_matrix(&tempm,&Unscaled_matrix);
355 vm_vec_rotate(v,&tempv,&tempm);
359 //delta rotation functions
360 vms_vector *g3_rotate_delta_x(vms_vector *dest,fix dx)
362 dest->x = fixmul(View_matrix.rvec.x,dx);
363 dest->y = fixmul(View_matrix.uvec.x,dx);
364 dest->z = fixmul(View_matrix.fvec.x,dx);
369 vms_vector *g3_rotate_delta_y(vms_vector *dest,fix dy)
371 dest->x = fixmul(View_matrix.rvec.y,dy);
372 dest->y = fixmul(View_matrix.uvec.y,dy);
373 dest->z = fixmul(View_matrix.fvec.y,dy);
378 vms_vector *g3_rotate_delta_z(vms_vector *dest,fix dz)
380 dest->x = fixmul(View_matrix.rvec.z,dz);
381 dest->y = fixmul(View_matrix.uvec.z,dz);
382 dest->z = fixmul(View_matrix.fvec.z,dz);
389 ubyte g3_add_delta_vec(g3s_point *dest,g3s_point *src,vms_vector *deltav)
391 vm_vec_add(&dest->p3_vec,&src->p3_vec,deltav);
393 dest->p3_flags = 0; //not projected
395 return g3_code_point(dest);
399 // calculate the depth of a point - returns the z coord of the rotated point
400 float g3_calc_point_depth(vector *pnt)
404 q = (pnt->x - View_position.x) * View_matrix.fvec.x;
405 q += (pnt->y - View_position.y) * View_matrix.fvec.y;
406 q += (pnt->z - View_position.z) * View_matrix.fvec.z;