diff options
author | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
commit | 89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch) | |
tree | bcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/newview/llviewerpartsim.cpp | |
parent | Second Life viewer sources 1.13.3.2 (diff) | |
download | meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2 meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz |
Second Life viewer sources 1.14.0.0
Diffstat (limited to 'linden/indra/newview/llviewerpartsim.cpp')
-rw-r--r-- | linden/indra/newview/llviewerpartsim.cpp | 305 |
1 files changed, 181 insertions, 124 deletions
diff --git a/linden/indra/newview/llviewerpartsim.cpp b/linden/indra/newview/llviewerpartsim.cpp index be2c90f..2658e67 100644 --- a/linden/indra/newview/llviewerpartsim.cpp +++ b/linden/indra/newview/llviewerpartsim.cpp | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "llviewercontrol.h" | 32 | #include "llviewercontrol.h" |
33 | 33 | ||
34 | #include "llagent.h" | 34 | #include "llagent.h" |
35 | #include "llviewercamera.h" | ||
35 | #include "llviewerobjectlist.h" | 36 | #include "llviewerobjectlist.h" |
36 | #include "llviewerpartsource.h" | 37 | #include "llviewerpartsource.h" |
37 | #include "llviewerregion.h" | 38 | #include "llviewerregion.h" |
@@ -41,7 +42,7 @@ | |||
41 | 42 | ||
42 | const S32 MAX_PART_COUNT = 4096; | 43 | const S32 MAX_PART_COUNT = 4096; |
43 | 44 | ||
44 | const F32 PART_SIM_BOX_SIDE = 32.f; | 45 | const F32 PART_SIM_BOX_SIDE = 16.f; |
45 | const F32 PART_SIM_BOX_OFFSET = 0.5f*PART_SIM_BOX_SIDE; | 46 | const F32 PART_SIM_BOX_OFFSET = 0.5f*PART_SIM_BOX_SIDE; |
46 | const F32 PART_SIM_BOX_RAD = 0.5f*F_SQRT3*PART_SIM_BOX_SIDE; | 47 | const F32 PART_SIM_BOX_RAD = 0.5f*F_SQRT3*PART_SIM_BOX_SIDE; |
47 | 48 | ||
@@ -52,18 +53,28 @@ S32 LLViewerPartSim::sParticleCount = 0; | |||
52 | 53 | ||
53 | U32 LLViewerPart::sNextPartID = 1; | 54 | U32 LLViewerPart::sNextPartID = 1; |
54 | 55 | ||
56 | F32 calc_desired_size(LLVector3 pos, LLVector2 scale) | ||
57 | { | ||
58 | F32 desired_size = (pos-gCamera->getOrigin()).magVec(); | ||
59 | desired_size /= 4; | ||
60 | return llclamp(desired_size, scale.magVec()*0.5f, PART_SIM_BOX_SIDE*2); | ||
61 | } | ||
62 | |||
55 | LLViewerPart::LLViewerPart() | 63 | LLViewerPart::LLViewerPart() |
56 | { | 64 | { |
65 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
57 | mPartSourcep = NULL; | 66 | mPartSourcep = NULL; |
58 | } | 67 | } |
59 | 68 | ||
60 | LLViewerPart::~LLViewerPart() | 69 | LLViewerPart::~LLViewerPart() |
61 | { | 70 | { |
71 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
62 | mPartSourcep = NULL; | 72 | mPartSourcep = NULL; |
63 | } | 73 | } |
64 | 74 | ||
65 | LLViewerPart &LLViewerPart::operator=(const LLViewerPart &part) | 75 | LLViewerPart &LLViewerPart::operator=(const LLViewerPart &part) |
66 | { | 76 | { |
77 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
67 | mPartID = part.mPartID; | 78 | mPartID = part.mPartID; |
68 | mFlags = part.mFlags; | 79 | mFlags = part.mFlags; |
69 | mMaxAge = part.mMaxAge; | 80 | mMaxAge = part.mMaxAge; |
@@ -93,6 +104,7 @@ LLViewerPart &LLViewerPart::operator=(const LLViewerPart &part) | |||
93 | 104 | ||
94 | void LLViewerPart::init(LLViewerPartSource *sourcep, LLViewerImage *imagep, LLVPCallback cb) | 105 | void LLViewerPart::init(LLViewerPartSource *sourcep, LLViewerImage *imagep, LLVPCallback cb) |
95 | { | 106 | { |
107 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
96 | mPartID = LLViewerPart::sNextPartID; | 108 | mPartID = LLViewerPart::sNextPartID; |
97 | LLViewerPart::sNextPartID++; | 109 | LLViewerPart::sNextPartID++; |
98 | mFlags = 0x00f; | 110 | mFlags = 0x00f; |
@@ -115,8 +127,13 @@ void LLViewerPart::init(LLViewerPartSource *sourcep, LLViewerImage *imagep, LLVP | |||
115 | 127 | ||
116 | LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 box_side) | 128 | LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 box_side) |
117 | { | 129 | { |
130 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
118 | mVOPartGroupp = NULL; | 131 | mVOPartGroupp = NULL; |
132 | mUniformParticles = TRUE; | ||
133 | |||
119 | mRegionp = gWorldPointer->getRegionFromPosAgent(center_agent); | 134 | mRegionp = gWorldPointer->getRegionFromPosAgent(center_agent); |
135 | llassert_always(center_agent.isFinite()); | ||
136 | |||
120 | if (!mRegionp) | 137 | if (!mRegionp) |
121 | { | 138 | { |
122 | //llwarns << "No region at position, using agent region!" << llendl; | 139 | //llwarns << "No region at position, using agent region!" << llendl; |
@@ -125,28 +142,39 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo | |||
125 | mCenterAgent = center_agent; | 142 | mCenterAgent = center_agent; |
126 | mBoxRadius = F_SQRT3*box_side*0.5f; | 143 | mBoxRadius = F_SQRT3*box_side*0.5f; |
127 | 144 | ||
128 | LLVector3 rad_vec(box_side*0.5f, box_side*0.5f, box_side*0.5f); | 145 | mVOPartGroupp = (LLVOPartGroup *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_PART_GROUP, getRegion()); |
129 | rad_vec += LLVector3(0.001f, 0.001f, 0.001f); | 146 | mVOPartGroupp->setViewerPartGroup(this); |
130 | mMinObjPos = mCenterAgent - rad_vec; | 147 | mVOPartGroupp->setPositionAgent(getCenterAgent()); |
131 | mMaxObjPos = mCenterAgent + rad_vec; | 148 | F32 scale = box_side * 0.5f; |
149 | mVOPartGroupp->setScale(LLVector3(scale,scale,scale)); | ||
150 | gPipeline.addObject(mVOPartGroupp); | ||
151 | |||
152 | LLSpatialGroup* group = mVOPartGroupp->mDrawable->getSpatialGroup(); | ||
153 | |||
154 | LLVector3 center(group->mOctreeNode->getCenter()); | ||
155 | LLVector3 size(group->mOctreeNode->getSize()); | ||
156 | size += LLVector3(0.01f, 0.01f, 0.01f); | ||
157 | mMinObjPos = center - size; | ||
158 | mMaxObjPos = center + size; | ||
159 | |||
160 | static U32 id_seed = 0; | ||
161 | mID = ++id_seed; | ||
132 | } | 162 | } |
133 | 163 | ||
134 | LLViewerPartGroup::~LLViewerPartGroup() | 164 | LLViewerPartGroup::~LLViewerPartGroup() |
135 | { | 165 | { |
166 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
136 | cleanup(); | 167 | cleanup(); |
137 | S32 count = mParticles.count(); | 168 | |
138 | S32 i; | 169 | S32 count = (S32) mParticles.size(); |
139 | 170 | mParticles.clear(); | |
140 | for (i = 0; i < count; i++) | 171 | |
141 | { | ||
142 | mParticles[i].mPartSourcep = NULL; | ||
143 | } | ||
144 | mParticles.reset(); | ||
145 | LLViewerPartSim::decPartCount(count); | 172 | LLViewerPartSim::decPartCount(count); |
146 | } | 173 | } |
147 | 174 | ||
148 | void LLViewerPartGroup::cleanup() | 175 | void LLViewerPartGroup::cleanup() |
149 | { | 176 | { |
177 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
150 | if (mVOPartGroupp) | 178 | if (mVOPartGroupp) |
151 | { | 179 | { |
152 | if (!mVOPartGroupp->isDead()) | 180 | if (!mVOPartGroupp->isDead()) |
@@ -157,8 +185,9 @@ void LLViewerPartGroup::cleanup() | |||
157 | } | 185 | } |
158 | } | 186 | } |
159 | 187 | ||
160 | BOOL LLViewerPartGroup::posInGroup(const LLVector3 &pos) | 188 | BOOL LLViewerPartGroup::posInGroup(const LLVector3 &pos, const F32 desired_size) |
161 | { | 189 | { |
190 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
162 | if ((pos.mV[VX] < mMinObjPos.mV[VX]) | 191 | if ((pos.mV[VX] < mMinObjPos.mV[VX]) |
163 | || (pos.mV[VY] < mMinObjPos.mV[VY]) | 192 | || (pos.mV[VY] < mMinObjPos.mV[VY]) |
164 | || (pos.mV[VZ] < mMinObjPos.mV[VZ])) | 193 | || (pos.mV[VZ] < mMinObjPos.mV[VZ])) |
@@ -173,29 +202,33 @@ BOOL LLViewerPartGroup::posInGroup(const LLVector3 &pos) | |||
173 | return FALSE; | 202 | return FALSE; |
174 | } | 203 | } |
175 | 204 | ||
205 | if (desired_size > 0 && | ||
206 | (desired_size < mBoxRadius*0.5f || | ||
207 | desired_size > mBoxRadius*2.f)) | ||
208 | { | ||
209 | return FALSE; | ||
210 | } | ||
211 | |||
176 | return TRUE; | 212 | return TRUE; |
177 | } | 213 | } |
178 | 214 | ||
179 | 215 | ||
180 | BOOL LLViewerPartGroup::addPart(LLViewerPart &part) | 216 | BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size) |
181 | { | 217 | { |
182 | if (!posInGroup(part.mPosAgent) || | 218 | LLMemType mt(LLMemType::MTYPE_PARTICLES); |
183 | (mVOPartGroupp.notNull() && (part.mImagep != mVOPartGroupp->getTEImage(0)))) | 219 | BOOL uniform_part = part->mScale.mV[0] == part->mScale.mV[1] && |
220 | !(part->mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK); | ||
221 | |||
222 | if (!posInGroup(part->mPosAgent, desired_size) || | ||
223 | (mUniformParticles && !uniform_part) || | ||
224 | (!mUniformParticles && uniform_part)) | ||
184 | { | 225 | { |
185 | return FALSE; | 226 | return FALSE; |
186 | } | 227 | } |
187 | 228 | ||
188 | if (!mVOPartGroupp) | 229 | gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); |
189 | { | ||
190 | mVOPartGroupp = (LLVOPartGroup *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_PART_GROUP, getRegion()); | ||
191 | mVOPartGroupp->setViewerPartGroup(this); | ||
192 | mVOPartGroupp->setPositionAgent(getCenterAgent()); | ||
193 | mVOPartGroupp->setScale(LLVector3(PART_SIM_BOX_SIDE, PART_SIM_BOX_SIDE, PART_SIM_BOX_SIDE)); | ||
194 | mVOPartGroupp->setTEImage(0, part.mImagep); | ||
195 | gPipeline.addObject(mVOPartGroupp); | ||
196 | } | ||
197 | 230 | ||
198 | mParticles.put(part); | 231 | mParticles.push_back(part); |
199 | LLViewerPartSim::incPartCount(1); | 232 | LLViewerPartSim::incPartCount(1); |
200 | return TRUE; | 233 | return TRUE; |
201 | } | 234 | } |
@@ -203,33 +236,29 @@ BOOL LLViewerPartGroup::addPart(LLViewerPart &part) | |||
203 | 236 | ||
204 | void LLViewerPartGroup::removePart(const S32 part_num) | 237 | void LLViewerPartGroup::removePart(const S32 part_num) |
205 | { | 238 | { |
239 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
206 | // Remove the entry for the particle we just deleted. | 240 | // Remove the entry for the particle we just deleted. |
207 | LLPointer<LLViewerPartSource> ps = mParticles[mParticles.count() - 1].mPartSourcep; | 241 | mParticles.erase(mParticles.begin() + part_num); |
208 | 242 | if (mVOPartGroupp.notNull()) | |
209 | mParticles[mParticles.count() - 1].mPartSourcep = NULL; | ||
210 | mParticles.remove(part_num); | ||
211 | if (part_num < mParticles.count()) | ||
212 | { | 243 | { |
213 | mParticles[part_num].mPartSourcep = ps; | 244 | gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); |
214 | } | 245 | } |
215 | |||
216 | LLViewerPartSim::decPartCount(1); | 246 | LLViewerPartSim::decPartCount(1); |
217 | } | 247 | } |
218 | 248 | ||
219 | |||
220 | void LLViewerPartGroup::updateParticles(const F32 dt) | 249 | void LLViewerPartGroup::updateParticles(const F32 dt) |
221 | { | 250 | { |
251 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
222 | S32 i, count; | 252 | S32 i, count; |
223 | 253 | ||
224 | |||
225 | LLVector3 gravity(0.f, 0.f, -9.8f); | 254 | LLVector3 gravity(0.f, 0.f, -9.8f); |
226 | 255 | ||
227 | LLViewerRegion *regionp = getRegion(); | 256 | LLViewerRegion *regionp = getRegion(); |
228 | count = mParticles.count(); | 257 | count = (S32) mParticles.size(); |
229 | for (i = 0; i < count; i++) | 258 | for (i = 0; i < count; i++) |
230 | { | 259 | { |
231 | LLVector3 a(0.f, 0.f, 0.f); | 260 | LLVector3 a(0.f, 0.f, 0.f); |
232 | LLViewerPart &part = mParticles[i]; | 261 | LLViewerPart& part = *((LLViewerPart*) mParticles[i]); |
233 | 262 | ||
234 | // Update current time | 263 | // Update current time |
235 | const F32 cur_time = part.mLastUpdateTime + dt; | 264 | const F32 cur_time = part.mLastUpdateTime + dt; |
@@ -271,8 +300,6 @@ void LLViewerPartGroup::updateParticles(const F32 dt) | |||
271 | 300 | ||
272 | part.mVelocity *= (1.f - step); | 301 | part.mVelocity *= (1.f - step); |
273 | part.mVelocity += step*delta_pos; | 302 | part.mVelocity += step*delta_pos; |
274 | //part.mPosAgent *= 1.f - to_target_frac; | ||
275 | //part.mPosAgent += to_target_frac*part.mPartSourcep->mTargetPosAgent; | ||
276 | } | 303 | } |
277 | 304 | ||
278 | 305 | ||
@@ -341,18 +368,22 @@ void LLViewerPartGroup::updateParticles(const F32 dt) | |||
341 | i--; | 368 | i--; |
342 | count--; | 369 | count--; |
343 | } | 370 | } |
344 | else if (!posInGroup(part.mPosAgent)) | 371 | else |
345 | { | 372 | { |
346 | // Transfer particles between groups | 373 | F32 desired_size = calc_desired_size(part.mPosAgent, part.mScale); |
347 | gWorldPointer->mPartSim.put(part); | 374 | if (!posInGroup(part.mPosAgent, desired_size)) |
348 | removePart(i); | 375 | { |
349 | i--; | 376 | // Transfer particles between groups |
350 | count--; | 377 | gWorldPointer->mPartSim.put(&part); |
378 | removePart(i); | ||
379 | i--; | ||
380 | count--; | ||
381 | } | ||
351 | } | 382 | } |
352 | } | 383 | } |
353 | 384 | ||
354 | // Kill the viewer object if this particle group is empty | 385 | // Kill the viewer object if this particle group is empty |
355 | if (!mParticles.count()) | 386 | if (mParticles.empty()) |
356 | { | 387 | { |
357 | gObjectList.killObject(mVOPartGroupp); | 388 | gObjectList.killObject(mVOPartGroupp); |
358 | mVOPartGroupp = NULL; | 389 | mVOPartGroupp = NULL; |
@@ -362,15 +393,16 @@ void LLViewerPartGroup::updateParticles(const F32 dt) | |||
362 | 393 | ||
363 | void LLViewerPartGroup::shift(const LLVector3 &offset) | 394 | void LLViewerPartGroup::shift(const LLVector3 &offset) |
364 | { | 395 | { |
396 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
365 | mCenterAgent += offset; | 397 | mCenterAgent += offset; |
366 | mMinObjPos += offset; | 398 | mMinObjPos += offset; |
367 | mMaxObjPos += offset; | 399 | mMaxObjPos += offset; |
368 | 400 | ||
369 | S32 count = mParticles.count(); | 401 | S32 count = (S32) mParticles.size(); |
370 | S32 i; | 402 | S32 i; |
371 | for (i = 0; i < count; i++) | 403 | for (i = 0; i < count; i++) |
372 | { | 404 | { |
373 | mParticles[i].mPosAgent += offset; | 405 | mParticles[i]->mPosAgent += offset; |
374 | } | 406 | } |
375 | } | 407 | } |
376 | 408 | ||
@@ -384,34 +416,34 @@ void LLViewerPartGroup::shift(const LLVector3 &offset) | |||
384 | 416 | ||
385 | LLViewerPartSim::LLViewerPartSim() | 417 | LLViewerPartSim::LLViewerPartSim() |
386 | { | 418 | { |
419 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
387 | sMaxParticleCount = gSavedSettings.getS32("RenderMaxPartCount"); | 420 | sMaxParticleCount = gSavedSettings.getS32("RenderMaxPartCount"); |
421 | static U32 id_seed = 0; | ||
422 | mID = ++id_seed; | ||
388 | } | 423 | } |
389 | 424 | ||
390 | 425 | ||
391 | LLViewerPartSim::~LLViewerPartSim() | 426 | LLViewerPartSim::~LLViewerPartSim() |
392 | { | 427 | { |
428 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
393 | S32 i; | 429 | S32 i; |
394 | S32 count; | 430 | S32 count; |
395 | 431 | ||
396 | // Kill all of the groups (and particles) | 432 | // Kill all of the groups (and particles) |
397 | count = mViewerPartGroups.count(); | 433 | count = (S32) mViewerPartGroups.size(); |
398 | for (i = 0; i < count; i++) | 434 | for (i = 0; i < count; i++) |
399 | { | 435 | { |
400 | delete mViewerPartGroups[i]; | 436 | delete mViewerPartGroups[i]; |
401 | } | 437 | } |
402 | mViewerPartGroups.reset(); | 438 | mViewerPartGroups.clear(); |
403 | 439 | ||
404 | // Kill all of the sources | 440 | // Kill all of the sources |
405 | count = mViewerPartSources.count(); | 441 | mViewerPartSources.clear(); |
406 | for (i = 0; i < count; i++) | ||
407 | { | ||
408 | mViewerPartSources[i] = NULL; | ||
409 | } | ||
410 | mViewerPartSources.reset(); | ||
411 | } | 442 | } |
412 | 443 | ||
413 | BOOL LLViewerPartSim::shouldAddPart() | 444 | BOOL LLViewerPartSim::shouldAddPart() |
414 | { | 445 | { |
446 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
415 | if (sParticleCount > 0.75f*sMaxParticleCount) | 447 | if (sParticleCount > 0.75f*sMaxParticleCount) |
416 | { | 448 | { |
417 | 449 | ||
@@ -432,33 +464,35 @@ BOOL LLViewerPartSim::shouldAddPart() | |||
432 | return TRUE; | 464 | return TRUE; |
433 | } | 465 | } |
434 | 466 | ||
435 | void LLViewerPartSim::addPart(LLViewerPart &part) | 467 | void LLViewerPartSim::addPart(LLViewerPart* part) |
436 | { | 468 | { |
469 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
437 | if (sParticleCount < MAX_PART_COUNT) | 470 | if (sParticleCount < MAX_PART_COUNT) |
438 | { | 471 | { |
439 | put(part); | 472 | put(part); |
440 | } | 473 | } |
441 | } | 474 | } |
442 | 475 | ||
443 | LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart &part) | 476 | |
477 | LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part) | ||
444 | { | 478 | { |
479 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
445 | const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million | 480 | const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million |
446 | if (part.mPosAgent.magVecSquared() > MAX_MAG) | 481 | if (part->mPosAgent.magVecSquared() > MAX_MAG || !part->mPosAgent.isFinite()) |
447 | { | 482 | { |
448 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 483 | #if !LL_RELEASE_FOR_DOWNLOAD |
449 | llwarns << "LLViewerPartSim::put Part out of range!" << llendl; | 484 | llwarns << "LLViewerPartSim::put Part out of range!" << llendl; |
450 | llwarns << part.mPosAgent << llendl; | 485 | llwarns << part->mPosAgent << llendl; |
451 | #endif | 486 | #endif |
452 | return NULL; | 487 | return NULL; |
453 | } | 488 | } |
489 | |||
490 | F32 desired_size = calc_desired_size(part->mPosAgent, part->mScale); | ||
454 | 491 | ||
455 | S32 i; | 492 | S32 count = (S32) mViewerPartGroups.size(); |
456 | S32 count; | 493 | for (S32 i = 0; i < count; i++) |
457 | |||
458 | count = mViewerPartGroups.count(); | ||
459 | for (i = 0; i < count; i++) | ||
460 | { | 494 | { |
461 | if (mViewerPartGroups[i]->addPart(part)) | 495 | if (mViewerPartGroups[i]->addPart(part, desired_size)) |
462 | { | 496 | { |
463 | // We found a spatial group that we fit into, add us and exit | 497 | // We found a spatial group that we fit into, add us and exit |
464 | return mViewerPartGroups[i]; | 498 | return mViewerPartGroups[i]; |
@@ -467,43 +501,27 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart &part) | |||
467 | 501 | ||
468 | // Hmm, we didn't fit in any of the existing spatial groups | 502 | // Hmm, we didn't fit in any of the existing spatial groups |
469 | // Create a new one... | 503 | // Create a new one... |
470 | LLViewerPartGroup *groupp = createViewerPartGroup(part.mPosAgent); | 504 | llassert_always(part->mPosAgent.isFinite()); |
505 | LLViewerPartGroup *groupp = createViewerPartGroup(part->mPosAgent, desired_size); | ||
506 | groupp->mUniformParticles = (part->mScale.mV[0] == part->mScale.mV[1] && | ||
507 | !(part->mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)); | ||
471 | if (!groupp->addPart(part)) | 508 | if (!groupp->addPart(part)) |
472 | { | 509 | { |
473 | llwarns << "LLViewerPartSim::put - Particle didn't go into its box!" << llendl; | 510 | llwarns << "LLViewerPartSim::put - Particle didn't go into its box!" << llendl; |
474 | llinfos << groupp->getCenterAgent() << llendl; | 511 | llinfos << groupp->getCenterAgent() << llendl; |
475 | llinfos << part.mPosAgent << llendl; | 512 | llinfos << part->mPosAgent << llendl; |
476 | return NULL; | 513 | return NULL; |
477 | } | 514 | } |
478 | return groupp; | 515 | return groupp; |
479 | } | 516 | } |
480 | 517 | ||
481 | LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent) | 518 | LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size) |
482 | { | 519 | { |
483 | F32 x_origin = ((S32)(pos_agent.mV[VX]/PART_SIM_BOX_SIDE))*PART_SIM_BOX_SIDE; | 520 | LLMemType mt(LLMemType::MTYPE_PARTICLES); |
484 | if (x_origin > pos_agent.mV[VX]) | 521 | //find a box that has a center position divisible by PART_SIM_BOX_SIDE that encompasses |
485 | { | 522 | //pos_agent |
486 | x_origin -= PART_SIM_BOX_SIDE; | 523 | LLViewerPartGroup *groupp = new LLViewerPartGroup(pos_agent, desired_size); |
487 | } | 524 | mViewerPartGroups.push_back(groupp); |
488 | |||
489 | F32 y_origin = ((S32)(pos_agent.mV[VY]/PART_SIM_BOX_SIDE))*PART_SIM_BOX_SIDE; | ||
490 | if (y_origin > pos_agent.mV[VY]) | ||
491 | { | ||
492 | y_origin -= PART_SIM_BOX_SIDE; | ||
493 | } | ||
494 | |||
495 | F32 z_origin = ((S32)(pos_agent.mV[VZ]/PART_SIM_BOX_SIDE))*PART_SIM_BOX_SIDE; | ||
496 | if (z_origin > pos_agent.mV[VZ]) | ||
497 | { | ||
498 | z_origin -= PART_SIM_BOX_SIDE; | ||
499 | } | ||
500 | |||
501 | LLVector3 group_center(x_origin + PART_SIM_BOX_OFFSET, | ||
502 | y_origin + PART_SIM_BOX_OFFSET, | ||
503 | z_origin + PART_SIM_BOX_OFFSET); | ||
504 | |||
505 | LLViewerPartGroup *groupp = new LLViewerPartGroup(group_center, PART_SIM_BOX_SIDE); | ||
506 | mViewerPartGroups.put(groupp); | ||
507 | return groupp; | 525 | return groupp; |
508 | } | 526 | } |
509 | 527 | ||
@@ -513,7 +531,7 @@ void LLViewerPartSim::shift(const LLVector3 &offset) | |||
513 | S32 i; | 531 | S32 i; |
514 | S32 count; | 532 | S32 count; |
515 | 533 | ||
516 | count = mViewerPartSources.count(); | 534 | count = (S32) mViewerPartSources.size(); |
517 | for (i = 0; i < count; i++) | 535 | for (i = 0; i < count; i++) |
518 | { | 536 | { |
519 | mViewerPartSources[i]->mPosAgent += offset; | 537 | mViewerPartSources[i]->mPosAgent += offset; |
@@ -521,13 +539,20 @@ void LLViewerPartSim::shift(const LLVector3 &offset) | |||
521 | mViewerPartSources[i]->mLastUpdatePosAgent += offset; | 539 | mViewerPartSources[i]->mLastUpdatePosAgent += offset; |
522 | } | 540 | } |
523 | 541 | ||
524 | count = mViewerPartGroups.count(); | 542 | count = (S32) mViewerPartGroups.size(); |
525 | for (i = 0; i < count; i++) | 543 | for (i = 0; i < count; i++) |
526 | { | 544 | { |
527 | mViewerPartGroups[i]->shift(offset); | 545 | mViewerPartGroups[i]->shift(offset); |
528 | } | 546 | } |
529 | } | 547 | } |
530 | 548 | ||
549 | S32 dist_rate_func(F32 distance) | ||
550 | { | ||
551 | //S32 dist = (S32) sqrtf(distance); | ||
552 | //dist /= 2; | ||
553 | //return llmax(dist,1); | ||
554 | return 1; | ||
555 | } | ||
531 | 556 | ||
532 | void LLViewerPartSim::updateSimulation() | 557 | void LLViewerPartSim::updateSimulation() |
533 | { | 558 | { |
@@ -542,13 +567,15 @@ void LLViewerPartSim::updateSimulation() | |||
542 | return; | 567 | return; |
543 | } | 568 | } |
544 | 569 | ||
570 | LLFastTimer ftm(LLFastTimer::FTM_SIMULATE_PARTICLES); | ||
571 | |||
545 | // Start at a random particle system so the same | 572 | // Start at a random particle system so the same |
546 | // particle system doesn't always get first pick at the | 573 | // particle system doesn't always get first pick at the |
547 | // particles. Theoretically we'd want to do this in distance | 574 | // particles. Theoretically we'd want to do this in distance |
548 | // order or something, but sorting particle sources will be a big | 575 | // order or something, but sorting particle sources will be a big |
549 | // pain. | 576 | // pain. |
550 | S32 i; | 577 | S32 i; |
551 | S32 count = mViewerPartSources.count(); | 578 | S32 count = (S32) mViewerPartSources.size(); |
552 | S32 start = (S32)ll_frand((F32)count); | 579 | S32 start = (S32)ll_frand((F32)count); |
553 | S32 dir = 1; | 580 | S32 dir = 1; |
554 | if (ll_frand() > 0.5f) | 581 | if (ll_frand() > 0.5f) |
@@ -570,12 +597,24 @@ void LLViewerPartSim::updateSimulation() | |||
570 | 597 | ||
571 | if (!mViewerPartSources[i]->isDead()) | 598 | if (!mViewerPartSources[i]->isDead()) |
572 | { | 599 | { |
573 | mViewerPartSources[i]->update(dt); | 600 | LLViewerObject* source_object = mViewerPartSources[i]->mSourceObjectp; |
601 | if (source_object && source_object->mDrawable.notNull()) | ||
602 | { | ||
603 | S32 dist = dist_rate_func(source_object->mDrawable->mDistanceWRTCamera); | ||
604 | if ((LLDrawable::getCurrentFrame()+mViewerPartSources[i]->mID)%dist == 0) | ||
605 | { | ||
606 | mViewerPartSources[i]->update(dt*dist); | ||
607 | } | ||
608 | } | ||
609 | else | ||
610 | { | ||
611 | mViewerPartSources[i]->update(dt); | ||
612 | } | ||
574 | } | 613 | } |
575 | 614 | ||
576 | if (mViewerPartSources[i]->isDead()) | 615 | if (mViewerPartSources[i]->isDead()) |
577 | { | 616 | { |
578 | mViewerPartSources.remove(i); | 617 | mViewerPartSources.erase(mViewerPartSources.begin() + i); |
579 | count--; | 618 | count--; |
580 | } | 619 | } |
581 | else | 620 | else |
@@ -586,16 +625,36 @@ void LLViewerPartSim::updateSimulation() | |||
586 | } | 625 | } |
587 | 626 | ||
588 | 627 | ||
589 | count = mViewerPartGroups.count(); | 628 | count = (S32) mViewerPartGroups.size(); |
590 | for (i = 0; i < count; i++) | 629 | for (i = 0; i < count; i++) |
591 | { | 630 | { |
592 | mViewerPartGroups[i]->updateParticles(dt); | 631 | LLViewerObject* vobj = mViewerPartGroups[i]->mVOPartGroupp; |
593 | if (!mViewerPartGroups[i]->getCount()) | 632 | |
633 | S32 dist = vobj && !vobj->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) ? | ||
634 | dist_rate_func(vobj->mDrawable->mDistanceWRTCamera) : 1; | ||
635 | if (vobj) | ||
594 | { | 636 | { |
595 | delete mViewerPartGroups[i]; | 637 | LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup(); |
596 | mViewerPartGroups.remove(i); | 638 | if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY)) |
597 | i--; | 639 | { |
598 | count--; | 640 | dist *= 8; |
641 | } | ||
642 | } | ||
643 | |||
644 | if ((LLDrawable::getCurrentFrame()+mViewerPartGroups[i]->mID)%dist == 0) | ||
645 | { | ||
646 | if (vobj) | ||
647 | { | ||
648 | gPipeline.markRebuild(vobj->mDrawable, LLDrawable::REBUILD_ALL, TRUE); | ||
649 | } | ||
650 | mViewerPartGroups[i]->updateParticles(dt*dist); | ||
651 | if (!mViewerPartGroups[i]->getCount()) | ||
652 | { | ||
653 | delete mViewerPartGroups[i]; | ||
654 | mViewerPartGroups.erase(mViewerPartGroups.begin() + i); | ||
655 | i--; | ||
656 | count--; | ||
657 | } | ||
599 | } | 658 | } |
600 | } | 659 | } |
601 | //llinfos << "Particles: " << sParticleCount << llendl; | 660 | //llinfos << "Particles: " << sParticleCount << llendl; |
@@ -604,42 +663,40 @@ void LLViewerPartSim::updateSimulation() | |||
604 | 663 | ||
605 | void LLViewerPartSim::addPartSource(LLViewerPartSource *sourcep) | 664 | void LLViewerPartSim::addPartSource(LLViewerPartSource *sourcep) |
606 | { | 665 | { |
666 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | ||
607 | if (!sourcep) | 667 | if (!sourcep) |
608 | { | 668 | { |
609 | llwarns << "Null part source!" << llendl; | 669 | llwarns << "Null part source!" << llendl; |
610 | return; | 670 | return; |
611 | } | 671 | } |
612 | mViewerPartSources.put(sourcep); | 672 | mViewerPartSources.push_back(sourcep); |
613 | } | 673 | } |
614 | 674 | ||
615 | 675 | ||
616 | void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) | 676 | void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) |
617 | { | 677 | { |
618 | S32 i, count; | 678 | LLMemType mt(LLMemType::MTYPE_PARTICLES); |
619 | count = mViewerPartGroups.count(); | 679 | for (group_list_t::iterator i = mViewerPartGroups.begin(); i != mViewerPartGroups.end(); ) |
620 | for (i = 0; i < count; i++) | ||
621 | { | 680 | { |
622 | if (mViewerPartGroups[i]->getRegion() == regionp) | 681 | group_list_t::iterator iter = i++; |
682 | |||
683 | if ((*iter)->getRegion() == regionp) | ||
623 | { | 684 | { |
624 | delete mViewerPartGroups[i]; | 685 | i = mViewerPartGroups.erase(iter); |
625 | mViewerPartGroups.remove(i); | ||
626 | i--; | ||
627 | count--; | ||
628 | } | 686 | } |
629 | } | 687 | } |
630 | } | 688 | } |
631 | 689 | ||
632 | void LLViewerPartSim::cleanMutedParticles(const LLUUID& task_id) | 690 | void LLViewerPartSim::cleanMutedParticles(const LLUUID& task_id) |
633 | { | 691 | { |
634 | S32 i; | 692 | LLMemType mt(LLMemType::MTYPE_PARTICLES); |
635 | S32 count = mViewerPartSources.count(); | 693 | for (source_list_t::iterator i = mViewerPartSources.begin(); i != mViewerPartSources.end(); ) |
636 | for (i = 0; i < count; ++i) | ||
637 | { | 694 | { |
638 | if (mViewerPartSources[i]->getOwnerUUID() == task_id) | 695 | source_list_t::iterator iter = i++; |
696 | |||
697 | if ((*iter)->getOwnerUUID() == task_id) | ||
639 | { | 698 | { |
640 | mViewerPartSources.remove(i); | 699 | i = mViewerPartSources.erase(iter); |
641 | i--; | ||
642 | count--; | ||
643 | } | 700 | } |
644 | } | 701 | } |
645 | } | 702 | } |