File: 3d.h

package info (click to toggle)
freespace2 3.7.0%2Brepack-2
  • links: PTS, VCS
  • area: non-free
  • in suites: jessie, jessie-kfreebsd
  • size: 22,848 kB
  • ctags: 41,897
  • sloc: cpp: 369,931; makefile: 1,060; xml: 129; sh: 112
file content (401 lines) | stat: -rw-r--r-- 12,810 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
/*
 * Copyright (C) Volition, Inc. 1999.  All rights reserved.
 *
 * All source code herein is the property of Volition, Inc. You may not sell 
 * or otherwise commercially exploit the source or things you created based on the 
 * source.
 *
*/


#ifndef _3D_H
#define _3D_H

#include "math/vecmat.h"
#include "graphics/tmapper.h"
#include "graphics/2d.h"
#include "graphics/grbatch.h"
#include "camera/camera.h"

//flags for point structure
#define PF_PROJECTED 	 1	//has been projected, so sx,sy valid
#define PF_OVERFLOW		 2	//can't project
#define PF_TEMP_POINT	 4	//created during clip

//clipping codes flags
#define CC_OFF_LEFT	1
#define CC_OFF_RIGHT	2
#define CC_OFF_BOT	4
#define CC_OFF_TOP	8
#define CC_OFF_USER	16
#define CC_BEHIND		0x80

// Combo!
#define CC_OFF			(CC_OFF_LEFT | CC_OFF_RIGHT | CC_OFF_BOT | CC_OFF_TOP | CC_OFF_USER | CC_BEHIND)

/**
 * Start the frame. Pass non-zero to enable zbuffering
 */
#define g3_start_frame(zbuffer_flag) g3_start_frame_func(zbuffer_flag, __FILE__, __LINE__ )

/**
 * Use the g3_start_frame macro instead of calling this directly.
 */
extern void g3_start_frame_func(int zbuffer_flag, char * filename, int lineno);

/**
 * End the frame
 */
#define g3_end_frame() g3_end_frame_func( __FILE__, __LINE__ )
extern void g3_end_frame_func(char *filename, int lineno);

/**
 * Currently in frame?
 */
extern int g3_in_frame();

/**
 * Set view from x,y,z & p,b,h, zoom.  Must call one of g3_set_view_*()
 */
void g3_set_view_angles(vec3d *view_pos,angles *view_orient,float zoom);

/**
 * Set view from camera
 */
void g3_set_view(camera *cam);

/**
 * Set view from x,y,z, viewer matrix, and zoom.  Must call one of g3_set_view_*()
 */
void g3_set_view_matrix(vec3d *view_pos,matrix *view_matrix,float zoom);

// Never set these!
extern matrix		View_matrix;		// The matrix to convert local coordinates to screen
extern vec3d		View_position;		// The offset to convert local coordinates to screen

extern matrix		Light_matrix;		// Used to rotate world points into current local coordinates
extern vec3d		Light_base;			// Used to rotate world points into current local coordinates

extern matrix		Eye_matrix;			// Where the viewer's eye is pointing in World coordinates
extern vec3d		Eye_position;		// Where the viewer's eye is at in World coordinates
extern float		Eye_fov;			// What the viewer's FOV is

extern vec3d Object_position;
extern matrix	Object_matrix;			// Where the opject is pointing in World coordinates

extern float Proj_fov;					// Projection matrix fov (for HT&L)

/**
 * Draw a horizon
 */
void g3_draw_horizon(int sky_color,int ground_color);

/**
 * Draws a line representing the horizon
 */
void g3_draw_horizon_line();

/**
 * Get vectors that are edge of horizon
 */
int g3_compute_sky_polygon(float *points_2d,vec3d *vecs);

/**
 * Instance at specified point with specified orientation
 */
void g3_start_instance_matrix(vec3d *pos,matrix *orient, bool set_api = true);

/**
 * Instance at specified point with specified orientation
 */
void g3_start_instance_angles(vec3d *pos,angles *orient);

/**
 * Pops the old context
 */
void g3_done_instance(bool set_api = false);

/**
 * Get current field of view.  Fills in angle for x & y
 */
void g3_get_FOV(float *fov_x,float *fov_y);

/**
 * Get zoom.  
 *
 * For a given window size, return the zoom which will achieve
 * the given FOV along the given axis.
 */
float g3_get_zoom(char axis,float fov,int window_width,int window_height);

/**
 * Returns the normalized, unscaled view vectors
 */
void g3_get_view_vectors(vec3d *forward,vec3d *up,vec3d *right);

/**
 * Returns true if a plane is facing the viewer. 
 *
 * Takes the unrotated surface normal of the plane, and a point on it.  The normal need not be normalized
 */
int g3_check_normal_facing(vec3d *v,vec3d *norm);

/**
 * Returns codes_and & codes_or of a list of points numbers
 */
ccodes g3_check_codes(int nv,vertex **pointlist);

/**
 * Rotates a point. returns codes.  does not check if already rotated
 */
ubyte g3_rotate_vertex(vertex *dest,vec3d *src);

