diff options
author | Jacek Antonelli | 2008-09-06 18:24:57 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-09-06 18:25:07 -0500 |
commit | 798d367d54a6c6379ad355bd8345fa40e31e7fe9 (patch) | |
tree | 1921f1708cd0240648c97bc02df2c2ab5f2fc41e /linden/indra/newview/llviewerpartsim.cpp | |
parent | Second Life viewer sources 1.20.15 (diff) | |
download | meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.zip meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.gz meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.bz2 meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.xz |
Second Life viewer sources 1.21.0-RC
Diffstat (limited to 'linden/indra/newview/llviewerpartsim.cpp')
-rw-r--r-- | linden/indra/newview/llviewerpartsim.cpp | 211 |
1 files changed, 122 insertions, 89 deletions
diff --git a/linden/indra/newview/llviewerpartsim.cpp b/linden/indra/newview/llviewerpartsim.cpp index 1788a7c..d27e0df 100644 --- a/linden/indra/newview/llviewerpartsim.cpp +++ b/linden/indra/newview/llviewerpartsim.cpp | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "llworld.h" | 44 | #include "llworld.h" |
45 | #include "pipeline.h" | 45 | #include "pipeline.h" |
46 | #include "llspatialpartition.h" | 46 | #include "llspatialpartition.h" |
47 | #include "llvovolume.h" | ||
47 | 48 | ||
48 | const F32 PART_SIM_BOX_SIDE = 16.f; | 49 | const F32 PART_SIM_BOX_SIDE = 16.f; |
49 | const F32 PART_SIM_BOX_OFFSET = 0.5f*PART_SIM_BOX_SIDE; | 50 | const F32 PART_SIM_BOX_OFFSET = 0.5f*PART_SIM_BOX_SIDE; |
@@ -169,6 +170,10 @@ LLViewerPartGroup::~LLViewerPartGroup() | |||
169 | cleanup(); | 170 | cleanup(); |
170 | 171 | ||
171 | S32 count = (S32) mParticles.size(); | 172 | S32 count = (S32) mParticles.size(); |
173 | for(S32 i = 0 ; i < count ; i++) | ||
174 | { | ||
175 | delete mParticles[i] ; | ||
176 | } | ||
172 | mParticles.clear(); | 177 | mParticles.clear(); |
173 | 178 | ||
174 | LLViewerPartSim::decPartCount(count); | 179 | LLViewerPartSim::decPartCount(count); |
@@ -240,151 +245,150 @@ BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size) | |||
240 | void LLViewerPartGroup::updateParticles(const F32 lastdt) | 245 | void LLViewerPartGroup::updateParticles(const F32 lastdt) |
241 | { | 246 | { |
242 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | 247 | LLMemType mt(LLMemType::MTYPE_PARTICLES); |
243 | S32 i; | ||
244 | F32 dt; | 248 | F32 dt; |
245 | 249 | ||
246 | LLVector3 gravity(0.f, 0.f, GRAVITY); | 250 | LLVector3 gravity(0.f, 0.f, GRAVITY); |
247 | 251 | ||
248 | LLViewerRegion *regionp = getRegion(); | 252 | LLViewerRegion *regionp = getRegion(); |
249 | S32 end = (S32) mParticles.size(); | 253 | S32 end = (S32) mParticles.size(); |
250 | for (i = 0; i < end; i++) | 254 | for (S32 i = 0 ; i < (S32)mParticles.size();) |
251 | { | 255 | { |
252 | LLVector3 a(0.f, 0.f, 0.f); | 256 | LLVector3 a(0.f, 0.f, 0.f); |
253 | LLViewerPart& part = *((LLViewerPart*) mParticles[i]); | 257 | LLViewerPart* part = mParticles[i] ; |
254 | 258 | ||
255 | dt=lastdt+mSkippedTime-part.mSkipOffset; | 259 | dt = lastdt + mSkippedTime - part->mSkipOffset; |
256 | part.mSkipOffset=0.f; | 260 | part->mSkipOffset = 0.f; |
257 | 261 | ||
258 | // Update current time | 262 | // Update current time |
259 | const F32 cur_time = part.mLastUpdateTime + dt; | 263 | const F32 cur_time = part->mLastUpdateTime + dt; |
260 | const F32 frac = cur_time/part.mMaxAge; | 264 | const F32 frac = cur_time / part->mMaxAge; |
261 | 265 | ||
262 | // "Drift" the object based on the source object | 266 | // "Drift" the object based on the source object |
263 | if (part.mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK) | 267 | if (part->mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK) |
264 | { | 268 | { |
265 | part.mPosAgent = part.mPartSourcep->mPosAgent; | 269 | part->mPosAgent = part->mPartSourcep->mPosAgent; |
266 | part.mPosAgent += part.mPosOffset; | 270 | part->mPosAgent += part->mPosOffset; |
267 | } | 271 | } |
268 | 272 | ||
269 | // Do a custom callback if we have one... | 273 | // Do a custom callback if we have one... |
270 | if (part.mVPCallback) | 274 | if (part->mVPCallback) |
271 | { | 275 | { |
272 | (*part.mVPCallback)(part, dt); | 276 | (*part->mVPCallback)(*part, dt); |
273 | } | 277 | } |
274 | 278 | ||
275 | if (part.mFlags & LLPartData::LL_PART_WIND_MASK) | 279 | if (part->mFlags & LLPartData::LL_PART_WIND_MASK) |
276 | { | 280 | { |
277 | LLVector3 tempVel(part.mVelocity); | 281 | LLVector3 tempVel(part->mVelocity); |
278 | part.mVelocity *= 1.f - 0.1f*dt; | 282 | part->mVelocity *= 1.f - 0.1f*dt; |
279 | part.mVelocity += 0.1f*dt*regionp->mWind.getVelocity(regionp->getPosRegionFromAgent(part.mPosAgent)); | 283 | part->mVelocity += 0.1f*dt*regionp->mWind.getVelocity(regionp->getPosRegionFromAgent(part->mPosAgent)); |
280 | } | 284 | } |
281 | 285 | ||
282 | // Now do interpolation towards a target | 286 | // Now do interpolation towards a target |
283 | if (part.mFlags & LLPartData::LL_PART_TARGET_POS_MASK) | 287 | if (part->mFlags & LLPartData::LL_PART_TARGET_POS_MASK) |
284 | { | 288 | { |
285 | F32 remaining = part.mMaxAge - part.mLastUpdateTime; | 289 | F32 remaining = part->mMaxAge - part->mLastUpdateTime; |
286 | F32 step = dt / remaining; | 290 | F32 step = dt / remaining; |
287 | 291 | ||
288 | step = llclamp(step, 0.f, 0.1f); | 292 | step = llclamp(step, 0.f, 0.1f); |
289 | step *= 5.f; | 293 | step *= 5.f; |
290 | // we want a velocity that will result in reaching the target in the | 294 | // we want a velocity that will result in reaching the target in the |
291 | // Interpolate towards the target. | 295 | // Interpolate towards the target. |
292 | LLVector3 delta_pos = part.mPartSourcep->mTargetPosAgent - part.mPosAgent; | 296 | LLVector3 delta_pos = part->mPartSourcep->mTargetPosAgent - part->mPosAgent; |
293 | 297 | ||
294 | delta_pos /= remaining; | 298 | delta_pos /= remaining; |
295 | 299 | ||
296 | part.mVelocity *= (1.f - step); | 300 | part->mVelocity *= (1.f - step); |
297 | part.mVelocity += step*delta_pos; | 301 | part->mVelocity += step*delta_pos; |
298 | } | 302 | } |
299 | 303 | ||
300 | 304 | ||
301 | if (part.mFlags & LLPartData::LL_PART_TARGET_LINEAR_MASK) | 305 | if (part->mFlags & LLPartData::LL_PART_TARGET_LINEAR_MASK) |
302 | { | 306 | { |
303 | LLVector3 delta_pos = part.mPartSourcep->mTargetPosAgent - part.mPartSourcep->mPosAgent; | 307 | LLVector3 delta_pos = part->mPartSourcep->mTargetPosAgent - part->mPartSourcep->mPosAgent; |
304 | part.mPosAgent = part.mPartSourcep->mPosAgent; | 308 | part->mPosAgent = part->mPartSourcep->mPosAgent; |
305 | part.mPosAgent += frac*delta_pos; | 309 | part->mPosAgent += frac*delta_pos; |
306 | part.mVelocity = delta_pos; | 310 | part->mVelocity = delta_pos; |
307 | } | 311 | } |
308 | else | 312 | else |
309 | { | 313 | { |
310 | // Do velocity interpolation | 314 | // Do velocity interpolation |
311 | part.mPosAgent += dt*part.mVelocity; | 315 | part->mPosAgent += dt*part->mVelocity; |
312 | part.mPosAgent += 0.5f*dt*dt*part.mAccel; | 316 | part->mPosAgent += 0.5f*dt*dt*part->mAccel; |
313 | part.mVelocity += part.mAccel*dt; | 317 | part->mVelocity += part->mAccel*dt; |
314 | } | 318 | } |
315 | 319 | ||
316 | // Do a bounce test | 320 | // Do a bounce test |
317 | if (part.mFlags & LLPartData::LL_PART_BOUNCE_MASK) | 321 | if (part->mFlags & LLPartData::LL_PART_BOUNCE_MASK) |
318 | { | 322 | { |
319 | // Need to do point vs. plane check... | 323 | // Need to do point vs. plane check... |
320 | // For now, just check relative to object height... | 324 | // For now, just check relative to object height... |
321 | F32 dz = part.mPosAgent.mV[VZ] - part.mPartSourcep->mPosAgent.mV[VZ]; | 325 | F32 dz = part->mPosAgent.mV[VZ] - part->mPartSourcep->mPosAgent.mV[VZ]; |
322 | if (dz < 0) | 326 | if (dz < 0) |
323 | { | 327 | { |
324 | part.mPosAgent.mV[VZ] += -2.f*dz; | 328 | part->mPosAgent.mV[VZ] += -2.f*dz; |
325 | part.mVelocity.mV[VZ] *= -0.75f; | 329 | part->mVelocity.mV[VZ] *= -0.75f; |
326 | } | 330 | } |
327 | } | 331 | } |
328 | 332 | ||
329 | 333 | ||
330 | // Reset the offset from the source position | 334 | // Reset the offset from the source position |
331 | if (part.mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK) | 335 | if (part->mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK) |
332 | { | 336 | { |
333 | part.mPosOffset = part.mPosAgent; | 337 | part->mPosOffset = part->mPosAgent; |
334 | part.mPosOffset -= part.mPartSourcep->mPosAgent; | 338 | part->mPosOffset -= part->mPartSourcep->mPosAgent; |
335 | } | 339 | } |
336 | 340 | ||
337 | // Do color interpolation | 341 | // Do color interpolation |
338 | if (part.mFlags & LLPartData::LL_PART_INTERP_COLOR_MASK) | 342 | if (part->mFlags & LLPartData::LL_PART_INTERP_COLOR_MASK) |
339 | { | 343 | { |
340 | part.mColor.setVec(part.mStartColor); | 344 | part->mColor.setVec(part->mStartColor); |
341 | // note: LLColor4's v%k means multiply-alpha-only, | 345 | // note: LLColor4's v%k means multiply-alpha-only, |
342 | // LLColor4's v*k means multiply-rgb-only | 346 | // LLColor4's v*k means multiply-rgb-only |
343 | part.mColor *= 1.f - frac; // rgb*k | 347 | part->mColor *= 1.f - frac; // rgb*k |
344 | part.mColor %= 1.f - frac; // alpha*k | 348 | part->mColor %= 1.f - frac; // alpha*k |
345 | part.mColor += frac%(frac*part.mEndColor); // rgb,alpha | 349 | part->mColor += frac%(frac*part->mEndColor); // rgb,alpha |
346 | } | 350 | } |
347 | 351 | ||
348 | // Do scale interpolation | 352 | // Do scale interpolation |
349 | if (part.mFlags & LLPartData::LL_PART_INTERP_SCALE_MASK) | 353 | if (part->mFlags & LLPartData::LL_PART_INTERP_SCALE_MASK) |
350 | { | 354 | { |
351 | part.mScale.setVec(part.mStartScale); | 355 | part->mScale.setVec(part->mStartScale); |
352 | part.mScale *= 1.f - frac; | 356 | part->mScale *= 1.f - frac; |
353 | part.mScale += frac*part.mEndScale; | 357 | part->mScale += frac*part->mEndScale; |
354 | } | 358 | } |
355 | 359 | ||
356 | // Set the last update time to now. | 360 | // Set the last update time to now. |
357 | part.mLastUpdateTime = cur_time; | 361 | part->mLastUpdateTime = cur_time; |
358 | 362 | ||
359 | 363 | ||
360 | // Kill dead particles (either flagged dead, or too old) | 364 | // Kill dead particles (either flagged dead, or too old) |
361 | if ((part.mLastUpdateTime > part.mMaxAge) || (LLViewerPart::LL_PART_DEAD_MASK == part.mFlags)) | 365 | if ((part->mLastUpdateTime > part->mMaxAge) || (LLViewerPart::LL_PART_DEAD_MASK == part->mFlags)) |
362 | { | 366 | { |
363 | end--; | 367 | mParticles[i] = mParticles.back() ; |
364 | LLPointer<LLViewerPart>::swap(mParticles[i], mParticles[end]); | 368 | mParticles.pop_back() ; |
365 | // be sure to process the particle we just swapped-in | 369 | delete part ; |
366 | i--; | ||
367 | } | 370 | } |
368 | else | 371 | else |
369 | { | 372 | { |
370 | F32 desired_size = calc_desired_size(part.mPosAgent, part.mScale); | 373 | F32 desired_size = calc_desired_size(part->mPosAgent, part->mScale); |
371 | if (!posInGroup(part.mPosAgent, desired_size)) | 374 | if (!posInGroup(part->mPosAgent, desired_size)) |
372 | { | 375 | { |
373 | // Transfer particles between groups | 376 | // Transfer particles between groups |
374 | LLViewerPartSim::getInstance()->put(&part); | 377 | LLViewerPartSim::getInstance()->put(part) ; |
375 | end--; | 378 | mParticles[i] = mParticles.back() ; |
376 | LLPointer<LLViewerPart>::swap(mParticles[i], mParticles[end]); | 379 | mParticles.pop_back() ; |
377 | // be sure to process the particle we just swapped-in | 380 | } |
378 | i--; | 381 | else |
382 | { | ||
383 | i++ ; | ||
379 | } | 384 | } |
380 | } | 385 | } |
381 | } | 386 | } |
382 | 387 | ||
383 | S32 removed = (S32)mParticles.size() - end; | 388 | S32 removed = end - (S32)mParticles.size(); |
384 | if (removed > 0) | 389 | if (removed > 0) |
385 | { | 390 | { |
386 | // we removed one or more particles, so flag this group for update | 391 | // we removed one or more particles, so flag this group for update |
387 | mParticles.erase(mParticles.begin() + end, mParticles.end()); | ||
388 | if (mVOPartGroupp.notNull()) | 392 | if (mVOPartGroupp.notNull()) |
389 | { | 393 | { |
390 | gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); | 394 | gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); |
@@ -408,9 +412,7 @@ void LLViewerPartGroup::shift(const LLVector3 &offset) | |||
408 | mMinObjPos += offset; | 412 | mMinObjPos += offset; |
409 | mMaxObjPos += offset; | 413 | mMaxObjPos += offset; |
410 | 414 | ||
411 | S32 count = (S32) mParticles.size(); | 415 | for (S32 i = 0 ; i < (S32)mParticles.size(); i++) |
412 | S32 i; | ||
413 | for (i = 0; i < count; i++) | ||
414 | { | 416 | { |
415 | mParticles[i]->mPosAgent += offset; | 417 | mParticles[i]->mPosAgent += offset; |
416 | } | 418 | } |
@@ -419,8 +421,8 @@ void LLViewerPartGroup::shift(const LLVector3 &offset) | |||
419 | void LLViewerPartGroup::removeParticlesByID(const U32 source_id) | 421 | void LLViewerPartGroup::removeParticlesByID(const U32 source_id) |
420 | { | 422 | { |
421 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | 423 | LLMemType mt(LLMemType::MTYPE_PARTICLES); |
422 | S32 end = (S32) mParticles.size(); | 424 | |
423 | for (int i = 0; i < end; i++) | 425 | for (S32 i = 0; i < (S32)mParticles.size(); i++) |
424 | { | 426 | { |
425 | if(mParticles[i]->mPartSourcep->getID() == source_id) | 427 | if(mParticles[i]->mPartSourcep->getID() == source_id) |
426 | { | 428 | { |
@@ -500,42 +502,57 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part) | |||
500 | { | 502 | { |
501 | LLMemType mt(LLMemType::MTYPE_PARTICLES); | 503 | LLMemType mt(LLMemType::MTYPE_PARTICLES); |
502 | const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million | 504 | const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million |
505 | LLViewerPartGroup *return_group = NULL ; | ||
503 | if (part->mPosAgent.magVecSquared() > MAX_MAG || !part->mPosAgent.isFinite()) | 506 | if (part->mPosAgent.magVecSquared() > MAX_MAG || !part->mPosAgent.isFinite()) |
504 | { | 507 | { |
505 | #if 0 && !LL_RELEASE_FOR_DOWNLOAD | 508 | #if 0 && !LL_RELEASE_FOR_DOWNLOAD |
506 | llwarns << "LLViewerPartSim::put Part out of range!" << llendl; | 509 | llwarns << "LLViewerPartSim::put Part out of range!" << llendl; |
507 | llwarns << part->mPosAgent << llendl; | 510 | llwarns << part->mPosAgent << llendl; |
508 | #endif | 511 | #endif |
509 | return NULL; | ||
510 | } | 512 | } |
511 | 513 | else | |
512 | F32 desired_size = calc_desired_size(part->mPosAgent, part->mScale); | 514 | { |
515 | F32 desired_size = calc_desired_size(part->mPosAgent, part->mScale); | ||
513 | 516 | ||
514 | S32 count = (S32) mViewerPartGroups.size(); | 517 | S32 count = (S32) mViewerPartGroups.size(); |
515 | for (S32 i = 0; i < count; i++) | 518 | for (S32 i = 0; i < count; i++) |
516 | { | ||
517 | if (mViewerPartGroups[i]->addPart(part, desired_size)) | ||
518 | { | 519 | { |
519 | // We found a spatial group that we fit into, add us and exit | 520 | if (mViewerPartGroups[i]->addPart(part, desired_size)) |
520 | return mViewerPartGroups[i]; | 521 | { |
522 | // We found a spatial group that we fit into, add us and exit | ||
523 | return_group = mViewerPartGroups[i]; | ||
524 | break ; | ||
525 | } | ||
526 | } | ||
527 | |||
528 | // Hmm, we didn't fit in any of the existing spatial groups | ||
529 | // Create a new one... | ||
530 | if(!return_group) | ||
531 | { | ||
532 | llassert_always(part->mPosAgent.isFinite()); | ||
533 | LLViewerPartGroup *groupp = createViewerPartGroup(part->mPosAgent, desired_size); | ||
534 | groupp->mUniformParticles = (part->mScale.mV[0] == part->mScale.mV[1] && | ||
535 | !(part->mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)); | ||
536 | if (!groupp->addPart(part)) | ||
537 | { | ||
538 | llwarns << "LLViewerPartSim::put - Particle didn't go into its box!" << llendl; | ||
539 | llinfos << groupp->getCenterAgent() << llendl; | ||
540 | llinfos << part->mPosAgent << llendl; | ||
541 | mViewerPartGroups.pop_back() ; | ||
542 | delete groupp; | ||
543 | groupp = NULL ; | ||
544 | } | ||
545 | return_group = groupp; | ||
521 | } | 546 | } |
522 | } | 547 | } |
523 | 548 | ||
524 | // Hmm, we didn't fit in any of the existing spatial groups | 549 | if(!return_group) //failed to insert the particle |
525 | // Create a new one... | ||
526 | llassert_always(part->mPosAgent.isFinite()); | ||
527 | LLViewerPartGroup *groupp = createViewerPartGroup(part->mPosAgent, desired_size); | ||
528 | groupp->mUniformParticles = (part->mScale.mV[0] == part->mScale.mV[1] && | ||
529 | !(part->mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)); | ||
530 | if (!groupp->addPart(part)) | ||
531 | { | 550 | { |
532 | llwarns << "LLViewerPartSim::put - Particle didn't go into its box!" << llendl; | 551 | delete part ; |
533 | llinfos << groupp->getCenterAgent() << llendl; | 552 | part = NULL ; |
534 | llinfos << part->mPosAgent << llendl; | ||
535 | delete groupp; | ||
536 | return NULL; | ||
537 | } | 553 | } |
538 | return groupp; | 554 | |
555 | return return_group ; | ||
539 | } | 556 | } |
540 | 557 | ||
541 | LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size) | 558 | LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size) |
@@ -614,7 +631,24 @@ void LLViewerPartSim::updateSimulation() | |||
614 | 631 | ||
615 | if (!mViewerPartSources[i]->isDead()) | 632 | if (!mViewerPartSources[i]->isDead()) |
616 | { | 633 | { |
617 | mViewerPartSources[i]->update(dt); | 634 | BOOL upd = TRUE; |
635 | if (!LLPipeline::sRenderAttachedParticles) | ||
636 | { | ||
637 | LLViewerObject* vobj = mViewerPartSources[i]->mSourceObjectp; | ||
638 | if (vobj && (vobj->getPCode() == LL_PCODE_VOLUME)) | ||
639 | { | ||
640 | LLVOVolume* vvo = (LLVOVolume *)vobj; | ||
641 | if (vvo && vvo->isAttachment()) | ||
642 | { | ||
643 | upd = FALSE; | ||
644 | } | ||
645 | } | ||
646 | } | ||
647 | |||
648 | if (upd) | ||
649 | { | ||
650 | mViewerPartSources[i]->update(dt); | ||
651 | } | ||
618 | } | 652 | } |
619 | 653 | ||
620 | if (mViewerPartSources[i]->isDead()) | 654 | if (mViewerPartSources[i]->isDead()) |
@@ -630,7 +664,6 @@ void LLViewerPartSim::updateSimulation() | |||
630 | num_updates++; | 664 | num_updates++; |
631 | } | 665 | } |
632 | 666 | ||
633 | |||
634 | count = (S32) mViewerPartGroups.size(); | 667 | count = (S32) mViewerPartGroups.size(); |
635 | for (i = 0; i < count; i++) | 668 | for (i = 0; i < count; i++) |
636 | { | 669 | { |