PageRenderTime 43ms CodeModel.GetById 7ms app.highlight 32ms RepoModel.GetById 1ms 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
  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
 27#include "linden_common.h"
 28
 29#include "llpartdata.h"
 30#include "message.h"
 31
 32#include "lldatapacker.h"
 33#include "v4coloru.h"
 34
 35#include "llsdutil.h"
 36#include "llsdutil_math.h"
 37
 38
 39
 40const S32 PS_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; // 18
 41const S32 PS_DATA_BLOCK_SIZE = 68 + PS_PART_DATA_BLOCK_SIZE; // 68 + 18 = 86
 42
 43
 44const F32 MAX_PART_SCALE = 4.f;
 45
 46BOOL LLPartData::pack(LLDataPacker &dp)
 47{
 48	LLColor4U coloru;
 49	dp.packU32(mFlags, "pdflags");
 50	dp.packFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
 51	coloru.setVec(mStartColor);
 52	dp.packColor4U(coloru, "pdstartcolor");
 53	coloru.setVec(mEndColor);
 54	dp.packColor4U(coloru, "pdendcolor");
 55	dp.packFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
 56	dp.packFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
 57	dp.packFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
 58	dp.packFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
 59	return TRUE;
 60}
 61
 62LLSD LLPartData::asLLSD() const
 63{
 64	LLSD sd = LLSD();
 65	sd["pdflags"] = ll_sd_from_U32(mFlags);
 66	sd["pdmaxage"] = mMaxAge;
 67	sd["pdstartcolor"] = ll_sd_from_color4(mStartColor);
 68	sd["pdendcolor"] = ll_sd_from_color4(mEndColor);
 69	sd["pdstartscale"] = ll_sd_from_vector2(mStartScale);
 70	sd["pdendscale"] = ll_sd_from_vector2(mEndScale);
 71	return sd;
 72}
 73
 74bool LLPartData::fromLLSD(LLSD& sd)
 75{
 76	mFlags = ll_U32_from_sd(sd["pdflags"]);
 77	mMaxAge = (F32)sd["pdmaxage"].asReal();
 78	mStartColor = ll_color4_from_sd(sd["pdstartcolor"]);
 79	mEndColor = ll_color4_from_sd(sd["pdendcolor"]);
 80	mStartScale = ll_vector2_from_sd(sd["pdstartscale"]);
 81	mEndScale = ll_vector2_from_sd(sd["pdendscale"]);
 82	return true;
 83}
 84
 85
 86BOOL LLPartData::unpack(LLDataPacker &dp)
 87{
 88	LLColor4U coloru;
 89
 90	dp.unpackU32(mFlags, "pdflags");
 91	dp.unpackFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
 92
 93	dp.unpackColor4U(coloru, "pdstartcolor");
 94	mStartColor.setVec(coloru);
 95	dp.unpackColor4U(coloru, "pdendcolor");
 96	mEndColor.setVec(coloru);
 97	dp.unpackFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
 98	dp.unpackFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
 99	dp.unpackFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
100	dp.unpackFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
101	return TRUE;
102}
103
104
105void LLPartData::setFlags(const U32 flags)
106{
107	mFlags = flags;
108}
109
110
111void LLPartData::setMaxAge(const F32 max_age)
112{
113	mMaxAge = llclamp(max_age, 0.f, 30.f);
114}
115
116
117void LLPartData::setStartScale(const F32 xs, const F32 ys)
118{
119	mStartScale.mV[VX] = llmin(xs, MAX_PART_SCALE);
120	mStartScale.mV[VY] = llmin(ys, MAX_PART_SCALE);
121}
122
123
124void LLPartData::setEndScale(const F32 xs, const F32 ys)
125{
126	mEndScale.mV[VX] = llmin(xs, MAX_PART_SCALE);
127	mEndScale.mV[VY] = llmin(ys, MAX_PART_SCALE);
128}
129
130
131void LLPartData::setStartColor(const LLVector3 &rgb)
132{
133	mStartColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]);
134}
135
136
137void LLPartData::setEndColor(const LLVector3 &rgb)
138{
139	mEndColor.setVec(rgb.mV[0], rgb.mV[1], rgb.mV[2]);
140}
141
142void LLPartData::setStartAlpha(const F32 alpha)
143{
144	mStartColor.mV[3] = alpha;
145}
146void LLPartData::setEndAlpha(const F32 alpha)
147{
148	mEndColor.mV[3] = alpha;
149}
150
151
152LLPartSysData::LLPartSysData()
153{
154	mCRC = 0;
155	mFlags = 0;
156
157	mPartData.mFlags = 0;
158	mPartData.mStartColor = LLColor4(1.f, 1.f, 1.f, 1.f);
159	mPartData.mEndColor = LLColor4(1.f, 1.f, 1.f, 1.f);
160	mPartData.mStartScale = LLVector2(1.f, 1.f);
161	mPartData.mEndScale = LLVector2(1.f, 1.f);
162	mPartData.mMaxAge = 10.0;
163
164	mMaxAge = 0.0;
165	mStartAge = 0.0;
166	mPattern = LL_PART_SRC_PATTERN_DROP;			// Pattern for particle velocity
167	mInnerAngle = 0.0;								// Inner angle of PATTERN_ANGLE_*
168	mOuterAngle = 0.0;								// Outer angle of PATTERN_ANGLE_*
169	mBurstRate = 0.1f;								// How often to do a burst of particles
170	mBurstPartCount = 1;							// How many particles in a burst
171	mBurstSpeedMin = 1.f;						// Minimum particle velocity
172	mBurstSpeedMax = 1.f;						// Maximum particle velocity
173	mBurstRadius = 0.f;
174
175	mNumParticles = 0;
176}
177
178
179BOOL LLPartSysData::pack(LLDataPacker &dp)
180{
181	dp.packU32(mCRC, "pscrc");
182	dp.packU32(mFlags, "psflags");
183	dp.packU8(mPattern, "pspattern");
184	dp.packFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
185	dp.packFixed(mStartAge, "psstartage", FALSE, 8, 8);
186	dp.packFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
187	dp.packFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
188	dp.packFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
189	dp.packFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
190	dp.packFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
191	dp.packFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
192	dp.packU8(mBurstPartCount, "psburstpartcount");
193
194	dp.packFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
195	dp.packFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
196	dp.packFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
197
198	dp.packFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
199	dp.packFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
200	dp.packFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
201
202	dp.packUUID(mPartImageID, "psuuid");
203	dp.packUUID(mTargetUUID, "pstargetuuid");
204	mPartData.pack(dp);
205	return TRUE;
206}
207
208
209BOOL LLPartSysData::unpack(LLDataPacker &dp)
210{
211	dp.unpackU32(mCRC, "pscrc");
212	dp.unpackU32(mFlags, "psflags");
213	dp.unpackU8(mPattern, "pspattern");
214	dp.unpackFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
215	dp.unpackFixed(mStartAge, "psstartage", FALSE, 8, 8);
216	dp.unpackFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
217	dp.unpackFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
218	dp.unpackFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
219	mBurstRate = llmax(0.01f, mBurstRate);
220	dp.unpackFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
221	dp.unpackFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
222	dp.unpackFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
223	dp.unpackU8(mBurstPartCount, "psburstpartcount");
224
225	dp.unpackFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
226	dp.unpackFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
227	dp.unpackFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
228
229	dp.unpackFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
230	dp.unpackFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
231	dp.unpackFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
232
233	dp.unpackUUID(mPartImageID, "psuuid");
234	dp.unpackUUID(mTargetUUID, "pstargetuuid");
235	mPartData.unpack(dp);
236	return TRUE;
237}
238
239std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
240{
241	s << "Flags: " << std::hex << data.mFlags;
242	s << " Pattern: " << std::hex << (U32) data.mPattern << "\n";
243	s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n";
244	s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n";
245	s << "Burst Rate: " << data.mBurstRate << "\n";
246	s << "Burst Radius: " << data.mBurstRadius << "\n";
247	s << "Burst Speed: [" << data.mBurstSpeedMin << ", " << data.mBurstSpeedMax << "]\n";
248	s << "Burst Part Count: " << std::hex << (U32) data.mBurstPartCount << "\n";
249	s << "Angular Velocity: " << data.mAngularVelocity << "\n";
250	s << "Accel: " << data.mPartAccel;
251	return s;
252}
253
254BOOL LLPartSysData::isNullPS(const S32 block_num)
255{
256	U8 ps_data_block[PS_DATA_BLOCK_SIZE];
257	U32 crc;
258
259	S32 size;
260	// Check size of block
261	size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
262	
263	if (!size)
264	{
265		return TRUE;
266	}
267	else if (size != PS_DATA_BLOCK_SIZE)
268	{
269		llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
270		return TRUE;
271	}
272	gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
273
274	LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
275	dp.unpackU32(crc, "crc");
276
277	if (crc == 0)
278	{
279		return TRUE;
280	}
281	return FALSE;
282}
283
284
285//static
286BOOL LLPartSysData::packNull()
287{
288	U8 ps_data_block[PS_DATA_BLOCK_SIZE];
289	gMessageSystem->addBinaryData("PSBlock", ps_data_block, 0);
290	return TRUE;
291}
292
293
294BOOL LLPartSysData::packBlock()
295{
296	U8 ps_data_block[PS_DATA_BLOCK_SIZE];
297
298	LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
299	pack(dp);
300
301	// Add to message
302	gMessageSystem->addBinaryData("PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE);
303
304	return TRUE;
305}                                         
306
307
308BOOL LLPartSysData::unpackBlock(const S32 block_num)
309{
310	U8 ps_data_block[PS_DATA_BLOCK_SIZE];
311
312	// Check size of block
313	S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
314
315	if (size != PS_DATA_BLOCK_SIZE)
316	{
317		llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
318		return FALSE;
319	}
320
321	// Get from message
322	gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
323
324	LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
325	unpack(dp);
326
327	return TRUE;
328}
329
330void LLPartSysData::clampSourceParticleRate()
331{
332	F32 particle_rate = 0;
333	particle_rate = mBurstPartCount/mBurstRate;
334	if (particle_rate > 256.f)
335	{
336		mBurstPartCount = llfloor(((F32)mBurstPartCount)*(256.f/particle_rate));
337	}
338}
339
340void LLPartSysData::setPartAccel(const LLVector3 &accel)
341{
342	mPartAccel.mV[VX] = llclamp(accel.mV[VX], -100.f, 100.f);
343	mPartAccel.mV[VY] = llclamp(accel.mV[VY], -100.f, 100.f);
344	mPartAccel.mV[VZ] = llclamp(accel.mV[VZ], -100.f, 100.f);
345}