/**
 * Same as above, only ignores the current instancing
 */
ubyte g3_rotate_vertex_popped(vertex *dest,vec3d *src);

/**
 * Use this for stars, etc
 */
ubyte g3_rotate_faraway_vertex(vertex *dest,vec3d *src);

/**
 * Projects a point
 */
int g3_project_vertex(vertex *point);

/**
 * Projects a vector
 */
ubyte g3_project_vector(vec3d *p, float *sx, float *sy );

/**
 * Rotates a point.  
 * @return Returns codes.
 */
ubyte g3_rotate_vector(vec3d *dest,vec3d *src);

/**
 * Codes a vector.  
 * @return Returns the codes of a point.
 */
ubyte g3_code_vector(vec3d * p);

/**
 * Calculate the depth of a point - returns the z coord of the rotated point
 */
float g3_calc_point_depth(vec3d *pnt);

/**
 * From a 2d point, compute the vector through that point
 */
void g3_point_to_vec(vec3d *v,int sx,int sy);

/**
 * From a 2d point, compute the vector through that point.
 *
 * This can be called outside of a g3_start_frame/g3_end_frame
 * pair as long g3_start_frame was previously called.
 */
void g3_point_to_vec_delayed(vec3d *v,int sx,int sy);

/*
 * Code a point. Fills in the p3_codes field of the point, and returns the codes
 */
ubyte g3_code_vertex(vertex *point);

vec3d *g3_rotate_delta_x(vec3d *dest,float dx);
vec3d *g3_rotate_delta_y(vec3d *dest,float dy);
vec3d *g3_rotate_delta_z(vec3d *dest,float dz);
vec3d *g3_rotate_delta_vec(vec3d *dest,vec3d *src);
ubyte g3_add_delta_vec(vertex *dest,vertex *src,vec3d *deltav);

/**
 * Draw a polygon.
 *
 * Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture.
 * @return Returns 1 if off screen, 0 if drawn
 */
int g3_draw_poly(int nv,vertex **pointlist,uint tmap_flags);

int g3_draw_polygon(vec3d *pos, matrix *ori, float width, float height, int tmap_flags = TMAP_FLAG_TEXTURED);
int g3_draw_polygon(vec3d *pos, vec3d *norm, float width, float height, int tmap_flags = TMAP_FLAG_TEXTURED);

/**
 * Draw a polygon.  
 *
 * Same as g3_draw_poly, but it bashes sw to a constant value
 * for all vertexes.  Needs to be done after clipping to get them all.
 *
 * Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture.
 * @return Returns 1 if off screen, 0 if drawn
 */
int g3_draw_poly_constant_sw(int nv,vertex **pointlist,uint tmap_flags, float constant_sw);

/**
 * Like g3_draw_poly(), but checks to see if facing.  
 * 
 * If surface normal is NULL, this routine must compute it, which will be slow.  
 * It is better to pre-compute the normal, and pass it to this function.  
 * When the normal is passed, this function works like g3_check_normal_facing() plus g3_draw_poly().
 *
 * Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture.
 * @return Returns -1 if not facing, 1 if off screen, 0 if drawn
 */
int g3_draw_poly_if_facing(int nv,vertex **pointlist,uint tmap_flags,vec3d *norm,vec3d *pnt);

/**
 * Draws a line.
 *
 * @param p0 First point
 * @param p1 Second point
 */
int g3_draw_line(vertex *p0,vertex *p1);

/**
 * Draws a polygon always facing the viewer.
 * Compute the corners of a rod.  fills in vertbuf.
 * Verts has any needs uv's or l's or can be NULL if none needed.
 */
int g3_draw_rod(vec3d *p0,float width1,vec3d *p1,float width2, vertex * verts, uint tmap_flags);

/**
 * Draws a bitmap with the specified 3d width & height
 *
 * Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture.
 * @return Returns 1 if off screen, 0 if drawn
 *
 * If bitmap is not square, rad will be the 3d size of the smallest dimension.
 * orient flips the bitmap in some way.  Pass 0 for normal or else pass a 
 * random nuber between 0 and 7, inclusive.
 */
int g3_draw_bitmap(vertex *pos,int orient, float radius, uint tmap_flags, float depth = 0.0f);

/**
 * Get bitmap dims onscreen as if g3_draw_bitmap() had been called
 */
int g3_get_bitmap_dims(int bitmap, vertex *pos, float radius, int *x, int *y, int *w, int *h, int *size);

/**
 * Draw a sortof sphere - i.e., the 2d radius is proportional to the 3d
 * radius, but not to the distance from the eye.  Uses the current 2d color.
 */
int g3_draw_sphere(vertex *pnt,float rad);

/**
 * Same as g3_draw_sphere, but you pass a vector and this rotates
 * and projects it and then call g3_draw_sphere.
 */
int g3_draw_sphere_ez(vec3d *pnt,float rad);

/**
 * Draw a laser shaped 3d looking thing.
 *
 * If max_len is > 1.0, then this caps the length to be no longer than max_len pixels
 */
