EffectCloud.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. #include "gosFXHeaders.hpp"
  2. //==========================================================================//
  3. // File: gosFX_EffectCloud.cpp //
  4. // Contents: Base gosFX::EffectCloud Component //
  5. //---------------------------------------------------------------------------//
  6. // Copyright (C) Microsoft Corporation. All rights reserved. //
  7. //===========================================================================//
  8. //------------------------------------------------------------------------------
  9. //
  10. gosFX::EffectCloud__Specification::EffectCloud__Specification(
  11. Stuff::MemoryStream *stream,
  12. int gfx_version
  13. ):
  14. SpinningCloud__Specification(gosFX::EffectCloudClassID, stream, gfx_version)
  15. {
  16. Check_Pointer(this);
  17. Check_Object(stream);
  18. Verify(gos_GetCurrentHeap() == Heap);
  19. Verify(m_class == EffectCloudClassID);
  20. m_totalParticleSize = gosFX::EffectCloud::ParticleSize;
  21. m_particleClassSize = sizeof(gosFX::EffectCloud::Particle);
  22. *stream >> m_particleEffectID;
  23. }
  24. //------------------------------------------------------------------------------
  25. //
  26. gosFX::EffectCloud__Specification::EffectCloud__Specification():
  27. SpinningCloud__Specification(gosFX::EffectCloudClassID)
  28. {
  29. Check_Pointer(this);
  30. Verify(gos_GetCurrentHeap() == Heap);
  31. m_totalParticleSize = gosFX::EffectCloud::ParticleSize;
  32. m_particleClassSize = sizeof(gosFX::EffectCloud::Particle);
  33. }
  34. //------------------------------------------------------------------------------
  35. //
  36. gosFX::EffectCloud__Specification*
  37. gosFX::EffectCloud__Specification::Make(
  38. Stuff::MemoryStream *stream,
  39. int gfx_version
  40. )
  41. {
  42. Check_Object(stream);
  43. gos_PushCurrentHeap(Heap);
  44. EffectCloud__Specification *spec =
  45. new gosFX::EffectCloud__Specification(stream, gfx_version);
  46. gos_PopCurrentHeap();
  47. return spec;
  48. }
  49. //------------------------------------------------------------------------------
  50. //
  51. void
  52. gosFX::EffectCloud__Specification::Save(Stuff::MemoryStream *stream)
  53. {
  54. Check_Object(this);
  55. Check_Object(stream);
  56. SpinningCloud__Specification::Save(stream);
  57. *stream << m_particleEffectID;
  58. }
  59. //------------------------------------------------------------------------------
  60. //
  61. void
  62. gosFX::EffectCloud__Specification::Copy(EffectCloud__Specification *spec)
  63. {
  64. Check_Object(this);
  65. Check_Object(spec);
  66. SpinningCloud__Specification::Copy(spec);
  67. m_particleEffectID = spec->m_particleEffectID;
  68. }
  69. //############################################################################
  70. //############################## gosFX::EffectCloud ################################
  71. //############################################################################
  72. gosFX::EffectCloud::ClassData*
  73. gosFX::EffectCloud::DefaultData = NULL;
  74. //------------------------------------------------------------------------------
  75. //
  76. void
  77. gosFX::EffectCloud::InitializeClass()
  78. {
  79. Verify(!DefaultData);
  80. Verify(gos_GetCurrentHeap() == Heap);
  81. DefaultData =
  82. new ClassData(
  83. EffectCloudClassID,
  84. "gosFX::EffectCloud",
  85. SpinningCloud::DefaultData,
  86. (Effect::Factory)&Make,
  87. (Specification::Factory)&Specification::Make
  88. );
  89. Check_Object(DefaultData);
  90. }
  91. //------------------------------------------------------------------------------
  92. //
  93. void
  94. gosFX::EffectCloud::TerminateClass()
  95. {
  96. Check_Object(DefaultData);
  97. delete DefaultData;
  98. DefaultData = NULL;
  99. }
  100. //------------------------------------------------------------------------------
  101. //
  102. gosFX::EffectCloud::EffectCloud(
  103. Specification *spec,
  104. unsigned flags
  105. ):
  106. SpinningCloud(DefaultData, spec, flags)
  107. {
  108. Check_Object(spec);
  109. Verify(gos_GetCurrentHeap() == Heap);
  110. }
  111. //------------------------------------------------------------------------------
  112. //
  113. gosFX::EffectCloud::~EffectCloud()
  114. {
  115. if (m_activeParticleCount)
  116. {
  117. for (int i=0; i < m_activeParticleCount; i++)
  118. {
  119. Particle *particle = GetParticle(i);
  120. Check_Object(particle);
  121. if (particle->m_effect)
  122. {
  123. Check_Object(particle->m_effect);
  124. delete particle->m_effect;
  125. }
  126. }
  127. }
  128. }
  129. //------------------------------------------------------------------------------
  130. //
  131. gosFX::EffectCloud*
  132. gosFX::EffectCloud::Make(
  133. Specification *spec,
  134. unsigned flags
  135. )
  136. {
  137. Check_Object(spec);
  138. gos_PushCurrentHeap(Heap);
  139. EffectCloud *cloud = new gosFX::EffectCloud(spec, flags);
  140. gos_PopCurrentHeap();
  141. return cloud;
  142. }
  143. //------------------------------------------------------------------------------
  144. //
  145. void
  146. gosFX::EffectCloud::CreateNewParticle(
  147. unsigned index,
  148. Stuff::Point3D *translation
  149. )
  150. {
  151. Check_Object(this);
  152. //
  153. //---------------------------
  154. // Let our parent do creation
  155. //---------------------------
  156. //
  157. SpinningCloud::CreateNewParticle(index, translation);
  158. //
  159. //----------------------------------------
  160. // Now create a new effect under ourselves
  161. //----------------------------------------
  162. //
  163. Specification *spec = GetSpecification();
  164. Check_Object(spec);
  165. Particle *particle = GetParticle(index);
  166. Check_Object(particle);
  167. particle->m_effect =
  168. EffectLibrary::Instance->MakeEffect(
  169. spec->m_particleEffectID,
  170. ExecuteFlag|DynamicWorldSpaceSimulationMode
  171. );
  172. Effect *effect = particle->m_effect;
  173. Check_Object(effect);
  174. particle->m_radius = 0.0f;
  175. //
  176. //-------------------------------------------------------------
  177. // Set the transform on the effect, then start the child effect
  178. //-------------------------------------------------------------
  179. //
  180. effect->m_localToParent.BuildTranslation(particle->m_localTranslation);
  181. effect->m_localToParent.BuildRotation(particle->m_localRotation);
  182. ExecuteInfo
  183. local_info(
  184. m_lastRan,
  185. &m_localToWorld,
  186. NULL,
  187. particle->m_seed
  188. );
  189. local_info.m_age = particle->m_age;
  190. local_info.m_ageRate = particle->m_ageRate;
  191. effect->Start(&local_info);
  192. }
  193. //------------------------------------------------------------------------------
  194. //
  195. bool
  196. gosFX::EffectCloud::AnimateParticle(
  197. unsigned index,
  198. const Stuff::LinearMatrix4D *world_to_new_local,
  199. Stuff::Time till
  200. )
  201. {
  202. Check_Object(this);
  203. //
  204. //--------------------------------------------------------------------
  205. // Make sure that we don't blow the age counters out of the base cloud
  206. // effects
  207. //--------------------------------------------------------------------
  208. //
  209. Particle *particle = GetParticle(index);
  210. Check_Object(particle);
  211. if (particle->m_age >= 1.0f)
  212. particle->m_age = 1.0f - Stuff::SMALL;
  213. SpinningCloud::AnimateParticle(index, world_to_new_local, till);
  214. //
  215. //---------------------------------
  216. // Update the location of the cloud
  217. //---------------------------------
  218. //
  219. Effect *effect = particle->m_effect;
  220. Check_Object(effect);
  221. effect->m_localToParent.BuildTranslation(particle->m_localTranslation);
  222. effect->m_localToParent.BuildRotation(particle->m_localRotation);
  223. //
  224. //-----------------------
  225. // Execute all the effect
  226. //-----------------------
  227. //
  228. Stuff::OBB bounds;
  229. ExecuteInfo
  230. info(
  231. till,
  232. &m_localToWorld,
  233. &bounds
  234. );
  235. if (effect->Execute(&info))
  236. {
  237. Stuff::Point3D center(bounds.localToParent);
  238. particle->m_radius = center.GetLength() + bounds.sphereRadius;
  239. return true;
  240. }
  241. particle->m_radius = 0.0f;
  242. delete particle->m_effect;
  243. particle->m_effect = NULL;
  244. return false;
  245. }
  246. //------------------------------------------------------------------------------
  247. //
  248. void gosFX::EffectCloud::DestroyParticle(unsigned index)
  249. {
  250. Check_Object(this);
  251. Particle *particle = GetParticle(index);
  252. Check_Object(particle);
  253. if (particle->m_effect)
  254. {
  255. Check_Object(particle->m_effect);
  256. delete particle->m_effect;
  257. particle->m_effect = NULL;
  258. }
  259. SpinningCloud::DestroyParticle(index);
  260. }
  261. //------------------------------------------------------------------------------
  262. //
  263. void gosFX::EffectCloud::Draw(DrawInfo *info)
  264. {
  265. Check_Object(this);
  266. Check_Object(info);
  267. //
  268. //---------------------------------------------------------
  269. // If we have active particles, set up the draw information
  270. //---------------------------------------------------------
  271. //
  272. if (m_activeParticleCount)
  273. {
  274. for (int i=0; i < m_activeParticleCount; i++)
  275. {
  276. Particle *particle = GetParticle(i);
  277. Check_Object(particle);
  278. //
  279. //-----------------------------------------------------------------
  280. // If the particle is still alive, concatenate into world space and
  281. // issue the draw command
  282. //-----------------------------------------------------------------
  283. //
  284. if (particle->m_age < 1.0f)
  285. {
  286. if (particle->m_effect)
  287. {
  288. Check_Object(particle->m_effect);
  289. particle->m_effect->Draw(info);
  290. }
  291. }
  292. }
  293. }
  294. SpinningCloud::Draw(info);
  295. }
  296. //------------------------------------------------------------------------------
  297. //
  298. void
  299. gosFX::EffectCloud::TestInstance() const
  300. {
  301. Verify(IsDerivedFrom(DefaultData));
  302. }