diff options
Diffstat (limited to 'indra/newview/llviewerpartsim.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/newview/llviewerpartsim.cpp | 162 |
1 files changed, 91 insertions, 71 deletions
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index cfb8340462..230bdca4ef 100644..100755 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -2,31 +2,25 @@ * @file llviewerpartsim.cpp * @brief LLViewerPart class implementation * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,8 +42,6 @@ #include "llvovolume.h" const F32 PART_SIM_BOX_SIDE = 16.f; -const F32 PART_SIM_BOX_OFFSET = 0.5f*PART_SIM_BOX_SIDE; -const F32 PART_SIM_BOX_RAD = 0.5f*F_SQRT3*PART_SIM_BOX_SIDE; //static S32 LLViewerPartSim::sMaxParticleCount = 0; @@ -71,9 +63,9 @@ const F32 LLViewerPartSim::PART_ADAPT_RATE_MULT_RECIP = 1.0f/PART_ADAPT_RATE_MUL U32 LLViewerPart::sNextPartID = 1; -F32 calc_desired_size(LLVector3 pos, LLVector2 scale) +F32 calc_desired_size(LLViewerCamera* camera, LLVector3 pos, LLVector2 scale) { - F32 desired_size = (pos-LLViewerCamera::getInstance()->getOrigin()).magVec(); + F32 desired_size = (pos - camera->getOrigin()).magVec(); desired_size /= 4; return llclamp(desired_size, scale.magVec()*0.5f, PART_SIM_BOX_SIDE*2); } @@ -81,18 +73,36 @@ F32 calc_desired_size(LLVector3 pos, LLVector2 scale) LLViewerPart::LLViewerPart() : mPartID(0), mLastUpdateTime(0.f), + mSkipOffset(0.f), mVPCallback(NULL), mImagep(NULL) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mPartSourcep = NULL; - + mParent = NULL; + mChild = NULL; ++LLViewerPartSim::sParticleCount2 ; } LLViewerPart::~LLViewerPart() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); + if (mPartSourcep.notNull() && mPartSourcep->mLastPart == this) + { + mPartSourcep->mLastPart = NULL; + } + + //patch up holes in the ribbon + if (mParent) + { + llassert(mParent->mChild == this); + mParent->mChild = mChild; + } + + if (mChild) + { + llassert (mChild->mParent == this); + mChild->mParent = mParent; + } + mPartSourcep = NULL; --LLViewerPartSim::sParticleCount2 ; @@ -100,7 +110,6 @@ LLViewerPart::~LLViewerPart() void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *imagep, LLVPCallback cb) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mPartID = LLViewerPart::sNextPartID; LLViewerPart::sNextPartID++; mFlags = 0x00f; @@ -125,7 +134,6 @@ void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture * LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 box_side, bool hud) : mHud(hud) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mVOPartGroupp = NULL; mUniformParticles = TRUE; @@ -134,7 +142,7 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo if (!mRegionp) { - //llwarns << "No region at position, using agent region!" << llendl; + //LL_WARNS() << "No region at position, using agent region!" << LL_ENDL; mRegionp = gAgent.getRegion(); } mCenterAgent = center_agent; @@ -150,7 +158,11 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo } mVOPartGroupp->setViewerPartGroup(this); mVOPartGroupp->setPositionAgent(getCenterAgent()); + + mBoxSide = box_side; + F32 scale = box_side * 0.5f; + mVOPartGroupp->setScale(LLVector3(scale,scale,scale)); //gPipeline.addObject(mVOPartGroupp); @@ -160,8 +172,8 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo if (group != NULL) { - LLVector3 center(group->mOctreeNode->getCenter()); - LLVector3 size(group->mOctreeNode->getSize()); + LLVector3 center(group->getOctreeNode()->getCenter().getF32ptr()); + LLVector3 size(group->getOctreeNode()->getSize().getF32ptr()); size += LLVector3(0.01f, 0.01f, 0.01f); mMinObjPos = center - size; mMaxObjPos = center + size; @@ -182,7 +194,6 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo LLViewerPartGroup::~LLViewerPartGroup() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); cleanup(); S32 count = (S32) mParticles.size(); @@ -197,7 +208,6 @@ LLViewerPartGroup::~LLViewerPartGroup() void LLViewerPartGroup::cleanup() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (mVOPartGroupp) { if (!mVOPartGroupp->isDead()) @@ -210,7 +220,6 @@ void LLViewerPartGroup::cleanup() BOOL LLViewerPartGroup::posInGroup(const LLVector3 &pos, const F32 desired_size) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if ((pos.mV[VX] < mMinObjPos.mV[VX]) || (pos.mV[VY] < mMinObjPos.mV[VY]) || (pos.mV[VZ] < mMinObjPos.mV[VZ])) @@ -238,8 +247,6 @@ BOOL LLViewerPartGroup::posInGroup(const LLVector3 &pos, const F32 desired_size) BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); - if (part->mFlags & LLPartData::LL_PART_HUD && !mHud) { return FALSE; @@ -266,13 +273,13 @@ BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size) void LLViewerPartGroup::updateParticles(const F32 lastdt) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); F32 dt; LLVector3 gravity(0.f, 0.f, GRAVITY); LLViewerPartSim::checkParticleCount(mParticles.size()); + LLViewerCamera* camera = LLViewerCamera::getInstance(); LLViewerRegion *regionp = getRegion(); S32 end = (S32) mParticles.size(); for (S32 i = 0 ; i < (S32)mParticles.size();) @@ -302,7 +309,6 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) if (part->mFlags & LLPartData::LL_PART_WIND_MASK) { - LLVector3 tempVel(part->mVelocity); part->mVelocity *= 1.f - 0.1f*dt; part->mVelocity += 0.1f*dt*regionp->mWind.getVelocity(regionp->getPosRegionFromAgent(part->mPosAgent)); } @@ -381,6 +387,9 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) part->mScale += frac*part->mEndScale; } + // Do glow interpolation + part->mGlow.mV[3] = (U8) ll_round(lerp(part->mStartGlow, part->mEndGlow, frac)*255.f); + // Set the last update time to now. part->mLastUpdateTime = cur_time; @@ -394,7 +403,7 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) } else { - F32 desired_size = calc_desired_size(part->mPosAgent, part->mScale); + F32 desired_size = calc_desired_size(camera, part->mPosAgent, part->mScale); if (!posInGroup(part->mPosAgent, desired_size)) { // Transfer particles between groups @@ -433,7 +442,6 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) void LLViewerPartGroup::shift(const LLVector3 &offset) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); mCenterAgent += offset; mMinObjPos += offset; mMaxObjPos += offset; @@ -446,8 +454,6 @@ void LLViewerPartGroup::shift(const LLVector3 &offset) void LLViewerPartGroup::removeParticlesByID(const U32 source_id) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); - for (S32 i = 0; i < (S32)mParticles.size(); i++) { if(mParticles[i]->mPartSourcep->getID() == source_id) @@ -468,27 +474,39 @@ void LLViewerPartSim::checkParticleCount(U32 size) { if(LLViewerPartSim::sParticleCount2 != LLViewerPartSim::sParticleCount) { - llerrs << "sParticleCount: " << LLViewerPartSim::sParticleCount << " ; sParticleCount2: " << LLViewerPartSim::sParticleCount2 << llendl ; + LL_ERRS() << "sParticleCount: " << LLViewerPartSim::sParticleCount << " ; sParticleCount2: " << LLViewerPartSim::sParticleCount2 << LL_ENDL ; } if(size > (U32)LLViewerPartSim::sParticleCount2) { - llerrs << "curren particle size: " << LLViewerPartSim::sParticleCount2 << " array size: " << size << llendl ; + LL_ERRS() << "curren particle size: " << LLViewerPartSim::sParticleCount2 << " array size: " << size << LL_ENDL ; } } LLViewerPartSim::LLViewerPartSim() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); - sMaxParticleCount = gSavedSettings.getS32("RenderMaxPartCount"); + sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT); static U32 id_seed = 0; mID = ++id_seed; } +//enable/disable particle system +void LLViewerPartSim::enable(bool enabled) +{ + if(!enabled && sMaxParticleCount > 0) + { + sMaxParticleCount = 0; //disable + } + else if(enabled && sMaxParticleCount < 1) + { + sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT); + } + + return; +} void LLViewerPartSim::destroyClass() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); S32 i; S32 count; @@ -504,12 +522,16 @@ void LLViewerPartSim::destroyClass() mViewerPartSources.clear(); } +//static BOOL LLViewerPartSim::shouldAddPart() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); - if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount) + if (sParticleCount >= MAX_PART_COUNT) { + return FALSE; + } + if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount) + { F32 frac = (F32)sParticleCount/(F32)sMaxParticleCount; frac -= PART_THROTTLE_THRESHOLD; frac *= PART_THROTTLE_RESCALE; @@ -519,7 +541,10 @@ BOOL LLViewerPartSim::shouldAddPart() return FALSE; } } - if (sParticleCount >= MAX_PART_COUNT) + + // Check frame rate, and don't add more if the viewer is really slow + const F32 MIN_FRAME_RATE_FOR_NEW_PARTICLES = 4.f; + if (gFPSClamped < MIN_FRAME_RATE_FOR_NEW_PARTICLES) { return FALSE; } @@ -529,7 +554,6 @@ BOOL LLViewerPartSim::shouldAddPart() void LLViewerPartSim::addPart(LLViewerPart* part) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (sParticleCount < MAX_PART_COUNT) { put(part); @@ -545,19 +569,19 @@ void LLViewerPartSim::addPart(LLViewerPart* part) LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million LLViewerPartGroup *return_group = NULL ; if (part->mPosAgent.magVecSquared() > MAX_MAG || !part->mPosAgent.isFinite()) { #if 0 && !LL_RELEASE_FOR_DOWNLOAD - llwarns << "LLViewerPartSim::put Part out of range!" << llendl; - llwarns << part->mPosAgent << llendl; + LL_WARNS() << "LLViewerPartSim::put Part out of range!" << LL_ENDL; + LL_WARNS() << part->mPosAgent << LL_ENDL; #endif } else { - F32 desired_size = calc_desired_size(part->mPosAgent, part->mScale); + LLViewerCamera* camera = LLViewerCamera::getInstance(); + F32 desired_size = calc_desired_size(camera, part->mPosAgent, part->mScale); S32 count = (S32) mViewerPartGroups.size(); for (S32 i = 0; i < count; i++) @@ -580,9 +604,9 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part) !(part->mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)); if (!groupp->addPart(part)) { - llwarns << "LLViewerPartSim::put - Particle didn't go into its box!" << llendl; - llinfos << groupp->getCenterAgent() << llendl; - llinfos << part->mPosAgent << llendl; + LL_WARNS() << "LLViewerPartSim::put - Particle didn't go into its box!" << LL_ENDL; + LL_INFOS() << groupp->getCenterAgent() << LL_ENDL; + LL_INFOS() << part->mPosAgent << LL_ENDL; mViewerPartGroups.pop_back() ; delete groupp; groupp = NULL ; @@ -602,7 +626,6 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part) LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size, bool hud) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); //find a box that has a center position divisible by PART_SIM_BOX_SIDE that encompasses //pos_agent LLViewerPartGroup *groupp = new LLViewerPartGroup(pos_agent, desired_size, hud); @@ -631,14 +654,15 @@ void LLViewerPartSim::shift(const LLVector3 &offset) } } -static LLFastTimer::DeclareTimer FTM_SIMULATE_PARTICLES("Simulate Particles"); +static LLTrace::BlockTimerStatHandle FTM_SIMULATE_PARTICLES("Simulate Particles"); void LLViewerPartSim::updateSimulation() { - LLMemType mt(LLMemType::MTYPE_PARTICLES); - static LLFrameTimer update_timer; + //reset VBO cursor + LLVOPartGroup::sVBSlotCursor = 0; + const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f); if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES))) @@ -646,7 +670,7 @@ void LLViewerPartSim::updateSimulation() return; } - LLFastTimer ftm(FTM_SIMULATE_PARTICLES); + LL_RECORD_BLOCK_TIME(FTM_SIMULATE_PARTICLES); // Start at a random particle system so the same // particle system doesn't always get first pick at the @@ -767,7 +791,7 @@ void LLViewerPartSim::updateSimulation() updatePartBurstRate() ; - //llinfos << "Particles: " << sParticleCount << " Adaptive Rate: " << sParticleAdaptiveRate << llendl; + //LL_INFOS() << "Particles: " << sParticleCount << " Adaptive Rate: " << sParticleAdaptiveRate << LL_ENDL; } void LLViewerPartSim::updatePartBurstRate() @@ -803,10 +827,9 @@ void LLViewerPartSim::updatePartBurstRate() void LLViewerPartSim::addPartSource(LLPointer<LLViewerPartSource> sourcep) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); if (!sourcep) { - llwarns << "Null part source!" << llendl; + LL_WARNS() << "Null part source!" << LL_ENDL; return; } sourcep->setStart() ; @@ -820,7 +843,6 @@ void LLViewerPartSim::removeLastCreatedSource() void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); for (group_list_t::iterator i = mViewerPartGroups.begin(); i != mViewerPartGroups.end(); ) { group_list_t::iterator iter = i++; @@ -835,7 +857,6 @@ void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) void LLViewerPartSim::clearParticlesByID(const U32 system_id) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); for (group_list_t::iterator g = mViewerPartGroups.begin(); g != mViewerPartGroups.end(); ++g) { (*g)->removeParticlesByID(system_id); @@ -853,7 +874,6 @@ void LLViewerPartSim::clearParticlesByID(const U32 system_id) void LLViewerPartSim::clearParticlesByOwnerID(const LLUUID& task_id) { - LLMemType mt(LLMemType::MTYPE_PARTICLES); for (source_list_t::iterator iter = mViewerPartSources.begin(); iter != mViewerPartSources.end(); ++iter) { if ((*iter)->getOwnerUUID() == task_id) |