explosion1.cc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  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. #include "objs/explosion1.hh"
  9. #include "map.hh"
  10. #include "map_man.hh"
  11. #include "objs/light_o.hh"
  12. #include "g1_render.hh"
  13. #include "time/profile.hh"
  14. #include "object_definer.hh"
  15. #include "r1_api.hh"
  16. #include "math/pi.hh"
  17. #include "objs/particle_emitter.hh"
  18. #include "sound_man.hh"
  19. #include "sound/sfx_id.hh"
  20. #include "resources.hh"
  21. #include "g1_rand.hh"
  22. #include "lisp/li_class.hh"
  23. #include "draw_context.hh"
  24. #include "r1_clip.hh"
  25. S1_SFX(explode_sfx, "explosion/generic.wav", S1_3D, 70);
  26. static g1_object_type lightbulb, particle_emitter_type;
  27. void g1_explosion_init()
  28. {
  29. lightbulb = g1_get_object_type("lightbulb");
  30. particle_emitter_type=g1_get_object_type("particle_emitter");
  31. }
  32. g1_object_definer<g1_explosion1_class>
  33. g1_explosion_def("explosion1", 0, g1_explosion_init);
  34. void g1_explosion1_class::create_light()
  35. {
  36. g1_light_object_class *l = (g1_light_object_class *)g1_create_object(lightbulb);
  37. if (l)
  38. {
  39. l->setup(x,y,h, 1.0, 0.7, 0, 1);
  40. l->occupy_location();
  41. light = l;
  42. }
  43. }
  44. void g1_explosion1_class::destroy_light()
  45. {
  46. if (light.valid())
  47. {
  48. if (light->get_flag(MAP_OCCUPIED))
  49. {
  50. light->unoccupy_location();
  51. light->request_remove();
  52. light = 0;
  53. }
  54. }
  55. }
  56. g1_explosion1_class::g1_explosion1_class(g1_object_type id,
  57. g1_loader_class *fp)
  58. : g1_object_class(id, fp)
  59. {
  60. light = 0;
  61. emitter = 0;
  62. x = -1;
  63. }
  64. g1_explosion1_class::~g1_explosion1_class()
  65. {
  66. destroy_light(); //make sure the light gets deleted
  67. if (emitter.valid())
  68. emitter->stop();
  69. }
  70. void g1_explosion1_class::think()
  71. {
  72. theta += i4_pi()/64;
  73. roll += i4_pi()/128;
  74. pitch += i4_pi()/32;
  75. if (exp_frame>=num_exp_frames)
  76. {
  77. unoccupy_location();
  78. if (emitter.get())
  79. emitter->stop();
  80. request_remove();
  81. destroy_light();
  82. }
  83. else
  84. {
  85. if (emitter.get())
  86. {
  87. i4_float terrain_height = g1_get_map()->terrain_height(x,y);
  88. h += zv;
  89. if (h<terrain_height)
  90. h = terrain_height;
  91. // emitter->move(x,y,h);
  92. zv -= g1_resources.gravity;
  93. }
  94. request_think();
  95. exp_frame++;
  96. }
  97. }
  98. void fast_transform(i4_transform_class *t,const i4_3d_vector &src, r1_3d_point_class &dst);
  99. void g1_explosion1_class::draw(g1_draw_context_class *context)
  100. {
  101. if (model_id && exp_frame<num_exp_frames)
  102. {
  103. g1_quad_object_class *obj = g1_model_list_man.get_model(model_id);
  104. i4_transform_class world_transform;
  105. calc_world_transform(g1_render.frame_ratio, &world_transform);
  106. i4_float growth_ratio = (exp_frame + g1_render.frame_ratio) / (float)num_exp_frames;
  107. i4_float angle = (i4_pi() * growth_ratio);
  108. i4_transform_class out;
  109. out.multiply(*context->transform, world_transform);
  110. i4_float texture_scale = 10*sin(angle);
  111. out.mult_uniscale(texture_scale);
  112. int i,j,k,num_vertices;
  113. r1_vert t_vertices[512], clip_buf_1[64], clip_buf_2[64];
  114. int src_quad[4];
  115. i4_transform_class view_transform;
  116. r1_render_api_class *r_api = g1_render.r_api;
  117. num_vertices = obj->num_vertex;
  118. r1_vert *v = t_vertices;
  119. g1_vert_class *src_vert = obj->get_verts(0,0);
  120. w8 ANDCODE = 0xFF;
  121. w8 ORCODE = 0;
  122. g1_vert_class *src_v=src_vert;
  123. //get this vector before we warp the transform
  124. i4_3d_vector cam_in_object_space, light_in_object_space;
  125. out.inverse_transform(i4_3d_vector(0,0,0),cam_in_object_space);
  126. world_transform.inverse_transform_3x3(i4_3d_vector(0,0,-1),light_in_object_space);
  127. view_transform.x.x = out.x.x * g1_render.scale_x;
  128. view_transform.x.y = out.x.y * g1_render.scale_y;
  129. view_transform.x.z = out.x.z;
  130. view_transform.y.x = out.y.x * g1_render.scale_x;
  131. view_transform.y.y = out.y.y * g1_render.scale_y;
  132. view_transform.y.z = out.y.z;
  133. view_transform.z.x = out.z.x * g1_render.scale_x;
  134. view_transform.z.y = out.z.y * g1_render.scale_y;
  135. view_transform.z.z = out.z.z;
  136. view_transform.t.x = out.t.x * g1_render.scale_x;
  137. view_transform.t.y = out.t.y * g1_render.scale_y;
  138. view_transform.t.z = out.t.z;
  139. for (i=0; i<num_vertices; i++, src_v++, v++)
  140. {
  141. fast_transform(&view_transform,src_v->v,v->v);
  142. w8 code = r1_calc_outcode(v);
  143. ANDCODE &= code;
  144. ORCODE |= code;
  145. if (!code)
  146. {
  147. //valid point
  148. i4_float ooz = 1.f / v->v.z;
  149. v->px = v->v.x * ooz * g1_render.center_x + g1_render.center_x;
  150. v->py = v->v.y * ooz * g1_render.center_y + g1_render.center_y;
  151. v->w = ooz;
  152. }
  153. }
  154. if (ANDCODE)
  155. return;
  156. r_api->disable_texture();
  157. r_api->set_shading_mode(R1_COLORED_SHADING);
  158. //r_api->set_alpha_mode(R1_ALPHA_LINEAR);
  159. //set their lighting values to 1
  160. src_v = src_vert;
  161. v = t_vertices;
  162. for (i=0; i<num_vertices; i++, v++, src_v++)
  163. {
  164. //v->r = 0.75f;
  165. //v->b = v->g = (growth_ratio);
  166. v->r = v->g = v->b = 1.f;
  167. /*
  168. i4_float dot = -src_vert[i].normal.dot(light_in_object_space);
  169. dot += 1.f;
  170. dot *= (0.5f * 0.75f);
  171. if (dot < 0.f)
  172. dot = 0.f;
  173. else
  174. if (dot > 1.f)
  175. dot = 1.f;
  176. v->r = v->g = v->b = 0.25f + dot;
  177. */
  178. v->a = 1;//-(growth_ratio*growth_ratio);
  179. }
  180. g1_quad_class *q_ptr = obj->quad, *q;
  181. for (i=0; i<obj->num_quad; i++, q_ptr++)
  182. {
  183. i4_3d_vector cam_to_pt = src_vert[q_ptr->vertex_ref[0]].v;
  184. cam_to_pt -= cam_in_object_space;
  185. float dot = cam_to_pt.dot(q_ptr->normal);
  186. if (1)//dot<0)
  187. {
  188. q=q_ptr;
  189. for (j=0; j<4; j++)
  190. {
  191. int ref=q->vertex_ref[j];
  192. src_quad[j]=ref;
  193. v = &t_vertices[ref];
  194. v->s = q->u[j];
  195. v->t = q->v[j];
  196. }
  197. if (ORCODE==0)
  198. {
  199. r_api->render_poly(4,t_vertices,q->vertex_ref);
  200. }
  201. else
  202. {
  203. sw32 num_poly_verts = 4;
  204. r1_vert *clipped_poly;
  205. clipped_poly = r_api->clip_poly(&num_poly_verts,
  206. t_vertices,
  207. q->vertex_ref,
  208. clip_buf_1,
  209. clip_buf_2,
  210. R1_CLIP_NO_CALC_OUTCODE
  211. );
  212. if (clipped_poly && num_poly_verts>=3)
  213. {
  214. r1_vert *temp_vert = clipped_poly;
  215. for (j=0; j<num_poly_verts; j++, temp_vert++)
  216. {
  217. i4_float ooz = 1 / temp_vert->v.z;
  218. temp_vert->w = ooz;
  219. temp_vert->px = temp_vert->v.x * ooz * g1_render.center_x + g1_render.center_x;
  220. temp_vert->py = temp_vert->v.y * ooz * g1_render.center_y + g1_render.center_y;
  221. }
  222. r_api->render_poly(num_poly_verts,clipped_poly);
  223. }
  224. }
  225. }
  226. }
  227. r_api->set_alpha_mode(R1_ALPHA_DISABLED);
  228. }
  229. }
  230. static r1_texture_ref explosion2("explosions2"), bullet_particle("bullet_particle");
  231. void g1_explosion1_class::setup(i4_float sx, i4_float sy, i4_float sh, w32 type)
  232. {
  233. if ((sw32)sx>=0 && (sw32)sx<g1_get_map()->width() &&
  234. (sw32)sy>=0 && (sw32)sy<g1_get_map()->height())
  235. {
  236. x=lx=sx;
  237. y=ly=sy;
  238. h=lh=sh;
  239. if (emitter.get())
  240. emitter->stop();
  241. g1_particle_emitter_params p;
  242. p.defaults();
  243. if (type & MAKE_SPHERE)
  244. {
  245. model_id = g1_model_list_man.find_handle("testsphere");
  246. num_exp_frames = 50;
  247. exp_frame = 0;
  248. }
  249. else
  250. model_id = 0;
  251. i4_bool make_emitter = i4_T;
  252. if (type==HIT_OBJECT)
  253. {
  254. num_exp_frames = 10;
  255. exp_frame = 0;
  256. p.start_size=0.2;
  257. p.grow_speed=0.05;
  258. p.max_speed=0.02;
  259. p.air_friction=0.90;
  260. p.particle_lifetime = 10;
  261. p.start_size_random_range=0.1;
  262. p.num_create_attempts_per_tick=1;
  263. p.creation_probability=1;
  264. p.gravity=g1_resources.gravity*-0.25;
  265. p.texture=explosion2.get();
  266. p.emitter_lifetime=2;
  267. }
  268. else if (type==HIT_GROUND)
  269. {
  270. num_exp_frames = 10;
  271. exp_frame = 0;
  272. p.start_size=0.02;
  273. p.grow_speed=0.0005;
  274. p.max_speed=0.2;
  275. p.air_friction=0.70;
  276. p.particle_lifetime=15;
  277. p.num_create_attempts_per_tick=1;
  278. p.creation_probability=0.4;
  279. p.texture=bullet_particle.get();
  280. }
  281. else
  282. make_emitter=i4_F;
  283. if (make_emitter)
  284. {
  285. emitter = (g1_particle_emitter_class *)g1_create_object(particle_emitter_type);
  286. {
  287. li_class_context sub(emitter->vars);
  288. emitter->setup(x,y,h, p);
  289. emitter->think();
  290. }
  291. if (type==HIT_GROUND)
  292. emitter->stop();
  293. zv = 0.1 * g1_float_rand(9);
  294. }
  295. else
  296. zv = 0;
  297. occupy_location();
  298. request_think();
  299. explode_sfx.play(x,y,h);
  300. if (!(type & MAKE_SPHERE))
  301. create_light();
  302. }
  303. }