00001
00032 #include "linden_common.h"
00033
00034 #include "llpartdata.h"
00035 #include "message.h"
00036
00037 #include "lldatapacker.h"
00038 #include "v4coloru.h"
00039
00040 #include "llsdutil.h"
00041
00042
00043 const S32 PS_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2;
00044 const S32 PS_DATA_BLOCK_SIZE = 68 + PS_PART_DATA_BLOCK_SIZE;
00045
00046
00047 const F32 MAX_PART_SCALE = 4.f;
00048
00049 BOOL LLPartData::pack(LLDataPacker &dp)
00050 {
00051 LLColor4U coloru;
00052 dp.packU32(mFlags, "pdflags");
00053 dp.packFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
00054 coloru.setVec(mStartColor);
00055 dp.packColor4U(coloru, "pdstartcolor");
00056 coloru.setVec(mEndColor);
00057 dp.packColor4U(coloru, "pdendcolor");
00058 dp.packFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
00059 dp.packFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
00060 dp.packFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
00061 dp.packFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
00062 return TRUE;
00063 }
00064
00065 LLSD LLPartData::asLLSD() const
00066 {
00067 LLSD sd = LLSD();
00068 sd["pdflags"] = ll_sd_from_U32(mFlags);
00069 sd["pdmaxage"] = mMaxAge;
00070 sd["pdstartcolor"] = ll_sd_from_color4(mStartColor);
00071 sd["pdendcolor"] = ll_sd_from_color4(mEndColor);
00072 sd["pdstartscale"] = ll_sd_from_vector2(mStartScale);
00073 sd["pdendscale"] = ll_sd_from_vector2(mEndScale);
00074 return sd;
00075 }
00076
00077 bool LLPartData::fromLLSD(LLSD& sd)
00078 {
00079 mFlags = ll_U32_from_sd(sd["pdflags"]);
00080 mMaxAge = (F32)sd["pdmaxage"].asReal();
00081 mStartColor = ll_color4_from_sd(sd["pdstartcolor"]);
00082 mEndColor = ll_color4_from_sd(sd["pdendcolor"]);
00083 mStartScale = ll_vector2_from_sd(sd["pdstartscale"]);
00084 mEndScale = ll_vector2_from_sd(sd["pdendscale"]);
00085 return true;
00086 }
00087
00088
00089 BOOL LLPartData::unpack(LLDataPacker &dp)
00090 {
00091 LLColor4U coloru;
00092
00093 dp.unpackU32(mFlags, "pdflags");
00094 dp.unpackFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
00095
00096 dp.unpackColor4U(coloru, "pdstartcolor");
00097 mStartColor.setVec(coloru);
00098 dp.unpackColor4U(coloru, "pdendcolor");
00099 mEndColor.setVec(coloru);
00100 dp.unpackFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
00101 dp.unpackFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
00102 dp.unpackFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
00103 dp.unpackFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
00104 return TRUE;
00105 }
00106
00107
00108 void LLPartData::setFlags(const U32 flags)
00109 {
00110 mFlags = flags;
00111 }
00112
00113
00114 void LLPartData::setMaxAge(const F32 max_age)
00115 {
00116 mMaxAge = llclamp(max_age, 0.f, 30.f);
00117 }
00118
00119
00120 void LLPartData::setStartScale(const F32 xs, const F32 ys)
00121 {
00122 mStartScale.mV[VX] = llmin(xs, MAX_PART_SCALE);
00123 mStartScale.mV[VY] = llmin(ys, MAX_PART_SCALE);
00124 }
00125
00126
00127 void LLPartData::setEndScale(const F32 xs, const F32 ys)
00128 {
00129 mEndScale.mV[VX] = llmin(xs, MAX_PART_SCALE);
00130 mEndScale.mV[VY] = llmin(ys, MAX_PART_SCALE);
00131 }
00132
00133
00134 void LLPartData::setStartColor(const LLVector3 &rgb)
00135 {
00136 mStartColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]);
00137 }
00138
00139
00140 void LLPartData::setEndColor(const LLVector3 &rgb)
00141 {
00142 mEndColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]);
00143 }
00144
00145 void LLPartData::setStartAlpha(const F32 alpha)
00146 {
00147 mStartColor.mV[3] = alpha;
00148 }
00149 void LLPartData::setEndAlpha(const F32 alpha)
00150 {
00151 mEndColor.mV[3] = alpha;
00152 }
00153
00154
00155 LLPartSysData::LLPartSysData()
00156 {
00157 mCRC = 0;
00158 mPartData.mFlags = 0;
00159 mPartData.mStartColor = LLColor4(1.f, 1.f, 1.f, 1.f);
00160 mPartData.mEndColor = LLColor4(1.f, 1.f, 1.f, 1.f);
00161 mPartData.mStartScale = LLVector2(1.f, 1.f);
00162 mPartData.mEndScale = LLVector2(1.f, 1.f);
00163 mPartData.mMaxAge = 10.0;
00164
00165 mMaxAge = 0.0;
00166 mStartAge = 0.0;
00167 mPattern = LL_PART_SRC_PATTERN_DROP;
00168 mInnerAngle = 0.0;
00169 mOuterAngle = 0.0;
00170 mBurstRate = 0.1f;
00171 mBurstPartCount = 1;
00172 mBurstSpeedMin = 1.f;
00173 mBurstSpeedMax = 1.f;
00174 mBurstRadius = 0.f;
00175 }
00176
00177
00178 BOOL LLPartSysData::pack(LLDataPacker &dp)
00179 {
00180 dp.packU32(mCRC, "pscrc");
00181 dp.packU32(mFlags, "psflags");
00182 dp.packU8(mPattern, "pspattern");
00183 dp.packFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
00184 dp.packFixed(mStartAge, "psstartage", FALSE, 8, 8);
00185 dp.packFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
00186 dp.packFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
00187 dp.packFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
00188 dp.packFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
00189 dp.packFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
00190 dp.packFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
00191 dp.packU8(mBurstPartCount, "psburstpartcount");
00192
00193 dp.packFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
00194 dp.packFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
00195 dp.packFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
00196
00197 dp.packFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
00198 dp.packFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
00199 dp.packFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
00200
00201 dp.packUUID(mPartImageID, "psuuid");
00202 dp.packUUID(mTargetUUID, "pstargetuuid");
00203 mPartData.pack(dp);
00204 return TRUE;
00205 }
00206
00207
00208 BOOL LLPartSysData::unpack(LLDataPacker &dp)
00209 {
00210 dp.unpackU32(mCRC, "pscrc");
00211 dp.unpackU32(mFlags, "psflags");
00212 dp.unpackU8(mPattern, "pspattern");
00213 dp.unpackFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
00214 dp.unpackFixed(mStartAge, "psstartage", FALSE, 8, 8);
00215 dp.unpackFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
00216 dp.unpackFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
00217 dp.unpackFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
00218 mBurstRate = llmax(0.01f, mBurstRate);
00219 dp.unpackFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
00220 dp.unpackFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
00221 dp.unpackFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
00222 dp.unpackU8(mBurstPartCount, "psburstpartcount");
00223
00224 dp.unpackFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
00225 dp.unpackFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
00226 dp.unpackFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
00227
00228 dp.unpackFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
00229 dp.unpackFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
00230 dp.unpackFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
00231
00232 dp.unpackUUID(mPartImageID, "psuuid");
00233 dp.unpackUUID(mTargetUUID, "pstargetuuid");
00234 mPartData.unpack(dp);
00235 return TRUE;
00236 }
00237
00238 std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
00239 {
00240 s << "Flags: " << std::hex << data.mFlags;
00241 s << " Pattern: " << std::hex << (U32) data.mPattern << "\n";
00242 s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n";
00243 s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n";
00244 s << "Burst Rate: " << data.mBurstRate << "\n";
00245 s << "Burst Radius: " << data.mBurstRadius << "\n";
00246 s << "Burst Speed: [" << data.mBurstSpeedMin << ", " << data.mBurstSpeedMax << "]\n";
00247 s << "Burst Part Count: " << std::hex << (U32) data.mBurstPartCount << "\n";
00248 s << "Angular Velocity: " << data.mAngularVelocity << "\n";
00249 s << "Accel: " << data.mPartAccel;
00250 return s;
00251 }
00252
00253 BOOL LLPartSysData::isNullPS(const S32 block_num)
00254 {
00255 U8 ps_data_block[PS_DATA_BLOCK_SIZE];
00256 U32 crc;
00257
00258 S32 size;
00259
00260 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
00261
00262 if (!size)
00263 {
00264 return TRUE;
00265 }
00266 else if (size != PS_DATA_BLOCK_SIZE)
00267 {
00268 llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
00269 return TRUE;
00270 }
00271 gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
00272
00273 LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
00274 dp.unpackU32(crc, "crc");
00275
00276 if (crc == 0)
00277 {
00278 return TRUE;
00279 }
00280 return FALSE;
00281 }
00282
00283
00284
00285 BOOL LLPartSysData::packNull()
00286 {
00287 U8 ps_data_block[PS_DATA_BLOCK_SIZE];
00288 gMessageSystem->addBinaryData("PSBlock", ps_data_block, 0);
00289 return TRUE;
00290 }
00291
00292
00293 BOOL LLPartSysData::packBlock()
00294 {
00295 U8 ps_data_block[PS_DATA_BLOCK_SIZE];
00296
00297 LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
00298 pack(dp);
00299
00300
00301 gMessageSystem->addBinaryData("PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE);
00302
00303 return TRUE;
00304 }
00305
00306
00307 BOOL LLPartSysData::unpackBlock(const S32 block_num)
00308 {
00309 U8 ps_data_block[PS_DATA_BLOCK_SIZE];
00310
00311
00312 S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
00313
00314 if (size != PS_DATA_BLOCK_SIZE)
00315 {
00316 llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
00317 return FALSE;
00318 }
00319
00320
00321 gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
00322
00323 LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
00324 unpack(dp);
00325
00326 return TRUE;
00327 }
00328
00329 void LLPartSysData::clampSourceParticleRate()
00330 {
00331 F32 particle_rate = 0;
00332 particle_rate = mBurstPartCount/mBurstRate;
00333 if (particle_rate > 256.f)
00334 {
00335 mBurstPartCount = llfloor(((F32)mBurstPartCount)*(256.f/particle_rate));
00336 }
00337 }
00338
00339 void LLPartSysData::setPartAccel(const LLVector3 &accel)
00340 {
00341 mPartAccel.mV[VX] = llclamp(accel.mV[VX], -100.f, 100.f);
00342 mPartAccel.mV[VY] = llclamp(accel.mV[VY], -100.f, 100.f);
00343 mPartAccel.mV[VZ] = llclamp(accel.mV[VZ], -100.f, 100.f);
00344 }