particle_halo.lsl 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // :SHOW:1
  2. // :CATEGORY:Light
  3. // :NAME:Rene Free Lighting System
  4. // :AUTHOR:Rene10957 Resident
  5. // :KEYWORDS: light,lamp,lighting light
  6. // :CREATED:2015-06-11 14:42:03
  7. // :EDITED:2016-03-30 20:29:28
  8. // :ID:1079
  9. // :NUM:1796
  10. // :REV:1
  11. // :WORLD:Opensim
  12. // :DESCRIPTION:
  13. // - Particle Plugin "Halo"
  14. // :CODE:
  15. // :LICENSE: CC0 (Public Domain)
  16. // Rene's Free Lighting System - Particle Plugin "Halo"
  17. //
  18. // Author: Rene10957 Resident
  19. // Date: 21-03-2014
  20. ////////////////////////////////////////////////////////////////////////////////
  21. // HOW TO USE: drop this script into the same prim where the LIGHT is located //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. string title = "Particle Plugin"; // title
  24. string name = "Halo"; // name
  25. string version = "1.4"; // version
  26. integer silent = TRUE; // silent startup
  27. // Constants
  28. // Note: the official upper limit for particles is 4.0 meters but for more delicate particle effects
  29. // it can be useful to set maxScale to a lower value, in order to achieve more fine-grained control.
  30. integer particleChannel = -75901; // particle channel
  31. integer feedbackChannel = -57910; // feedback channel
  32. float minScale = 0.03125; // min. startScale or endScale
  33. float maxScale = 4.0; // max. startScale or endScale
  34. // Particle parameters
  35. // Note: startScale and endScale are not actual sizes, but more like aspect ratios.
  36. // The real size is determined by particleSize in the notecard, a percentage of maxScale.
  37. float age = 1.5; // particle lifetime
  38. float rate = 0.05; // particle burst rate
  39. integer count = 1; // particle count
  40. vector startScale = <0.0, 0.0, 0.0>; // particle start size
  41. vector endScale = <2.0, 2.0, 0.0>; // particle end size
  42. float minSpeed = 0.0; // particle min. burst speed
  43. float maxSpeed = 0.0; // particle max. burst speed
  44. float burstRadius = 0.0; // particle burst radius
  45. vector partAccel = <0.0, 0.0, 0.0>; // particle accelleration
  46. // Variables
  47. float particleSize; // particle size (percentage)
  48. float defParticleSize; // default particle size (percentage)
  49. float minParticleSize; // minimum particle size (percentage)
  50. // Functions
  51. startParticles(vector color, vector start, vector end, float min, float max, float radius, vector push, string txtr)
  52. {
  53. llParticleSystem([
  54. PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP,
  55. PSYS_PART_START_COLOR, color,
  56. PSYS_PART_END_COLOR, color,
  57. PSYS_PART_START_ALPHA, 0.5,
  58. PSYS_PART_END_ALPHA, 0.0,
  59. PSYS_PART_START_SCALE, start,
  60. PSYS_PART_END_SCALE, end,
  61. PSYS_PART_MAX_AGE, age,
  62. PSYS_SRC_BURST_RATE, rate,
  63. PSYS_SRC_BURST_PART_COUNT, count,
  64. PSYS_SRC_BURST_SPEED_MIN, min,
  65. PSYS_SRC_BURST_SPEED_MAX, max,
  66. PSYS_SRC_BURST_RADIUS, radius,
  67. PSYS_SRC_ACCEL, push,
  68. PSYS_SRC_TEXTURE, txtr,
  69. PSYS_PART_FLAGS,
  70. 0 |
  71. PSYS_PART_EMISSIVE_MASK |
  72. PSYS_PART_FOLLOW_SRC_MASK |
  73. PSYS_PART_INTERP_COLOR_MASK |
  74. PSYS_PART_INTERP_SCALE_MASK ]);
  75. }
  76. /////////////////////////////////////////////////////////////////
  77. // From this point onwards, every particle script is identical //
  78. /////////////////////////////////////////////////////////////////
  79. // Particle size = largest dimension across both scale vectors
  80. float getParticleSize (vector start, vector end)
  81. {
  82. float max = 0.0;
  83. if (start.x > max) max = start.x;
  84. if (start.y > max) max = start.y;
  85. if (end.x > max) max = end.x;
  86. if (end.y > max) max = end.y;
  87. return max / (maxScale / 100.0);
  88. }
  89. // Particle size is too small if both start.x and end.x < minScale (0.03125), or...
  90. // both start.y and end.y < minScale (0.03125)
  91. float getMinSize (vector start, vector end, float size)
  92. {
  93. float maxX = 0.0;
  94. float maxY = 0.0;
  95. float minXY = 0.0;
  96. if (start.x < minScale && end.x < minScale) {
  97. if (start.x > end.x) maxX = start.x;
  98. else maxX = end.x;
  99. }
  100. if (start.y < minScale && end.y < minScale) {
  101. if (start.y > end.y) maxY = start.y;
  102. else maxY = end.y;
  103. }
  104. if (maxX == 0.0 && maxY == 0.0) return size;
  105. if (maxX == 0.0) minXY = maxY;
  106. else if (maxY == 0.0) minXY = maxX;
  107. else if (maxX < maxY) minXY = maxX;
  108. else minXY = maxY;
  109. return (float)llCeil((minScale / minXY) * size);
  110. }
  111. unpackMessage(string msg)
  112. {
  113. list msgList = llCSV2List(msg);
  114. integer on = (integer)llList2String(msgList, 0); // particles on/off
  115. vector color = (vector)llList2String(msgList, 1); // particle color
  116. float size = (float)llList2String(msgList, 2); // particle size (%) from notecard
  117. float inc = (float)llList2String(msgList, 3); // particle increase/decrease (%) from menu
  118. string texture = llList2String(msgList, 4); // particle texture from notecard
  119. if (inc == 999) particleSize = size; // reset particle size
  120. else particleSize += inc; // increase/decrease particle size
  121. if (particleSize < 1) particleSize = 1; // correct if size < 1%
  122. else if (particleSize > 100) particleSize = 100; // correct if size > 100%
  123. if (particleSize < minParticleSize) particleSize = minParticleSize; // correct undersized particles
  124. if (on) {
  125. vector start = startScale / defParticleSize * particleSize; // start scale
  126. vector end = endScale / defParticleSize * particleSize; // end scale
  127. float min = minSpeed / defParticleSize * particleSize; // equally resize min. burst speed
  128. float max = maxSpeed / defParticleSize * particleSize; // equally resize max. burst speed
  129. float radius = burstRadius / defParticleSize * particleSize; // equally resize burst radius
  130. vector push = partAccel / defParticleSize * particleSize; // equally resize accelleration
  131. startParticles(color, start, end, min, max, radius, push, texture);
  132. }
  133. else {
  134. llParticleSystem([]);
  135. }
  136. }
  137. default
  138. {
  139. state_entry()
  140. {
  141. defParticleSize = getParticleSize(startScale, endScale); // default particle size (percentage)
  142. vector start = startScale / defParticleSize; // start scale = 1%
  143. vector end = endScale / defParticleSize; // end scale = 1%
  144. minParticleSize = getMinSize(start, end, 1.0); // minimum particle size (percentage)
  145. if (!silent) llWhisper(0, title + " \"" + name + "\" " + version + " ready");
  146. llMessageLinked(LINK_THIS, feedbackChannel, "READY", ""); // request particle info from light script
  147. }
  148. on_rez(integer start_param)
  149. {
  150. llResetScript();
  151. }
  152. link_message(integer sender_number, integer number, string msg, key id)
  153. {
  154. if (number == particleChannel) unpackMessage(msg);
  155. }
  156. }