diff options
Diffstat (limited to 'indra/llmessage/llpartdata.cpp')
-rw-r--r-- | indra/llmessage/llpartdata.cpp | 307 |
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); +} |