1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 
13 #include "math/vecmat.h"
14 #include "graphics/tmapper.h"
15 #include "render/3d.h"
16 #include "fireball/fireballs.h"
17 #include "mission/missionparse.h"
18 #include "nebula/neb.h"
19 #include "globalincs/pstypes.h"
20 #include "model/model.h"
21 #include "ship/ship.h"
22 #include "cmdline/cmdline.h"
23 
24 
25 extern int Warp_model;
26 extern int Warp_glow_bitmap;
27 extern int Warp_ball_bitmap;
28 
29 
draw_face(vertex * v1,vertex * v2,vertex * v3)30 void draw_face( vertex *v1, vertex *v2, vertex *v3 )
31 {
32 	vec3d norm;
33 	vertex *vertlist[3];
34 
35 	vm_vec_perp(&norm,&v1->world, &v2->world, &v3->world);
36 	if ( vm_vec_dot(&norm, &v1->world ) >= 0.0 ) {
37 		vertlist[0] = v3;
38 		vertlist[1] = v2;
39 		vertlist[2] = v1;
40 	} else {
41 		vertlist[0] = v1;
42 		vertlist[1] = v2;
43 		vertlist[2] = v3;
44 	}
45 
46 	g3_draw_poly( 3, vertlist, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
47 
48 }
49 
warpin_render(object * obj,matrix * orient,vec3d * pos,int texture_bitmap_num,float radius,float life_percent,float max_radius,int warp_3d)50 void warpin_render(object *obj, matrix *orient, vec3d *pos, int texture_bitmap_num, float radius, float life_percent, float max_radius, int warp_3d)
51 {
52 	vec3d center;
53 	vec3d vecs[5];
54 	vertex verts[5];
55 	int saved_gr_zbuffering = gr_zbuffer_get();
56 
57 	gr_zbuffer_set(GR_ZBUFF_READ);
58 
59 	vm_vec_scale_add( &center, pos, &orient->vec.fvec, -(max_radius/2.5f)/3.0f );
60 
61 
62 	if (Warp_glow_bitmap >= 0) {
63 		float r = radius;
64 		bool render_it = true;
65 
66 		#define OUT_PERCENT1 0.80f
67 		#define OUT_PERCENT2 0.90f
68 
69 		#define IN_PERCENT1 0.10f
70 		#define IN_PERCENT2 0.20f
71 
72 		if (Cmdline_warp_flash)
73 		{
74 			if ( (life_percent >= IN_PERCENT1) && (life_percent < IN_PERCENT2) ) {
75 				r *= (life_percent - IN_PERCENT1) / (IN_PERCENT2 - IN_PERCENT1);
76 				//render_it = true;
77 			} else if ( (life_percent >= OUT_PERCENT1) && (life_percent < OUT_PERCENT2) ) {
78 				r *= (OUT_PERCENT2 - life_percent) / (OUT_PERCENT2 - OUT_PERCENT1);
79 				//render_it = true;
80 			}
81 		}
82 
83 		if (render_it) {
84 			// Add in noise
85 			int noise_frame = fl2i(Missiontime/15.0f) % NOISE_NUM_FRAMES;
86 
87 			r *= (0.40f + Noise[noise_frame] * 0.30f);
88 
89 			// Bobboau's warp thingie, toggled by cmdline
90 			if (Cmdline_warp_flash) {
91 				r += powf((2.0f * life_percent) - 1.0f, 24.0f) * max_radius * 1.5f;
92 			}
93 
94 			vecs[4] = center;
95 			verts[4].texture_position.u = 0.5f; verts[4].texture_position.v = 0.5f;
96 
97 			if (Cmdline_nohtl) {
98 				g3_rotate_vertex( &verts[4], &vecs[4] );
99 			} else {
100 				g3_transfer_vertex( &verts[4], &vecs[4] );
101 			}
102 
103 			float alpha = (The_mission.flags & MISSION_FLAG_FULLNEB) ? (1.0f - neb2_get_fog_intensity(obj)) : 1.0f;
104 			gr_set_bitmap( Warp_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, alpha );
105 
106 			g3_draw_bitmap( &verts[4], 0, r, TMAP_FLAG_TEXTURED | TMAP_HTL_3D_UNLIT );
107 		}
108 	}
109 
110 	if ( (Warp_model >= 0) && (warp_3d || Cmdline_3dwarp) ) {
111 		float scale = radius / 25.0f;
112 		model_set_warp_globals(scale, scale, scale, texture_bitmap_num, (radius/max_radius) );
113 
114 		float dist = vm_vec_dist_quick( pos, &Eye_position );
115 		model_set_detail_level((int)(dist / (radius * 10.0f)));
116 
117 		model_render( Warp_model, orient, pos, MR_LOCK_DETAIL | MR_NO_LIGHTING | MR_NORMAL | MR_NO_FOGGING | MR_NO_CULL );
118 
119 		model_set_warp_globals();
120 	} else {
121 		float Grid_depth = radius/2.5f;
122 
123 		gr_set_bitmap( texture_bitmap_num, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f );
124 
125 		vm_vec_scale_add( &vecs[0], &center, &orient->vec.uvec, radius );
126 		vm_vec_scale_add2( &vecs[0], &orient->vec.rvec, -radius );
127 		vm_vec_scale_add2( &vecs[0], &orient->vec.fvec, Grid_depth );
128 
129 		vm_vec_scale_add( &vecs[1], &center, &orient->vec.uvec, radius );
130 		vm_vec_scale_add2( &vecs[1], &orient->vec.rvec, radius );
131 		vm_vec_scale_add2( &vecs[1], &orient->vec.fvec, Grid_depth );
132 
133 		vm_vec_scale_add( &vecs[2], &center, &orient->vec.uvec, -radius );
134 		vm_vec_scale_add2( &vecs[2], &orient->vec.rvec, radius );
135 		vm_vec_scale_add2( &vecs[2], &orient->vec.fvec, Grid_depth );
136 
137 		vm_vec_scale_add( &vecs[3], &center, &orient->vec.uvec, -radius );
138 		vm_vec_scale_add2( &vecs[3], &orient->vec.rvec, -radius );
139 		vm_vec_scale_add2( &vecs[3], &orient->vec.fvec, Grid_depth );
140 
141 	//	vm_vec_scale_add( &vecs[4], �er, &orient->vec.fvec, -Grid_depth );
142 		vecs[4] = center;
143 
144 		verts[0].texture_position.u = 0.01f;
145 		verts[0].texture_position.v = 0.01f;
146 
147 		verts[1].texture_position.u = 0.99f;
148 		verts[1].texture_position.v = 0.01f;
149 
150 		verts[2].texture_position.u = 0.99f;
151 		verts[2].texture_position.v = 0.99f;
152 
153 		verts[3].texture_position.u = 0.01f;
154 		verts[3].texture_position.v = 0.99f;
155 
156 		verts[4].texture_position.u = 0.5f;
157 		verts[4].texture_position.v = 0.5f;
158 
159 		if (Cmdline_nohtl) {
160 			g3_rotate_vertex( &verts[0], &vecs[0] );
161 			g3_rotate_vertex( &verts[1], &vecs[1] );
162 			g3_rotate_vertex( &verts[2], &vecs[2] );
163 			g3_rotate_vertex( &verts[3], &vecs[3] );
164 			g3_rotate_vertex( &verts[4], &vecs[4] );
165 		} else {
166 			g3_transfer_vertex( &verts[0], &vecs[0] );
167 			g3_transfer_vertex( &verts[1], &vecs[1] );
168 			g3_transfer_vertex( &verts[2], &vecs[2] );
169 			g3_transfer_vertex( &verts[3], &vecs[3] );
170 			g3_transfer_vertex( &verts[4], &vecs[4] );
171 		}
172 
173 		int cull = gr_set_cull(0); // fixes rendering problem in D3D - taylor
174 		draw_face( &verts[0], &verts[4], &verts[1] );
175 		draw_face( &verts[1], &verts[4], &verts[2] );
176 		draw_face( &verts[4], &verts[3], &verts[2] );
177 		draw_face( &verts[0], &verts[3], &verts[4] );
178 		gr_set_cull(cull);
179 	}
180 
181 	if (Warp_ball_bitmap > -1 && Cmdline_warp_flash == 1) {
182 		flash_ball warp_ball(20, .1f,.25f, &vmd_z_vector, &vmd_zero_vector, 4.0f, 0.5f);
183 		float adg = (2.0f * life_percent) - 1.0f;
184 		float pct = (powf(adg, 4.0f) - powf(adg, 128.0f)) * 4.0f;
185 
186 		if (pct > 0.00001f) {
187 			g3_start_instance_matrix(pos, orient, true);
188 
189 			gr_set_bitmap(Warp_ball_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
190 
191 			warp_ball.render(max_radius * pct * 0.5f, adg * adg, adg * adg * 6.0f);
192 
193 			g3_done_instance(true);
194 		}
195 	}
196 
197 	gr_zbuffer_set( saved_gr_zbuffering );
198 }
199