CParticleRingEmitter.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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 "CParticleRingEmitter.h"
  5. #include "os.h"
  6. #include "IAttributes.h"
  7. namespace irr
  8. {
  9. namespace scene
  10. {
  11. //! constructor
  12. CParticleRingEmitter::CParticleRingEmitter(
  13. const core::vector3df& center, f32 radius, f32 ringThickness,
  14. const core::vector3df& direction, u32 minParticlesPerSecond,
  15. u32 maxParticlesPerSecond, const video::SColor& minStartColor,
  16. const video::SColor& maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax,
  17. s32 maxAngleDegrees,
  18. const core::dimension2df& minStartSize,
  19. const core::dimension2df& maxStartSize )
  20. : Center(center), Radius(radius), RingThickness(ringThickness),
  21. Direction(direction),
  22. MaxStartSize(maxStartSize), MinStartSize(minStartSize),
  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("CParticleRingEmitter");
  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 CParticleRingEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray)
  36. {
  37. Time += timeSinceLastCall;
  38. u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond);
  39. f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond;
  40. 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. f32 distance = os::Randomizer::frand() * RingThickness * 0.5f;
  52. if (os::Randomizer::rand() % 2)
  53. distance -= Radius;
  54. else
  55. distance += Radius;
  56. p.pos.set(Center.X + distance, Center.Y, Center.Z + distance);
  57. p.pos.rotateXZBy(os::Randomizer::frand() * 360, 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, Center );
  64. tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees, Center );
  65. tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees, Center );
  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 CParticleRingEmitter::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
  91. {
  92. out->addVector3d("Center", Center);
  93. out->addFloat("Radius", Radius);
  94. out->addFloat("RingThickness", RingThickness);
  95. out->addVector3d("Direction", Direction);
  96. out->addFloat("MinStartSizeWidth", MinStartSize.Width);
  97. out->addFloat("MinStartSizeHeight", MinStartSize.Height);
  98. out->addFloat("MaxStartSizeWidth", MaxStartSize.Width);
  99. out->addFloat("MaxStartSizeHeight", MaxStartSize.Height);
  100. out->addInt("MinParticlesPerSecond", MinParticlesPerSecond);
  101. out->addInt("MaxParticlesPerSecond", MaxParticlesPerSecond);
  102. out->addColor("MinStartColor", MinStartColor);
  103. out->addColor("MaxStartColor", MaxStartColor);
  104. out->addInt("MinLifeTime", MinLifeTime);
  105. out->addInt("MaxLifeTime", MaxLifeTime);
  106. out->addInt("MaxAngleDegrees", MaxAngleDegrees);
  107. }
  108. //! Reads attributes of the object.
  109. void CParticleRingEmitter::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
  110. {
  111. Center = in->getAttributeAsVector3d("Center");
  112. Radius = in->getAttributeAsFloat("Radius");
  113. RingThickness = in->getAttributeAsFloat("RingThickness");
  114. Direction = in->getAttributeAsVector3d("Direction");
  115. if (Direction.getLength() == 0)
  116. Direction.set(0,0.01f,0);
  117. int idx = -1;
  118. idx = in->findAttribute("MinStartSizeWidth");
  119. if ( idx >= 0 )
  120. MinStartSize.Width = in->getAttributeAsFloat(idx);
  121. idx = in->findAttribute("MinStartSizeHeight");
  122. if ( idx >= 0 )
  123. MinStartSize.Height = in->getAttributeAsFloat(idx);
  124. idx = in->findAttribute("MaxStartSizeWidth");
  125. if ( idx >= 0 )
  126. MaxStartSize.Width = in->getAttributeAsFloat(idx);
  127. idx = in->findAttribute("MaxStartSizeHeight");
  128. if ( idx >= 0 )
  129. MaxStartSize.Height = in->getAttributeAsFloat(idx);
  130. MinParticlesPerSecond = in->getAttributeAsInt("MinParticlesPerSecond");
  131. MaxParticlesPerSecond = in->getAttributeAsInt("MaxParticlesPerSecond");
  132. MinParticlesPerSecond = core::max_(1u, MinParticlesPerSecond);
  133. MaxParticlesPerSecond = core::max_(MaxParticlesPerSecond, 1u);
  134. MaxParticlesPerSecond = core::min_(MaxParticlesPerSecond, 200u);
  135. MinParticlesPerSecond = core::min_(MinParticlesPerSecond, MaxParticlesPerSecond);
  136. MinStartColor = in->getAttributeAsColor("MinStartColor");
  137. MaxStartColor = in->getAttributeAsColor("MaxStartColor");
  138. MinLifeTime = in->getAttributeAsInt("MinLifeTime");
  139. MaxLifeTime = in->getAttributeAsInt("MaxLifeTime");
  140. MinLifeTime = core::max_(0u, MinLifeTime);
  141. MaxLifeTime = core::max_(MaxLifeTime, MinLifeTime);
  142. MinLifeTime = core::min_(MinLifeTime, MaxLifeTime);
  143. MaxAngleDegrees = in->getAttributeAsInt("MaxAngleDegrees");
  144. }
  145. } // end namespace scene
  146. } // end namespace irr