aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewerpartsim.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-09-06 18:24:57 -0500
committerJacek Antonelli2008-09-06 18:25:07 -0500
commit798d367d54a6c6379ad355bd8345fa40e31e7fe9 (patch)
tree1921f1708cd0240648c97bc02df2c2ab5f2fc41e /linden/indra/newview/llviewerpartsim.cpp
parentSecond Life viewer sources 1.20.15 (diff)
downloadmeta-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.cpp211
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
48const F32 PART_SIM_BOX_SIDE = 16.f; 49const F32 PART_SIM_BOX_SIDE = 16.f;
49const F32 PART_SIM_BOX_OFFSET = 0.5f*PART_SIM_BOX_SIDE; 50const 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)
240void LLViewerPartGroup::updateParticles(const F32 lastdt) 245void 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)
419void LLViewerPartGroup::removeParticlesByID(const U32 source_id) 421void 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
541LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size) 558LLViewerPartGroup *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 {