source: golgotha/src/golg/objs/explosion1.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 12 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 9.7 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "objs/explosion1.hh"
10#include "map.hh"
11#include "map_man.hh"
12#include "objs/light_o.hh"
13#include "g1_render.hh"
14#include "time/profile.hh"
15#include "object_definer.hh"
16#include "r1_api.hh"
17#include "math/pi.hh"
18#include "objs/particle_emitter.hh"
19#include "sound_man.hh"
20#include "sound/sfx_id.hh"
21#include "resources.hh"
22#include "g1_rand.hh"
23#include "lisp/li_class.hh"
24#include "draw_context.hh"
25#include "r1_clip.hh"
26
27S1_SFX(explode_sfx, "explosion/generic.wav", S1_3D, 70);
28
29
30static g1_object_type lightbulb, particle_emitter_type;
31void g1_explosion_init()
32{
33  lightbulb = g1_get_object_type("lightbulb");
34  particle_emitter_type=g1_get_object_type("particle_emitter");
35}
36
37g1_object_definer<g1_explosion1_class>
38g1_explosion_def("explosion1", 0, g1_explosion_init);
39
40void g1_explosion1_class::create_light()
41{
42  g1_light_object_class *l = (g1_light_object_class *)g1_create_object(lightbulb); 
43  if (l)
44  {
45    l->setup(x,y,h, 1.0, 0.7, 0, 1);
46    l->occupy_location();
47    light = l;
48  }
49}
50
51void g1_explosion1_class::destroy_light()
52{
53  if (light.valid())
54  {
55    if (light->get_flag(MAP_OCCUPIED))
56    {
57      light->unoccupy_location();
58      light->request_remove();
59      light = 0;
60    }
61  }
62}
63
64g1_explosion1_class::g1_explosion1_class(g1_object_type id,
65                                         g1_loader_class *fp)
66  : g1_object_class(id, fp)
67{
68  light   = 0;
69  emitter = 0;
70  x = -1;
71}
72
73g1_explosion1_class::~g1_explosion1_class()
74{
75  destroy_light(); //make sure the light gets deleted
76 
77  if (emitter.valid())
78    emitter->stop();
79}
80
81void g1_explosion1_class::think()
82{
83  theta += i4_pi()/64;
84  roll  += i4_pi()/128;
85  pitch += i4_pi()/32;
86
87
88  if (exp_frame>=num_exp_frames)
89  {   
90    unoccupy_location();
91   
92    if (emitter.get())
93      emitter->stop();
94
95    request_remove();
96    destroy_light();
97  }
98  else
99  {
100    if (emitter.get())
101    {
102      i4_float terrain_height = g1_get_map()->terrain_height(x,y);
103     
104      h += zv;
105     
106      if (h<terrain_height)
107        h = terrain_height;
108   
109      //      emitter->move(x,y,h);
110
111      zv -= g1_resources.gravity;
112    }
113
114    request_think();
115    exp_frame++;
116  }
117}
118
119void fast_transform(i4_transform_class *t,const i4_3d_vector &src, r1_3d_point_class &dst);
120
121void g1_explosion1_class::draw(g1_draw_context_class *context)
122{
123  if (model_id && exp_frame<num_exp_frames)
124  {
125    g1_quad_object_class *obj = g1_model_list_man.get_model(model_id);   
126   
127    i4_transform_class world_transform;
128    calc_world_transform(g1_render.frame_ratio, &world_transform);
129
130    i4_float growth_ratio = (exp_frame + g1_render.frame_ratio) / (float)num_exp_frames;
131   
132    i4_float angle = (i4_pi() * growth_ratio);
133
134    i4_transform_class out;
135    out.multiply(*context->transform, world_transform);
136
137    i4_float texture_scale = 10*sin(angle);
138
139    out.mult_uniscale(texture_scale);
140
141    int i,j,k,num_vertices;
142    r1_vert t_vertices[512], clip_buf_1[64], clip_buf_2[64];
143    int src_quad[4];
144    i4_transform_class view_transform;
145 
146    r1_render_api_class *r_api = g1_render.r_api;
147
148    num_vertices            = obj->num_vertex;
149    r1_vert *v              = t_vertices;
150    g1_vert_class *src_vert = obj->get_verts(0,0);
151   
152    w8 ANDCODE = 0xFF;
153    w8 ORCODE  = 0;
154
155    g1_vert_class *src_v=src_vert;
156
157    //get this vector before we warp the transform
158   
159    i4_3d_vector cam_in_object_space, light_in_object_space;
160   
161    out.inverse_transform(i4_3d_vector(0,0,0),cam_in_object_space);   
162   
163    world_transform.inverse_transform_3x3(i4_3d_vector(0,0,-1),light_in_object_space);
164
165    view_transform.x.x = out.x.x * g1_render.scale_x;
166    view_transform.x.y = out.x.y * g1_render.scale_y;
167    view_transform.x.z = out.x.z;
168    view_transform.y.x = out.y.x * g1_render.scale_x;
169    view_transform.y.y = out.y.y * g1_render.scale_y;
170    view_transform.y.z = out.y.z;
171    view_transform.z.x = out.z.x * g1_render.scale_x;
172    view_transform.z.y = out.z.y * g1_render.scale_y;
173    view_transform.z.z = out.z.z;
174    view_transform.t.x = out.t.x * g1_render.scale_x;
175    view_transform.t.y = out.t.y * g1_render.scale_y;
176    view_transform.t.z = out.t.z;
177 
178    for (i=0; i<num_vertices; i++, src_v++, v++)
179    {
180      fast_transform(&view_transform,src_v->v,v->v);
181
182      w8 code = r1_calc_outcode(v);
183      ANDCODE &= code;
184      ORCODE  |= code;
185     
186      if (!code)
187      {
188        //valid point
189        i4_float ooz = 1.f / v->v.z;
190     
191        v->px = v->v.x * ooz * g1_render.center_x + g1_render.center_x;
192        v->py = v->v.y * ooz * g1_render.center_y + g1_render.center_y;
193
194        v->w  = ooz;
195      }
196    }
197
198    if (ANDCODE)
199      return;
200
201    r_api->disable_texture();
202    r_api->set_shading_mode(R1_COLORED_SHADING);
203    //r_api->set_alpha_mode(R1_ALPHA_LINEAR);
204
205    //set their lighting values to 1
206   
207    src_v = src_vert;
208    v     = t_vertices;   
209   
210    for (i=0; i<num_vertices; i++, v++, src_v++)
211    {
212      //v->r = 0.75f;
213      //v->b = v->g = (growth_ratio);
214
215      v->r = v->g = v->b = 1.f;
216     
217/*
218      i4_float dot = -src_vert[i].normal.dot(light_in_object_space);
219     
220      dot += 1.f;
221      dot *= (0.5f * 0.75f);
222
223      if (dot < 0.f)
224        dot = 0.f;
225      else
226      if (dot > 1.f)
227        dot = 1.f;
228
229      v->r = v->g = v->b = 0.25f + dot;
230      */
231     
232      v->a = 1;//-(growth_ratio*growth_ratio);
233    } 
234 
235    g1_quad_class *q_ptr = obj->quad, *q;
236    for (i=0; i<obj->num_quad; i++, q_ptr++)
237    {
238      i4_3d_vector cam_to_pt = src_vert[q_ptr->vertex_ref[0]].v;
239      cam_to_pt -= cam_in_object_space;
240
241      float dot = cam_to_pt.dot(q_ptr->normal);
242
243      if (1)//dot<0)
244      {
245        q=q_ptr;
246         
247        for (j=0; j<4; j++)     
248        {
249          int ref=q->vertex_ref[j];
250          src_quad[j]=ref;
251 
252          v = &t_vertices[ref];
253          v->s = q->u[j];
254          v->t = q->v[j];
255        }
256     
257
258        if (ORCODE==0)
259        {
260          r_api->render_poly(4,t_vertices,q->vertex_ref);
261        }
262        else
263        {
264          sw32 num_poly_verts = 4;
265          r1_vert *clipped_poly;
266         
267          clipped_poly = r_api->clip_poly(&num_poly_verts,
268                                           t_vertices,
269                                           q->vertex_ref,
270                                           clip_buf_1,
271                                           clip_buf_2,
272                                           R1_CLIP_NO_CALC_OUTCODE
273                                           );
274
275          if (clipped_poly && num_poly_verts>=3)     
276          {
277            r1_vert *temp_vert = clipped_poly;
278
279            for (j=0; j<num_poly_verts; j++, temp_vert++)
280            {       
281              i4_float ooz = 1 / temp_vert->v.z;
282
283              temp_vert->w  = ooz;
284              temp_vert->px = temp_vert->v.x * ooz * g1_render.center_x + g1_render.center_x;
285              temp_vert->py = temp_vert->v.y * ooz * g1_render.center_y + g1_render.center_y;
286            }                 
287           
288            r_api->render_poly(num_poly_verts,clipped_poly);
289          }
290        }
291      }
292    }
293   
294    r_api->set_alpha_mode(R1_ALPHA_DISABLED);
295  }
296}
297
298static r1_texture_ref explosion2("explosions2"), bullet_particle("bullet_particle");
299
300void g1_explosion1_class::setup(i4_float sx, i4_float sy, i4_float sh, w32 type)
301{
302 
303  if ((sw32)sx>=0 && (sw32)sx<g1_get_map()->width() &&
304      (sw32)sy>=0 && (sw32)sy<g1_get_map()->height())
305  {
306    x=lx=sx;
307    y=ly=sy;
308    h=lh=sh;
309
310    if (emitter.get())
311      emitter->stop();
312
313    g1_particle_emitter_params p;
314    p.defaults();
315   
316    if (type & MAKE_SPHERE)
317    {
318      model_id = g1_model_list_man.find_handle("testsphere");
319     
320      num_exp_frames = 50;
321      exp_frame = 0;
322    }
323    else
324      model_id = 0;
325
326    i4_bool make_emitter = i4_T;
327
328    if (type==HIT_OBJECT)
329    {
330      num_exp_frames = 10;
331      exp_frame = 0;
332
333      p.start_size=0.2;
334      p.grow_speed=0.05;
335      p.max_speed=0.02;
336      p.air_friction=0.90;
337      p.particle_lifetime = 10;
338      p.start_size_random_range=0.1;
339
340      p.num_create_attempts_per_tick=1;
341      p.creation_probability=1;
342      p.gravity=g1_resources.gravity*-0.25;
343
344      p.texture=explosion2.get();
345      p.emitter_lifetime=2;
346    }
347    else if (type==HIT_GROUND)
348    {
349      num_exp_frames = 10;
350      exp_frame = 0;
351
352      p.start_size=0.02;
353      p.grow_speed=0.0005;
354      p.max_speed=0.2;
355      p.air_friction=0.70;
356      p.particle_lifetime=15;
357      p.num_create_attempts_per_tick=1;
358      p.creation_probability=0.4;
359      p.texture=bullet_particle.get();
360    }
361    else
362      make_emitter=i4_F;
363   
364    if (make_emitter)
365    {
366      emitter = (g1_particle_emitter_class *)g1_create_object(particle_emitter_type);
367      {
368        li_class_context sub(emitter->vars);
369        emitter->setup(x,y,h, p);
370        emitter->think();
371      }
372
373      if (type==HIT_GROUND)
374        emitter->stop();
375     
376      zv = 0.1 * g1_float_rand(9);
377    }
378    else
379      zv = 0;
380   
381
382    occupy_location();
383    request_think();
384
385
386    explode_sfx.play(x,y,h);
387
388    if (!(type & MAKE_SPHERE))
389      create_light();
390  } 
391}
Note: See TracBrowser for help on using the repository browser.