PageRenderTime 141ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmessage/llpartdata.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 345 lines | 249 code | 66 blank | 30 comment | 9 complexity | 5ebcda39e15cc30db3c364c02d115ae0 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llpartdata.cpp
  3. * @brief Particle system data packing
  4. *
  5. * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llpartdata.h"
  28. #include "message.h"
  29. #include "lldatapacker.h"
  30. #include "v4coloru.h"
  31. #include "llsdutil.h"
  32. #include "llsdutil_math.h"
  33. const S32 PS_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; // 18
  34. const S32 PS_DATA_BLOCK_SIZE = 68 + PS_PART_DATA_BLOCK_SIZE; // 68 + 18 = 86
  35. const F32 MAX_PART_SCALE = 4.f;
  36. BOOL LLPartData::pack(LLDataPacker &dp)
  37. {
  38. LLColor4U coloru;
  39. dp.packU32(mFlags, "pdflags");
  40. dp.packFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
  41. coloru.setVec(mStartColor);
  42. dp.packColor4U(coloru, "pdstartcolor");
  43. coloru.setVec(mEndColor);
  44. dp.packColor4U(coloru, "pdendcolor");
  45. dp.packFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
  46. dp.packFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
  47. dp.packFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
  48. dp.packFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
  49. return TRUE;
  50. }
  51. LLSD LLPartData::asLLSD() const
  52. {
  53. LLSD sd = LLSD();
  54. sd["pdflags"] = ll_sd_from_U32(mFlags);
  55. sd["pdmaxage"] = mMaxAge;
  56. sd["pdstartcolor"] = ll_sd_from_color4(mStartColor);
  57. sd["pdendcolor"] = ll_sd_from_color4(mEndColor);
  58. sd["pdstartscale"] = ll_sd_from_vector2(mStartScale);
  59. sd["pdendscale"] = ll_sd_from_vector2(mEndScale);
  60. return sd;
  61. }
  62. bool LLPartData::fromLLSD(LLSD& sd)
  63. {
  64. mFlags = ll_U32_from_sd(sd["pdflags"]);
  65. mMaxAge = (F32)sd["pdmaxage"].asReal();
  66. mStartColor = ll_color4_from_sd(sd["pdstartcolor"]);
  67. mEndColor = ll_color4_from_sd(sd["pdendcolor"]);
  68. mStartScale = ll_vector2_from_sd(sd["pdstartscale"]);
  69. mEndScale = ll_vector2_from_sd(sd["pdendscale"]);
  70. return true;
  71. }
  72. BOOL LLPartData::unpack(LLDataPacker &dp)
  73. {
  74. LLColor4U coloru;
  75. dp.unpackU32(mFlags, "pdflags");
  76. dp.unpackFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
  77. dp.unpackColor4U(coloru, "pdstartcolor");
  78. mStartColor.setVec(coloru);
  79. dp.unpackColor4U(coloru, "pdendcolor");
  80. mEndColor.setVec(coloru);
  81. dp.unpackFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
  82. dp.unpackFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
  83. dp.unpackFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
  84. dp.unpackFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
  85. return TRUE;
  86. }
  87. void LLPartData::setFlags(const U32 flags)
  88. {
  89. mFlags = flags;
  90. }
  91. void LLPartData::setMaxAge(const F32 max_age)
  92. {
  93. mMaxAge = llclamp(max_age, 0.f, 30.f);
  94. }
  95. void LLPartData::setStartScale(const F32 xs, const F32 ys)
  96. {
  97. mStartScale.mV[VX] = llmin(xs, MAX_PART_SCALE);
  98. mStartScale.mV[VY] = llmin(ys, MAX_PART_SCALE);
  99. }
  100. void LLPartData::setEndScale(const F32 xs, const F32 ys)
  101. {
  102. mEndScale.mV[VX] = llmin(xs, MAX_PART_SCALE);
  103. mEndScale.mV[VY] = llmin(ys, MAX_PART_SCALE);
  104. }
  105. void LLPartData::setStartColor(const LLVector3 &rgb)
  106. {
  107. mStartColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]);
  108. }
  109. void LLPartData::setEndColor(const LLVector3 &rgb)
  110. {
  111. mEndColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]);
  112. }
  113. void LLPartData::setStartAlpha(const F32 alpha)
  114. {
  115. mStartColor.mV[3] = alpha;
  116. }
  117. void LLPartData::setEndAlpha(const F32 alpha)
  118. {
  119. mEndColor.mV[3] = alpha;
  120. }
  121. LLPartSysData::LLPartSysData()
  122. {
  123. mCRC = 0;
  124. mFlags = 0;
  125. mPartData.mFlags = 0;
  126. mPartData.mStartColor = LLColor4(1.f, 1.f, 1.f, 1.f);
  127. mPartData.mEndColor = LLColor4(1.f, 1.f, 1.f, 1.f);
  128. mPartData.mStartScale = LLVector2(1.f, 1.f);
  129. mPartData.mEndScale = LLVector2(1.f, 1.f);
  130. mPartData.mMaxAge = 10.0;
  131. mMaxAge = 0.0;
  132. mStartAge = 0.0;
  133. mPattern = LL_PART_SRC_PATTERN_DROP; // Pattern for particle velocity
  134. mInnerAngle = 0.0; // Inner angle of PATTERN_ANGLE_*
  135. mOuterAngle = 0.0; // Outer angle of PATTERN_ANGLE_*
  136. mBurstRate = 0.1f; // How often to do a burst of particles
  137. mBurstPartCount = 1; // How many particles in a burst
  138. mBurstSpeedMin = 1.f; // Minimum particle velocity
  139. mBurstSpeedMax = 1.f; // Maximum particle velocity
  140. mBurstRadius = 0.f;
  141. mNumParticles = 0;
  142. }
  143. BOOL LLPartSysData::pack(LLDataPacker &dp)
  144. {
  145. dp.packU32(mCRC, "pscrc");
  146. dp.packU32(mFlags, "psflags");
  147. dp.packU8(mPattern, "pspattern");
  148. dp.packFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
  149. dp.packFixed(mStartAge, "psstartage", FALSE, 8, 8);
  150. dp.packFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
  151. dp.packFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
  152. dp.packFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
  153. dp.packFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
  154. dp.packFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
  155. dp.packFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
  156. dp.packU8(mBurstPartCount, "psburstpartcount");
  157. dp.packFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
  158. dp.packFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
  159. dp.packFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
  160. dp.packFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
  161. dp.packFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
  162. dp.packFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
  163. dp.packUUID(mPartImageID, "psuuid");
  164. dp.packUUID(mTargetUUID, "pstargetuuid");
  165. mPartData.pack(dp);
  166. return TRUE;
  167. }
  168. BOOL LLPartSysData::unpack(LLDataPacker &dp)
  169. {
  170. dp.unpackU32(mCRC, "pscrc");
  171. dp.unpackU32(mFlags, "psflags");
  172. dp.unpackU8(mPattern, "pspattern");
  173. dp.unpackFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
  174. dp.unpackFixed(mStartAge, "psstartage", FALSE, 8, 8);
  175. dp.unpackFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
  176. dp.unpackFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
  177. dp.unpackFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
  178. mBurstRate = llmax(0.01f, mBurstRate);
  179. dp.unpackFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
  180. dp.unpackFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
  181. dp.unpackFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
  182. dp.unpackU8(mBurstPartCount, "psburstpartcount");
  183. dp.unpackFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
  184. dp.unpackFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
  185. dp.unpackFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
  186. dp.unpackFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
  187. dp.unpackFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
  188. dp.unpackFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
  189. dp.unpackUUID(mPartImageID, "psuuid");
  190. dp.unpackUUID(mTargetUUID, "pstargetuuid");
  191. mPartData.unpack(dp);
  192. return TRUE;
  193. }
  194. std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
  195. {
  196. s << "Flags: " << std::hex << data.mFlags;
  197. s << " Pattern: " << std::hex << (U32) data.mPattern << "\n";
  198. s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n";
  199. s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n";
  200. s << "Burst Rate: " << data.mBurstRate << "\n";
  201. s << "Burst Radius: " << data.mBurstRadius << "\n";
  202. s << "Burst Speed: [" << data.mBurstSpeedMin << ", " << data.mBurstSpeedMax << "]\n";
  203. s << "Burst Part Count: " << std::hex << (U32) data.mBurstPartCount << "\n";
  204. s << "Angular Velocity: " << data.mAngularVelocity << "\n";
  205. s << "Accel: " << data.mPartAccel;
  206. return s;
  207. }
  208. BOOL LLPartSysData::isNullPS(const S32 block_num)
  209. {
  210. U8 ps_data_block[PS_DATA_BLOCK_SIZE];
  211. U32 crc;
  212. S32 size;
  213. // Check size of block
  214. size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
  215. if (!size)
  216. {
  217. return TRUE;
  218. }
  219. else if (size != PS_DATA_BLOCK_SIZE)
  220. {
  221. llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
  222. return TRUE;
  223. }
  224. gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
  225. LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
  226. dp.unpackU32(crc, "crc");
  227. if (crc == 0)
  228. {
  229. return TRUE;
  230. }
  231. return FALSE;
  232. }
  233. //static
  234. BOOL LLPartSysData::packNull()
  235. {
  236. U8 ps_data_block[PS_DATA_BLOCK_SIZE];
  237. gMessageSystem->addBinaryData("PSBlock", ps_data_block, 0);
  238. return TRUE;
  239. }
  240. BOOL LLPartSysData::packBlock()
  241. {
  242. U8 ps_data_block[PS_DATA_BLOCK_SIZE];
  243. LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
  244. pack(dp);
  245. // Add to message
  246. gMessageSystem->addBinaryData("PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE);
  247. return TRUE;
  248. }
  249. BOOL LLPartSysData::unpackBlock(const S32 block_num)
  250. {
  251. U8 ps_data_block[PS_DATA_BLOCK_SIZE];
  252. // Check size of block
  253. S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
  254. if (size != PS_DATA_BLOCK_SIZE)
  255. {
  256. llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
  257. return FALSE;
  258. }
  259. // Get from message
  260. gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
  261. LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
  262. unpack(dp);
  263. return TRUE;
  264. }
  265. void LLPartSysData::clampSourceParticleRate()
  266. {
  267. F32 particle_rate = 0;
  268. particle_rate = mBurstPartCount/mBurstRate;
  269. if (particle_rate > 256.f)
  270. {
  271. mBurstPartCount = llfloor(((F32)mBurstPartCount)*(256.f/particle_rate));
  272. }
  273. }
  274. void LLPartSysData::setPartAccel(const LLVector3 &accel)
  275. {
  276. mPartAccel.mV[VX] = llclamp(accel.mV[VX], -100.f, 100.f);
  277. mPartAccel.mV[VY] = llclamp(accel.mV[VY], -100.f, 100.f);
  278. mPartAccel.mV[VZ] = llclamp(accel.mV[VZ], -100.f, 100.f);
  279. }