This commit was manufactured by cvs2svn to create tag 'd2x-0_1_2'.
[btb/d2x.git] / 3d / rod.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13 /*
14  * $Source: /cvs/cvsroot/d2x/3d/rod.c,v $
15  * $Revision: 1.3 $
16  * $Author: bradleyb $
17  * $Date: 2001-10-31 03:54:51 $
18  * 
19  * Rod routines
20  * 
21  * $Log: not supported by cvs2svn $
22  * Revision 1.2  2001/01/31 15:17:48  bradleyb
23  * Makefile and conf.h fixes
24  *
25  * Revision 1.1.1.1  2001/01/19 03:29:58  bradleyb
26  * Import of d2x-0.0.8
27  *
28  * Revision 1.2  1999/09/21 04:05:55  donut
29  * mostly complete OGL implementation (still needs bitmap handling (reticle), and door/fan textures are corrupt)
30  *
31  * Revision 1.1.1.1  1999/06/14 21:57:50  donut
32  * Import of d1x 1.37 source.
33  *
34  * Revision 1.2  1995/09/13  11:31:46  allender
35  * removed checkmuldiv in PPC implemenation
36  *
37  * Revision 1.1  1995/05/05  08:52:45  allender
38  * Initial revision
39  *
40  * Revision 1.1  1995/04/17  06:42:08  matt
41  * Initial revision
42  * 
43  * 
44  */
45
46 #ifdef HAVE_CONFIG_H
47 #include <conf.h>
48 #endif
49
50 #ifdef RCS
51 static char rcsid[] = "$Id: rod.c,v 1.3 2001-10-31 03:54:51 bradleyb Exp $";
52 #endif
53
54 #include "3d.h"
55 #include "globvars.h"
56 #include "fix.h"
57
58 grs_point blob_vertices[4];
59 g3s_point rod_points[4];
60 g3s_point *rod_point_list[] = {&rod_points[0],&rod_points[1],&rod_points[2],&rod_points[3]};
61
62 g3s_uvl uvl_list[4] = { { 0x0200,0x0200,0 },
63                                                                 { 0xfe00,0x0200,0 },
64                                                                 { 0xfe00,0xfe00,0 },
65                                                                 { 0x0200,0xfe00,0 }};
66
67 //compute the corners of a rod.  fills in vertbuf.
68 int calc_rod_corners(g3s_point *bot_point,fix bot_width,g3s_point *top_point,fix top_width)
69 {
70         vms_vector delta_vec,top,tempv,rod_norm;
71         ubyte codes_and;
72         int i;
73
74         //compute vector from one point to other, do cross product with vector
75         //from eye to get perpendiclar
76
77         vm_vec_sub(&delta_vec,&bot_point->p3_vec,&top_point->p3_vec);
78
79         //unscale for aspect
80
81         delta_vec.x = fixdiv(delta_vec.x,Matrix_scale.x);
82         delta_vec.y = fixdiv(delta_vec.y,Matrix_scale.y);
83
84         //calc perp vector
85
86         //do lots of normalizing to prevent overflowing.  When this code works,
87         //it should be optimized
88
89         vm_vec_normalize(&delta_vec);
90
91         vm_vec_copy_normalize(&top,&top_point->p3_vec);
92
93         vm_vec_cross(&rod_norm,&delta_vec,&top);
94
95         vm_vec_normalize(&rod_norm);
96
97         //scale for aspect
98
99         rod_norm.x = fixmul(rod_norm.x,Matrix_scale.x);
100         rod_norm.y = fixmul(rod_norm.y,Matrix_scale.y);
101
102         //now we have the usable edge.  generate four points
103
104         //top points
105
106         vm_vec_copy_scale(&tempv,&rod_norm,top_width);
107         tempv.z = 0;
108
109         vm_vec_add(&rod_points[0].p3_vec,&top_point->p3_vec,&tempv);
110         vm_vec_sub(&rod_points[1].p3_vec,&top_point->p3_vec,&tempv);
111
112         vm_vec_copy_scale(&tempv,&rod_norm,bot_width);
113         tempv.z = 0;
114
115         vm_vec_sub(&rod_points[2].p3_vec,&bot_point->p3_vec,&tempv);
116         vm_vec_add(&rod_points[3].p3_vec,&bot_point->p3_vec,&tempv);
117
118
119         //now code the four points
120
121         for (i=0,codes_and=0xff;i<4;i++)
122                 codes_and &= g3_code_point(&rod_points[i]);
123
124         if (codes_and)
125                 return 1;               //1 means off screen
126
127         //clear flags for new points (not projected)
128
129         for (i=0;i<4;i++)
130                 rod_points[i].p3_flags = 0;
131
132         return 0;
133 }
134
135 //draw a polygon that is always facing you
136 //returns 1 if off screen, 0 if drew
137 bool g3_draw_rod_flat(g3s_point *bot_point,fix bot_width,g3s_point *top_point,fix top_width)
138 {
139         if (calc_rod_corners(bot_point,bot_width,top_point,top_width))
140                 return 0;
141
142         return g3_draw_poly(4,rod_point_list);
143
144 }
145
146 //draw a bitmap object that is always facing you
147 //returns 1 if off screen, 0 if drew
148 bool g3_draw_rod_tmap(grs_bitmap *bitmap,g3s_point *bot_point,fix bot_width,g3s_point *top_point,fix top_width,fix light)
149 {
150         if (calc_rod_corners(bot_point,bot_width,top_point,top_width))
151                 return 0;
152
153         uvl_list[0].l = uvl_list[1].l = uvl_list[2].l = uvl_list[3].l = light;
154
155         return g3_draw_tmap(4,rod_point_list,uvl_list,bitmap);
156 }
157
158 #ifndef __powerc
159 int checkmuldiv(fix *r,fix a,fix b,fix c);
160 #endif
161
162 #if (!(defined(D1XD3D) || defined(OGL)))
163 //draws a bitmap with the specified 3d width & height 
164 //returns 1 if off screen, 0 if drew
165 bool g3_draw_bitmap(vms_vector *pos,fix width,fix height,grs_bitmap *bm, int orientation)
166 {
167 #ifndef __powerc
168         g3s_point pnt;
169         fix t,w,h;
170
171         if (g3_rotate_point(&pnt,pos) & CC_BEHIND)
172                 return 1;
173
174         g3_project_point(&pnt);
175
176         if (pnt.p3_flags & PF_OVERFLOW)
177                 return 1;
178
179         if (checkmuldiv(&t,width,Canv_w2,pnt.p3_z))
180                 w = fixmul(t,Matrix_scale.x);
181         else
182                 return 1;
183
184         if (checkmuldiv(&t,height,Canv_h2,pnt.p3_z))
185                 h = fixmul(t,Matrix_scale.y);
186         else
187                 return 1;
188
189         blob_vertices[0].x = pnt.p3_sx - w;
190         blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h;
191         blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w;
192         blob_vertices[2].y = pnt.p3_sy + h;
193
194         scale_bitmap(bm,blob_vertices,0);
195
196         return 0;
197 #else
198         g3s_point pnt;
199         fix w,h;
200         double fz;
201
202         if (g3_rotate_point(&pnt,pos) & CC_BEHIND)
203                 return 1;
204
205         g3_project_point(&pnt);
206
207         if (pnt.p3_flags & PF_OVERFLOW)
208                 return 1;
209
210         if (pnt.p3_z == 0)
211                 return 1;
212                 
213         fz = f2fl(pnt.p3_z);
214         w = fixmul(fl2f(((f2fl(width)*fCanv_w2) / fz)), Matrix_scale.x);
215         h = fixmul(fl2f(((f2fl(height)*fCanv_h2) / fz)), Matrix_scale.y);
216
217         blob_vertices[0].x = pnt.p3_sx - w;
218         blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h;
219         blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w;
220         blob_vertices[2].y = pnt.p3_sy + h;
221
222         scale_bitmap(bm,blob_vertices);
223
224         return 0;
225 #endif
226 }
227 #endif
228
229
230