Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Emitter.cpp 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. /*================================================================
  3. *
  4. * Project : Freyja
  5. * Author : Terry 'Mongoose' Hendrix II
  6. * Website : http://www.westga.edu/~stu7440/
  7. * Email : stu7440@westga.edu
  8. * Object : Emitter
  9. * License : No use w/o permission (C)2001Mongoose
  10. * Comments: Particle emitter for freyja
  11. *
  12. *
  13. * This file was generated using Mongoose's C++
  14. * template generator script. <stu7440@westga.edu>
  15. *
  16. *-- History -------------------------------------------------
  17. *
  18. * 2001.06.30:
  19. * Mongoose - Created
  20. =================================================================*/
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <stdio.h>
  24. #ifdef __APPLE__
  25. #include <OpenGL/gl.h>
  26. #include <OpenGL/glu.h>
  27. #else
  28. #include <GL/gl.h>
  29. #include <GL/glu.h>
  30. #endif
  31. #include <Emitter.h>
  32. #ifdef DEBUG_MEMORY
  33. #include <memory_test.h>
  34. #endif
  35. vec_t Emitter::mFrustum[6][4];
  36. int Emitter::compareParticleDist(const void *voidA, const void *voidB)
  37. {
  38. Particle *a = (Particle *)voidA, *b = (Particle *)voidB;
  39. float x, y, z, distA, distB;
  40. if (!a || !b)
  41. return -1; // error really
  42. a->Pos(&x, &y, &z);
  43. distA = (Emitter::mFrustum[5][0] * x +
  44. Emitter::mFrustum[5][1] * y +
  45. Emitter::mFrustum[5][2] * z +
  46. Emitter::mFrustum[5][3]);
  47. b->Pos(&x, &y, &z);
  48. distB = (Emitter::mFrustum[5][0] * x +
  49. Emitter::mFrustum[5][1] * y +
  50. Emitter::mFrustum[5][2] * z +
  51. Emitter::mFrustum[5][3]);
  52. // reverse less/greater than
  53. // less than
  54. if (distA > distB)
  55. return -1;
  56. // greater than ( no need for equal )
  57. return 1;
  58. }
  59. Emitter::Emitter(const char *name, int n)
  60. {
  61. _name = NULL;
  62. _flags = 0;
  63. _particle = NULL;
  64. _count = 0;
  65. _pos[0] = _pos[1] = _pos[2] = 0.0;
  66. _mangle[0] = _mangle[1] = _mangle[2] = 0.0;
  67. Name(name);
  68. ParticleArray(n);
  69. }
  70. Emitter::~Emitter()
  71. {
  72. if (_name)
  73. {
  74. delete [] _name;
  75. }
  76. if (_particle)
  77. {
  78. delete [] _particle;
  79. }
  80. _count = 0;
  81. }
  82. Particle *Emitter::Particles()
  83. {
  84. return _particle;
  85. }
  86. int Emitter::Count()
  87. {
  88. return _count;
  89. }
  90. void Emitter::Pos(float *x, float *y, float *z)
  91. {
  92. *x = _pos[0];
  93. *y = _pos[1];
  94. *z = _pos[2];
  95. }
  96. void Emitter::Pos(float x, float y, float z)
  97. {
  98. _pos[0] = x;
  99. _pos[1] = y;
  100. _pos[2] = z;
  101. }
  102. void Emitter::Orientation(float *x, float *y, float *z)
  103. {
  104. *x = _mangle[0];
  105. *y = _mangle[1];
  106. *z = _mangle[2];
  107. }
  108. void Emitter::Orientation(float x, float y, float z)
  109. {
  110. _mangle[0] = x;
  111. _mangle[1] = y;
  112. _mangle[2] = z;
  113. }
  114. unsigned int Emitter::Flags()
  115. {
  116. return _flags;
  117. }
  118. void Emitter::Flags(unsigned int flag, bool op)
  119. {
  120. _flags |= flag;
  121. if (!op)
  122. _flags ^= flag;
  123. }
  124. void Emitter::ParticleArray(int n)
  125. {
  126. if (n)
  127. {
  128. if (_particle)
  129. {
  130. _count = 0;
  131. delete [] _particle;
  132. }
  133. _count = n;
  134. _particle = new Particle[_count];
  135. }
  136. }
  137. void Emitter::Name(const char *name)
  138. {
  139. int l;
  140. if (name && name[0])
  141. {
  142. if (_name)
  143. {
  144. delete [] _name;
  145. }
  146. l = strlen(name);
  147. _name = new char[l+1];
  148. // Mongoose 2002.01.09, Mongoose says 'Only you can prevent overflows'
  149. strncpy(_name, name, l);
  150. _name[l] = 0;
  151. }
  152. }
  153. void Emitter::SetTextureId(int id)
  154. {
  155. unsigned int i;
  156. for (i = 0; i < _count; i++)
  157. _particle[i].TextureId(id);
  158. }
  159. void Emitter::TextureId(unsigned int particle_start,
  160. unsigned int particle_end, int id)
  161. {
  162. unsigned int i;
  163. if ((particle_start < _count) &&
  164. (particle_end > 0 && particle_end <= _count) &&
  165. (particle_start < particle_end))
  166. {
  167. for (i = particle_start; i < particle_end; i++)
  168. _particle[i].TextureId(id);
  169. }
  170. }
  171. void Emitter::Color(unsigned int particle_start, unsigned int particle_end,
  172. float r, float g, float b)
  173. {
  174. unsigned int i;
  175. if ((particle_start < _count) &&
  176. (particle_end > 0 && particle_end <= _count) &&
  177. (particle_start < particle_end))
  178. {
  179. for (i = particle_start; i < particle_end; i++)
  180. _particle[i].Color(r, g, b);
  181. }
  182. }
  183. void Emitter::Speed(unsigned int particle_start, unsigned int particle_end,
  184. float x, float y, float z)
  185. {
  186. unsigned int i;
  187. if ((particle_start < _count) &&
  188. (particle_end > 0 && particle_end <= _count) &&
  189. (particle_start < particle_end))
  190. {
  191. for (i = particle_start; i < particle_end; i++)
  192. _particle[i].Speed(x, y, z);
  193. }
  194. }
  195. void Emitter::Force(unsigned int particle_start, unsigned int particle_end,
  196. float x, float y, float z)
  197. {
  198. unsigned int i;
  199. if ((particle_start < _count) &&
  200. (particle_end > 0 && particle_end <= _count) &&
  201. (particle_start < particle_end))
  202. {
  203. for (i = particle_start; i < particle_end; i++)
  204. _particle[i].Force(x, y, z);
  205. }
  206. }
  207. void Emitter::Draw()
  208. {
  209. unsigned int i, p;
  210. float x, y, z;
  211. float r, g, b;
  212. float life;
  213. if (!_count || !_particle)
  214. {
  215. printf("Emitter::Draw> No particles!\n");
  216. return;
  217. }
  218. glPushMatrix();
  219. //glRotatef(_mangle[0], 1.0, 0.0, 0.0);
  220. //glRotatef(_mangle[1], 0.0, 1.0, 0.0);
  221. //glRotatef(_mangle[2], 0.0, 0.0, 1.0);
  222. //glTranslatef(_pos[0], _pos[1], _pos[2]);
  223. if (_flags & fUseDepthSorting)
  224. {
  225. qsort(_particle, _count, sizeof(Particle), compareParticleDist);
  226. }
  227. for (i = 0; i < _count; i++)
  228. {
  229. if (_particle[i].isActive())
  230. {
  231. _particle[i].Pos(&x, &y, &z);
  232. if (_flags & fUseFrustumCulling)
  233. {
  234. for (p = 0; p < 6; ++p)
  235. {
  236. if (mFrustum[p][0] * x +
  237. mFrustum[p][1] * y +
  238. mFrustum[p][2] * z +
  239. mFrustum[p][3] < 0)
  240. {
  241. _particle[i].setActive(false);
  242. break;
  243. }
  244. }
  245. if (!_particle[i].isActive())
  246. continue;
  247. }
  248. _particle[i].Color(&r, &g, &b);
  249. life = _particle[i].Life();
  250. // Mongoose 2002.01.01, Removed Texture agent dep
  251. glBindTexture(GL_TEXTURE_2D, _particle[i].Texture());
  252. // Alpha is determined by life, which is affected by blend amount
  253. glColor4f(r, g, b, life);
  254. // Render tristrip quad
  255. glBegin(GL_TRIANGLE_STRIP);
  256. glTexCoord2d(1.0, 1.0);
  257. glVertex3f(x + 0.5, y + 0.5, z);
  258. glTexCoord2d(0.0, 1.0);
  259. glVertex3f(x - 0.5, y + 0.5, z);
  260. glTexCoord2d(1.0, 0.0);
  261. glVertex3f(x + 0.5, y - 0.5, z);
  262. glTexCoord2d(0.0, 0.0);
  263. glVertex3f(x - 0.5, y - 0.5, z);
  264. glEnd();
  265. // Update particle's attributes for it's life cycle
  266. _particle[i].Update();
  267. }
  268. }
  269. glPopMatrix();
  270. }