Effects 3D.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. static const Vec2 nrm[3]=
  6. {
  7. Vec2(Cos(PI2*0/3), Sin(PI2*0/3)),
  8. Vec2(Cos(PI2*1/3), Sin(PI2*1/3)),
  9. Vec2(Cos(PI2*2/3), Sin(PI2*2/3)),
  10. };
  11. /******************************************************************************/
  12. void DrawVelocityBlur(Flt power, C Ball &ball)
  13. {
  14. if(Renderer._vel)
  15. {
  16. Mtn.load();
  17. SetOneMatrix();
  18. Sh.h_Step->set(power);
  19. #if DX9
  20. D.colWrite(0); // disable color writes, we want to write only to velocity RT and not color RT, #BlendRT
  21. #endif
  22. D .depthWrite(false); Renderer.needDepthTest(); // !! 'needDepthTest' after 'depthWrite' !!
  23. D .alpha (ALPHA_NONE);
  24. D .stencil (STENCIL_NONE);
  25. VI.shader (Mtn.h_Explosion);
  26. VI.cull (true); ball.drawVI(true);
  27. VI.end ( );
  28. #if DX9
  29. D.colWrite(COL_WRITE_RGBA); // restore color writes
  30. #endif
  31. }
  32. }
  33. /******************************************************************************/
  34. struct LaserSegment
  35. {
  36. Vec p[3],
  37. n[3];
  38. Matrix m;
  39. };
  40. void DrawLaser(C Color &color, C Color &middle_color, Flt middle_exponent, Flt radius, Bool sharp_ending, C MemPtr<Vec> &points)
  41. {
  42. if(Renderer.firstPass() && points.elms()>1)
  43. {
  44. Vec2 pnt[3]=
  45. {
  46. nrm[0]*radius,
  47. nrm[1]*radius,
  48. nrm[2]*radius,
  49. };
  50. LaserSegment s[2], *c=&s[0], *n=&s[1];
  51. c->m.setPosDir(points[0], !(points[1]-points[0]));
  52. Bool normals=(color!=middle_color && middle_exponent>EPS_GPU && Renderer()!=RM_AMBIENT),
  53. closed =Equal(points.first(), points.last());
  54. if(sharp_ending && points.elms()<3)sharp_ending=false;
  55. if(sharp_ending)
  56. {
  57. closed=false;
  58. c->p[0]=points[0];
  59. c->p[1]=points[0];
  60. c->p[2]=points[0];
  61. if(normals)
  62. {
  63. c->n[0]=-c->m.z;
  64. c->n[1]=-c->m.z;
  65. c->n[2]=-c->m.z;
  66. }
  67. }else
  68. {
  69. c->p[0]=c->m.convert(pnt[0]);
  70. c->p[1]=c->m.convert(pnt[1]);
  71. c->p[2]=c->m.convert(pnt[2]);
  72. if(normals)
  73. {
  74. if(closed)
  75. {
  76. c->n[0]=c->m.orn().convert(nrm[0]);
  77. c->n[1]=c->m.orn().convert(nrm[1]);
  78. c->n[2]=c->m.orn().convert(nrm[2]);
  79. }else
  80. {
  81. c->n[0]=!(c->m.orn().convert(nrm[0]) - c->m.z);
  82. c->n[1]=!(c->m.orn().convert(nrm[1]) - c->m.z);
  83. c->n[2]=!(c->m.orn().convert(nrm[2]) - c->m.z);
  84. }
  85. }
  86. }
  87. if(Renderer()==RM_AMBIENT)
  88. {
  89. VI.color (Color(255, 255, 255, 0));
  90. VI.color2(Color(255, 255, 255, 0));
  91. }else
  92. {
  93. VI.shader(Sh.h_Laser[normals]);
  94. VI.color ( color);
  95. VI.color2(middle_color);
  96. Sh.h_Step->set(middle_exponent);
  97. if(color.a || middle_color.a)Renderer._has_glow=true;
  98. }
  99. VI.cull (true);
  100. VI.setType(normals ? VI_3D_LASER : VI_3D_FLAT);
  101. if(!closed)
  102. {
  103. if(normals)
  104. {
  105. if(Vtx3DLaser *v=(Vtx3DLaser*)VI.addVtx(3))
  106. {
  107. v[0].pos=c->p[2];
  108. v[1].pos=c->p[1];
  109. v[2].pos=c->p[0];
  110. v[0].nrm=c->n[2];
  111. v[1].nrm=c->n[1];
  112. v[2].nrm=c->n[0];
  113. }
  114. }else
  115. {
  116. if(Vtx3DFlat *v=(Vtx3DFlat*)VI.addVtx(3))
  117. {
  118. v[0].pos=c->p[2];
  119. v[1].pos=c->p[1];
  120. v[2].pos=c->p[0];
  121. }
  122. }
  123. }
  124. for(Int i=1; i<points.elms(); i++)
  125. {
  126. n->m.pos=points[i];
  127. if(i+1<points.elms())
  128. {
  129. n->m.z=!(points[i+1]-points[i]);
  130. n->m.y=PointOnPlane(c->m.y, n->m.z); if(!n->m.y.normalize())n->m.y=PerpN(n->m.z);
  131. n->m.x=Cross(n->m.y, n->m.z);
  132. }else
  133. {
  134. if(!closed)n->m.orn()=c->m.orn();else
  135. {
  136. n->m.orn().setDir(!(points[1]-points[0]));
  137. }
  138. }
  139. if(i==points.elms()-1 && sharp_ending)
  140. {
  141. n->p[0]=points[i];
  142. n->p[1]=points[i];
  143. n->p[2]=points[i];
  144. if(normals)
  145. {
  146. n->n[0]=c->m.z;
  147. n->n[1]=c->m.z;
  148. n->n[2]=c->m.z;
  149. }
  150. }else
  151. {
  152. n->p[0]=n->m.convert(pnt[0]);
  153. n->p[1]=n->m.convert(pnt[1]);
  154. n->p[2]=n->m.convert(pnt[2]);
  155. if(normals)
  156. {
  157. if(i==points.elms()-1 && !closed)
  158. {
  159. n->n[0]=!(n->m.orn().convert(nrm[0]) + n->m.z);
  160. n->n[1]=!(n->m.orn().convert(nrm[1]) + n->m.z);
  161. n->n[2]=!(n->m.orn().convert(nrm[2]) + n->m.z);
  162. }else
  163. {
  164. n->n[0]=n->m.orn().convert(nrm[0]);
  165. n->n[1]=n->m.orn().convert(nrm[1]);
  166. n->n[2]=n->m.orn().convert(nrm[2]);
  167. }
  168. }
  169. }
  170. if(normals)
  171. {
  172. if(Vtx3DLaser *v=(Vtx3DLaser*)VI.addVtx(6*3)) // 3 quads (quad=2*3 vertexes)
  173. {
  174. // 0-1 quad
  175. v[ 0].pos=c->p[0];
  176. v[ 1].pos=c->p[1];
  177. v[ 2].pos=n->p[1];
  178. v[ 3].pos=n->p[1];
  179. v[ 4].pos=n->p[0];
  180. v[ 5].pos=c->p[0];
  181. v[ 0].nrm=c->n[0];
  182. v[ 1].nrm=c->n[1];
  183. v[ 2].nrm=n->n[1];
  184. v[ 3].nrm=n->n[1];
  185. v[ 4].nrm=n->n[0];
  186. v[ 5].nrm=c->n[0];
  187. // 1-2 quad
  188. v[ 6].pos=c->p[1];
  189. v[ 7].pos=c->p[2];
  190. v[ 8].pos=n->p[2];
  191. v[ 9].pos=n->p[2];
  192. v[10].pos=n->p[1];
  193. v[11].pos=c->p[1];
  194. v[ 6].nrm=c->n[1];
  195. v[ 7].nrm=c->n[2];
  196. v[ 8].nrm=n->n[2];
  197. v[ 9].nrm=n->n[2];
  198. v[10].nrm=n->n[1];
  199. v[11].nrm=c->n[1];
  200. // 2-0 quad
  201. v[12].pos=c->p[2];
  202. v[13].pos=c->p[0];
  203. v[14].pos=n->p[0];
  204. v[15].pos=n->p[0];
  205. v[16].pos=n->p[2];
  206. v[17].pos=c->p[2];
  207. v[12].nrm=c->n[2];
  208. v[13].nrm=c->n[0];
  209. v[14].nrm=n->n[0];
  210. v[15].nrm=n->n[0];
  211. v[16].nrm=n->n[2];
  212. v[17].nrm=c->n[2];
  213. }
  214. }else
  215. {
  216. if(Vtx3DFlat *v=(Vtx3DFlat*)VI.addVtx(6*3)) // 3 quads (quad=2*3 vertexes)
  217. {
  218. // 0-1 quad
  219. v[ 0].pos=c->p[0];
  220. v[ 1].pos=c->p[1];
  221. v[ 2].pos=n->p[1];
  222. v[ 3].pos=n->p[1];
  223. v[ 4].pos=n->p[0];
  224. v[ 5].pos=c->p[0];
  225. // 1-2 quad
  226. v[ 6].pos=c->p[1];
  227. v[ 7].pos=c->p[2];
  228. v[ 8].pos=n->p[2];
  229. v[ 9].pos=n->p[2];
  230. v[10].pos=n->p[1];
  231. v[11].pos=c->p[1];
  232. // 2-0 quad
  233. v[12].pos=c->p[2];
  234. v[13].pos=c->p[0];
  235. v[14].pos=n->p[0];
  236. v[15].pos=n->p[0];
  237. v[16].pos=n->p[2];
  238. v[17].pos=c->p[2];
  239. }
  240. }
  241. Swap(n, c);
  242. }
  243. if(!closed)
  244. {
  245. if(normals)
  246. {
  247. if(Vtx3DLaser *v=(Vtx3DLaser*)VI.addVtx(3))
  248. {
  249. v[0].pos=c->p[0];
  250. v[1].pos=c->p[1];
  251. v[2].pos=c->p[2];
  252. v[0].nrm=c->n[0];
  253. v[1].nrm=c->n[1];
  254. v[2].nrm=c->n[2];
  255. }
  256. }else
  257. {
  258. if(Vtx3DFlat *v=(Vtx3DFlat*)VI.addVtx(3))
  259. {
  260. v[0].pos=c->p[0];
  261. v[1].pos=c->p[1];
  262. v[2].pos=c->p[2];
  263. }
  264. }
  265. }
  266. VI.end();
  267. }
  268. }
  269. /******************************************************************************/
  270. ElectricityFx::ElectricityFx()
  271. {
  272. color .set(64, 96, 176);
  273. middle_color =WHITE;
  274. middle_exponent=5;
  275. radius =0.008f;
  276. time =0;
  277. frequency =0.03f;
  278. random_step =0.1f;
  279. random_radius =0.1f;
  280. }
  281. void ElectricityFx::update()
  282. {
  283. time-=Time.d();
  284. if(time<=0)
  285. {
  286. time+=frequency; if(time<=0)time=frequency;
  287. randomized.clear();
  288. if(original.elms()>1)
  289. {
  290. Ball ball(random_radius);
  291. Vec prev=randomized.New()=original.first();
  292. for(Int i=1; i<original.elms(); i++)
  293. {
  294. Vec next=original[i];
  295. for(;;)
  296. {
  297. Flt dist=Dist(prev, next);
  298. if( dist>random_step)
  299. {
  300. if(i==original.elms()-1 && dist<random_step*1.5)break;
  301. prev=Lerp(prev, next, random_step/dist);
  302. randomized.New()=prev+Random(ball);
  303. }else break;
  304. }
  305. }
  306. randomized.New()=original.last();
  307. }
  308. }
  309. }
  310. void ElectricityFx::draw()
  311. {
  312. DrawLaser(color, middle_color, middle_exponent, radius, false, randomized);
  313. }
  314. /******************************************************************************/
  315. }
  316. /******************************************************************************/