float g3_draw_laser(vec3d *headp, float head_width, vec3d *tailp, float tail_width, uint tmap_flags = TMAP_FLAG_TEXTURED, float max_len = 0.0f );

/**
 * Draw a laser shaped 3d looking thing using vertex coloring (useful for things like colored laser glows)
 *
 * If max_len is > 1.0, then this caps the length to be no longer than max_len pixels
 */
float g3_draw_laser_rgb(vec3d *headp, float head_width, vec3d *tailp, float tail_width, int r, int g, int b, uint tmap_flags = TMAP_FLAG_TEXTURED | TMAP_FLAG_RGB, float max_len = 0.0f );

/**
 * Draw a bitmap that is always facing, but rotates.
 *
 * If bitmap is not square, rad will be the 3d size of the smallest dimension.
 */
int g3_draw_rotated_bitmap(vertex *pnt,float angle, float radius, uint tmap_flags, float depth = 0.0f);

/**
 * Draw a perspective bitmap based on angles and radius
 */
int g3_draw_perspective_bitmap(angles *a, float scale_x, float scale_y, int div_x, int div_y, uint tmap_flags);

/**
 * Draw a 2D shield icon w/ 6 points
 */
void g3_draw_2d_shield_icon(const coord2d coords[6], const int r, const int g, const int b, const int a);

/**
 * Draw a 2D rectangle
 */
void g3_draw_2d_rect(int x, int y, int w, int h, int r, int g, int b, int a);

/**
 * Draw a 2d bitmap on a poly
 */
int g3_draw_2d_poly_bitmap(float x, float y, float w, float h, uint additional_tmap_flags = 0);

/**
 * Enables clipping with an arbritary plane.   
 *
 * This will be on until g3_stop_clip_plane is called or until next frame.
 * The points passed should be relative to the instance. Probably
 * that means world coordinates.
 * 
 * This works like any other clip plane... if this is enabled and you
 * rotate a point, the CC_OFF_USER bit will be set in the clipping codes.
 * It is completely handled by most g3_draw primitives, except maybe lines.
 *
 * As far as performance, when enabled, it will slow down each point
 * rotation (or g3_code_vertex call) by a vec3d subtraction and dot
 * product.   It won't slow anything down for polys that are completely
 * clipped on or off by the plane, and will slow each clipped polygon by
 * not much more than any other clipping we do.
 */
void g3_start_user_clip_plane( vec3d *plane_point, vec3d *plane_normal );

/**
 * Stops arbritary plane clipping
 */
void g3_stop_user_clip_plane();

ubyte g3_transfer_vertex(vertex *dest, vec3d *src);

int g3_draw_2d_poly_bitmap_list(bitmap_2d_list* b_list, int n_bm, uint additional_tmap_flags);
int g3_draw_2d_poly_bitmap_rect_list(bitmap_rect_list* b_list, int n_bm, uint additional_tmap_flags);

/**
 * Draw a line in HTL mode without having to go through the rotate/project stuff
 */
void g3_draw_htl_line(vec3d *start, vec3d *end);

/**
 * Draw a sphere mode without having to go through the rotate/project stuff
 */
void g3_draw_htl_sphere(vec3d *position, float radius);

/**
 * Flash ball
 *
 * A neat looking ball of rays that move around and look all energetic and stuff
 */
struct flash_beam{
	vertex start;
	vertex end;
	float width;
};

class flash_ball{
	flash_beam *ray;
	vec3d center;
	int n_rays;
	static geometry_batcher batcher;
	void parse_bsp(int offset, ubyte *bsp_data);
	void defpoint(int off, ubyte *bsp_data);

public:
	flash_ball(int number, float min_ray_width, float max_ray_width = 0, vec3d* dir = &vmd_zero_vector, vec3d*pcenter = &vmd_zero_vector, float outer = PI2, float inner = 0.0f, ubyte max_r = 255, ubyte max_g = 255, ubyte max_b = 255, ubyte min_r = 255, ubyte min_g = 255, ubyte min_b = 255)
		:ray(NULL),n_rays(0)
		{initialize(number, min_ray_width, max_ray_width , dir , pcenter , outer , inner , max_r , max_g , max_b , min_r , min_g ,min_b);}
	~flash_ball(){if(ray)vm_free(ray);}

	void initialize(int number, float min_ray_width, float max_ray_width = 0, vec3d* dir = &vmd_zero_vector, vec3d*pcenter = &vmd_zero_vector, float outer = PI2, float inner = 0.0f, ubyte max_r = 255, ubyte max_g = 255, ubyte max_b = 255, ubyte min_r = 255, ubyte min_g = 255, ubyte min_b = 255);
	void initialize(ubyte *bsp_data, float min_ray_width, float max_ray_width = 0, vec3d* dir = &vmd_zero_vector, vec3d*pcenter = &vmd_zero_vector, float outer = PI2, float inner = 0.0f, ubyte max_r = 255, ubyte max_g = 255, ubyte max_b = 255, ubyte min_r = 255, ubyte min_g = 255, ubyte min_b = 255);
	void render(float rad, float intinsity, float life);
};
#endif