CParticleSphereEmitter.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #include "IrrCompileConfig.h"
  5. #include "CParticleSphereEmitter.h"
  6. #include "os.h"
  7. #include "IAttributes.h"
  8. namespace irr
  9. {
  10. namespace scene
  11. {
  12. //! constructor
  13. CParticleSphereEmitter::CParticleSphereEmitter(
  14. const core::vector3df& center, f32 radius,
  15. const core::vector3df& direction, u32 minParticlesPerSecond,
  16. u32 maxParticlesPerSecond, const video::SColor& minStartColor,
  17. const video::SColor& maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax,
  18. s32 maxAngleDegrees,
  19. const core::dimension2df& minStartSize,
  20. const core::dimension2df& maxStartSize )
  21. : Center(center), Radius(radius), Direction(direction),
  22. MinStartSize(minStartSize), MaxStartSize(maxStartSize),
  23. MinParticlesPerSecond(minParticlesPerSecond),
  24. MaxParticlesPerSecond(maxParticlesPerSecond),
  25. MinStartColor(minStartColor), MaxStartColor(maxStartColor),
  26. MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax),
  27. Time(0), MaxAngleDegrees(maxAngleDegrees)
  28. {
  29. #ifdef _DEBUG
  30. setDebugName("CParticleSphereEmitter");
  31. #endif
  32. }
  33. //! Prepares an array with new particles to emitt into the system
  34. //! and returns how much new particles there are.
  35. s32 CParticleSphereEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray)
  36. {
  37. Time += timeSinceLastCall;
  38. const u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond);
  39. const f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond;
  40. const f32 everyWhatMillisecond = 1000.0f / perSecond;
  41. if(Time > everyWhatMillisecond)
  42. {
  43. Particles.set_used(0);
  44. u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f);
  45. Time = 0;
  46. SParticle p;
  47. if(amount > MaxParticlesPerSecond*2)
  48. amount = MaxParticlesPerSecond * 2;
  49. for(u32 i=0; i<amount; ++i)
  50. {
  51. // Random distance from center
  52. const f32 distance = os::Randomizer::frand() * Radius;
  53. // Random direction from center
  54. p.pos.set(Center + distance);
  55. p.pos.rotateXYBy(os::Randomizer::frand() * 360.f, Center );
  56. p.pos.rotateYZBy(os::Randomizer::frand() * 360.f, Center );
  57. p.pos.rotateXZBy(os::Randomizer::frand() * 360.f, Center );
  58. p.startTime = now;
  59. p.vector = Direction;
  60. if(MaxAngleDegrees)
  61. {
  62. core::vector3df tgt = Direction;
  63. tgt.rotateXYBy(os::Randomizer::frand() * MaxAngleDegrees);
  64. tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees);
  65. tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees);
  66. p.vector = tgt;
  67. }
  68. p.endTime = now + MinLifeTime;
  69. if (MaxLifeTime != MinLifeTime)
  70. p.endTime += os::Randomizer::rand() % (MaxLifeTime - MinLifeTime);
  71. if (MinStartColor==MaxStartColor)
  72. p.color=MinStartColor;
  73. else
  74. p.color = MinStartColor.getInterpolated(MaxStartColor, os::Randomizer::frand());
  75. p.startColor = p.color;
  76. p.startVector = p.vector;
  77. if (MinStartSize==MaxStartSize)
  78. p.startSize = MinStartSize;
  79. else
  80. p.startSize = MinStartSize.getInterpolated(MaxStartSize, os::Randomizer::frand());
  81. p.size = p.startSize;
  82. Particles.push_back(p);
  83. }
  84. outArray = Particles.pointer();
  85. return Particles.size();
  86. }
  87. return 0;
  88. }
  89. //! Writes attributes of the object.
  90. void CParticleSphereEmitter::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
  91. {
  92. out->addVector3d("Center", Direction);
  93. out->addFloat("Radius", Radius);
  94. out->addVector3d("Direction", Direction);
  95. out->addFloat("MinStartSizeWidth", MinStartSize.Width);
  96. out->addFloat("MinStartSizeHeight", MinStartSize.Height);
  97. out->addFloat("MaxStartSizeWidth", MaxStartSize.Width);
  98. out->addFloat("MaxStartSizeHeight", MaxStartSize.Height);
  99. out->addInt("MinParticlesPerSecond", MinParticlesPerSecond);
  100. out->addInt("MaxParticlesPerSecond", MaxParticlesPerSecond);
  101. out->addColor("MinStartColor", MinStartColor);
  102. out->addColor("MaxStartColor", MaxStartColor);
  103. out->addInt("MinLifeTime", MinLifeTime);
  104. out->addInt("MaxLifeTime", MaxLifeTime);
  105. out->addInt("MaxAngleDegrees", MaxAngleDegrees);
  106. }
  107. //! Reads attributes of the object.
  108. void CParticleSphereEmitter::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
  109. {
  110. Center = in->getAttributeAsVector3d("Center");
  111. Radius = in->getAttributeAsFloat("Radius");
  112. Direction = in->getAttributeAsVector3d("Direction");
  113. if (Direction.getLength() == 0)
  114. Direction.set(0,0.01f,0);
  115. int idx = -1;
  116. idx = in->findAttribute("MinStartSizeWidth");
  117. if ( idx >= 0 )
  118. MinStartSize.Width = in->getAttributeAsFloat(idx);
  119. idx = in->findAttribute("MinStartSizeHeight");
  120. if ( idx >= 0 )
  121. MinStartSize.Height = in->getAttributeAsFloat(idx);
  122. idx = in->findAttribute("MaxStartSizeWidth");
  123. if ( idx >= 0 )
  124. MaxStartSize.Width = in->getAttributeAsFloat(idx);
  125. idx = in->findAttribute("MaxStartSizeHeight");
  126. if ( idx >= 0 )
  127. MaxStartSize.Height = in->getAttributeAsFloat(idx);
  128. MinParticlesPerSecond = in->getAttributeAsInt("MinParticlesPerSecond");
  129. MaxParticlesPerSecond = in->getAttributeAsInt("MaxParticlesPerSecond");
  130. MinParticlesPerSecond = core::max_(1u, MinParticlesPerSecond);
  131. MaxParticlesPerSecond = core::max_(MaxParticlesPerSecond, 1u);
  132. MaxParticlesPerSecond = core::min_(MaxParticlesPerSecond, 200u);
  133. MinParticlesPerSecond = core::min_(MinParticlesPerSecond, MaxParticlesPerSecond);
  134. MinStartColor = in->getAttributeAsColor("MinStartColor");
  135. MaxStartColor = in->getAttributeAsColor("MaxStartColor");
  136. MinLifeTime = in->getAttributeAsInt("MinLifeTime");
  137. MaxLifeTime = in->getAttributeAsInt("MaxLifeTime");
  138. MinLifeTime = core::max_(0u, MinLifeTime);
  139. MaxLifeTime = core::max_(MaxLifeTime, MinLifeTime);
  140. MinLifeTime = core::min_(MinLifeTime, MaxLifeTime);
  141. MaxAngleDegrees = in->getAttributeAsInt("MaxAngleDegrees");
  142. }
  143. } // end namespace scene
  144. } // end namespace irr