summaryrefslogtreecommitdiff
path: root/indra/llmessage/llpartdata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage/llpartdata.cpp')
-rw-r--r--indra/llmessage/llpartdata.cpp307
1 files changed, 307 insertions, 0 deletions
diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp
new file mode 100644
index 0000000000..4ce7bc1fcd
--- /dev/null
+++ b/indra/llmessage/llpartdata.cpp
@@ -0,0 +1,307 @@
+/**
+ * @file llpartdata.cpp
+ * @brief Particle system data packing
+ *
+ * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "linden_common.h"
+
+#include "llpartdata.h"
+#include "message.h"
+
+#include "lldatapacker.h"
+#include "v4coloru.h"
+
+#include "llsdutil.h"
+
+
+const S32 PS_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; // 18
+const S32 PS_DATA_BLOCK_SIZE = 68 + PS_PART_DATA_BLOCK_SIZE; // 68 + 18 = 86
+
+
+const F32 MAX_PART_SCALE = 4.f;
+
+BOOL LLPartData::pack(LLDataPacker &dp)
+{
+ LLColor4U coloru;
+ dp.packU32(mFlags, "pdflags");
+ dp.packFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
+ coloru.setVec(mStartColor);
+ dp.packColor4U(coloru, "pdstartcolor");
+ coloru.setVec(mEndColor);
+ dp.packColor4U(coloru, "pdendcolor");
+ dp.packFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
+ dp.packFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
+ dp.packFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
+ dp.packFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
+ return TRUE;
+}
+
+LLSD LLPartData::asLLSD() const
+{
+ LLSD sd = LLSD();
+ sd["pdflags"] = ll_sd_from_U32(mFlags);
+ sd["pdmaxage"] = mMaxAge;
+ sd["pdstartcolor"] = ll_sd_from_color4(mStartColor);
+ sd["pdendcolor"] = ll_sd_from_color4(mEndColor);
+ sd["pdstartscale"] = ll_sd_from_vector2(mStartScale);
+ sd["pdendscale"] = ll_sd_from_vector2(mEndScale);
+ return sd;
+}
+
+bool LLPartData::fromLLSD(LLSD& sd)
+{
+ mFlags = ll_U32_from_sd(sd["pdflags"]);
+ mMaxAge = (F32)sd["pdmaxage"].asReal();
+ mStartColor = ll_color4_from_sd(sd["pdstartcolor"]);
+ mEndColor = ll_color4_from_sd(sd["pdendcolor"]);
+ mStartScale = ll_vector2_from_sd(sd["pdstartscale"]);
+ mEndScale = ll_vector2_from_sd(sd["pdendscale"]);
+ return true;
+}
+
+
+BOOL LLPartData::unpack(LLDataPacker &dp)
+{
+ LLColor4U coloru;
+
+ dp.unpackU32(mFlags, "pdflags");
+ dp.unpackFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
+
+ dp.unpackColor4U(coloru, "pdstartcolor");
+ mStartColor.setVec(coloru);
+ dp.unpackColor4U(coloru, "pdendcolor");
+ mEndColor.setVec(coloru);
+ dp.unpackFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
+ dp.unpackFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
+ dp.unpackFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
+ dp.unpackFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
+ return TRUE;
+}
+
+
+void LLPartData::setFlags(const U32 flags)
+{
+ mFlags = flags;
+}
+
+
+void LLPartData::setMaxAge(const F32 max_age)
+{
+ mMaxAge = llclamp(max_age, 0.f, 30.f);
+}
+
+
+void LLPartData::setStartScale(const F32 xs, const F32 ys)
+{
+ mStartScale.mV[VX] = llmin(xs, MAX_PART_SCALE);
+ mStartScale.mV[VY] = llmin(ys, MAX_PART_SCALE);
+}
+
+
+void LLPartData::setEndScale(const F32 xs, const F32 ys)
+{
+ mEndScale.mV[VX] = llmin(xs, MAX_PART_SCALE);
+ mEndScale.mV[VY] = llmin(ys, MAX_PART_SCALE);
+}
+
+
+void LLPartData::setStartColor(const LLVector3 &rgb)
+{
+ mStartColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]);
+}
+
+
+void LLPartData::setEndColor(const LLVector3 &rgb)
+{
+ mEndColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]);
+}
+
+void LLPartData::setStartAlpha(const F32 alpha)
+{
+ mStartColor.mV[3] = alpha;
+}
+void LLPartData::setEndAlpha(const F32 alpha)
+{
+ mEndColor.mV[3] = alpha;
+}
+
+
+LLPartSysData::LLPartSysData()
+{
+ mCRC = 0;
+ mPartData.mFlags = 0;
+ mPartData.mStartColor = LLColor4(1.f, 1.f, 1.f, 1.f);
+ mPartData.mEndColor = LLColor4(1.f, 1.f, 1.f, 1.f);
+ mPartData.mStartScale = LLVector2(1.f, 1.f);
+ mPartData.mEndScale = LLVector2(1.f, 1.f);
+ mPartData.mMaxAge = 10.0;
+
+ mMaxAge = 0.0;
+ mStartAge = 0.0;
+ mPattern = LL_PART_SRC_PATTERN_DROP; // Pattern for particle velocity
+ mInnerAngle = 0.0; // Inner angle of PATTERN_ANGLE_*
+ mOuterAngle = 0.0; // Outer angle of PATTERN_ANGLE_*
+ mBurstRate = 0.1f; // How often to do a burst of particles
+ mBurstPartCount = 1; // How many particles in a burst
+ mBurstSpeedMin = 1.f; // Minimum particle velocity
+ mBurstSpeedMax = 1.f; // Maximum particle velocity
+ mBurstRadius = 0.f;
+}
+
+
+BOOL LLPartSysData::pack(LLDataPacker &dp)
+{
+ dp.packU32(mCRC, "pscrc");
+ dp.packU32(mFlags, "psflags");
+ dp.packU8(mPattern, "pspattern");
+ dp.packFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
+ dp.packFixed(mStartAge, "psstartage", FALSE, 8, 8);
+ dp.packFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
+ dp.packFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
+ dp.packFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
+ dp.packFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
+ dp.packFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
+ dp.packFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
+ dp.packU8(mBurstPartCount, "psburstpartcount");
+
+ dp.packFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
+ dp.packFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
+ dp.packFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
+
+ dp.packFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
+ dp.packFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
+ dp.packFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
+
+ dp.packUUID(mPartImageID, "psuuid");
+ dp.packUUID(mTargetUUID, "pstargetuuid");
+ mPartData.pack(dp);
+ return TRUE;
+}
+
+
+BOOL LLPartSysData::unpack(LLDataPacker &dp)
+{
+ dp.unpackU32(mCRC, "pscrc");
+ dp.unpackU32(mFlags, "psflags");
+ dp.unpackU8(mPattern, "pspattern");
+ dp.unpackFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
+ dp.unpackFixed(mStartAge, "psstartage", FALSE, 8, 8);
+ dp.unpackFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
+ dp.unpackFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
+ dp.unpackFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
+ mBurstRate = llmax(0.01f, mBurstRate);
+ dp.unpackFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
+ dp.unpackFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
+ dp.unpackFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
+ dp.unpackU8(mBurstPartCount, "psburstpartcount");
+
+ dp.unpackFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
+ dp.unpackFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
+ dp.unpackFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
+
+ dp.unpackFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
+ dp.unpackFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
+ dp.unpackFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
+
+ dp.unpackUUID(mPartImageID, "psuuid");
+ dp.unpackUUID(mTargetUUID, "pstargetuuid");
+ mPartData.unpack(dp);
+ return TRUE;
+}
+
+
+BOOL LLPartSysData::isNullPS(const S32 block_num)
+{
+ U8 ps_data_block[PS_DATA_BLOCK_SIZE];
+ U32 crc;
+
+ S32 size;
+ // Check size of block
+ size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
+
+ if (!size)
+ {
+ return TRUE;
+ }
+ else if (size != PS_DATA_BLOCK_SIZE)
+ {
+ llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
+ return TRUE;
+ }
+ gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
+
+ LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
+ dp.unpackU32(crc, "crc");
+
+ if (crc == 0)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//static
+BOOL LLPartSysData::packNull()
+{
+ U8 ps_data_block[PS_DATA_BLOCK_SIZE];
+ gMessageSystem->addBinaryData("PSBlock", ps_data_block, 0);
+ return TRUE;
+}
+
+
+BOOL LLPartSysData::packBlock()
+{
+ U8 ps_data_block[PS_DATA_BLOCK_SIZE];
+
+ LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
+ pack(dp);
+
+ // Add to message
+ gMessageSystem->addBinaryData("PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE);
+
+ return TRUE;
+}
+
+
+BOOL LLPartSysData::unpackBlock(const S32 block_num)
+{
+ U8 ps_data_block[PS_DATA_BLOCK_SIZE];
+
+ // Check size of block
+ S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
+
+ if (size != PS_DATA_BLOCK_SIZE)
+ {
+ llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
+ return FALSE;
+ }
+
+ // Get from message
+ gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
+
+ LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
+ unpack(dp);
+
+ return TRUE;
+}
+
+void LLPartSysData::clampSourceParticleRate()
+{
+ F32 particle_rate = 0;
+ particle_rate = mBurstPartCount/mBurstRate;
+ if (particle_rate > 256.f)
+ {
+ mBurstPartCount = llfloor(((F32)mBurstPartCount)*(256.f/particle_rate));
+ }
+}
+
+void LLPartSysData::setPartAccel(const LLVector3 &accel)
+{
+ mPartAccel.mV[VX] = llclamp(accel.mV[VX], -100.f, 100.f);
+ mPartAccel.mV[VY] = llclamp(accel.mV[VY], -100.f, 100.f);
+ mPartAccel.mV[VZ] = llclamp(accel.mV[VZ], -100.f, 100.f);
+}