diff options
Diffstat (limited to 'indra/newview/llvovolume.cpp')
-rw-r--r-- | indra/newview/llvovolume.cpp | 8274 |
1 files changed, 4137 insertions, 4137 deletions
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e3f2afadc5..ea6fb2e55b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvovolume.cpp * @brief LLVOVolume class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * 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. - * + * * 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. - * + * * 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 - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -97,7 +97,7 @@ U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1; BOOL gAnimateTextures = TRUE; F32 LLVOVolume::sLODFactor = 1.f; -F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop +F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop F32 LLVOVolume::sDistanceFactor = 1.0f; S32 LLVOVolume::sNumLODChanges = 0; S32 LLVOVolume::mRenderComplexity_last = 0; @@ -111,213 +111,213 @@ extern BOOL gCubeSnapshot; class LLMediaDataClientObjectImpl : public LLMediaDataClientObject { public: - LLMediaDataClientObjectImpl(LLVOVolume *obj, bool isNew) : mObject(obj), mNew(isNew) - { - mObject->addMDCImpl(); - } - ~LLMediaDataClientObjectImpl() - { - mObject->removeMDCImpl(); - } - - virtual U8 getMediaDataCount() const - { return mObject->getNumTEs(); } - - virtual LLSD getMediaDataLLSD(U8 index) const - { - LLSD result; - LLTextureEntry *te = mObject->getTE(index); - if (NULL != te) - { - llassert((te->getMediaData() != NULL) == te->hasMedia()); - if (te->getMediaData() != NULL) - { - result = te->getMediaData()->asLLSD(); - // XXX HACK: workaround bug in asLLSD() where whitelist is not set properly - // See DEV-41949 - if (!result.has(LLMediaEntry::WHITELIST_KEY)) - { - result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray(); - } - } - } - return result; - } - virtual bool isCurrentMediaUrl(U8 index, const std::string &url) const - { - LLTextureEntry *te = mObject->getTE(index); - if (te) - { - if (te->getMediaData()) - { - return (te->getMediaData()->getCurrentURL() == url); - } - } - return url.empty(); - } - - virtual LLUUID getID() const - { return mObject->getID(); } - - virtual void mediaNavigateBounceBack(U8 index) - { mObject->mediaNavigateBounceBack(index); } - - virtual bool hasMedia() const - { return mObject->hasMedia(); } - - virtual void updateObjectMediaData(LLSD const &data, const std::string &version_string) - { mObject->updateObjectMediaData(data, version_string); } - - virtual F64 getMediaInterest() const - { - F64 interest = mObject->getTotalMediaInterest(); - if (interest < (F64)0.0) - { - // media interest not valid yet, try pixel area - interest = mObject->getPixelArea(); - // HACK: force recalculation of pixel area if interest is the "magic default" of 1024. - if (interest == 1024.f) - { - const_cast<LLVOVolume*>(static_cast<LLVOVolume*>(mObject))->setPixelAreaAndAngle(gAgent); - interest = mObject->getPixelArea(); - } - } - return interest; - } - - virtual bool isInterestingEnough() const - { - return LLViewerMedia::getInstance()->isInterestingEnough(mObject, getMediaInterest()); - } - - virtual std::string getCapabilityUrl(const std::string &name) const - { return mObject->getRegion()->getCapability(name); } - - virtual bool isDead() const - { return mObject->isDead(); } - - virtual U32 getMediaVersion() const - { return LLTextureEntry::getVersionFromMediaVersionString(mObject->getMediaURL()); } - - virtual bool isNew() const - { return mNew; } + LLMediaDataClientObjectImpl(LLVOVolume *obj, bool isNew) : mObject(obj), mNew(isNew) + { + mObject->addMDCImpl(); + } + ~LLMediaDataClientObjectImpl() + { + mObject->removeMDCImpl(); + } + + virtual U8 getMediaDataCount() const + { return mObject->getNumTEs(); } + + virtual LLSD getMediaDataLLSD(U8 index) const + { + LLSD result; + LLTextureEntry *te = mObject->getTE(index); + if (NULL != te) + { + llassert((te->getMediaData() != NULL) == te->hasMedia()); + if (te->getMediaData() != NULL) + { + result = te->getMediaData()->asLLSD(); + // XXX HACK: workaround bug in asLLSD() where whitelist is not set properly + // See DEV-41949 + if (!result.has(LLMediaEntry::WHITELIST_KEY)) + { + result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray(); + } + } + } + return result; + } + virtual bool isCurrentMediaUrl(U8 index, const std::string &url) const + { + LLTextureEntry *te = mObject->getTE(index); + if (te) + { + if (te->getMediaData()) + { + return (te->getMediaData()->getCurrentURL() == url); + } + } + return url.empty(); + } + + virtual LLUUID getID() const + { return mObject->getID(); } + + virtual void mediaNavigateBounceBack(U8 index) + { mObject->mediaNavigateBounceBack(index); } + + virtual bool hasMedia() const + { return mObject->hasMedia(); } + + virtual void updateObjectMediaData(LLSD const &data, const std::string &version_string) + { mObject->updateObjectMediaData(data, version_string); } + + virtual F64 getMediaInterest() const + { + F64 interest = mObject->getTotalMediaInterest(); + if (interest < (F64)0.0) + { + // media interest not valid yet, try pixel area + interest = mObject->getPixelArea(); + // HACK: force recalculation of pixel area if interest is the "magic default" of 1024. + if (interest == 1024.f) + { + const_cast<LLVOVolume*>(static_cast<LLVOVolume*>(mObject))->setPixelAreaAndAngle(gAgent); + interest = mObject->getPixelArea(); + } + } + return interest; + } + + virtual bool isInterestingEnough() const + { + return LLViewerMedia::getInstance()->isInterestingEnough(mObject, getMediaInterest()); + } + + virtual std::string getCapabilityUrl(const std::string &name) const + { return mObject->getRegion()->getCapability(name); } + + virtual bool isDead() const + { return mObject->isDead(); } + + virtual U32 getMediaVersion() const + { return LLTextureEntry::getVersionFromMediaVersionString(mObject->getMediaURL()); } + + virtual bool isNew() const + { return mNew; } private: - LLPointer<LLVOVolume> mObject; - bool mNew; + LLPointer<LLVOVolume> mObject; + bool mNew; }; LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) - : LLViewerObject(id, pcode, regionp), - mVolumeImpl(NULL) + : LLViewerObject(id, pcode, regionp), + mVolumeImpl(NULL) { - mTexAnimMode = 0; - mRelativeXform.setIdentity(); - mRelativeXformInvTrans.setIdentity(); + mTexAnimMode = 0; + mRelativeXform.setIdentity(); + mRelativeXformInvTrans.setIdentity(); - mFaceMappingChanged = FALSE; - mLOD = MIN_LOD; + mFaceMappingChanged = FALSE; + mLOD = MIN_LOD; mLODDistance = 0.0f; mLODAdjustedDistance = 0.0f; mLODRadius = 0.0f; - mTextureAnimp = NULL; - mVolumeChanged = FALSE; - mVObjRadius = LLVector3(1,1,0.5f).length(); - mNumFaces = 0; - mLODChanged = FALSE; - mSculptChanged = FALSE; + mTextureAnimp = NULL; + mVolumeChanged = FALSE; + mVObjRadius = LLVector3(1,1,0.5f).length(); + mNumFaces = 0; + mLODChanged = FALSE; + mSculptChanged = FALSE; mColorChanged = FALSE; - mSpotLightPriority = 0.f; + mSpotLightPriority = 0.f; mSkinInfoUnavaliable = false; - mSkinInfo = NULL; + mSkinInfo = NULL; - mMediaImplList.resize(getNumTEs()); - mLastFetchedMediaVersion = -1; + mMediaImplList.resize(getNumTEs()); + mLastFetchedMediaVersion = -1; mServerDrawableUpdateCount = 0; - memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS); - mMDCImplCount = 0; - mLastRiggingInfoLOD = -1; - mResetDebugText = false; + memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS); + mMDCImplCount = 0; + mLastRiggingInfoLOD = -1; + mResetDebugText = false; } LLVOVolume::~LLVOVolume() { LL_PROFILE_ZONE_SCOPED; - delete mTextureAnimp; - mTextureAnimp = NULL; - delete mVolumeImpl; - mVolumeImpl = NULL; + delete mTextureAnimp; + mTextureAnimp = NULL; + delete mVolumeImpl; + mVolumeImpl = NULL; - gMeshRepo.unregisterMesh(this); + gMeshRepo.unregisterMesh(this); - if(!mMediaImplList.empty()) - { - for(U32 i = 0 ; i < mMediaImplList.size() ; i++) - { - if(mMediaImplList[i].notNull()) - { - mMediaImplList[i]->removeObject(this) ; - } - } - } + if(!mMediaImplList.empty()) + { + for(U32 i = 0 ; i < mMediaImplList.size() ; i++) + { + if(mMediaImplList[i].notNull()) + { + mMediaImplList[i]->removeObject(this) ; + } + } + } } void LLVOVolume::markDead() { - if (!mDead) - { + if (!mDead) + { LL_PROFILE_ZONE_SCOPED; if (getVolume()) { LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID()); } - if(getMDCImplCount() > 0) - { - LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false); - if (sObjectMediaClient) sObjectMediaClient->removeFromQueue(obj); - if (sObjectMediaNavigateClient) sObjectMediaNavigateClient->removeFromQueue(obj); - } - - // Detach all media impls from this object - for(U32 i = 0 ; i < mMediaImplList.size() ; i++) - { - removeMediaImpl(i); - } + if(getMDCImplCount() > 0) + { + LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false); + if (sObjectMediaClient) sObjectMediaClient->removeFromQueue(obj); + if (sObjectMediaNavigateClient) sObjectMediaNavigateClient->removeFromQueue(obj); + } + + // Detach all media impls from this object + for(U32 i = 0 ; i < mMediaImplList.size() ; i++) + { + removeMediaImpl(i); + } + + if (mSculptTexture.notNull()) + { + mSculptTexture->removeVolume(LLRender::SCULPT_TEX, this); + } - if (mSculptTexture.notNull()) - { - mSculptTexture->removeVolume(LLRender::SCULPT_TEX, this); - } + if (mLightTexture.notNull()) + { + mLightTexture->removeVolume(LLRender::LIGHT_TEX, this); + } + } - if (mLightTexture.notNull()) - { - mLightTexture->removeVolume(LLRender::LIGHT_TEX, this); - } - } - - LLViewerObject::markDead(); + LLViewerObject::markDead(); } // static void LLVOVolume::initClass() { - // gSavedSettings better be around - if (gSavedSettings.getBOOL("PrimMediaMasterEnabled")) - { - const F32 queue_timer_delay = gSavedSettings.getF32("PrimMediaRequestQueueDelay"); - const F32 retry_timer_delay = gSavedSettings.getF32("PrimMediaRetryTimerDelay"); - const U32 max_retries = gSavedSettings.getU32("PrimMediaMaxRetries"); - const U32 max_sorted_queue_size = gSavedSettings.getU32("PrimMediaMaxSortedQueueSize"); - const U32 max_round_robin_queue_size = gSavedSettings.getU32("PrimMediaMaxRoundRobinQueueSize"); - sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries, - max_sorted_queue_size, max_round_robin_queue_size); - sObjectMediaNavigateClient = new LLObjectMediaNavigateClient(queue_timer_delay, retry_timer_delay, - max_retries, max_sorted_queue_size, max_round_robin_queue_size); - } + // gSavedSettings better be around + if (gSavedSettings.getBOOL("PrimMediaMasterEnabled")) + { + const F32 queue_timer_delay = gSavedSettings.getF32("PrimMediaRequestQueueDelay"); + const F32 retry_timer_delay = gSavedSettings.getF32("PrimMediaRetryTimerDelay"); + const U32 max_retries = gSavedSettings.getU32("PrimMediaMaxRetries"); + const U32 max_sorted_queue_size = gSavedSettings.getU32("PrimMediaMaxSortedQueueSize"); + const U32 max_round_robin_queue_size = gSavedSettings.getU32("PrimMediaMaxRoundRobinQueueSize"); + sObjectMediaClient = new LLObjectMediaDataClient(queue_timer_delay, retry_timer_delay, max_retries, + max_sorted_queue_size, max_round_robin_queue_size); + sObjectMediaNavigateClient = new LLObjectMediaNavigateClient(queue_timer_delay, retry_timer_delay, + max_retries, max_sorted_queue_size, max_round_robin_queue_size); + } } // static @@ -328,65 +328,65 @@ void LLVOVolume::cleanupClass() } U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, - void **user_data, - U32 block_num, EObjectUpdateType update_type, - LLDataPacker *dp) + void **user_data, + U32 block_num, EObjectUpdateType update_type, + LLDataPacker *dp) { - - LLColor4U color; - const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA); + + LLColor4U color; + const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA); const bool previously_volume_changed = mVolumeChanged; const bool previously_face_mapping_changed = mFaceMappingChanged; const bool previously_color_changed = mColorChanged; - // Do base class updates... - U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); + // Do base class updates... + U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); - LLUUID sculpt_id; - U8 sculpt_type = 0; - if (isSculpted()) - { - LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - sculpt_id = sculpt_params->getSculptTexture(); - sculpt_type = sculpt_params->getSculptType(); + LLUUID sculpt_id; + U8 sculpt_type = 0; + if (isSculpted()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); + sculpt_id = sculpt_params->getSculptTexture(); + sculpt_type = sculpt_params->getSculptType(); LL_DEBUGS("ObjectUpdate") << "uuid " << mID << " set sculpt_id " << sculpt_id << LL_ENDL; dumpStack("ObjectUpdateStack"); - } - - if (!dp) - { - if (update_type == OUT_FULL) - { - //////////////////////////////// - // - // Unpack texture animation data - // - // - - if (mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureAnim)) - { - if (!mTextureAnimp) - { - mTextureAnimp = new LLViewerTextureAnim(this); - } - else - { - if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) - { - mTextureAnimp->reset(); - } - } - mTexAnimMode = 0; - - mTextureAnimp->unpackTAMessage(mesgsys, block_num); - } - else - { - if (mTextureAnimp) - { - delete mTextureAnimp; - mTextureAnimp = NULL; + } + + if (!dp) + { + if (update_type == OUT_FULL) + { + //////////////////////////////// + // + // Unpack texture animation data + // + // + + if (mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureAnim)) + { + if (!mTextureAnimp) + { + mTextureAnimp = new LLViewerTextureAnim(this); + } + else + { + if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) + { + mTextureAnimp->reset(); + } + } + mTexAnimMode = 0; + + mTextureAnimp->unpackTAMessage(mesgsys, block_num); + } + else + { + if (mTextureAnimp) + { + delete mTextureAnimp; + mTextureAnimp = NULL; for (S32 i = 0; i < getNumTEs(); i++) { @@ -399,98 +399,98 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, } } - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - mTexAnimMode = 0; - } - } - - // Unpack volume data - LLVolumeParams volume_params; - LLVolumeMessage::unpackVolumeParams(&volume_params, mesgsys, _PREHASH_ObjectData, block_num); - volume_params.setSculptID(sculpt_id, sculpt_type); - - if (setVolume(volume_params, 0)) - { - markForUpdate(); - } - } - - // Sigh, this needs to be done AFTER the volume is set as well, otherwise bad stuff happens... - //////////////////////////// - // - // Unpack texture entry data - // - - S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); - - if (result & TEM_CHANGE_MEDIA) - { - retval |= MEDIA_FLAGS_CHANGED; - } - } - else - { - if (update_type != OUT_TERSE_IMPROVED) - { - LLVolumeParams volume_params; - BOOL res = LLVolumeMessage::unpackVolumeParams(&volume_params, *dp); - if (!res) - { - LL_WARNS() << "Bogus volume parameters in object " << getID() << LL_ENDL; - LL_WARNS() << getRegion()->getOriginGlobal() << LL_ENDL; - } - - volume_params.setSculptID(sculpt_id, sculpt_type); - - if (setVolume(volume_params, 0)) - { - markForUpdate(); - } - S32 res2 = unpackTEMessage(*dp); - if (TEM_INVALID == res2) - { - // There's something bogus in the data that we're unpacking. - dp->dumpBufferToLog(); - LL_WARNS() << "Flushing cache files" << LL_ENDL; - - if(LLVOCache::instanceExists() && getRegion()) - { - LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ; - } - - LL_WARNS() << "Bogus TE data in " << getID() << LL_ENDL; - } - else - { - if (res2 & TEM_CHANGE_MEDIA) - { - retval |= MEDIA_FLAGS_CHANGED; - } - } - - U32 value = dp->getPassFlags(); - - if (value & 0x40) - { - if (!mTextureAnimp) - { - mTextureAnimp = new LLViewerTextureAnim(this); - } - else - { - if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) - { - mTextureAnimp->reset(); - } - } - mTexAnimMode = 0; - mTextureAnimp->unpackTAMessage(*dp); - } - else if (mTextureAnimp) - { - delete mTextureAnimp; - mTextureAnimp = NULL; + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + mTexAnimMode = 0; + } + } + + // Unpack volume data + LLVolumeParams volume_params; + LLVolumeMessage::unpackVolumeParams(&volume_params, mesgsys, _PREHASH_ObjectData, block_num); + volume_params.setSculptID(sculpt_id, sculpt_type); + + if (setVolume(volume_params, 0)) + { + markForUpdate(); + } + } + + // Sigh, this needs to be done AFTER the volume is set as well, otherwise bad stuff happens... + //////////////////////////// + // + // Unpack texture entry data + // + + S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); + + if (result & TEM_CHANGE_MEDIA) + { + retval |= MEDIA_FLAGS_CHANGED; + } + } + else + { + if (update_type != OUT_TERSE_IMPROVED) + { + LLVolumeParams volume_params; + BOOL res = LLVolumeMessage::unpackVolumeParams(&volume_params, *dp); + if (!res) + { + LL_WARNS() << "Bogus volume parameters in object " << getID() << LL_ENDL; + LL_WARNS() << getRegion()->getOriginGlobal() << LL_ENDL; + } + + volume_params.setSculptID(sculpt_id, sculpt_type); + + if (setVolume(volume_params, 0)) + { + markForUpdate(); + } + S32 res2 = unpackTEMessage(*dp); + if (TEM_INVALID == res2) + { + // There's something bogus in the data that we're unpacking. + dp->dumpBufferToLog(); + LL_WARNS() << "Flushing cache files" << LL_ENDL; + + if(LLVOCache::instanceExists() && getRegion()) + { + LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ; + } + + LL_WARNS() << "Bogus TE data in " << getID() << LL_ENDL; + } + else + { + if (res2 & TEM_CHANGE_MEDIA) + { + retval |= MEDIA_FLAGS_CHANGED; + } + } + + U32 value = dp->getPassFlags(); + + if (value & 0x40) + { + if (!mTextureAnimp) + { + mTextureAnimp = new LLViewerTextureAnim(this); + } + else + { + if (!(mTextureAnimp->mMode & LLTextureAnim::SMOOTH)) + { + mTextureAnimp->reset(); + } + } + mTexAnimMode = 0; + mTextureAnimp->unpackTAMessage(*dp); + } + else if (mTextureAnimp) + { + delete mTextureAnimp; + mTextureAnimp = NULL; for (S32 i = 0; i < getNumTEs(); i++) { @@ -503,59 +503,59 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, } } - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - mTexAnimMode = 0; - } - - if (value & 0x400) - { //particle system (new) - unpackParticleSource(*dp, mOwnerID, false); - } - } - else - { - S32 texture_length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureEntry); - if (texture_length) - { - U8 tdpbuffer[1024]; - LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024); - mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num, 1024); - S32 result = unpackTEMessage(tdp); - if (result & teDirtyBits) - { - if (mDrawable) + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + mTexAnimMode = 0; + } + + if (value & 0x400) + { //particle system (new) + unpackParticleSource(*dp, mOwnerID, false); + } + } + else + { + S32 texture_length = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureEntry); + if (texture_length) + { + U8 tdpbuffer[1024]; + LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024); + mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num, 1024); + S32 result = unpackTEMessage(tdp); + if (result & teDirtyBits) + { + if (mDrawable) { //on the fly TE updates break batches, isolate in octree shrinkWrap(); } - } - if (result & TEM_CHANGE_MEDIA) - { - retval |= MEDIA_FLAGS_CHANGED; - } - } - } - } - if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED)) - { - // If only the media URL changed, and it isn't a media version URL, - // ignore it - if ( ! ( retval & (MEDIA_URL_ADDED | MEDIA_URL_UPDATED) && - mMedia && ! mMedia->mMediaURL.empty() && - ! LLTextureEntry::isMediaVersionString(mMedia->mMediaURL) ) ) - { - // If the media changed at all, request new media data - LL_DEBUGS("MediaOnAPrim") << "Media update: " << getID() << ": retval=" << retval << " Media URL: " << + } + if (result & TEM_CHANGE_MEDIA) + { + retval |= MEDIA_FLAGS_CHANGED; + } + } + } + } + if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED)) + { + // If only the media URL changed, and it isn't a media version URL, + // ignore it + if ( ! ( retval & (MEDIA_URL_ADDED | MEDIA_URL_UPDATED) && + mMedia && ! mMedia->mMediaURL.empty() && + ! LLTextureEntry::isMediaVersionString(mMedia->mMediaURL) ) ) + { + // If the media changed at all, request new media data + LL_DEBUGS("MediaOnAPrim") << "Media update: " << getID() << ": retval=" << retval << " Media URL: " << ((mMedia) ? mMedia->mMediaURL : std::string("")) << LL_ENDL; - requestMediaDataUpdate(retval & MEDIA_FLAGS_CHANGED); - } + requestMediaDataUpdate(retval & MEDIA_FLAGS_CHANGED); + } else { LL_INFOS("MediaOnAPrim") << "Ignoring media update for: " << getID() << " Media URL: " << ((mMedia) ? mMedia->mMediaURL : std::string("")) << LL_ENDL; } - } - // ...and clean up any media impls - cleanUpMediaImpls(); + } + // ...and clean up any media impls + cleanUpMediaImpls(); if (( (mVolumeChanged && !previously_volume_changed) || @@ -566,7 +566,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, onDrawableUpdateFromServer(); } - return retval; + return retval; } // Called when a volume, material, etc is updated by the server, possibly by a @@ -585,117 +585,117 @@ void LLVOVolume::onDrawableUpdateFromServer() void LLVOVolume::animateTextures() { - if (!mDead) - { + if (!mDead) + { shrinkWrap(); - F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; - S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); - - if (result) - { - if (!mTexAnimMode) - { - mFaceMappingChanged = TRUE; - gPipeline.markTextured(mDrawable); - } - mTexAnimMode = result | mTextureAnimp->mMode; - - S32 start=0, end=mDrawable->getNumFaces()-1; - if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) - { - start = end = mTextureAnimp->mFace; - } - - for (S32 i = start; i <= end; i++) - { - LLFace* facep = mDrawable->getFace(i); - if (!facep) continue; - if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; - - const LLTextureEntry* te = facep->getTextureEntry(); - - if (!te) - { - continue; - } - - if (!(result & LLViewerTextureAnim::ROTATE)) - { - te->getRotation(&rot); - } - if (!(result & LLViewerTextureAnim::TRANSLATE)) - { - te->getOffset(&off_s,&off_t); - } - if (!(result & LLViewerTextureAnim::SCALE)) - { - te->getScale(&scale_s, &scale_t); - } - - if (!facep->mTextureMatrix) - { - facep->mTextureMatrix = new LLMatrix4(); - } - - LLMatrix4& tex_mat = *facep->mTextureMatrix; - tex_mat.setIdentity(); - LLVector3 trans ; - - trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); - tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); - - LLVector3 scale(scale_s, scale_t, 1.f); - LLQuaternion quat; - quat.setQuat(rot, 0, 0, -1.f); - - tex_mat.rotate(quat); - - LLMatrix4 mat; - mat.initAll(scale, LLQuaternion(), LLVector3()); - tex_mat *= mat; - - tex_mat.translate(trans); - } - } - else - { - if (mTexAnimMode && mTextureAnimp->mRate == 0) - { - U8 start, count; - - if (mTextureAnimp->mFace == -1) - { - start = 0; - count = getNumTEs(); - } - else - { - start = (U8) mTextureAnimp->mFace; - count = 1; - } - - for (S32 i = start; i < start + count; i++) - { - if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) - { - setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); - } - if (mTexAnimMode & LLViewerTextureAnim::SCALE) - { - setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); - } - if (mTexAnimMode & LLViewerTextureAnim::ROTATE) - { - setTERotation(i, mTextureAnimp->mRot); - } - } - - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - mTexAnimMode = 0; - } - } - } + F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; + S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); + + if (result) + { + if (!mTexAnimMode) + { + mFaceMappingChanged = TRUE; + gPipeline.markTextured(mDrawable); + } + mTexAnimMode = result | mTextureAnimp->mMode; + + S32 start=0, end=mDrawable->getNumFaces()-1; + if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end) + { + start = end = mTextureAnimp->mFace; + } + + for (S32 i = start; i <= end; i++) + { + LLFace* facep = mDrawable->getFace(i); + if (!facep) continue; + if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; + + const LLTextureEntry* te = facep->getTextureEntry(); + + if (!te) + { + continue; + } + + if (!(result & LLViewerTextureAnim::ROTATE)) + { + te->getRotation(&rot); + } + if (!(result & LLViewerTextureAnim::TRANSLATE)) + { + te->getOffset(&off_s,&off_t); + } + if (!(result & LLViewerTextureAnim::SCALE)) + { + te->getScale(&scale_s, &scale_t); + } + + if (!facep->mTextureMatrix) + { + facep->mTextureMatrix = new LLMatrix4(); + } + + LLMatrix4& tex_mat = *facep->mTextureMatrix; + tex_mat.setIdentity(); + LLVector3 trans ; + + trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); + tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + + LLVector3 scale(scale_s, scale_t, 1.f); + LLQuaternion quat; + quat.setQuat(rot, 0, 0, -1.f); + + tex_mat.rotate(quat); + + LLMatrix4 mat; + mat.initAll(scale, LLQuaternion(), LLVector3()); + tex_mat *= mat; + + tex_mat.translate(trans); + } + } + else + { + if (mTexAnimMode && mTextureAnimp->mRate == 0) + { + U8 start, count; + + if (mTextureAnimp->mFace == -1) + { + start = 0; + count = getNumTEs(); + } + else + { + start = (U8) mTextureAnimp->mFace; + count = 1; + } + + for (S32 i = start; i < start + count; i++) + { + if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE) + { + setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT); + } + if (mTexAnimMode & LLViewerTextureAnim::SCALE) + { + setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT); + } + if (mTexAnimMode & LLViewerTextureAnim::ROTATE) + { + setTERotation(i, mTextureAnimp->mRot); + } + } + + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + mTexAnimMode = 0; + } + } + } } void LLVOVolume::updateTextures() @@ -704,403 +704,403 @@ void LLVOVolume::updateTextures() updateTextureVirtualSize(); } -BOOL LLVOVolume::isVisible() const +BOOL LLVOVolume::isVisible() const { - if(mDrawable.notNull() && mDrawable->isVisible()) - { - return TRUE ; - } + if(mDrawable.notNull() && mDrawable->isVisible()) + { + return TRUE ; + } - if(isAttachment()) - { - LLViewerObject* objp = (LLViewerObject*)getParent() ; - while(objp && !objp->isAvatar()) - { - objp = (LLViewerObject*)objp->getParent() ; - } + if(isAttachment()) + { + LLViewerObject* objp = (LLViewerObject*)getParent() ; + while(objp && !objp->isAvatar()) + { + objp = (LLViewerObject*)objp->getParent() ; + } - return objp && objp->mDrawable.notNull() && objp->mDrawable->isVisible() ; - } + return objp && objp->mDrawable.notNull() && objp->mDrawable->isVisible() ; + } - return FALSE ; + return FALSE ; } void LLVOVolume::updateTextureVirtualSize(bool forced) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - // Update the pixel area of all faces + // Update the pixel area of all faces if (mDrawable.isNull() || gCubeSnapshot) { return; } - if(!forced) - { - if(!isVisible()) - { //don't load textures for non-visible faces - const S32 num_faces = mDrawable->getNumFaces(); - for (S32 i = 0; i < num_faces; i++) - { - LLFace* face = mDrawable->getFace(i); - if (face) - { - face->setPixelArea(0.f); - face->setVirtualSize(0.f); - } - } - - return ; - } - - if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE)) - { - return; - } - } - - static LLCachedControl<bool> dont_load_textures(gSavedSettings,"TextureDisable", false); - - if (dont_load_textures || LLAppViewer::getTextureFetch()->mDebugPause) // || !mDrawable->isVisible()) - { - return; - } - - mTextureUpdateTimer.reset(); - - F32 old_area = mPixelArea; - mPixelArea = 0.f; - - const S32 num_faces = mDrawable->getNumFaces(); - F32 min_vsize=999999999.f, max_vsize=0.f; - LLViewerCamera* camera = LLViewerCamera::getInstance(); + if(!forced) + { + if(!isVisible()) + { //don't load textures for non-visible faces + const S32 num_faces = mDrawable->getNumFaces(); + for (S32 i = 0; i < num_faces; i++) + { + LLFace* face = mDrawable->getFace(i); + if (face) + { + face->setPixelArea(0.f); + face->setVirtualSize(0.f); + } + } + + return ; + } + + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE)) + { + return; + } + } + + static LLCachedControl<bool> dont_load_textures(gSavedSettings,"TextureDisable", false); + + if (dont_load_textures || LLAppViewer::getTextureFetch()->mDebugPause) // || !mDrawable->isVisible()) + { + return; + } + + mTextureUpdateTimer.reset(); + + F32 old_area = mPixelArea; + mPixelArea = 0.f; + + const S32 num_faces = mDrawable->getNumFaces(); + F32 min_vsize=999999999.f, max_vsize=0.f; + LLViewerCamera* camera = LLViewerCamera::getInstance(); std::stringstream debug_text; - for (S32 i = 0; i < num_faces; i++) - { - LLFace* face = mDrawable->getFace(i); - if (!face) continue; - const LLTextureEntry *te = face->getTextureEntry(); - LLViewerTexture *imagep = face->getTexture(); - if (!imagep || !te || - face->mExtents[0].equals3(face->mExtents[1])) - { - continue; - } - - F32 vsize; - F32 old_size = face->getVirtualSize(); - - if (isHUDAttachment()) - { - F32 area = (F32) camera->getScreenPixelArea(); - vsize = area; - imagep->setBoostLevel(LLGLTexture::BOOST_HUD); - face->setPixelArea(area); // treat as full screen - face->setVirtualSize(vsize); - } - else - { - vsize = face->getTextureVirtualSize(); - } - - mPixelArea = llmax(mPixelArea, face->getPixelArea()); + for (S32 i = 0; i < num_faces; i++) + { + LLFace* face = mDrawable->getFace(i); + if (!face) continue; + const LLTextureEntry *te = face->getTextureEntry(); + LLViewerTexture *imagep = face->getTexture(); + if (!imagep || !te || + face->mExtents[0].equals3(face->mExtents[1])) + { + continue; + } + + F32 vsize; + F32 old_size = face->getVirtualSize(); + + if (isHUDAttachment()) + { + F32 area = (F32) camera->getScreenPixelArea(); + vsize = area; + imagep->setBoostLevel(LLGLTexture::BOOST_HUD); + face->setPixelArea(area); // treat as full screen + face->setVirtualSize(vsize); + } + else + { + vsize = face->getTextureVirtualSize(); + } + + mPixelArea = llmax(mPixelArea, face->getPixelArea()); // if the face has gotten small enough to turn off texture animation and texture // animation is running, rebuild the render batch for this face to turn off // texture animation - if (face->mTextureMatrix != NULL) - { - if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) || - (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE)) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - } - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) - { - LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ; - if(img) - { + if (face->mTextureMatrix != NULL) + { + if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) || + (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE)) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + } + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) + { + LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ; + if(img) + { debug_text << img->getDiscardLevel() << ":" << img->getDesiredDiscardLevel() << ":" << img->getWidth() << ":" << (S32) sqrtf(vsize) << ":" << (S32) sqrtf(img->getMaxVirtualSize()) << "\n"; - /*F32 pri = img->getDecodePriority(); - pri = llmax(pri, 0.0f); - if (pri < min_vsize) min_vsize = pri; - if (pri > max_vsize) max_vsize = pri;*/ - } - } - else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) - { - F32 pri = mPixelArea; - if (pri < min_vsize) min_vsize = pri; - if (pri > max_vsize) max_vsize = pri; - } - } - - if (isSculpted()) - { + /*F32 pri = img->getDecodePriority(); + pri = llmax(pri, 0.0f); + if (pri < min_vsize) min_vsize = pri; + if (pri > max_vsize) max_vsize = pri;*/ + } + } + else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) + { + F32 pri = mPixelArea; + if (pri < min_vsize) min_vsize = pri; + if (pri > max_vsize) max_vsize = pri; + } + } + + if (isSculpted()) + { updateSculptTexture(); - - - - if (mSculptTexture.notNull()) - { - mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), - (S32)LLGLTexture::BOOST_SCULPTED)); - mSculptTexture->setForSculpt() ; - - if(!mSculptTexture->isCachedRawImageReady()) - { - S32 lod = llmin(mLOD, 3); - F32 lodf = ((F32)(lod + 1.0f)/4.f); - F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ; - mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE); - } - - S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture - S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ; - - if (texture_discard >= 0 && //texture has some data available - (texture_discard < current_discard || //texture has more data than last rebuild - current_discard < 0)) //no previous rebuild - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - mSculptChanged = TRUE; - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED)) - { - setDebugText(llformat("T%d C%d V%d\n%dx%d", - texture_discard, current_discard, getVolume()->getSculptLevel(), - mSculptTexture->getHeight(), mSculptTexture->getWidth())); - } - } - - } - - if (getLightTextureID().notNull()) - { - LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - LLUUID id = params->getLightTexture(); - mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE); - if (mLightTexture.notNull()) - { - F32 rad = getLightRadius(); - mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(), - LLVector3(rad,rad,rad), - *camera)); - } - } - - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) - { - setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); - } - else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) - { - //setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); + + + + if (mSculptTexture.notNull()) + { + mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), + (S32)LLGLTexture::BOOST_SCULPTED)); + mSculptTexture->setForSculpt() ; + + if(!mSculptTexture->isCachedRawImageReady()) + { + S32 lod = llmin(mLOD, 3); + F32 lodf = ((F32)(lod + 1.0f)/4.f); + F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ; + mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE); + } + + S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture + S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ; + + if (texture_discard >= 0 && //texture has some data available + (texture_discard < current_discard || //texture has more data than last rebuild + current_discard < 0)) //no previous rebuild + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + mSculptChanged = TRUE; + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED)) + { + setDebugText(llformat("T%d C%d V%d\n%dx%d", + texture_discard, current_discard, getVolume()->getSculptLevel(), + mSculptTexture->getHeight(), mSculptTexture->getWidth())); + } + } + + } + + if (getLightTextureID().notNull()) + { + LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + LLUUID id = params->getLightTexture(); + mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE); + if (mLightTexture.notNull()) + { + F32 rad = getLightRadius(); + mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(), + LLVector3(rad,rad,rad), + *camera)); + } + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) + { + setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); + } + else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) + { + //setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); setDebugText(debug_text.str()); - } - else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) - { - setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); - } + } + else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) + { + setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); + } - if (mPixelArea == 0) - { //flexi phasing issues make this happen - mPixelArea = old_area; - } + if (mPixelArea == 0) + { //flexi phasing issues make this happen + mPixelArea = old_area; + } } BOOL LLVOVolume::isActive() const { - return !mStatic; + return !mStatic; } BOOL LLVOVolume::setMaterial(const U8 material) { - BOOL res = LLViewerObject::setMaterial(material); - - return res; + BOOL res = LLViewerObject::setMaterial(material); + + return res; } void LLVOVolume::setTexture(const S32 face) { - llassert(face < getNumTEs()); - gGL.getTexUnit(0)->bind(getTEImage(face)); + llassert(face < getNumTEs()); + gGL.getTexUnit(0)->bind(getTEImage(face)); } void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped) { - if (scale != getScale()) - { - // store local radius - LLViewerObject::setScale(scale); + if (scale != getScale()) + { + // store local radius + LLViewerObject::setScale(scale); + + if (mVolumeImpl) + { + mVolumeImpl->onSetScale(scale, damped); + } - if (mVolumeImpl) - { - mVolumeImpl->onSetScale(scale, damped); - } - - updateRadius(); + updateRadius(); - //since drawable transforms do not include scale, changing volume scale - //requires an immediate rebuild of volume verts. - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); + //since drawable transforms do not include scale, changing volume scale + //requires an immediate rebuild of volume verts. + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION); if (mDrawable) { shrinkWrap(); } - } + } } LLFace* LLVOVolume::addFace(S32 f) { - const LLTextureEntry* te = getTE(f); - LLViewerTexture* imagep = getTEImage(f); - if (te->getMaterialParams().notNull()) - { - LLViewerTexture* normalp = getTENormalMap(f); - LLViewerTexture* specularp = getTESpecularMap(f); - return mDrawable->addFace(te, imagep, normalp, specularp); - } - return mDrawable->addFace(te, imagep); + const LLTextureEntry* te = getTE(f); + LLViewerTexture* imagep = getTEImage(f); + if (te->getMaterialParams().notNull()) + { + LLViewerTexture* normalp = getTENormalMap(f); + LLViewerTexture* specularp = getTESpecularMap(f); + return mDrawable->addFace(te, imagep, normalp, specularp); + } + return mDrawable->addFace(te, imagep); } LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) { - pipeline->allocDrawable(this); - - mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME); + pipeline->allocDrawable(this); - S32 max_tes_to_set = getNumTEs(); - for (S32 i = 0; i < max_tes_to_set; i++) - { - addFace(i); - } - mNumFaces = max_tes_to_set; + mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME); - if (isAttachment()) - { - mDrawable->makeActive(); - } + S32 max_tes_to_set = getNumTEs(); + for (S32 i = 0; i < max_tes_to_set; i++) + { + addFace(i); + } + mNumFaces = max_tes_to_set; - if (getIsLight()) - { - // Add it to the pipeline mLightSet - gPipeline.setLight(mDrawable, TRUE); - } + if (isAttachment()) + { + mDrawable->makeActive(); + } + + if (getIsLight()) + { + // Add it to the pipeline mLightSet + gPipeline.setLight(mDrawable, TRUE); + } if (isReflectionProbe()) { updateReflectionProbePtr(); } - updateRadius(); - bool force_update = true; // avoid non-alpha mDistance update being optimized away - mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update); + updateRadius(); + bool force_update = true; // avoid non-alpha mDistance update being optimized away + mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update); - return mDrawable; + return mDrawable; } BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bool unique_volume) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - LLVolumeParams volume_params = params_in; - - S32 last_lod = mVolumep.notNull() ? LLVolumeLODGroup::getVolumeDetailFromScale(mVolumep->getDetail()) : -1; - S32 lod = mLOD; - - BOOL is404 = FALSE; - - if (isSculpted()) - { - // if it's a mesh - if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) - { //meshes might not have all LODs, get the force detail to best existing LOD - if (NO_LOD != lod) - { - lod = gMeshRepo.getActualMeshLOD(volume_params, lod); - if (lod == -1) - { - is404 = TRUE; - lod = 0; - } - } - } - } - - // Check if we need to change implementations - bool is_flexible = (volume_params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE); - if (is_flexible) - { - setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, false); - if (!mVolumeImpl) - { - LLFlexibleObjectData* data = (LLFlexibleObjectData*)getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); - mVolumeImpl = new LLVolumeImplFlexible(this, data); - } - } - else - { - // Mark the parameter not in use - setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, false); - if (mVolumeImpl) - { - delete mVolumeImpl; - mVolumeImpl = NULL; - if (mDrawable.notNull()) - { - // Undo the damage we did to this matrix - mDrawable->updateXform(FALSE); - } - } - } - - if (is404) - { - setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI)); - //render prim proxy when mesh loading attempts give up - volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE); - - } - - if ((LLPrimitive::setVolume(volume_params, lod, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged) - { - mFaceMappingChanged = TRUE; - - if (mVolumeImpl) - { - mVolumeImpl->onSetVolume(volume_params, mLOD); - } - - updateSculptTexture(); - - if (isSculpted()) - { - updateSculptTexture(); - // if it's a mesh - if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) - { - if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID()) - { - mSkinInfo = NULL; - mSkinInfoUnavaliable = false; - } - - if (!getVolume()->isMeshAssetLoaded()) - { - //load request not yet issued, request pipeline load this mesh - S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod); - if (available_lod != lod) - { - LLPrimitive::setVolume(volume_params, available_lod); - } - } - - if (!mSkinInfo && !mSkinInfoUnavaliable) - { + LLVolumeParams volume_params = params_in; + + S32 last_lod = mVolumep.notNull() ? LLVolumeLODGroup::getVolumeDetailFromScale(mVolumep->getDetail()) : -1; + S32 lod = mLOD; + + BOOL is404 = FALSE; + + if (isSculpted()) + { + // if it's a mesh + if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) + { //meshes might not have all LODs, get the force detail to best existing LOD + if (NO_LOD != lod) + { + lod = gMeshRepo.getActualMeshLOD(volume_params, lod); + if (lod == -1) + { + is404 = TRUE; + lod = 0; + } + } + } + } + + // Check if we need to change implementations + bool is_flexible = (volume_params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE); + if (is_flexible) + { + setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, false); + if (!mVolumeImpl) + { + LLFlexibleObjectData* data = (LLFlexibleObjectData*)getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); + mVolumeImpl = new LLVolumeImplFlexible(this, data); + } + } + else + { + // Mark the parameter not in use + setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, false); + if (mVolumeImpl) + { + delete mVolumeImpl; + mVolumeImpl = NULL; + if (mDrawable.notNull()) + { + // Undo the damage we did to this matrix + mDrawable->updateXform(FALSE); + } + } + } + + if (is404) + { + setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI)); + //render prim proxy when mesh loading attempts give up + volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE); + + } + + if ((LLPrimitive::setVolume(volume_params, lod, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged) + { + mFaceMappingChanged = TRUE; + + if (mVolumeImpl) + { + mVolumeImpl->onSetVolume(volume_params, mLOD); + } + + updateSculptTexture(); + + if (isSculpted()) + { + updateSculptTexture(); + // if it's a mesh + if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) + { + if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID()) + { + mSkinInfo = NULL; + mSkinInfoUnavaliable = false; + } + + if (!getVolume()->isMeshAssetLoaded()) + { + //load request not yet issued, request pipeline load this mesh + S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod); + if (available_lod != lod) + { + LLPrimitive::setVolume(volume_params, available_lod); + } + } + + if (!mSkinInfo && !mSkinInfoUnavaliable) + { LLUUID mesh_id = volume_params.getSculptID(); if (gMeshRepo.hasHeader(mesh_id) && !gMeshRepo.hasSkinInfo(mesh_id)) { @@ -1117,60 +1117,60 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo notifySkinInfoLoaded(skin_info); } } - } - } - else // otherwise is sculptie - { - if (mSculptTexture.notNull()) - { - sculpt(); - } - } - } + } + } + else // otherwise is sculptie + { + if (mSculptTexture.notNull()) + { + sculpt(); + } + } + } return TRUE; - } - else if (NO_LOD == lod) - { - LLSculptIDSize::instance().resetSizeSum(volume_params.getSculptID()); - } + } + else if (NO_LOD == lod) + { + LLSculptIDSize::instance().resetSizeSum(volume_params.getSculptID()); + } - return FALSE; + return FALSE; } void LLVOVolume::updateSculptTexture() { - LLPointer<LLViewerFetchedTexture> old_sculpt = mSculptTexture; + LLPointer<LLViewerFetchedTexture> old_sculpt = mSculptTexture; - if (isSculpted() && !isMesh()) - { - LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID id = sculpt_params->getSculptTexture(); - if (id.notNull()) - { - mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - } + if (isSculpted() && !isMesh()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLUUID id = sculpt_params->getSculptTexture(); + if (id.notNull()) + { + mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } mSkinInfoUnavaliable = false; - mSkinInfo = NULL; - } - else - { - mSculptTexture = NULL; - } - - if (mSculptTexture != old_sculpt) - { - if (old_sculpt.notNull()) - { - old_sculpt->removeVolume(LLRender::SCULPT_TEX, this); - } - if (mSculptTexture.notNull()) - { - mSculptTexture->addVolume(LLRender::SCULPT_TEX, this); - } - } - + mSkinInfo = NULL; + } + else + { + mSculptTexture = NULL; + } + + if (mSculptTexture != old_sculpt) + { + if (old_sculpt.notNull()) + { + old_sculpt->removeVolume(LLRender::SCULPT_TEX, this); + } + if (mSculptTexture.notNull()) + { + mSculptTexture->addVolume(LLRender::SCULPT_TEX, this); + } + } + } void LLVOVolume::updateVisualComplexity() @@ -1188,9 +1188,9 @@ void LLVOVolume::updateVisualComplexity() } void LLVOVolume::notifyMeshLoaded() -{ - mSculptChanged = TRUE; - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); +{ + mSculptChanged = TRUE; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY); if (!mSkinInfo && !mSkinInfoUnavaliable) { @@ -1220,137 +1220,137 @@ void LLVOVolume::notifyMeshLoaded() void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin) { mSkinInfoUnavaliable = false; - mSkinInfo = skin; + mSkinInfo = skin; - notifyMeshLoaded(); + notifyMeshLoaded(); } void LLVOVolume::notifySkinInfoUnavailable() { - mSkinInfoUnavaliable = true; - mSkinInfo = nullptr; + mSkinInfoUnavaliable = true; + mSkinInfo = nullptr; } // sculpt replaces generate() for sculpted surfaces void LLVOVolume::sculpt() -{ - if (mSculptTexture.notNull()) - { - U16 sculpt_height = 0; - U16 sculpt_width = 0; - S8 sculpt_components = 0; - const U8* sculpt_data = NULL; - - S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; - LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; - - S32 max_discard = mSculptTexture->getMaxDiscardLevel(); - if (discard_level > max_discard) - { - discard_level = max_discard; // clamp to the best we can do - } - if(discard_level > MAX_DISCARD_LEVEL) - { - return; //we think data is not ready yet. - } - - S32 current_discard = getVolume()->getSculptLevel() ; - if(current_discard < -2) - { - static S32 low_sculpty_discard_warning_count = 1; - S32 exponent = llmax(1, llfloor( log10((F64) low_sculpty_discard_warning_count) )); - S32 interval = pow(10.0, exponent); - if ( low_sculpty_discard_warning_count < 10 || - (low_sculpty_discard_warning_count % interval) == 0) - { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs - LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() - << " at " << current_discard - << " is less than -2." - << " Hit this " << low_sculpty_discard_warning_count << " times" - << LL_ENDL; - } - low_sculpty_discard_warning_count++; - - // corrupted volume... don't update the sculpty - return; - } - else if (current_discard > MAX_DISCARD_LEVEL) - { - static S32 high_sculpty_discard_warning_count = 1; - S32 exponent = llmax(1, llfloor( log10((F64) high_sculpty_discard_warning_count) )); - S32 interval = pow(10.0, exponent); - if ( high_sculpty_discard_warning_count < 10 || - (high_sculpty_discard_warning_count % interval) == 0) - { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs - LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() - << " at " << current_discard - << " is more than than allowed max of " << MAX_DISCARD_LEVEL - << ". Hit this " << high_sculpty_discard_warning_count << " times" - << LL_ENDL; - } - high_sculpty_discard_warning_count++; - - // corrupted volume... don't update the sculpty - return; - } - - if (current_discard == discard_level) // no work to do here - return; - - if(!raw_image) - { - llassert(discard_level < 0) ; - - sculpt_width = 0; - sculpt_height = 0; - sculpt_data = NULL ; - - if(LLViewerTextureManager::sTesterp) - { - LLViewerTextureManager::sTesterp->updateGrayTextureBinding(); - } - } - else - { - sculpt_height = raw_image->getHeight(); - sculpt_width = raw_image->getWidth(); - sculpt_components = raw_image->getComponents(); - - sculpt_data = raw_image->getData(); - - if(LLViewerTextureManager::sTesterp) - { - mSculptTexture->updateBindStatsForTester() ; - } - } - getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset()); - - //notify rebuild any other VOVolumes that reference this sculpty volume - for (S32 i = 0; i < mSculptTexture->getNumVolumes(LLRender::SCULPT_TEX); ++i) - { - LLVOVolume* volume = (*(mSculptTexture->getVolumeList(LLRender::SCULPT_TEX)))[i]; - if (volume != this && volume->getVolume() == getVolume()) - { - gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY); - } - } - } -} - -S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor) -{ - S32 cur_detail; - if (LLPipeline::sDynamicLOD) - { - // We've got LOD in the profile, and in the twist. Use radius. - F32 tan_angle = (lod_factor*radius)/distance; - cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); - } - else - { - cur_detail = llclamp((S32) (sqrtf(radius)*lod_factor*4.f), 0, 3); - } - return cur_detail; +{ + if (mSculptTexture.notNull()) + { + U16 sculpt_height = 0; + U16 sculpt_width = 0; + S8 sculpt_components = 0; + const U8* sculpt_data = NULL; + + S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; + LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; + + S32 max_discard = mSculptTexture->getMaxDiscardLevel(); + if (discard_level > max_discard) + { + discard_level = max_discard; // clamp to the best we can do + } + if(discard_level > MAX_DISCARD_LEVEL) + { + return; //we think data is not ready yet. + } + + S32 current_discard = getVolume()->getSculptLevel() ; + if(current_discard < -2) + { + static S32 low_sculpty_discard_warning_count = 1; + S32 exponent = llmax(1, llfloor( log10((F64) low_sculpty_discard_warning_count) )); + S32 interval = pow(10.0, exponent); + if ( low_sculpty_discard_warning_count < 10 || + (low_sculpty_discard_warning_count % interval) == 0) + { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs + LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() + << " at " << current_discard + << " is less than -2." + << " Hit this " << low_sculpty_discard_warning_count << " times" + << LL_ENDL; + } + low_sculpty_discard_warning_count++; + + // corrupted volume... don't update the sculpty + return; + } + else if (current_discard > MAX_DISCARD_LEVEL) + { + static S32 high_sculpty_discard_warning_count = 1; + S32 exponent = llmax(1, llfloor( log10((F64) high_sculpty_discard_warning_count) )); + S32 interval = pow(10.0, exponent); + if ( high_sculpty_discard_warning_count < 10 || + (high_sculpty_discard_warning_count % interval) == 0) + { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs + LL_WARNS() << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID() + << " at " << current_discard + << " is more than than allowed max of " << MAX_DISCARD_LEVEL + << ". Hit this " << high_sculpty_discard_warning_count << " times" + << LL_ENDL; + } + high_sculpty_discard_warning_count++; + + // corrupted volume... don't update the sculpty + return; + } + + if (current_discard == discard_level) // no work to do here + return; + + if(!raw_image) + { + llassert(discard_level < 0) ; + + sculpt_width = 0; + sculpt_height = 0; + sculpt_data = NULL ; + + if(LLViewerTextureManager::sTesterp) + { + LLViewerTextureManager::sTesterp->updateGrayTextureBinding(); + } + } + else + { + sculpt_height = raw_image->getHeight(); + sculpt_width = raw_image->getWidth(); + sculpt_components = raw_image->getComponents(); + + sculpt_data = raw_image->getData(); + + if(LLViewerTextureManager::sTesterp) + { + mSculptTexture->updateBindStatsForTester() ; + } + } + getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset()); + + //notify rebuild any other VOVolumes that reference this sculpty volume + for (S32 i = 0; i < mSculptTexture->getNumVolumes(LLRender::SCULPT_TEX); ++i) + { + LLVOVolume* volume = (*(mSculptTexture->getVolumeList(LLRender::SCULPT_TEX)))[i]; + if (volume != this && volume->getVolume() == getVolume()) + { + gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY); + } + } + } +} + +S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor) +{ + S32 cur_detail; + if (LLPipeline::sDynamicLOD) + { + // We've got LOD in the profile, and in the twist. Use radius. + F32 tan_angle = (lod_factor*radius)/distance; + cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); + } + else + { + cur_detail = llclamp((S32) (sqrtf(radius)*lod_factor*4.f), 0, 3); + } + return cur_detail; } std::string get_debug_object_lod_text(LLVOVolume *rootp) @@ -1395,28 +1395,28 @@ std::string get_debug_object_lod_text(LLVOVolume *rootp) BOOL LLVOVolume::calcLOD() { - if (mDrawable.isNull()) - { - return FALSE; - } + if (mDrawable.isNull()) + { + return FALSE; + } - S32 cur_detail = 0; - - F32 radius; - F32 distance; - F32 lod_factor = LLVOVolume::sLODFactor; + S32 cur_detail = 0; - if (mDrawable->isState(LLDrawable::RIGGED)) - { - LLVOAvatar* avatar = getAvatar(); - - // Not sure how this can really happen, but alas it does. Better exit here than crashing. - if( !avatar || !avatar->mDrawable ) - { - return FALSE; - } + F32 radius; + F32 distance; + F32 lod_factor = LLVOVolume::sLODFactor; - distance = avatar->mDrawable->mDistanceWRTCamera; + if (mDrawable->isState(LLDrawable::RIGGED)) + { + LLVOAvatar* avatar = getAvatar(); + + // Not sure how this can really happen, but alas it does. Better exit here than crashing. + if( !avatar || !avatar->mDrawable ) + { + return FALSE; + } + + distance = avatar->mDrawable->mDistanceWRTCamera; if (avatar->isControlAvatar()) @@ -1443,20 +1443,20 @@ BOOL LLVOVolume::calcLOD() LL_DEBUGS("DynamicBox","CalcLOD") << "avatar distance/radius uninitialized, skipping" << LL_ENDL; return FALSE; } - } - else - { - distance = mDrawable->mDistanceWRTCamera; - radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length(); + } + else + { + distance = mDrawable->mDistanceWRTCamera; + radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length(); if (distance <= 0.f || radius <= 0.f) { LL_DEBUGS("DynamicBox","CalcLOD") << "non-avatar distance/radius uninitialized, skipping" << LL_ENDL; return FALSE; } - } - - //hold onto unmodified distance for debugging - //F32 debug_distance = distance; + } + + //hold onto unmodified distance for debugging + //F32 debug_distance = distance; mLODDistance = distance; mLODRadius = radius; @@ -1482,24 +1482,24 @@ BOOL LLVOVolume::calcLOD() distance *= sDistanceFactor; - F32 rampDist = LLVOVolume::sLODFactor * 2; - - if (distance < rampDist) - { - // Boost LOD when you're REALLY close - distance *= 1.0f/rampDist; - distance *= distance; - distance *= rampDist; - } - - - distance *= F_PI/3.f; - - static LLCachedControl<bool> ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs"); - if(!ignore_fov_zoom) - { - lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV(); - } + F32 rampDist = LLVOVolume::sLODFactor * 2; + + if (distance < rampDist) + { + // Boost LOD when you're REALLY close + distance *= 1.0f/rampDist; + distance *= distance; + distance *= rampDist; + } + + + distance *= F_PI/3.f; + + static LLCachedControl<bool> ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs"); + if(!ignore_fov_zoom) + { + lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV(); + } mLODAdjustedDistance = distance; @@ -1522,189 +1522,189 @@ BOOL LLVOVolume::calcLOD() setDebugText(llformat("TRIS SHOWN %d EST %d", total_tris, est_max_tris)); } } - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) && - mDrawable->getFace(0)) - { + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) && + mDrawable->getFace(0)) + { // This is a debug display for LODs. Please don't put the texture index here. setDebugText(llformat("%d", cur_detail)); - } + } - if (cur_detail != mLOD) - { - LL_DEBUGS("DynamicBox","CalcLOD") << "new LOD " << cur_detail << " change from " << mLOD + if (cur_detail != mLOD) + { + LL_DEBUGS("DynamicBox","CalcLOD") << "new LOD " << cur_detail << " change from " << mLOD << " distance " << distance << " radius " << radius << " rampDist " << rampDist << " drawable rigged? " << (mDrawable ? (S32) mDrawable->isState(LLDrawable::RIGGED) : (S32) -1) - << " mRiggedVolume " << (void*)getRiggedVolume() + << " mRiggedVolume " << (void*)getRiggedVolume() << " distanceWRTCamera " << (mDrawable ? mDrawable->mDistanceWRTCamera : -1.f) << LL_ENDL; - - mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); - mLOD = cur_detail; + + mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); + mLOD = cur_detail; return TRUE; - } + } - return FALSE; + return FALSE; } BOOL LLVOVolume::updateLOD() { - if (mDrawable.isNull()) - { - return FALSE; - } + if (mDrawable.isNull()) + { + return FALSE; + } LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - BOOL lod_changed = FALSE; - - if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID())) - { - lod_changed = calcLOD(); - } - else - { - return FALSE; - } - - if (lod_changed) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - mLODChanged = TRUE; - } - else - { - F32 new_radius = getBinRadius(); - F32 old_radius = mDrawable->getBinRadius(); - if (new_radius < old_radius * 0.9f || new_radius > old_radius*1.1f) - { - gPipeline.markPartitionMove(mDrawable); - } - } - - lod_changed = lod_changed || LLViewerObject::updateLOD(); - - return lod_changed; + BOOL lod_changed = FALSE; + + if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID())) + { + lod_changed = calcLOD(); + } + else + { + return FALSE; + } + + if (lod_changed) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + mLODChanged = TRUE; + } + else + { + F32 new_radius = getBinRadius(); + F32 old_radius = mDrawable->getBinRadius(); + if (new_radius < old_radius * 0.9f || new_radius > old_radius*1.1f) + { + gPipeline.markPartitionMove(mDrawable); + } + } + + lod_changed = lod_changed || LLViewerObject::updateLOD(); + + return lod_changed; } BOOL LLVOVolume::setDrawableParent(LLDrawable* parentp) { - if (!LLViewerObject::setDrawableParent(parentp)) - { - // no change in drawable parent - return FALSE; - } - - if (!mDrawable->isRoot()) - { - // rebuild vertices in parent relative space - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - - if (mDrawable->isActive() && !parentp->isActive()) - { - parentp->makeActive(); - } - else if (mDrawable->isStatic() && parentp->isActive()) - { - mDrawable->makeActive(); - } - } - - return TRUE; + if (!LLViewerObject::setDrawableParent(parentp)) + { + // no change in drawable parent + return FALSE; + } + + if (!mDrawable->isRoot()) + { + // rebuild vertices in parent relative space + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + + if (mDrawable->isActive() && !parentp->isActive()) + { + parentp->makeActive(); + } + else if (mDrawable->isStatic() && parentp->isActive()) + { + mDrawable->makeActive(); + } + } + + return TRUE; } void LLVOVolume::updateFaceFlags() { - // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() - for (S32 i = 0; i < getVolume()->getNumFaces() && i < mDrawable->getNumFaces(); i++) - { - LLFace *face = mDrawable->getFace(i); - if (face) - { - BOOL fullbright = getTE(i)->getFullbright(); - face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); - - if (fullbright || (mMaterial == LL_MCODE_LIGHT)) - { - face->setState(LLFace::FULLBRIGHT); - } - if (mDrawable->isLight()) - { - face->setState(LLFace::LIGHT); - } - if (isHUDAttachment()) - { - face->setState(LLFace::HUD_RENDER); - } - } - } + // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() + for (S32 i = 0; i < getVolume()->getNumFaces() && i < mDrawable->getNumFaces(); i++) + { + LLFace *face = mDrawable->getFace(i); + if (face) + { + BOOL fullbright = getTE(i)->getFullbright(); + face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); + + if (fullbright || (mMaterial == LL_MCODE_LIGHT)) + { + face->setState(LLFace::FULLBRIGHT); + } + if (mDrawable->isLight()) + { + face->setState(LLFace::LIGHT); + } + if (isHUDAttachment()) + { + face->setState(LLFace::HUD_RENDER); + } + } + } } BOOL LLVOVolume::setParent(LLViewerObject* parent) { - BOOL ret = FALSE ; + BOOL ret = FALSE ; LLViewerObject *old_parent = (LLViewerObject*) getParent(); - if (parent != old_parent) - { - ret = LLViewerObject::setParent(parent); - if (ret && mDrawable) - { - gPipeline.markMoved(mDrawable); - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - } + if (parent != old_parent) + { + ret = LLViewerObject::setParent(parent); + if (ret && mDrawable) + { + gPipeline.markMoved(mDrawable); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + } onReparent(old_parent, parent); - } + } - return ret ; + return ret ; } // NOTE: regenFaces() MUST be followed by genTriangles()! void LLVOVolume::regenFaces() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - // remove existing faces - BOOL count_changed = mNumFaces != getNumTEs(); - - if (count_changed) - { - deleteFaces(); - // add new faces - mNumFaces = getNumTEs(); - } - - for (S32 i = 0; i < mNumFaces; i++) - { - LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i); - if (!facep) continue; - - facep->setTEOffset(i); - facep->setTexture(getTEImage(i)); - if (facep->getTextureEntry()->getMaterialParams().notNull()) - { - facep->setNormalMap(getTENormalMap(i)); - facep->setSpecularMap(getTESpecularMap(i)); - } - facep->setViewerObject(this); - - // If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face. - // Re-establish the link. - if((int)mMediaImplList.size() > i) - { - if(mMediaImplList[i]) - { - LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[i]->getMediaTextureID()) ; - if(media_tex) - { - media_tex->addMediaToFace(facep) ; - } - } - } - } - - if (!count_changed) - { - updateFaceFlags(); - } + // remove existing faces + BOOL count_changed = mNumFaces != getNumTEs(); + + if (count_changed) + { + deleteFaces(); + // add new faces + mNumFaces = getNumTEs(); + } + + for (S32 i = 0; i < mNumFaces; i++) + { + LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i); + if (!facep) continue; + + facep->setTEOffset(i); + facep->setTexture(getTEImage(i)); + if (facep->getTextureEntry()->getMaterialParams().notNull()) + { + facep->setNormalMap(getTENormalMap(i)); + facep->setSpecularMap(getTESpecularMap(i)); + } + facep->setViewerObject(this); + + // If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face. + // Re-establish the link. + if((int)mMediaImplList.size() > i) + { + if(mMediaImplList[i]) + { + LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[i]->getMediaTextureID()) ; + if(media_tex) + { + media_tex->addMediaToFace(facep) ; + } + } + } + } + + if (!count_changed) + { + updateFaceFlags(); + } } BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds) @@ -1822,7 +1822,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds) mDrawable->setPositionGroup(min); } } - + updateRadius(); mDrawable->movePartition(); } @@ -1836,581 +1836,581 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds) void LLVOVolume::preRebuild() { - if (mVolumeImpl != NULL) - { - mVolumeImpl->preRebuild(); - } + if (mVolumeImpl != NULL) + { + mVolumeImpl->preRebuild(); + } } void LLVOVolume::updateRelativeXform(bool force_identity) { - if (mVolumeImpl) - { - mVolumeImpl->updateRelativeXform(force_identity); - return; - } - - LLDrawable* drawable = mDrawable; - - if (drawable->isState(LLDrawable::RIGGED) && mRiggedVolume.notNull()) - { //rigged volume (which is in agent space) is used for generating bounding boxes etc - //inverse of render matrix should go to partition space - mRelativeXform = getRenderMatrix(); - - F32* dst = (F32*) mRelativeXformInvTrans.mMatrix; - F32* src = (F32*) mRelativeXform.mMatrix; - dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; - dst[3] = src[4]; dst[4] = src[5]; dst[5] = src[6]; - dst[6] = src[8]; dst[7] = src[9]; dst[8] = src[10]; - - mRelativeXform.invert(); - mRelativeXformInvTrans.transpose(); - } - else if (drawable->isActive() || force_identity) - { - // setup relative transforms - LLQuaternion delta_rot; - LLVector3 delta_pos, delta_scale; - - //matrix from local space to parent relative/global space - bool use_identity = force_identity || drawable->isSpatialRoot(); - delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation(); - delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition(); - delta_scale = mDrawable->getScale(); - - // Vertex transform (4x4) - LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot; - LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot; - LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot; - - mRelativeXform.initRows(LLVector4(x_axis, 0.f), - LLVector4(y_axis, 0.f), - LLVector4(z_axis, 0.f), - LLVector4(delta_pos, 1.f)); - - - // compute inverse transpose for normals - // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); - // mRelativeXformInvTrans.invert(); - // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); - // grumble - invert is NOT a matrix invert, so we do it by hand: - - LLMatrix3 rot_inverse = LLMatrix3(~delta_rot); - - LLMatrix3 scale_inverse; - scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / delta_scale.mV[VX], - LLVector3(0.0, 1.0, 0.0) / delta_scale.mV[VY], - LLVector3(0.0, 0.0, 1.0) / delta_scale.mV[VZ]); - - - mRelativeXformInvTrans = rot_inverse * scale_inverse; - - mRelativeXformInvTrans.transpose(); - } - else - { - LLVector3 pos = getPosition(); - LLVector3 scale = getScale(); - LLQuaternion rot = getRotation(); - - if (mParent) - { - pos *= mParent->getRotation(); - pos += mParent->getPosition(); - rot *= mParent->getRotation(); - } - - //LLViewerRegion* region = getRegion(); - //pos += region->getOriginAgent(); - - LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot; - LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot; - LLVector3 z_axis = LLVector3(0.f, 0.f, scale.mV[VZ]) * rot; - - mRelativeXform.initRows(LLVector4(x_axis, 0.f), - LLVector4(y_axis, 0.f), - LLVector4(z_axis, 0.f), - LLVector4(pos, 1.f)); - - // compute inverse transpose for normals - LLMatrix3 rot_inverse = LLMatrix3(~rot); - - LLMatrix3 scale_inverse; - scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / scale.mV[VX], - LLVector3(0.0, 1.0, 0.0) / scale.mV[VY], - LLVector3(0.0, 0.0, 1.0) / scale.mV[VZ]); - - - mRelativeXformInvTrans = rot_inverse * scale_inverse; - - mRelativeXformInvTrans.transpose(); - } + if (mVolumeImpl) + { + mVolumeImpl->updateRelativeXform(force_identity); + return; + } + + LLDrawable* drawable = mDrawable; + + if (drawable->isState(LLDrawable::RIGGED) && mRiggedVolume.notNull()) + { //rigged volume (which is in agent space) is used for generating bounding boxes etc + //inverse of render matrix should go to partition space + mRelativeXform = getRenderMatrix(); + + F32* dst = (F32*) mRelativeXformInvTrans.mMatrix; + F32* src = (F32*) mRelativeXform.mMatrix; + dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; + dst[3] = src[4]; dst[4] = src[5]; dst[5] = src[6]; + dst[6] = src[8]; dst[7] = src[9]; dst[8] = src[10]; + + mRelativeXform.invert(); + mRelativeXformInvTrans.transpose(); + } + else if (drawable->isActive() || force_identity) + { + // setup relative transforms + LLQuaternion delta_rot; + LLVector3 delta_pos, delta_scale; + + //matrix from local space to parent relative/global space + bool use_identity = force_identity || drawable->isSpatialRoot(); + delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation(); + delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition(); + delta_scale = mDrawable->getScale(); + + // Vertex transform (4x4) + LLVector3 x_axis = LLVector3(delta_scale.mV[VX], 0.f, 0.f) * delta_rot; + LLVector3 y_axis = LLVector3(0.f, delta_scale.mV[VY], 0.f) * delta_rot; + LLVector3 z_axis = LLVector3(0.f, 0.f, delta_scale.mV[VZ]) * delta_rot; + + mRelativeXform.initRows(LLVector4(x_axis, 0.f), + LLVector4(y_axis, 0.f), + LLVector4(z_axis, 0.f), + LLVector4(delta_pos, 1.f)); + + + // compute inverse transpose for normals + // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); + // mRelativeXformInvTrans.invert(); + // mRelativeXformInvTrans.setRows(x_axis, y_axis, z_axis); + // grumble - invert is NOT a matrix invert, so we do it by hand: + + LLMatrix3 rot_inverse = LLMatrix3(~delta_rot); + + LLMatrix3 scale_inverse; + scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / delta_scale.mV[VX], + LLVector3(0.0, 1.0, 0.0) / delta_scale.mV[VY], + LLVector3(0.0, 0.0, 1.0) / delta_scale.mV[VZ]); + + + mRelativeXformInvTrans = rot_inverse * scale_inverse; + + mRelativeXformInvTrans.transpose(); + } + else + { + LLVector3 pos = getPosition(); + LLVector3 scale = getScale(); + LLQuaternion rot = getRotation(); + + if (mParent) + { + pos *= mParent->getRotation(); + pos += mParent->getPosition(); + rot *= mParent->getRotation(); + } + + //LLViewerRegion* region = getRegion(); + //pos += region->getOriginAgent(); + + LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot; + LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot; + LLVector3 z_axis = LLVector3(0.f, 0.f, scale.mV[VZ]) * rot; + + mRelativeXform.initRows(LLVector4(x_axis, 0.f), + LLVector4(y_axis, 0.f), + LLVector4(z_axis, 0.f), + LLVector4(pos, 1.f)); + + // compute inverse transpose for normals + LLMatrix3 rot_inverse = LLMatrix3(~rot); + + LLMatrix3 scale_inverse; + scale_inverse.setRows(LLVector3(1.0, 0.0, 0.0) / scale.mV[VX], + LLVector3(0.0, 1.0, 0.0) / scale.mV[VY], + LLVector3(0.0, 0.0, 1.0) / scale.mV[VZ]); + + + mRelativeXformInvTrans = rot_inverse * scale_inverse; + + mRelativeXformInvTrans.transpose(); + } } bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &should_update_octree_bounds) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - bool regen_faces = false; + bool regen_faces = false; - LLVolume *old_volumep, *new_volumep; - F32 old_lod, new_lod; - S32 old_num_faces, new_num_faces; + LLVolume *old_volumep, *new_volumep; + F32 old_lod, new_lod; + S32 old_num_faces, new_num_faces; - old_volumep = getVolume(); - old_lod = old_volumep->getDetail(); - old_num_faces = old_volumep->getNumFaces(); - old_volumep = NULL; + old_volumep = getVolume(); + old_lod = old_volumep->getDetail(); + old_num_faces = old_volumep->getNumFaces(); + old_volumep = NULL; - { - const LLVolumeParams &volume_params = getVolume()->getParams(); - setVolume(volume_params, 0); - } + { + const LLVolumeParams &volume_params = getVolume()->getParams(); + setVolume(volume_params, 0); + } - new_volumep = getVolume(); - new_lod = new_volumep->getDetail(); - new_num_faces = new_volumep->getNumFaces(); - new_volumep = NULL; + new_volumep = getVolume(); + new_lod = new_volumep->getDetail(); + new_num_faces = new_volumep->getNumFaces(); + new_volumep = NULL; - if ((new_lod != old_lod) || mSculptChanged) - { + if ((new_lod != old_lod) || mSculptChanged) + { if (mDrawable->isState(LLDrawable::RIGGED)) { updateVisualComplexity(); } - compiled = TRUE; + compiled = TRUE; // new_lod > old_lod breaks a feedback loop between LOD updates and // bounding box updates. should_update_octree_bounds = should_update_octree_bounds || mSculptChanged || new_lod > old_lod; - sNumLODChanges += new_num_faces; - - if ((S32)getNumTEs() != getVolume()->getNumFaces()) - { - setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces. - } - - drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() - - { - regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs(); - if (regen_faces) - { - regenFaces(); - } - - if (mSculptChanged) - { //changes in sculpt maps can thrash an object bounding box without - //triggering a spatial group bounding box update -- force spatial group - //to update bounding boxes - LLSpatialGroup* group = mDrawable->getSpatialGroup(); - if (group) - { - group->unbound(); - } - } - } - } - - return regen_faces; + sNumLODChanges += new_num_faces; + + if ((S32)getNumTEs() != getVolume()->getNumFaces()) + { + setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces. + } + + drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() + + { + regen_faces = new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs(); + if (regen_faces) + { + regenFaces(); + } + + if (mSculptChanged) + { //changes in sculpt maps can thrash an object bounding box without + //triggering a spatial group bounding box update -- force spatial group + //to update bounding boxes + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->unbound(); + } + } + } + } + + return regen_faces; } BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - - if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) - { + + if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) + { updateRiggedVolume(false); - genBBoxes(FALSE); - mDrawable->clearState(LLDrawable::REBUILD_RIGGED); - } - - if (mVolumeImpl != NULL) - { - BOOL res; - { - res = mVolumeImpl->doUpdateGeometry(drawable); - } - updateFaceFlags(); - return res; - } - - LLSpatialGroup* group = drawable->getSpatialGroup(); - if (group) - { + genBBoxes(FALSE); + mDrawable->clearState(LLDrawable::REBUILD_RIGGED); + } + + if (mVolumeImpl != NULL) + { + BOOL res; + { + res = mVolumeImpl->doUpdateGeometry(drawable); + } + updateFaceFlags(); + return res; + } + + LLSpatialGroup* group = drawable->getSpatialGroup(); + if (group) + { group->dirtyMesh(); - } + } - updateRelativeXform(); - - if (mDrawable.isNull()) // Not sure why this is happening, but it is... - { - return TRUE; // No update to complete - } + updateRelativeXform(); - BOOL compiled = FALSE; + if (mDrawable.isNull()) // Not sure why this is happening, but it is... + { + return TRUE; // No update to complete + } + + BOOL compiled = FALSE; // This should be true in most cases, unless we're sure no octree update is // needed. BOOL should_update_octree_bounds = bool(getRiggedVolume()) || mDrawable->isState(LLDrawable::REBUILD_POSITION) || !mDrawable->getSpatialExtents()->isFinite3(); - if (mVolumeChanged || mFaceMappingChanged) - { - dirtySpatialGroup(); + if (mVolumeChanged || mFaceMappingChanged) + { + dirtySpatialGroup(); - bool was_regen_faces = false; + bool was_regen_faces = false; should_update_octree_bounds = true; - if (mVolumeChanged) - { + if (mVolumeChanged) + { was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); - drawable->setState(LLDrawable::REBUILD_VOLUME); - } - else if (mSculptChanged || mLODChanged || mColorChanged) - { - compiled = TRUE; + drawable->setState(LLDrawable::REBUILD_VOLUME); + } + else if (mSculptChanged || mLODChanged || mColorChanged) + { + compiled = TRUE; was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); - } - - if (!was_regen_faces) { - regenFaces(); - } - } - else if (mLODChanged || mSculptChanged || mColorChanged) - { - dirtySpatialGroup(); - compiled = TRUE; + } + + if (!was_regen_faces) { + regenFaces(); + } + } + else if (mLODChanged || mSculptChanged || mColorChanged) + { + dirtySpatialGroup(); + compiled = TRUE; lodOrSculptChanged(drawable, compiled, should_update_octree_bounds); - - if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED)) - { - updateRiggedVolume(false); - } - } - // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local - else - { - compiled = TRUE; - // All it did was move or we changed the texture coordinate offset - } + + if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED)) + { + updateRiggedVolume(false); + } + } + // it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local + else + { + compiled = TRUE; + // All it did was move or we changed the texture coordinate offset + } // Generate bounding boxes if needed, and update the object's size in the // octree genBBoxes(FALSE, should_update_octree_bounds); - // Update face flags - updateFaceFlags(); - - if(compiled) - { - LLPipeline::sCompiles++; - } - - mVolumeChanged = FALSE; - mLODChanged = FALSE; - mSculptChanged = FALSE; - mFaceMappingChanged = FALSE; + // Update face flags + updateFaceFlags(); + + if(compiled) + { + LLPipeline::sCompiles++; + } + + mVolumeChanged = FALSE; + mLODChanged = FALSE; + mSculptChanged = FALSE; + mFaceMappingChanged = FALSE; mColorChanged = FALSE; - - return LLViewerObject::updateGeometry(drawable); + + return LLViewerObject::updateGeometry(drawable); } void LLVOVolume::updateFaceSize(S32 idx) { - if( mDrawable->getNumFaces() <= idx ) - { - return; - } - - LLFace* facep = mDrawable->getFace(idx); - if (facep) - { - if (idx >= getVolume()->getNumVolumeFaces()) - { - facep->setSize(0,0, true); - } - else - { - const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); - facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, - true); // <--- volume faces should be padded for 16-byte alignment - - } - } + if( mDrawable->getNumFaces() <= idx ) + { + return; + } + + LLFace* facep = mDrawable->getFace(idx); + if (facep) + { + if (idx >= getVolume()->getNumVolumeFaces()) + { + facep->setSize(0,0, true); + } + else + { + const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); + facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, + true); // <--- volume faces should be padded for 16-byte alignment + + } + } } BOOL LLVOVolume::isRootEdit() const { - if (mParent && !((LLViewerObject*)mParent)->isAvatar()) - { - return FALSE; - } - return TRUE; + if (mParent && !((LLViewerObject*)mParent)->isAvatar()) + { + return FALSE; + } + return TRUE; } //virtual void LLVOVolume::setNumTEs(const U8 num_tes) { - const U8 old_num_tes = getNumTEs() ; - - if(old_num_tes && old_num_tes < num_tes) //new faces added - { - LLViewerObject::setNumTEs(num_tes) ; - - if(mMediaImplList.size() >= old_num_tes && mMediaImplList[old_num_tes -1].notNull())//duplicate the last media textures if exists. - { - mMediaImplList.resize(num_tes) ; - const LLTextureEntry* te = getTE(old_num_tes - 1) ; - for(U8 i = old_num_tes; i < num_tes ; i++) - { - setTE(i, *te) ; - mMediaImplList[i] = mMediaImplList[old_num_tes -1] ; - } - mMediaImplList[old_num_tes -1]->setUpdated(TRUE) ; - } - } - else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed - { - U8 end = (U8)(mMediaImplList.size()) ; - for(U8 i = num_tes; i < end ; i++) - { - removeMediaImpl(i) ; - } - mMediaImplList.resize(num_tes) ; - - LLViewerObject::setNumTEs(num_tes) ; - } - else - { - LLViewerObject::setNumTEs(num_tes) ; - } - - return ; + const U8 old_num_tes = getNumTEs() ; + + if(old_num_tes && old_num_tes < num_tes) //new faces added + { + LLViewerObject::setNumTEs(num_tes) ; + + if(mMediaImplList.size() >= old_num_tes && mMediaImplList[old_num_tes -1].notNull())//duplicate the last media textures if exists. + { + mMediaImplList.resize(num_tes) ; + const LLTextureEntry* te = getTE(old_num_tes - 1) ; + for(U8 i = old_num_tes; i < num_tes ; i++) + { + setTE(i, *te) ; + mMediaImplList[i] = mMediaImplList[old_num_tes -1] ; + } + mMediaImplList[old_num_tes -1]->setUpdated(TRUE) ; + } + } + else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed + { + U8 end = (U8)(mMediaImplList.size()) ; + for(U8 i = num_tes; i < end ; i++) + { + removeMediaImpl(i) ; + } + mMediaImplList.resize(num_tes) ; + + LLViewerObject::setNumTEs(num_tes) ; + } + else + { + LLViewerObject::setNumTEs(num_tes) ; + } + + return ; } //virtual void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep) { - BOOL changed = (mTEImages[index] != imagep); - LLViewerObject::changeTEImage(index, imagep); - if (changed) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } + BOOL changed = (mTEImages[index] != imagep); + LLViewerObject::changeTEImage(index, imagep); + if (changed) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } } void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep) { - BOOL changed = (mTEImages[te] != imagep); - LLViewerObject::setTEImage(te, imagep); - if (changed) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } + BOOL changed = (mTEImages[te] != imagep); + LLViewerObject::setTEImage(te, imagep); + if (changed) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } } S32 LLVOVolume::setTETexture(const U8 te, const LLUUID &uuid) { - S32 res = LLViewerObject::setTETexture(te, uuid); - if (res) - { + S32 res = LLViewerObject::setTETexture(te, uuid); + if (res) + { if (mDrawable) { // dynamic texture changes break batches, isolate in octree shrinkWrap(); gPipeline.markTextured(mDrawable); } - mFaceMappingChanged = TRUE; - } - return res; + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEColor(const U8 te, const LLColor3& color) { - return setTEColor(te, LLColor4(color)); + return setTEColor(te, LLColor4(color)); } S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) - { - LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; - } - else if (color != tep->getColor()) - { - F32 old_alpha = tep->getColor().mV[3]; - if (color.mV[3] != old_alpha) - { - gPipeline.markTextured(mDrawable); - //treat this alpha change as an LoD update since render batches may need to get rebuilt - mLODChanged = TRUE; - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); - } - retval = LLPrimitive::setTEColor(te, color); - if (mDrawable.notNull() && retval) - { - // These should only happen on updates which are not the initial update. + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + } + else if (color != tep->getColor()) + { + F32 old_alpha = tep->getColor().mV[3]; + if (color.mV[3] != old_alpha) + { + gPipeline.markTextured(mDrawable); + //treat this alpha change as an LoD update since render batches may need to get rebuilt + mLODChanged = TRUE; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME); + } + retval = LLPrimitive::setTEColor(te, color); + if (mDrawable.notNull() && retval) + { + // These should only happen on updates which are not the initial update. mColorChanged = TRUE; - mDrawable->setState(LLDrawable::REBUILD_COLOR); + mDrawable->setState(LLDrawable::REBUILD_COLOR); shrinkWrap(); - dirtyMesh(); - } - } + dirtyMesh(); + } + } - return retval; + return retval; } S32 LLVOVolume::setTEBumpmap(const U8 te, const U8 bumpmap) { - S32 res = LLViewerObject::setTEBumpmap(te, bumpmap); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEBumpmap(te, bumpmap); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTETexGen(const U8 te, const U8 texgen) { - S32 res = LLViewerObject::setTETexGen(te, texgen); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTETexGen(te, texgen); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEMediaTexGen(const U8 te, const U8 media) { - S32 res = LLViewerObject::setTEMediaTexGen(te, media); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEMediaTexGen(te, media); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEShiny(const U8 te, const U8 shiny) { - S32 res = LLViewerObject::setTEShiny(te, shiny); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEShiny(te, shiny); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEFullbright(const U8 te, const U8 fullbright) { - S32 res = LLViewerObject::setTEFullbright(te, fullbright); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEFullbright(te, fullbright); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEBumpShinyFullbright(const U8 te, const U8 bump) { - S32 res = LLViewerObject::setTEBumpShinyFullbright(te, bump); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEBumpShinyFullbright(te, bump); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags) { - S32 res = LLViewerObject::setTEMediaFlags(te, media_flags); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEMediaFlags(te, media_flags); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow) { - S32 res = LLViewerObject::setTEGlow(te, glow); - if (res) - { + S32 res = LLViewerObject::setTEGlow(te, glow); + if (res) + { if (mDrawable) { gPipeline.markTextured(mDrawable); shrinkWrap(); } - mFaceMappingChanged = TRUE; - } - return res; + mFaceMappingChanged = TRUE; + } + return res; } void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams, U32 te) { - LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID); - if (pVol) - { - LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL; - if (te >= pVol->getNumTEs()) - return; + LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID); + if (pVol) + { + LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL; + if (te >= pVol->getNumTEs()) + return; - LLTextureEntry* texture_entry = pVol->getTE(te); - if (texture_entry && (texture_entry->getMaterialID() == pMaterialID)) - { - pVol->setTEMaterialParams(te, pMaterialParams); - } - } + LLTextureEntry* texture_entry = pVol->getTE(te); + if (texture_entry && (texture_entry->getMaterialID() == pMaterialID)) + { + pVol->setTEMaterialParams(te, pMaterialParams); + } + } } S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) { - S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID); - LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res - << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) - << LL_ENDL; - - LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL; - if (res) - { - LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3)); - - setChanged(ALL_CHANGED); - if (!mDrawable.isNull()) - { - gPipeline.markTextured(mDrawable); - gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); - } - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID); + LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res + << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) + << LL_ENDL; + + LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL; + if (res) + { + LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3)); + + setChanged(ALL_CHANGED); + if (!mDrawable.isNull()) + { + gPipeline.markTextured(mDrawable); + gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); + } + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) { - S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); + S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); - LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res - << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) - << LL_ENDL; - setChanged(ALL_CHANGED); - if (!mDrawable.isNull()) - { - gPipeline.markTextured(mDrawable); - gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); - } - mFaceMappingChanged = TRUE; - return TEM_CHANGE_TEXTURE; + LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res + << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" ) + << LL_ENDL; + setChanged(ALL_CHANGED); + if (!mDrawable.isNull()) + { + gPipeline.markTextured(mDrawable); + gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL); + } + mFaceMappingChanged = TRUE; + return TEM_CHANGE_TEXTURE; } S32 LLVOVolume::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) @@ -2433,230 +2433,230 @@ S32 LLVOVolume::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t) { - S32 res = LLViewerObject::setTEScale(te, s, t); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEScale(te, s, t); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEScaleS(const U8 te, const F32 s) { - S32 res = LLViewerObject::setTEScaleS(te, s); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEScaleS(te, s); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } S32 LLVOVolume::setTEScaleT(const U8 te, const F32 t) { - S32 res = LLViewerObject::setTEScaleT(te, t); - if (res) - { - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - return res; + S32 res = LLViewerObject::setTEScaleT(te, t); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; } bool LLVOVolume::hasMedia() const { - bool result = false; - const U8 numTEs = getNumTEs(); - for (U8 i = 0; i < numTEs; i++) - { - const LLTextureEntry* te = getTE(i); - if(te->hasMedia()) - { - result = true; - break; - } - } - return result; + bool result = false; + const U8 numTEs = getNumTEs(); + for (U8 i = 0; i < numTEs; i++) + { + const LLTextureEntry* te = getTE(i); + if(te->hasMedia()) + { + result = true; + break; + } + } + return result; } LLVector3 LLVOVolume::getApproximateFaceNormal(U8 face_id) { - LLVolume* volume = getVolume(); - LLVector4a result; - result.clear(); + LLVolume* volume = getVolume(); + LLVector4a result; + result.clear(); - LLVector3 ret; + LLVector3 ret; - if (volume && face_id < volume->getNumVolumeFaces()) - { - const LLVolumeFace& face = volume->getVolumeFace(face_id); - for (S32 i = 0; i < (S32)face.mNumVertices; ++i) - { - result.add(face.mNormals[i]); - } + if (volume && face_id < volume->getNumVolumeFaces()) + { + const LLVolumeFace& face = volume->getVolumeFace(face_id); + for (S32 i = 0; i < (S32)face.mNumVertices; ++i) + { + result.add(face.mNormals[i]); + } + + LLVector3 ret(result.getF32ptr()); + ret = volumeDirectionToAgent(ret); + ret.normVec(); + } - LLVector3 ret(result.getF32ptr()); - ret = volumeDirectionToAgent(ret); - ret.normVec(); - } - - return ret; + return ret; } void LLVOVolume::requestMediaDataUpdate(bool isNew) { if (sObjectMediaClient) - sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this, isNew)); + sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this, isNew)); } bool LLVOVolume::isMediaDataBeingFetched() const { - // I know what I'm doing by const_casting this away: this is just - // a wrapper class that is only going to do a lookup. - return (sObjectMediaClient) ? sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false)) : false; + // I know what I'm doing by const_casting this away: this is just + // a wrapper class that is only going to do a lookup. + return (sObjectMediaClient) ? sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false)) : false; } void LLVOVolume::cleanUpMediaImpls() { - // Iterate through our TEs and remove any Impls that are no longer used - const U8 numTEs = getNumTEs(); - for (U8 i = 0; i < numTEs; i++) - { - const LLTextureEntry* te = getTE(i); - if( ! te->hasMedia()) - { - // Delete the media IMPL! - removeMediaImpl(i) ; - } - } + // Iterate through our TEs and remove any Impls that are no longer used + const U8 numTEs = getNumTEs(); + for (U8 i = 0; i < numTEs; i++) + { + const LLTextureEntry* te = getTE(i); + if( ! te->hasMedia()) + { + // Delete the media IMPL! + removeMediaImpl(i) ; + } + } } void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array, const std::string &media_version) { - // media_data_array is an array of media entry maps - // media_version is the version string in the response. - U32 fetched_version = LLTextureEntry::getVersionFromMediaVersionString(media_version); - - // Only update it if it is newer! - if ( (S32)fetched_version > mLastFetchedMediaVersion) - { - mLastFetchedMediaVersion = fetched_version; - //LL_INFOS() << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << LL_ENDL; - - LLSD::array_const_iterator iter = media_data_array.beginArray(); - LLSD::array_const_iterator end = media_data_array.endArray(); - U8 texture_index = 0; - for (; iter != end; ++iter, ++texture_index) - { - syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/); - } - } + // media_data_array is an array of media entry maps + // media_version is the version string in the response. + U32 fetched_version = LLTextureEntry::getVersionFromMediaVersionString(media_version); + + // Only update it if it is newer! + if ( (S32)fetched_version > mLastFetchedMediaVersion) + { + mLastFetchedMediaVersion = fetched_version; + //LL_INFOS() << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << LL_ENDL; + + LLSD::array_const_iterator iter = media_data_array.beginArray(); + LLSD::array_const_iterator end = media_data_array.endArray(); + U8 texture_index = 0; + for (; iter != end; ++iter, ++texture_index) + { + syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/); + } + } } void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool merge, bool ignore_agent) { - if(mDead) - { - // If the object has been marked dead, don't process media updates. - return; - } - - LLTextureEntry *te = getTE(texture_index); - if(!te) - { - return ; - } - - LL_DEBUGS("MediaOnAPrim") << "BEFORE: texture_index = " << texture_index - << " hasMedia = " << te->hasMedia() << " : " - << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL; - - std::string previous_url; - LLMediaEntry* mep = te->getMediaData(); - if(mep) - { - // Save the "current url" from before the update so we can tell if - // it changes. - previous_url = mep->getCurrentURL(); - } - - if (merge) - { - te->mergeIntoMediaData(media_data); - } - else { - // XXX Question: what if the media data is undefined LLSD, but the - // update we got above said that we have media flags?? Here we clobber - // that, assuming the data from the service is more up-to-date. - te->updateMediaData(media_data); - } - - mep = te->getMediaData(); - if(mep) - { - bool update_from_self = false; - if (!ignore_agent) - { - LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL()); - update_from_self = (updating_agent == gAgent.getID()); - } - viewer_media_t media_impl = LLViewerMedia::getInstance()->updateMediaImpl(mep, previous_url, update_from_self); - - addMediaImpl(media_impl, texture_index) ; - } - else - { - removeMediaImpl(texture_index); - } - - LL_DEBUGS("MediaOnAPrim") << "AFTER: texture_index = " << texture_index - << " hasMedia = " << te->hasMedia() << " : " - << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL; + if(mDead) + { + // If the object has been marked dead, don't process media updates. + return; + } + + LLTextureEntry *te = getTE(texture_index); + if(!te) + { + return ; + } + + LL_DEBUGS("MediaOnAPrim") << "BEFORE: texture_index = " << texture_index + << " hasMedia = " << te->hasMedia() << " : " + << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL; + + std::string previous_url; + LLMediaEntry* mep = te->getMediaData(); + if(mep) + { + // Save the "current url" from before the update so we can tell if + // it changes. + previous_url = mep->getCurrentURL(); + } + + if (merge) + { + te->mergeIntoMediaData(media_data); + } + else { + // XXX Question: what if the media data is undefined LLSD, but the + // update we got above said that we have media flags?? Here we clobber + // that, assuming the data from the service is more up-to-date. + te->updateMediaData(media_data); + } + + mep = te->getMediaData(); + if(mep) + { + bool update_from_self = false; + if (!ignore_agent) + { + LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL()); + update_from_self = (updating_agent == gAgent.getID()); + } + viewer_media_t media_impl = LLViewerMedia::getInstance()->updateMediaImpl(mep, previous_url, update_from_self); + + addMediaImpl(media_impl, texture_index) ; + } + else + { + removeMediaImpl(texture_index); + } + + LL_DEBUGS("MediaOnAPrim") << "AFTER: texture_index = " << texture_index + << " hasMedia = " << te->hasMedia() << " : " + << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << LL_ENDL; } void LLVOVolume::mediaNavigateBounceBack(U8 texture_index) { - // Find the media entry for this navigate - const LLMediaEntry* mep = NULL; - viewer_media_t impl = getMediaImpl(texture_index); - LLTextureEntry *te = getTE(texture_index); - if(te) - { - mep = te->getMediaData(); - } - - if (mep && impl) - { + // Find the media entry for this navigate + const LLMediaEntry* mep = NULL; + viewer_media_t impl = getMediaImpl(texture_index); + LLTextureEntry *te = getTE(texture_index); + if(te) + { + mep = te->getMediaData(); + } + + if (mep && impl) + { std::string url = mep->getCurrentURL(); - // Look for a ":", if not there, assume "http://" - if (!url.empty() && std::string::npos == url.find(':')) - { - url = "http://" + url; - } - // If the url we're trying to "bounce back" to is either empty or not - // allowed by the whitelist, try the home url. If *that* doesn't work, - // set the media as failed and unload it + // Look for a ":", if not there, assume "http://" + if (!url.empty() && std::string::npos == url.find(':')) + { + url = "http://" + url; + } + // If the url we're trying to "bounce back" to is either empty or not + // allowed by the whitelist, try the home url. If *that* doesn't work, + // set the media as failed and unload it if (url.empty() || !mep->checkCandidateUrl(url)) { url = mep->getHomeURL(); - // Look for a ":", if not there, assume "http://" - if (!url.empty() && std::string::npos == url.find(':')) - { - url = "http://" + url; - } + // Look for a ":", if not there, assume "http://" + if (!url.empty() && std::string::npos == url.find(':')) + { + url = "http://" + url; + } } if (url.empty() || !mep->checkCandidateUrl(url)) - { - // The url to navigate back to is not good, and we have nowhere else - // to go. - LL_WARNS("MediaOnAPrim") << "FAILED to bounce back URL \"" << url << "\" -- unloading impl" << LL_ENDL; - impl->setMediaFailed(true); - } - // Make sure we are not bouncing to url we came from - else if (impl->getCurrentMediaURL() != url) - { - // Okay, navigate now + { + // The url to navigate back to is not good, and we have nowhere else + // to go. + LL_WARNS("MediaOnAPrim") << "FAILED to bounce back URL \"" << url << "\" -- unloading impl" << LL_ENDL; + impl->setMediaFailed(true); + } + // Make sure we are not bouncing to url we came from + else if (impl->getCurrentMediaURL() != url) + { + // Okay, navigate now LL_INFOS("MediaOnAPrim") << "bouncing back to URL: " << url << LL_ENDL; impl->navigateTo(url, "", false, true); } @@ -2667,153 +2667,153 @@ bool LLVOVolume::hasMediaPermission(const LLMediaEntry* media_entry, MediaPermTy { // NOTE: This logic ALMOST duplicates the logic in the server (in particular, in llmediaservice.cpp). if (NULL == media_entry ) return false; // XXX should we assert here? - + // The agent has permissions if: // - world permissions are on, or // - group permissions are on, and agent_id is in the group, or // - agent permissions are on, and agent_id is the owner - - // *NOTE: We *used* to check for modify permissions here (i.e. permissions were - // granted if permModify() was true). However, this doesn't make sense in the - // viewer: we don't want to show controls or allow interaction if the author - // has deemed it so. See DEV-42115. - + + // *NOTE: We *used* to check for modify permissions here (i.e. permissions were + // granted if permModify() was true). However, this doesn't make sense in the + // viewer: we don't want to show controls or allow interaction if the author + // has deemed it so. See DEV-42115. + U8 media_perms = (perm_type == MEDIA_PERM_INTERACT) ? media_entry->getPermsInteract() : media_entry->getPermsControl(); - + // World permissions - if (0 != (media_perms & LLMediaEntry::PERM_ANYONE)) + if (0 != (media_perms & LLMediaEntry::PERM_ANYONE)) { return true; } - + // Group permissions else if (0 != (media_perms & LLMediaEntry::PERM_GROUP)) { - LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this); - if (obj_perm && gAgent.isInGroup(obj_perm->getGroup())) - { - return true; - } + LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(this); + if (obj_perm && gAgent.isInGroup(obj_perm->getGroup())) + { + return true; + } } - + // Owner permissions - else if (0 != (media_perms & LLMediaEntry::PERM_OWNER) && permYouOwner()) + else if (0 != (media_perms & LLMediaEntry::PERM_OWNER) && permYouOwner()) { return true; } - + return false; - + } void LLVOVolume::mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location) { - bool block_navigation = false; - // FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed - // to deal with multiple face indices. - int face_index = getFaceIndexWithMediaImpl(impl, -1); - - // Find the media entry for this navigate - LLMediaEntry* mep = NULL; - LLTextureEntry *te = getTE(face_index); - if(te) - { - mep = te->getMediaData(); - } - - if(mep) - { - if(!mep->checkCandidateUrl(new_location)) - { - block_navigation = true; - } - if (!block_navigation && !hasMediaPermission(mep, MEDIA_PERM_INTERACT)) - { - block_navigation = true; - } - } - else - { - LL_WARNS("MediaOnAPrim") << "Couldn't find media entry!" << LL_ENDL; - } - - if(block_navigation) - { - LL_INFOS("MediaOnAPrim") << "blocking navigate to URI " << new_location << LL_ENDL; - - // "bounce back" to the current URL from the media entry - mediaNavigateBounceBack(face_index); - } - else if (sObjectMediaNavigateClient) - { - - LL_DEBUGS("MediaOnAPrim") << "broadcasting navigate with URI " << new_location << LL_ENDL; - - sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this, false), face_index, new_location); - } + bool block_navigation = false; + // FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed + // to deal with multiple face indices. + int face_index = getFaceIndexWithMediaImpl(impl, -1); + + // Find the media entry for this navigate + LLMediaEntry* mep = NULL; + LLTextureEntry *te = getTE(face_index); + if(te) + { + mep = te->getMediaData(); + } + + if(mep) + { + if(!mep->checkCandidateUrl(new_location)) + { + block_navigation = true; + } + if (!block_navigation && !hasMediaPermission(mep, MEDIA_PERM_INTERACT)) + { + block_navigation = true; + } + } + else + { + LL_WARNS("MediaOnAPrim") << "Couldn't find media entry!" << LL_ENDL; + } + + if(block_navigation) + { + LL_INFOS("MediaOnAPrim") << "blocking navigate to URI " << new_location << LL_ENDL; + + // "bounce back" to the current URL from the media entry + mediaNavigateBounceBack(face_index); + } + else if (sObjectMediaNavigateClient) + { + + LL_DEBUGS("MediaOnAPrim") << "broadcasting navigate with URI " << new_location << LL_ENDL; + + sObjectMediaNavigateClient->navigate(new LLMediaDataClientObjectImpl(this, false), face_index, new_location); + } } void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event) { - switch(event) - { - - case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED: - { - switch(impl->getNavState()) - { - case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED: - { - // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back. - mediaNavigated(impl, plugin, plugin->getLocation()); - } - break; - - case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS: - // This navigate didn't change the current URL. - LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL; - break; - - case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED: - // This is the first location changed event after the start of a server-directed nav. Don't broadcast it. - LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL; - break; - - default: - // This is a subsequent location-changed due to a redirect. Don't broadcast. - LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (redirect)" << LL_ENDL; - break; - } - } - break; - - case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE: - { - switch(impl->getNavState()) - { - case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED: - { - // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back. - mediaNavigated(impl, plugin, plugin->getNavigateURI()); - } - break; - - case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS: - // This navigate didn't change the current URL. - LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL; - break; - - case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED: - // This is the the navigate complete event from a server-directed nav. Don't broadcast it. - LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL; - break; - - default: - // For all other states, the navigate should have been handled by LOCATION_CHANGED events already. - break; - } - } - break; + switch(event) + { + + case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED: + { + switch(impl->getNavState()) + { + case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED: + { + // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back. + mediaNavigated(impl, plugin, plugin->getLocation()); + } + break; + + case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS: + // This navigate didn't change the current URL. + LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL; + break; + + case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED: + // This is the first location changed event after the start of a server-directed nav. Don't broadcast it. + LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL; + break; + + default: + // This is a subsequent location-changed due to a redirect. Don't broadcast. + LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (redirect)" << LL_ENDL; + break; + } + } + break; + + case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE: + { + switch(impl->getNavState()) + { + case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED: + { + // This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast or bounced back. + mediaNavigated(impl, plugin, plugin->getNavigateURI()); + } + break; + + case LLViewerMediaImpl::MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS: + // This navigate didn't change the current URL. + LL_DEBUGS("MediaOnAPrim") << " NOT broadcasting navigate (spurious)" << LL_ENDL; + break; + + case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED: + // This is the the navigate complete event from a server-directed nav. Don't broadcast it. + LL_INFOS("MediaOnAPrim") << " NOT broadcasting navigate (server-directed)" << LL_ENDL; + break; + + default: + // For all other states, the navigate should have been handled by LOCATION_CHANGED events already. + break; + } + } + break; case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD: { @@ -2825,233 +2825,233 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLNotificationsUtil::add("MediaFileDownloadUnsupported"); } break; - - default: - break; - } + + default: + break; + } } void LLVOVolume::sendMediaDataUpdate() { if (sObjectMediaClient) - sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this, false)); + sObjectMediaClient->updateMedia(new LLMediaDataClientObjectImpl(this, false)); } void LLVOVolume::removeMediaImpl(S32 texture_index) { - if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull()) - { - return ; - } - - //make the face referencing to mMediaImplList[texture_index] to point back to the old texture. - if(mDrawable && texture_index < mDrawable->getNumFaces()) - { - LLFace* facep = mDrawable->getFace(texture_index) ; - if(facep) - { - LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; - if(media_tex) - { - media_tex->removeMediaFromFace(facep) ; - } - } - } - - //check if some other face(s) of this object reference(s)to this media impl. - S32 i ; - S32 end = (S32)mMediaImplList.size() ; - for(i = 0; i < end ; i++) - { - if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index]) - { - break ; - } - } - - if(i == end) //this object does not need this media impl. - { - mMediaImplList[texture_index]->removeObject(this) ; - } - - mMediaImplList[texture_index] = NULL ; - return ; + if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull()) + { + return ; + } + + //make the face referencing to mMediaImplList[texture_index] to point back to the old texture. + if(mDrawable && texture_index < mDrawable->getNumFaces()) + { + LLFace* facep = mDrawable->getFace(texture_index) ; + if(facep) + { + LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; + if(media_tex) + { + media_tex->removeMediaFromFace(facep) ; + } + } + } + + //check if some other face(s) of this object reference(s)to this media impl. + S32 i ; + S32 end = (S32)mMediaImplList.size() ; + for(i = 0; i < end ; i++) + { + if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index]) + { + break ; + } + } + + if(i == end) //this object does not need this media impl. + { + mMediaImplList[texture_index]->removeObject(this) ; + } + + mMediaImplList[texture_index] = NULL ; + return ; } void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) { - if((S32)mMediaImplList.size() < texture_index + 1) - { - mMediaImplList.resize(texture_index + 1) ; - } - - if(mMediaImplList[texture_index].notNull()) - { - if(mMediaImplList[texture_index] == media_impl) - { - return ; - } - - removeMediaImpl(texture_index) ; - } - - mMediaImplList[texture_index] = media_impl; - media_impl->addObject(this) ; - - //add the face to show the media if it is in playing - if(mDrawable) - { - LLFace* facep(NULL); - if( texture_index < mDrawable->getNumFaces() ) - { - facep = mDrawable->getFace(texture_index) ; - } - - if(facep) - { - LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; - if(media_tex) - { - media_tex->addMediaToFace(facep) ; - } - } - else //the face is not available now, start media on this face later. - { - media_impl->setUpdated(TRUE) ; - } - } - return ; + if((S32)mMediaImplList.size() < texture_index + 1) + { + mMediaImplList.resize(texture_index + 1) ; + } + + if(mMediaImplList[texture_index].notNull()) + { + if(mMediaImplList[texture_index] == media_impl) + { + return ; + } + + removeMediaImpl(texture_index) ; + } + + mMediaImplList[texture_index] = media_impl; + media_impl->addObject(this) ; + + //add the face to show the media if it is in playing + if(mDrawable) + { + LLFace* facep(NULL); + if( texture_index < mDrawable->getNumFaces() ) + { + facep = mDrawable->getFace(texture_index) ; + } + + if(facep) + { + LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; + if(media_tex) + { + media_tex->addMediaToFace(facep) ; + } + } + else //the face is not available now, start media on this face later. + { + media_impl->setUpdated(TRUE) ; + } + } + return ; } viewer_media_t LLVOVolume::getMediaImpl(U8 face_id) const { - if(mMediaImplList.size() > face_id) - { - return mMediaImplList[face_id]; - } - return NULL; + if(mMediaImplList.size() > face_id) + { + return mMediaImplList[face_id]; + } + return NULL; } F64 LLVOVolume::getTotalMediaInterest() const { - // If this object is currently focused, this object has "high" interest - if (LLViewerMediaFocus::getInstance()->getFocusedObjectID() == getID()) - return F64_MAX; - - F64 interest = (F64)-1.0; // means not interested; - - // If this object is selected, this object has "high" interest, but since - // there can be more than one, we still add in calculated impl interest - // XXX Sadly, 'contains()' doesn't take a const :( - if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this))) - interest = F64_MAX / 2.0; - - int i = 0; - const int end = getNumTEs(); - for ( ; i < end; ++i) - { - const viewer_media_t &impl = getMediaImpl(i); - if (!impl.isNull()) - { - if (interest == (F64)-1.0) interest = (F64)0.0; - interest += impl->getInterest(); - } - } - return interest; + // If this object is currently focused, this object has "high" interest + if (LLViewerMediaFocus::getInstance()->getFocusedObjectID() == getID()) + return F64_MAX; + + F64 interest = (F64)-1.0; // means not interested; + + // If this object is selected, this object has "high" interest, but since + // there can be more than one, we still add in calculated impl interest + // XXX Sadly, 'contains()' doesn't take a const :( + if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this))) + interest = F64_MAX / 2.0; + + int i = 0; + const int end = getNumTEs(); + for ( ; i < end; ++i) + { + const viewer_media_t &impl = getMediaImpl(i); + if (!impl.isNull()) + { + if (interest == (F64)-1.0) interest = (F64)0.0; + interest += impl->getInterest(); + } + } + return interest; } S32 LLVOVolume::getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id) { - S32 end = (S32)mMediaImplList.size() ; - for(S32 face_id = start_face_id + 1; face_id < end; face_id++) - { - if(mMediaImplList[face_id] == media_impl) - { - return face_id ; - } - } - return -1 ; + S32 end = (S32)mMediaImplList.size() ; + for(S32 face_id = start_face_id + 1; face_id < end; face_id++) + { + if(mMediaImplList[face_id] == media_impl) + { + return face_id ; + } + } + return -1 ; } //---------------------------------------------------------------------------- void LLVOVolume::setLightTextureID(LLUUID id) { - LLViewerTexture* old_texturep = getLightTexture(); // same as mLightTexture, but inits if nessesary - if (id.notNull()) - { - if (!hasLightTexture()) - { - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true); - } - else if (old_texturep) - { - old_texturep->removeVolume(LLRender::LIGHT_TEX, this); - } - LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block && param_block->getLightTexture() != id) - { - param_block->setLightTexture(id); - parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); - } - LLViewerTexture* tex = getLightTexture(); - if (tex) - { - tex->addVolume(LLRender::LIGHT_TEX, this); // new texture - } - else - { - LL_WARNS() << "Can't get light texture for ID " << id.asString() << LL_ENDL; - } - } - else if (hasLightTexture()) - { - if (old_texturep) - { - old_texturep->removeVolume(LLRender::LIGHT_TEX, this); - } - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true); - parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); - mLightTexture = NULL; - } + LLViewerTexture* old_texturep = getLightTexture(); // same as mLightTexture, but inits if nessesary + if (id.notNull()) + { + if (!hasLightTexture()) + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true); + } + else if (old_texturep) + { + old_texturep->removeVolume(LLRender::LIGHT_TEX, this); + } + LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block && param_block->getLightTexture() != id) + { + param_block->setLightTexture(id); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + } + LLViewerTexture* tex = getLightTexture(); + if (tex) + { + tex->addVolume(LLRender::LIGHT_TEX, this); // new texture + } + else + { + LL_WARNS() << "Can't get light texture for ID " << id.asString() << LL_ENDL; + } + } + else if (hasLightTexture()) + { + if (old_texturep) + { + old_texturep->removeVolume(LLRender::LIGHT_TEX, this); + } + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + mLightTexture = NULL; + } } void LLVOVolume::setSpotLightParams(LLVector3 params) { - LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block && param_block->getParams() != params) - { - param_block->setParams(params); - parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); - } + LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block && param_block->getParams() != params) + { + param_block->setParams(params); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + } } - + void LLVOVolume::setIsLight(BOOL is_light) { - BOOL was_light = getIsLight(); - if (is_light != was_light) - { - if (is_light) - { - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, TRUE, true); - } - else - { - setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, FALSE, true); - } - - if (is_light) - { - // Add it to the pipeline mLightSet - gPipeline.setLight(mDrawable, TRUE); - } - else - { - // Not a light. Remove it from the pipeline's light set. - gPipeline.setLight(mDrawable, FALSE); - } - } + BOOL was_light = getIsLight(); + if (is_light != was_light) + { + if (is_light) + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, TRUE, true); + } + else + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT, FALSE, true); + } + + if (is_light) + { + // Add it to the pipeline mLightSet + gPipeline.setLight(mDrawable, TRUE); + } + else + { + // Not a light. Remove it from the pipeline's light set. + gPipeline.setLight(mDrawable, FALSE); + } + } } void LLVOVolume::setLightSRGBColor(const LLColor3& color) @@ -3061,69 +3061,69 @@ void LLVOVolume::setLightSRGBColor(const LLColor3& color) void LLVOVolume::setLightLinearColor(const LLColor3& color) { - LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - if (param_block->getLinearColor() != color) - { - param_block->setLinearColor(LLColor4(color, param_block->getLinearColor().mV[3])); - parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - gPipeline.markTextured(mDrawable); - mFaceMappingChanged = TRUE; - } - } + LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + if (param_block->getLinearColor() != color) + { + param_block->setLinearColor(LLColor4(color, param_block->getLinearColor().mV[3])); + parameterChanged(LLNetworkData::PARAMS_LIGHT, true); + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + } } void LLVOVolume::setLightIntensity(F32 intensity) { - LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - if (param_block->getLinearColor().mV[3] != intensity) - { - param_block->setLinearColor(LLColor4(LLColor3(param_block->getLinearColor()), intensity)); - parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - } - } + LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + if (param_block->getLinearColor().mV[3] != intensity) + { + param_block->setLinearColor(LLColor4(LLColor3(param_block->getLinearColor()), intensity)); + parameterChanged(LLNetworkData::PARAMS_LIGHT, true); + } + } } void LLVOVolume::setLightRadius(F32 radius) { - LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - if (param_block->getRadius() != radius) - { - param_block->setRadius(radius); - parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - } - } + LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + if (param_block->getRadius() != radius) + { + param_block->setRadius(radius); + parameterChanged(LLNetworkData::PARAMS_LIGHT, true); + } + } } void LLVOVolume::setLightFalloff(F32 falloff) { - LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - if (param_block->getFalloff() != falloff) - { - param_block->setFalloff(falloff); - parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - } - } + LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + if (param_block->getFalloff() != falloff) + { + param_block->setFalloff(falloff); + parameterChanged(LLNetworkData::PARAMS_LIGHT, true); + } + } } void LLVOVolume::setLightCutoff(F32 cutoff) { - LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - if (param_block->getCutoff() != cutoff) - { - param_block->setCutoff(cutoff); - parameterChanged(LLNetworkData::PARAMS_LIGHT, true); - } - } + LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + if (param_block->getCutoff() != cutoff) + { + param_block->setCutoff(cutoff); + parameterChanged(LLNetworkData::PARAMS_LIGHT, true); + } + } } //---------------------------------------------------------------------------- @@ -3146,15 +3146,15 @@ LLColor3 LLVOVolume::getLightSRGBBaseColor() const LLColor3 LLVOVolume::getLightLinearBaseColor() const { - const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - return LLColor3(param_block->getLinearColor()); - } - else - { - return LLColor3(1,1,1); - } + const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + return LLColor3(param_block->getLinearColor()); + } + else + { + return LLColor3(1,1,1); + } } LLColor3 LLVOVolume::getLightLinearColor() const @@ -3179,36 +3179,36 @@ LLColor3 LLVOVolume::getLightSRGBColor() const LLUUID LLVOVolume::getLightTextureID() const { - if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) - { - const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block) - { - return param_block->getLightTexture(); - } - } - - return LLUUID::null; + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block) + { + return param_block->getLightTexture(); + } + } + + return LLUUID::null; } LLVector3 LLVOVolume::getSpotLightParams() const { - if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) - { - const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (param_block) - { - return param_block->getParams(); - } - } - - return LLVector3(); + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block) + { + return param_block->getParams(); + } + } + + return LLVector3(); } F32 LLVOVolume::getSpotLightPriority() const { - return mSpotLightPriority; + return mSpotLightPriority; } void LLVOVolume::updateSpotLightPriority() @@ -3219,104 +3219,104 @@ void LLVOVolume::updateSpotLightPriority() } F32 r = getLightRadius(); - LLVector3 pos = mDrawable->getPositionAgent(); + LLVector3 pos = mDrawable->getPositionAgent(); - LLVector3 at(0,0,-1); - at *= getRenderRotation(); - pos += at * r; + LLVector3 at(0,0,-1); + at *= getRenderRotation(); + pos += at * r; - at = LLViewerCamera::getInstance()->getAtAxis(); - pos -= at * r; + at = LLViewerCamera::getInstance()->getAtAxis(); + pos -= at * r; - mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance()); + mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance()); - if (mLightTexture.notNull()) - { - mLightTexture->addTextureStats(mSpotLightPriority); - } + if (mLightTexture.notNull()) + { + mLightTexture->addTextureStats(mSpotLightPriority); + } } bool LLVOVolume::isLightSpotlight() const { - LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); - if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) - { - return params->isLightSpotlight(); - } - return false; + LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + return params->isLightSpotlight(); + } + return false; } LLViewerTexture* LLVOVolume::getLightTexture() { - LLUUID id = getLightTextureID(); + LLUUID id = getLightTextureID(); - if (id.notNull()) - { - if (mLightTexture.isNull() || id != mLightTexture->getID()) - { - mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE); - } - } - else - { - mLightTexture = NULL; - } + if (id.notNull()) + { + if (mLightTexture.isNull() || id != mLightTexture->getID()) + { + mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE); + } + } + else + { + mLightTexture = NULL; + } - return mLightTexture; + return mLightTexture; } F32 LLVOVolume::getLightIntensity() const { - const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - return param_block->getLinearColor().mV[3]; - } - else - { - return 1.f; - } + const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + return param_block->getLinearColor().mV[3]; + } + else + { + return 1.f; + } } F32 LLVOVolume::getLightRadius() const { - const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - return param_block->getRadius(); - } - else - { - return 0.f; - } + const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + return param_block->getRadius(); + } + else + { + return 0.f; + } } F32 LLVOVolume::getLightFalloff(const F32 fudge_factor) const { - const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - return param_block->getFalloff() * fudge_factor; - } - else - { - return 0.f; - } + const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + return param_block->getFalloff() * fudge_factor; + } + else + { + return 0.f; + } } F32 LLVOVolume::getLightCutoff() const { - const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); - if (param_block) - { - return param_block->getCutoff(); - } - else - { - return 0.f; - } + const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); + if (param_block) + { + return param_block->getCutoff(); + } + else + { + return 0.f; + } } BOOL LLVOVolume::isReflectionProbe() const @@ -3441,7 +3441,7 @@ bool LLVOVolume::getReflectionProbeIsBox() const { return param_block->getIsBox(); } - + return false; } @@ -3458,68 +3458,68 @@ bool LLVOVolume::getReflectionProbeIsDynamic() const U32 LLVOVolume::getVolumeInterfaceID() const { - if (mVolumeImpl) - { - return mVolumeImpl->getID(); - } + if (mVolumeImpl) + { + return mVolumeImpl->getID(); + } - return 0; + return 0; } BOOL LLVOVolume::isFlexible() const { - if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE)) - { - LLVolume* volume = getVolume(); - if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE) - { - LLVolumeParams volume_params = getVolume()->getParams(); - U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); - volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE); - } - return TRUE; - } - else - { - return FALSE; - } + if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE)) + { + LLVolume* volume = getVolume(); + if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE) + { + LLVolumeParams volume_params = getVolume()->getParams(); + U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); + volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE); + } + return TRUE; + } + else + { + return FALSE; + } } BOOL LLVOVolume::isSculpted() const { - if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) - { - return TRUE; - } - - return FALSE; + if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) + { + return TRUE; + } + + return FALSE; } BOOL LLVOVolume::isMesh() const { - if (isSculpted()) - { - LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - U8 sculpt_type = sculpt_params->getSculptType(); + if (isSculpted()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); + U8 sculpt_type = sculpt_params->getSculptType(); - if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) - // mesh is a mesh - { - return TRUE; - } - } + if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) + // mesh is a mesh + { + return TRUE; + } + } - return FALSE; + return FALSE; } BOOL LLVOVolume::hasLightTexture() const { - if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) - { - return TRUE; - } + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + return TRUE; + } - return FALSE; + return FALSE; } bool LLVOVolume::isFlexibleFast() const @@ -3549,67 +3549,67 @@ bool LLVOVolume::isAnimatedObjectFast() const BOOL LLVOVolume::isVolumeGlobal() const { - if (mVolumeImpl) - { - return mVolumeImpl->isVolumeGlobal() ? TRUE : FALSE; - } - else if (mRiggedVolume.notNull()) - { - return TRUE; - } + if (mVolumeImpl) + { + return mVolumeImpl->isVolumeGlobal() ? TRUE : FALSE; + } + else if (mRiggedVolume.notNull()) + { + return TRUE; + } - return FALSE; + return FALSE; } BOOL LLVOVolume::canBeFlexible() const { - U8 path = getVolume()->getParams().getPathParams().getCurveType(); - return (path == LL_PCODE_PATH_FLEXIBLE || path == LL_PCODE_PATH_LINE); + U8 path = getVolume()->getParams().getPathParams().getCurveType(); + return (path == LL_PCODE_PATH_FLEXIBLE || path == LL_PCODE_PATH_LINE); } BOOL LLVOVolume::setIsFlexible(BOOL is_flexible) { - BOOL res = FALSE; - BOOL was_flexible = isFlexible(); - LLVolumeParams volume_params; - if (is_flexible) - { - if (!was_flexible) - { - volume_params = getVolume()->getParams(); - U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); - volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE); - res = TRUE; - setFlags(FLAGS_USE_PHYSICS, FALSE); - setFlags(FLAGS_PHANTOM, TRUE); - setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, true); - if (mDrawable) - { - mDrawable->makeActive(); - } - } - } - else - { - if (was_flexible) - { - volume_params = getVolume()->getParams(); - U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); - volume_params.setType(profile_and_hole, LL_PCODE_PATH_LINE); - res = TRUE; - setFlags(FLAGS_PHANTOM, FALSE); - setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, true); - } - } - if (res) - { - res = setVolume(volume_params, 1); - if (res) - { - markForUpdate(); - } - } - return res; + BOOL res = FALSE; + BOOL was_flexible = isFlexible(); + LLVolumeParams volume_params; + if (is_flexible) + { + if (!was_flexible) + { + volume_params = getVolume()->getParams(); + U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); + volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE); + res = TRUE; + setFlags(FLAGS_USE_PHYSICS, FALSE); + setFlags(FLAGS_PHANTOM, TRUE); + setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, TRUE, true); + if (mDrawable) + { + mDrawable->makeActive(); + } + } + } + else + { + if (was_flexible) + { + volume_params = getVolume()->getParams(); + U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); + volume_params.setType(profile_and_hole, LL_PCODE_PATH_LINE); + res = TRUE; + setFlags(FLAGS_PHANTOM, FALSE); + setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, FALSE, true); + } + } + if (res) + { + res = setVolume(volume_params, 1); + if (res) + { + markForUpdate(); + } + } + return res; } const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const @@ -3633,16 +3633,16 @@ BOOL LLVOVolume::isRiggedMesh() const //---------------------------------------------------------------------------- U32 LLVOVolume::getExtendedMeshFlags() const { - const LLExtendedMeshParams *param_block = + const LLExtendedMeshParams *param_block = (const LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH); - if (param_block) - { - return param_block->getFlags(); - } - else - { - return 0; - } + if (param_block) + { + return param_block->getFlags(); + } + else + { + return 0; + } } void LLVOVolume::onSetExtendedMeshFlags(U32 flags) @@ -3651,7 +3651,7 @@ void LLVOVolume::onSetExtendedMeshFlags(U32 flags) // The isAnySelected() check was needed at one point to prevent // graphics problems. These are now believed to be fixed so the // check has been disabled. - if (/*!getRootEdit()->isAnySelected() &&*/ mDrawable.notNull()) + if (/*!getRootEdit()->isAnySelected() &&*/ mDrawable.notNull()) { // Need to trigger rebuildGeom(), which is where control avatars get created/removed getRootEdit()->recursiveMarkForUpdate(); @@ -3679,7 +3679,7 @@ void LLVOVolume::setExtendedMeshFlags(U32 flags) { bool in_use = true; setParameterEntryInUse(LLNetworkData::PARAMS_EXTENDED_MESH, in_use, true); - LLExtendedMeshParams *param_block = + LLExtendedMeshParams *param_block = (LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH); if (param_block) { @@ -3749,13 +3749,13 @@ void LLVOVolume::onReparent(LLViewerObject *old_parent, LLViewerObject *new_pare void LLVOVolume::afterReparent() { { - LL_DEBUGS("AnimatedObjects") << "new child added for parent " + LL_DEBUGS("AnimatedObjects") << "new child added for parent " << ((LLViewerObject*)getParent())->getID() << LL_ENDL; } - + if (isAnimatedObject() && getControlAvatar()) { - LL_DEBUGS("AnimatedObjects") << "adding attachment overrides, parent is animated object " + LL_DEBUGS("AnimatedObjects") << "adding attachment overrides, parent is animated object " << ((LLViewerObject*)getParent())->getID() << LL_ENDL; // MAINT-8239 - doing a full rebuild whenever parent is set @@ -3763,15 +3763,15 @@ void LLVOVolume::afterReparent() // addAttachmentOverrides should be sufficient, but in // practice doing a full rebuild helps compensate for // notifyMeshLoaded() not being called reliably enough. - + // was: getControlAvatar()->addAttachmentOverridesForObject(this); //getControlAvatar()->rebuildAttachmentOverrides(); getControlAvatar()->updateAnimations(); } else { - LL_DEBUGS("AnimatedObjects") << "not adding overrides, parent: " - << ((LLViewerObject*)getParent())->getID() + LL_DEBUGS("AnimatedObjects") << "not adding overrides, parent: " + << ((LLViewerObject*)getParent())->getID() << " isAnimated: " << isAnimatedObject() << " cav " << getControlAvatar() << LL_ENDL; } @@ -3804,8 +3804,8 @@ void LLVOVolume::updateRiggingInfo() } // Keep the highest LOD info available. mLastRiggingInfoLOD = getLOD(); - LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume " - << this << " lod " << mLastRiggingInfoLOD + LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume " + << this << " lod " << mLastRiggingInfoLOD << LL_ENDL; } } @@ -3816,86 +3816,86 @@ void LLVOVolume::updateRiggingInfo() void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point) { - LLVolume *volume = getVolume(); - - if (volume) - { - LLVector3 view_vector; - view_vector = view_point; - - //transform view vector into volume space - view_vector -= getRenderPosition(); - //mDrawable->mDistanceWRTCamera = view_vector.length(); - LLQuaternion worldRot = getRenderRotation(); - view_vector = view_vector * ~worldRot; - if (!isVolumeGlobal()) - { - LLVector3 objScale = getScale(); - LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); - view_vector.scaleVec(invObjScale); - } - - updateRelativeXform(); - LLMatrix4 trans_mat = mRelativeXform; - if (mDrawable->isStatic()) - { - trans_mat.translate(getRegion()->getOriginAgent()); - } - - volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask()); - - nodep->mSilhouetteExists = TRUE; - } + LLVolume *volume = getVolume(); + + if (volume) + { + LLVector3 view_vector; + view_vector = view_point; + + //transform view vector into volume space + view_vector -= getRenderPosition(); + //mDrawable->mDistanceWRTCamera = view_vector.length(); + LLQuaternion worldRot = getRenderRotation(); + view_vector = view_vector * ~worldRot; + if (!isVolumeGlobal()) + { + LLVector3 objScale = getScale(); + LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); + view_vector.scaleVec(invObjScale); + } + + updateRelativeXform(); + LLMatrix4 trans_mat = mRelativeXform; + if (mDrawable->isStatic()) + { + trans_mat.translate(getRegion()->getOriginAgent()); + } + + volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask()); + + nodep->mSilhouetteExists = TRUE; + } } void LLVOVolume::deleteFaces() { - S32 face_count = mNumFaces; - if (mDrawable.notNull()) - { - mDrawable->deleteFaces(0, face_count); - } + S32 face_count = mNumFaces; + if (mDrawable.notNull()) + { + mDrawable->deleteFaces(0, face_count); + } - mNumFaces = 0; + mNumFaces = 0; } void LLVOVolume::updateRadius() { - if (mDrawable.isNull()) - { - return; - } - - mVObjRadius = getScale().length(); - mDrawable->setRadius(mVObjRadius); + if (mDrawable.isNull()) + { + return; + } + + mVObjRadius = getScale().length(); + mDrawable->setRadius(mVObjRadius); } BOOL LLVOVolume::isAttachment() const { - return mAttachmentState != 0 ; + return mAttachmentState != 0 ; } BOOL LLVOVolume::isHUDAttachment() const { - // *NOTE: we assume hud attachment points are in defined range - // since this range is constant for backwards compatibility - // reasons this is probably a reasonable assumption to make - S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mAttachmentState); - return ( attachment_id >= 31 && attachment_id <= 38 ); + // *NOTE: we assume hud attachment points are in defined range + // since this range is constant for backwards compatibility + // reasons this is probably a reasonable assumption to make + S32 attachment_id = ATTACHMENT_ID_FROM_STATE(mAttachmentState); + return ( attachment_id >= 31 && attachment_id <= 38 ); } const LLMatrix4 LLVOVolume::getRenderMatrix() const { - if (mDrawable->isActive() && !mDrawable->isRoot()) - { - return mDrawable->getParent()->getWorldMatrix(); - } - return mDrawable->getWorldMatrix(); + if (mDrawable->isActive() && !mDrawable->isRoot()) + { + return mDrawable->getParent()->getWorldMatrix(); + } + return mDrawable->getWorldMatrix(); } -//static +//static S32 LLVOVolume::getTextureCost(const LLViewerTexture* img) { static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested @@ -3937,57 +3937,57 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const * the official viewer for consideration. *****************************************************************/ - // Get access to params we'll need at various points. - // Skip if this is object doesn't have a volume (e.g. is an avatar). + // Get access to params we'll need at various points. + // Skip if this is object doesn't have a volume (e.g. is an avatar). if (getVolume() == NULL) { return 0; } - U32 num_triangles = 0; + U32 num_triangles = 0; - // per-prim costs - static const U32 ARC_PARTICLE_COST = 1; // determined experimentally - static const U32 ARC_PARTICLE_MAX = 2048; // default values - static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims - static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face + // per-prim costs + static const U32 ARC_PARTICLE_COST = 1; // determined experimentally + static const U32 ARC_PARTICLE_MAX = 2048; // default values + static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims + static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face - // per-prim multipliers - static const F32 ARC_GLOW_MULT = 1.5f; // tested based on performance - static const F32 ARC_BUMP_MULT = 1.25f; // tested based on performance - static const F32 ARC_FLEXI_MULT = 5; // tested based on performance - static const F32 ARC_SHINY_MULT = 1.6f; // tested based on performance - static const F32 ARC_INVISI_COST = 1.2f; // tested based on performance - static const F32 ARC_WEIGHTED_MESH = 1.2f; // tested based on performance + // per-prim multipliers + static const F32 ARC_GLOW_MULT = 1.5f; // tested based on performance + static const F32 ARC_BUMP_MULT = 1.25f; // tested based on performance + static const F32 ARC_FLEXI_MULT = 5; // tested based on performance + static const F32 ARC_SHINY_MULT = 1.6f; // tested based on performance + static const F32 ARC_INVISI_COST = 1.2f; // tested based on performance + static const F32 ARC_WEIGHTED_MESH = 1.2f; // tested based on performance - static const F32 ARC_PLANAR_COST = 1.0f; // tested based on performance to have negligible impact - static const F32 ARC_ANIM_TEX_COST = 4.f; // tested based on performance - static const F32 ARC_ALPHA_COST = 4.f; // 4x max - based on performance + static const F32 ARC_PLANAR_COST = 1.0f; // tested based on performance to have negligible impact + static const F32 ARC_ANIM_TEX_COST = 4.f; // tested based on performance + static const F32 ARC_ALPHA_COST = 4.f; // 4x max - based on performance - F32 shame = 0; + F32 shame = 0; - U32 invisi = 0; - U32 shiny = 0; - U32 glow = 0; - U32 alpha = 0; - U32 flexi = 0; - U32 animtex = 0; - U32 particles = 0; - U32 bump = 0; - U32 planar = 0; - U32 weighted_mesh = 0; - U32 produces_light = 0; - U32 media_faces = 0; + U32 invisi = 0; + U32 shiny = 0; + U32 glow = 0; + U32 alpha = 0; + U32 flexi = 0; + U32 animtex = 0; + U32 particles = 0; + U32 bump = 0; + U32 planar = 0; + U32 weighted_mesh = 0; + U32 produces_light = 0; + U32 media_faces = 0; - const LLDrawable* drawablep = mDrawable; - U32 num_faces = drawablep->getNumFaces(); + const LLDrawable* drawablep = mDrawable; + U32 num_faces = drawablep->getNumFaces(); - const LLVolumeParams& volume_params = getVolume()->getParams(); + const LLVolumeParams& volume_params = getVolume()->getParams(); LLMeshCostData costs; - if (getCostData(costs)) - { + if (getCostData(costs)) + { if (isAnimatedObjectFast() && isRiggedMeshFast()) { // Scaling here is to make animated object vs @@ -4000,58 +4000,58 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const F32 radius = getScale().length()*0.5f; num_triangles = costs.getRadiusWeightedTris(radius); } - } - - - if (num_triangles <= 0) - { - num_triangles = 4; - } - - if (isSculptedFast()) - { - if (isMeshFast()) - { - // base cost is dependent on mesh complexity - // note that 3 is the highest LOD as of the time of this coding. - S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD()); - if ( size > 0) - { - if (isRiggedMeshFast()) - { - // weighted attachment - 1 point for every 3 bytes - weighted_mesh = 1; - } - } - else - { - // something went wrong - user should know their content isn't render-free - return 0; - } - } - else - { + } + + + if (num_triangles <= 0) + { + num_triangles = 4; + } + + if (isSculptedFast()) + { + if (isMeshFast()) + { + // base cost is dependent on mesh complexity + // note that 3 is the highest LOD as of the time of this coding. + S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD()); + if ( size > 0) + { + if (isRiggedMeshFast()) + { + // weighted attachment - 1 point for every 3 bytes + weighted_mesh = 1; + } + } + else + { + // something went wrong - user should know their content isn't render-free + return 0; + } + } + else + { LLViewerFetchedTexture* texture = mSculptTexture; - if (texture && textures.find(texture) == textures.end()) - { + if (texture && textures.find(texture) == textures.end()) + { textures.insert(texture); - } - } - } + } + } + } - if (isFlexibleFast()) - { - flexi = 1; - } - if (isParticleSource()) - { - particles = 1; - } + if (isFlexibleFast()) + { + flexi = 1; + } + if (isParticleSource()) + { + particles = 1; + } - if (getIsLightFast()) - { - produces_light = 1; - } + if (getIsLightFast()) + { + produces_light = 1; + } { LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("ARC - face list"); @@ -4109,79 +4109,79 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const } } - // shame currently has the "base" cost of 1 point per 15 triangles, min 2. - shame = num_triangles * 5.f; - shame = shame < 2.f ? 2.f : shame; - - // multiply by per-face modifiers - if (planar) - { - shame *= planar * ARC_PLANAR_COST; - } - - if (animtex) - { - shame *= animtex * ARC_ANIM_TEX_COST; - } - - if (alpha) - { - shame *= alpha * ARC_ALPHA_COST; - } - - if(invisi) - { - shame *= invisi * ARC_INVISI_COST; - } - - if (glow) - { - shame *= glow * ARC_GLOW_MULT; - } - - if (bump) - { - shame *= bump * ARC_BUMP_MULT; - } - - if (shiny) - { - shame *= shiny * ARC_SHINY_MULT; - } - - - // multiply shame by multipliers - if (weighted_mesh) - { - shame *= weighted_mesh * ARC_WEIGHTED_MESH; - } - - if (flexi) - { - shame *= flexi * ARC_FLEXI_MULT; - } - - - // add additional costs - if (particles) - { - const LLPartSysData *part_sys_data = &(mPartSourcep->mPartSysData); - const LLPartData *part_data = &(part_sys_data->mPartData); - U32 num_particles = (U32)(part_sys_data->mBurstPartCount * llceil( part_data->mMaxAge / part_sys_data->mBurstRate)); - num_particles = num_particles > ARC_PARTICLE_MAX ? ARC_PARTICLE_MAX : num_particles; - F32 part_size = (llmax(part_data->mStartScale[0], part_data->mEndScale[0]) + llmax(part_data->mStartScale[1], part_data->mEndScale[1])) / 2.f; - shame += num_particles * part_size * ARC_PARTICLE_COST; - } - - if (produces_light) - { - shame += ARC_LIGHT_COST; - } - - if (media_faces) - { - shame += media_faces * ARC_MEDIA_FACE_COST; - } + // shame currently has the "base" cost of 1 point per 15 triangles, min 2. + shame = num_triangles * 5.f; + shame = shame < 2.f ? 2.f : shame; + + // multiply by per-face modifiers + if (planar) + { + shame *= planar * ARC_PLANAR_COST; + } + + if (animtex) + { + shame *= animtex * ARC_ANIM_TEX_COST; + } + + if (alpha) + { + shame *= alpha * ARC_ALPHA_COST; + } + + if(invisi) + { + shame *= invisi * ARC_INVISI_COST; + } + + if (glow) + { + shame *= glow * ARC_GLOW_MULT; + } + + if (bump) + { + shame *= bump * ARC_BUMP_MULT; + } + + if (shiny) + { + shame *= shiny * ARC_SHINY_MULT; + } + + + // multiply shame by multipliers + if (weighted_mesh) + { + shame *= weighted_mesh * ARC_WEIGHTED_MESH; + } + + if (flexi) + { + shame *= flexi * ARC_FLEXI_MULT; + } + + + // add additional costs + if (particles) + { + const LLPartSysData *part_sys_data = &(mPartSourcep->mPartSysData); + const LLPartData *part_data = &(part_sys_data->mPartData); + U32 num_particles = (U32)(part_sys_data->mBurstPartCount * llceil( part_data->mMaxAge / part_sys_data->mBurstRate)); + num_particles = num_particles > ARC_PARTICLE_MAX ? ARC_PARTICLE_MAX : num_particles; + F32 part_size = (llmax(part_data->mStartScale[0], part_data->mEndScale[0]) + llmax(part_data->mStartScale[1], part_data->mEndScale[1])) / 2.f; + shame += num_particles * part_size * ARC_PARTICLE_COST; + } + + if (produces_light) + { + shame += ARC_LIGHT_COST; + } + + if (media_faces) + { + shame += media_faces * ARC_MEDIA_FACE_COST; + } // Streaming cost for animated objects includes a fixed cost // per linkset. Add a corresponding charge here translated into @@ -4191,35 +4191,35 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const shame += (ANIMATED_OBJECT_BASE_COST/0.06) * 5.0f; } - if (shame > mRenderComplexity_current) - { - mRenderComplexity_current = (S32)shame; - } + if (shame > mRenderComplexity_current) + { + mRenderComplexity_current = (S32)shame; + } - return (U32)shame; + return (U32)shame; } F32 LLVOVolume::getEstTrianglesMax() const { - if (isMeshFast() && getVolume()) - { - return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID()); - } + if (isMeshFast() && getVolume()) + { + return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID()); + } return 0.f; } F32 LLVOVolume::getEstTrianglesStreamingCost() const { - if (isMeshFast() && getVolume()) - { - return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID()); - } + if (isMeshFast() && getVolume()) + { + return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID()); + } return 0.f; } F32 LLVOVolume::getStreamingCost() const { - F32 radius = getScale().length()*0.5f; + F32 radius = getScale().length()*0.5f; F32 linkset_base_cost = 0.f; LLMeshCostData costs; @@ -4263,87 +4263,87 @@ bool LLVOVolume::getCostData(LLMeshCostData& costs) const } else { - LLVolume* volume = getVolume(); - S32 counts[4]; - LLVolume::getLoDTriangleCounts(volume->getParams(), counts); + LLVolume* volume = getVolume(); + S32 counts[4]; + LLVolume::getLoDTriangleCounts(volume->getParams(), counts); LLMeshHeader header; - header.mLodSize[0] = counts[0] * 10; - header.mLodSize[1] = counts[1] * 10; - header.mLodSize[2] = counts[2] * 10; - header.mLodSize[3] = counts[3] * 10; + header.mLodSize[0] = counts[0] * 10; + header.mLodSize[1] = counts[1] * 10; + header.mLodSize[2] = counts[2] * 10; + header.mLodSize[3] = counts[3] * 10; - return gMeshRepo.getCostData(header, costs); + return gMeshRepo.getCostData(header, costs); } } -//static +//static void LLVOVolume::updateRenderComplexity() { - mRenderComplexity_last = mRenderComplexity_current; - mRenderComplexity_current = 0; + mRenderComplexity_last = mRenderComplexity_current; + mRenderComplexity_current = 0; } U32 LLVOVolume::getTriangleCount(S32* vcount) const { - U32 count = 0; - LLVolume* volume = getVolume(); - if (volume) - { - count = volume->getNumTriangles(vcount); - } + U32 count = 0; + LLVolume* volume = getVolume(); + if (volume) + { + count = volume->getNumTriangles(vcount); + } - return count; + return count; } U32 LLVOVolume::getHighLODTriangleCount() { - U32 ret = 0; - - LLVolume* volume = getVolume(); - - if (!isSculpted()) - { - LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3); - ret = ref->getNumTriangles(); - LLPrimitive::getVolumeManager()->unrefVolume(ref); - } - else if (isMesh()) - { - LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3); - if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0) - { - gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH); - } - ret = ref->getNumTriangles(); - LLPrimitive::getVolumeManager()->unrefVolume(ref); - } - else - { //default sculpts have a constant number of triangles - ret = 31*2*31; //31 rows of 31 columns of quads for a 32x32 vertex patch - } - - return ret; + U32 ret = 0; + + LLVolume* volume = getVolume(); + + if (!isSculpted()) + { + LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3); + ret = ref->getNumTriangles(); + LLPrimitive::getVolumeManager()->unrefVolume(ref); + } + else if (isMesh()) + { + LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3); + if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0) + { + gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH); + } + ret = ref->getNumTriangles(); + LLPrimitive::getVolumeManager()->unrefVolume(ref); + } + else + { //default sculpts have a constant number of triangles + ret = 31*2*31; //31 rows of 31 columns of quads for a 32x32 vertex patch + } + + return ret; } //static void LLVOVolume::preUpdateGeom() { - sNumLODChanges = 0; + sNumLODChanges = 0; } void LLVOVolume::parameterChanged(U16 param_type, bool local_origin) { - LLViewerObject::parameterChanged(param_type, local_origin); + LLViewerObject::parameterChanged(param_type, local_origin); } void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) { - LLViewerObject::parameterChanged(param_type, data, in_use, local_origin); - if (mVolumeImpl) - { - mVolumeImpl->onParameterChanged(param_type, data, in_use, local_origin); - } + LLViewerObject::parameterChanged(param_type, data, in_use, local_origin); + if (mVolumeImpl) + { + mVolumeImpl->onParameterChanged(param_type, data, in_use, local_origin); + } if (!local_origin && param_type == LLNetworkData::PARAMS_EXTENDED_MESH) { U32 extended_mesh_flags = getExtendedMeshFlags(); @@ -4359,15 +4359,15 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u onSetExtendedMeshFlags(extended_mesh_flags); } } - if (mDrawable.notNull()) - { - BOOL is_light = getIsLight(); - if (is_light != mDrawable->isState(LLDrawable::LIGHT)) - { - gPipeline.setLight(mDrawable, is_light); - } - } - + if (mDrawable.notNull()) + { + BOOL is_light = getIsLight(); + if (is_light != mDrawable->isState(LLDrawable::LIGHT)) + { + gPipeline.setLight(mDrawable, is_light); + } + } + updateReflectionProbePtr(); } @@ -4388,7 +4388,7 @@ void LLVOVolume::updateReflectionProbePtr() void LLVOVolume::setSelected(BOOL sel) { - LLViewerObject::setSelected(sel); + LLViewerObject::setSelected(sel); if (isAnimatedObject()) { getRootEdit()->recursiveMarkForUpdate(); @@ -4403,7 +4403,7 @@ void LLVOVolume::setSelected(BOOL sel) } void LLVOVolume::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) -{ +{ } F32 LLVOVolume::getBinRadius() @@ -4468,104 +4468,104 @@ F32 LLVOVolume::getBinRadius() const LLVector3 LLVOVolume::getPivotPositionAgent() const { - if (mVolumeImpl) - { - return mVolumeImpl->getPivotPosition(); - } - return LLViewerObject::getPivotPositionAgent(); + if (mVolumeImpl) + { + return mVolumeImpl->getPivotPosition(); + } + return LLViewerObject::getPivotPositionAgent(); } void LLVOVolume::onShift(const LLVector4a &shift_vector) { - if (mVolumeImpl) - { - mVolumeImpl->onShift(shift_vector); - } + if (mVolumeImpl) + { + mVolumeImpl->onShift(shift_vector); + } - updateRelativeXform(); + updateRelativeXform(); } const LLMatrix4& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const { - if (mVolumeImpl) - { - return mVolumeImpl->getWorldMatrix(xform); - } - return xform->getWorldMatrix(); + if (mVolumeImpl) + { + return mVolumeImpl->getWorldMatrix(xform); + } + return xform->getWorldMatrix(); } void LLVOVolume::markForUpdate() -{ +{ if (mDrawable) { shrinkWrap(); } - LLViewerObject::markForUpdate(); - mVolumeChanged = TRUE; + LLViewerObject::markForUpdate(); + mVolumeChanged = TRUE; } LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const { - LLVector3 ret = pos - getRenderPosition(); - ret = ret * ~getRenderRotation(); - if (!isVolumeGlobal()) - { - LLVector3 objScale = getScale(); - LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); - ret.scaleVec(invObjScale); - } - - return ret; + LLVector3 ret = pos - getRenderPosition(); + ret = ret * ~getRenderRotation(); + if (!isVolumeGlobal()) + { + LLVector3 objScale = getScale(); + LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); + ret.scaleVec(invObjScale); + } + + return ret; } LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const { - LLVector3 ret = dir * ~getRenderRotation(); - - LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); - ret.scaleVec(objScale); + LLVector3 ret = dir * ~getRenderRotation(); - return ret; + LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); + ret.scaleVec(objScale); + + return ret; } LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const { - LLVector3 ret = dir; - if (!isVolumeGlobal()) - { - LLVector3 objScale = getScale(); - ret.scaleVec(objScale); - } + LLVector3 ret = dir; + if (!isVolumeGlobal()) + { + LLVector3 objScale = getScale(); + ret.scaleVec(objScale); + } + + ret = ret * getRenderRotation(); + ret += getRenderPosition(); - ret = ret * getRenderRotation(); - ret += getRenderPosition(); - - return ret; + return ret; } LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const { - LLVector3 ret = dir; - LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); - LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); - ret.scaleVec(invObjScale); - ret = ret * getRenderRotation(); + LLVector3 ret = dir; + LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); + LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); + ret.scaleVec(invObjScale); + ret = ret * getRenderRotation(); - return ret; + return ret; } BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp, - LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) - + LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) + { - if (!mbCanSelect - || mDrawable->isDead() - || !gPipeline.hasRenderType(mDrawable->getRenderType())) - { - return FALSE; - } + if (!mbCanSelect + || mDrawable->isDead() + || !gPipeline.hasRenderType(mDrawable->getRenderType())) + { + return FALSE; + } if (!pick_unselectable) { @@ -4580,203 +4580,203 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& return FALSE; } - BOOL ret = FALSE; + BOOL ret = FALSE; - LLVolume* volume = getVolume(); + LLVolume* volume = getVolume(); - bool transform = true; + bool transform = true; - if (mDrawable->isState(LLDrawable::RIGGED)) - { - if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) - { + if (mDrawable->isState(LLDrawable::RIGGED)) + { + if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) + { updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES); - volume = mRiggedVolume; - transform = false; - } - else - { //cannot pick rigged attachments on other avatars or when not in build mode - return FALSE; - } - } - - if (volume) - { - LLVector4a local_start = start; - LLVector4a local_end = end; - - if (transform) - { - LLVector3 v_start(start.getF32ptr()); - LLVector3 v_end(end.getF32ptr()); - - v_start = agentPositionToVolume(v_start); - v_end = agentPositionToVolume(v_end); - - local_start.load3(v_start.mV); - local_end.load3(v_end.mV); - } - - LLVector4a p; - LLVector4a n; - LLVector2 tc; - LLVector4a tn; - - if (intersection != NULL) - { - p = *intersection; - } - - if (tex_coord != NULL) - { - tc = *tex_coord; - } - - if (normal != NULL) - { - n = *normal; - } - - if (tangent != NULL) - { - tn = *tangent; - } - - S32 face_hit = -1; - - S32 start_face, end_face; - if (face == -1) - { - start_face = 0; - end_face = volume->getNumVolumeFaces(); - } - else - { - start_face = face; - end_face = face+1; - } - pick_transparent |= isHiglightedOrBeacon(); + volume = mRiggedVolume; + transform = false; + } + else + { //cannot pick rigged attachments on other avatars or when not in build mode + return FALSE; + } + } + + if (volume) + { + LLVector4a local_start = start; + LLVector4a local_end = end; + + if (transform) + { + LLVector3 v_start(start.getF32ptr()); + LLVector3 v_end(end.getF32ptr()); + + v_start = agentPositionToVolume(v_start); + v_end = agentPositionToVolume(v_end); + + local_start.load3(v_start.mV); + local_end.load3(v_end.mV); + } + + LLVector4a p; + LLVector4a n; + LLVector2 tc; + LLVector4a tn; + + if (intersection != NULL) + { + p = *intersection; + } + + if (tex_coord != NULL) + { + tc = *tex_coord; + } + + if (normal != NULL) + { + n = *normal; + } + + if (tangent != NULL) + { + tn = *tangent; + } + + S32 face_hit = -1; + + S32 start_face, end_face; + if (face == -1) + { + start_face = 0; + end_face = volume->getNumVolumeFaces(); + } + else + { + start_face = face; + end_face = face+1; + } + pick_transparent |= isHiglightedOrBeacon(); // we *probably* shouldn't care about special cursor at all, but we *definitely* // don't care about special cursor for reflection probes -- makes alt-zoom // go through reflection probes on vehicles - bool special_cursor = mReflectionProbe.isNull() && specialHoverCursor(); + bool special_cursor = mReflectionProbe.isNull() && specialHoverCursor(); - for (S32 i = start_face; i < end_face; ++i) - { - if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f) - { //don't attempt to pick completely transparent faces unless - //pick_transparent is true - continue; - } + for (S32 i = start_face; i < end_face; ++i) + { + if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f) + { //don't attempt to pick completely transparent faces unless + //pick_transparent is true + continue; + } // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree. // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking. updateRiggedVolume(true, i, false); - face_hit = volume->lineSegmentIntersect(local_start, local_end, i, - &p, &tc, &n, &tn); - - if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit) - { - LLFace* face = mDrawable->getFace(face_hit); - - bool ignore_alpha = false; - - const LLTextureEntry* te = face->getTextureEntry(); - if (te) - { - LLMaterial* mat = te->getMaterialParams(); - if (mat) - { - U8 mode = mat->getDiffuseAlphaMode(); - - if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE - || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE - || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && mat->getAlphaMaskCutoff() == 0)) - { - ignore_alpha = true; - } - } - } + face_hit = volume->lineSegmentIntersect(local_start, local_end, i, + &p, &tc, &n, &tn); + + if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit) + { + LLFace* face = mDrawable->getFace(face_hit); + + bool ignore_alpha = false; + + const LLTextureEntry* te = face->getTextureEntry(); + if (te) + { + LLMaterial* mat = te->getMaterialParams(); + if (mat) + { + U8 mode = mat->getDiffuseAlphaMode(); + + if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE + || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE + || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && mat->getAlphaMaskCutoff() == 0)) + { + ignore_alpha = true; + } + } + } BOOL no_texture = !face->getTexture() || !face->getTexture()->hasGLTexture(); BOOL mask = no_texture ? FALSE : face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)); - if (face && - (ignore_alpha || pick_transparent || no_texture || mask)) - { - local_end = p; - if (face_hitp != NULL) - { - *face_hitp = face_hit; - } - - if (intersection != NULL) - { - if (transform) - { - LLVector3 v_p(p.getF32ptr()); - - intersection->load3(volumePositionToAgent(v_p).mV); // must map back to agent space - } - else - { - *intersection = p; - } - } - - if (normal != NULL) - { - if (transform) - { - LLVector3 v_n(n.getF32ptr()); - normal->load3(volumeDirectionToAgent(v_n).mV); - } - else - { - *normal = n; - } - (*normal).normalize3fast(); - } - - if (tangent != NULL) - { - if (transform) - { - LLVector3 v_tn(tn.getF32ptr()); - - LLVector4a trans_tangent; - trans_tangent.load3(volumeDirectionToAgent(v_tn).mV); - - LLVector4Logical mask; - mask.clear(); - mask.setElement<3>(); - - tangent->setSelectWithMask(mask, tn, trans_tangent); - } - else - { - *tangent = tn; - } - (*tangent).normalize3fast(); - } - - if (tex_coord != NULL) - { - *tex_coord = tc; - } - - ret = TRUE; - } - } - } - } - - return ret; + if (face && + (ignore_alpha || pick_transparent || no_texture || mask)) + { + local_end = p; + if (face_hitp != NULL) + { + *face_hitp = face_hit; + } + + if (intersection != NULL) + { + if (transform) + { + LLVector3 v_p(p.getF32ptr()); + + intersection->load3(volumePositionToAgent(v_p).mV); // must map back to agent space + } + else + { + *intersection = p; + } + } + + if (normal != NULL) + { + if (transform) + { + LLVector3 v_n(n.getF32ptr()); + normal->load3(volumeDirectionToAgent(v_n).mV); + } + else + { + *normal = n; + } + (*normal).normalize3fast(); + } + + if (tangent != NULL) + { + if (transform) + { + LLVector3 v_tn(tn.getF32ptr()); + + LLVector4a trans_tangent; + trans_tangent.load3(volumeDirectionToAgent(v_tn).mV); + + LLVector4Logical mask; + mask.clear(); + mask.setElement<3>(); + + tangent->setSelectWithMask(mask, tn, trans_tangent); + } + else + { + *tangent = tn; + } + (*tangent).normalize3fast(); + } + + if (tex_coord != NULL) + { + *tex_coord = tc; + } + + ret = TRUE; + } + } + } + } + + return ret; } bool LLVOVolume::treatAsRigged() { - return isSelected() && + return isSelected() && (isAttachment() || isAnimatedObject()) && mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED); @@ -4784,52 +4784,52 @@ bool LLVOVolume::treatAsRigged() LLRiggedVolume* LLVOVolume::getRiggedVolume() { - return mRiggedVolume; + return mRiggedVolume; } void LLVOVolume::clearRiggedVolume() { - if (mRiggedVolume.notNull()) - { - mRiggedVolume = NULL; - updateRelativeXform(); - } + if (mRiggedVolume.notNull()) + { + mRiggedVolume = NULL; + updateRelativeXform(); + } } void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - //Update mRiggedVolume to match current animation frame of avatar. - //Also update position/size in octree. + //Update mRiggedVolume to match current animation frame of avatar. + //Also update position/size in octree. if ((!force_treat_as_rigged) && (!treatAsRigged())) - { - clearRiggedVolume(); - - return; - } - - LLVolume* volume = getVolume(); - const LLMeshSkinInfo* skin = getSkinInfo(); - if (!skin) - { - clearRiggedVolume(); - return; - } - - LLVOAvatar* avatar = getAvatar(); - if (!avatar) - { - clearRiggedVolume(); - return; - } - - if (!mRiggedVolume) - { - LLVolumeParams p; - mRiggedVolume = new LLRiggedVolume(p); - updateRelativeXform(); - } + { + clearRiggedVolume(); + + return; + } + + LLVolume* volume = getVolume(); + const LLMeshSkinInfo* skin = getSkinInfo(); + if (!skin) + { + clearRiggedVolume(); + return; + } + + LLVOAvatar* avatar = getAvatar(); + if (!avatar) + { + clearRiggedVolume(); + return; + } + + if (!mRiggedVolume) + { + LLVolumeParams p; + mRiggedVolume = new LLRiggedVolume(p); + updateRelativeXform(); + } mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees); } @@ -4842,47 +4842,47 @@ void LLRiggedVolume::update( bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - bool copy = false; - if (volume->getNumVolumeFaces() != getNumVolumeFaces()) - { - copy = true; - } - - for (S32 i = 0; i < volume->getNumVolumeFaces() && !copy; ++i) - { - const LLVolumeFace& src_face = volume->getVolumeFace(i); - const LLVolumeFace& dst_face = getVolumeFace(i); - - if (src_face.mNumIndices != dst_face.mNumIndices || - src_face.mNumVertices != dst_face.mNumVertices) - { - copy = true; - } - } - - if (copy) - { - copyVolumeFaces(volume); - } + bool copy = false; + if (volume->getNumVolumeFaces() != getNumVolumeFaces()) + { + copy = true; + } + + for (S32 i = 0; i < volume->getNumVolumeFaces() && !copy; ++i) + { + const LLVolumeFace& src_face = volume->getVolumeFace(i); + const LLVolumeFace& dst_face = getVolumeFace(i); + + if (src_face.mNumIndices != dst_face.mNumIndices || + src_face.mNumVertices != dst_face.mNumVertices) + { + copy = true; + } + } + + if (copy) + { + copyVolumeFaces(volume); + } else { bool is_paused = avatar && avatar->areAnimationsPaused(); - if (is_paused) - { + if (is_paused) + { S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame(); if (frames_paused > 1) { return; } - } + } } - //build matrix palette - static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; + //build matrix palette + static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; - LLMatrix4a mat[kMaxJoints]; - U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); + LLMatrix4a mat[kMaxJoints]; + U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar); const LLMatrix4a bind_shape_matrix = skin->mBindShapeMatrix; @@ -4907,21 +4907,21 @@ void LLRiggedVolume::update( face_end = face_begin + 1; } for (S32 i = face_begin; i < face_end; ++i) - { - const LLVolumeFace& vol_face = volume->getVolumeFace(i); - - LLVolumeFace& dst_face = mVolumeFaces[i]; - - LLVector4a* weight = vol_face.mWeights; - - if ( weight ) - { + { + const LLVolumeFace& vol_face = volume->getVolumeFace(i); + + LLVolumeFace& dst_face = mVolumeFaces[i]; + + LLVector4a* weight = vol_face.mWeights; + + if ( weight ) + { LLSkinningUtil::checkSkinWeights(weight, dst_face.mNumVertices, skin); - LLVector4a* pos = dst_face.mPositions; + LLVector4a* pos = dst_face.mPositions; - if (pos && dst_face.mExtents) - { + if (pos && dst_face.mExtents) + { U32 max_joints = LLSkinningUtil::getMaxJointCount(); rigged_vert_count += dst_face.mNumVertices; rigged_face_count++; @@ -4933,71 +4933,71 @@ void LLRiggedVolume::update( U8* joint_indices_cursor = vol_face.mJointIndices; LLVector4a* just_weights = vol_face.mJustWeights; for (U32 j = 0; j < dst_face.mNumVertices; ++j) - { - LLMatrix4a final_mat; + { + LLMatrix4a final_mat; F32* w = just_weights[j].getF32ptr(); LLSkinningUtil::getPerVertexSkinMatrixWithIndices(w, joint_indices_cursor, mat, final_mat, src); joint_indices_cursor += 4; - LLVector4a& v = vol_face.mPositions[j]; - LLVector4a t; - LLVector4a dst; - bind_shape_matrix.affineTransform(v, t); - final_mat.affineTransform(t, dst); - pos[j] = dst; - } + LLVector4a& v = vol_face.mPositions[j]; + LLVector4a t; + LLVector4a dst; + bind_shape_matrix.affineTransform(v, t); + final_mat.affineTransform(t, dst); + pos[j] = dst; + } } else #endif { - for (U32 j = 0; j < dst_face.mNumVertices; ++j) - { - LLMatrix4a final_mat; + for (U32 j = 0; j < dst_face.mNumVertices; ++j) + { + LLMatrix4a final_mat; LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints); - - LLVector4a& v = vol_face.mPositions[j]; - LLVector4a t; - LLVector4a dst; - bind_shape_matrix.affineTransform(v, t); - final_mat.affineTransform(t, dst); - pos[j] = dst; - } + + LLVector4a& v = vol_face.mPositions[j]; + LLVector4a t; + LLVector4a dst; + bind_shape_matrix.affineTransform(v, t); + final_mat.affineTransform(t, dst); + pos[j] = dst; + } } - //update bounding box - // VFExtents change - LLVector4a& min = dst_face.mExtents[0]; - LLVector4a& max = dst_face.mExtents[1]; + //update bounding box + // VFExtents change + LLVector4a& min = dst_face.mExtents[0]; + LLVector4a& max = dst_face.mExtents[1]; - min = pos[0]; - max = pos[1]; + min = pos[0]; + max = pos[1]; if (i==0) { box_min = min; box_max = max; } - for (U32 j = 1; j < dst_face.mNumVertices; ++j) - { - min.setMin(min, pos[j]); - max.setMax(max, pos[j]); - } + for (U32 j = 1; j < dst_face.mNumVertices; ++j) + { + min.setMin(min, pos[j]); + max.setMax(max, pos[j]); + } box_min.setMin(min,box_min); box_max.setMax(max,box_max); - dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]); - dst_face.mCenter->mul(0.5f); + dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]); + dst_face.mCenter->mul(0.5f); - } + } if (rebuild_face_octrees) - { + { dst_face.destroyOctree(); dst_face.createOctree(); - } - } - } + } + } + } mExtraDebugText = llformat("rigged %d/%d - box (%f %f %f) (%f %f %f)", rigged_face_count, rigged_vert_count, box_min[0], box_min[1], box_min[2], @@ -5006,111 +5006,111 @@ void LLRiggedVolume::update( U32 LLVOVolume::getPartitionType() const { - if (isHUDAttachment()) - { - return LLViewerRegion::PARTITION_HUD; - } - if (isAnimatedObject() && getControlAvatar()) - { - return LLViewerRegion::PARTITION_CONTROL_AV; - } - if (isAttachment()) - { - return LLViewerRegion::PARTITION_AVATAR; - } + if (isHUDAttachment()) + { + return LLViewerRegion::PARTITION_HUD; + } + if (isAnimatedObject() && getControlAvatar()) + { + return LLViewerRegion::PARTITION_CONTROL_AV; + } + if (isAttachment()) + { + return LLViewerRegion::PARTITION_AVATAR; + } - return LLViewerRegion::PARTITION_VOLUME; + return LLViewerRegion::PARTITION_VOLUME; } LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp) : LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, regionp), LLVolumeGeometryManager() { - mLODPeriod = 32; - mDepthMask = FALSE; - mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; - mPartitionType = LLViewerRegion::PARTITION_VOLUME; - mSlopRatio = 0.25f; + mLODPeriod = 32; + mDepthMask = FALSE; + mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; + mPartitionType = LLViewerRegion::PARTITION_VOLUME; + mSlopRatio = 0.25f; } LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp) : LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp), LLVolumeGeometryManager() { - mDepthMask = FALSE; - mLODPeriod = 32; - mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; - mPartitionType = LLViewerRegion::PARTITION_BRIDGE; - - mSlopRatio = 0.25f; + mDepthMask = FALSE; + mLODPeriod = 32; + mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; + mPartitionType = LLViewerRegion::PARTITION_BRIDGE; + + mSlopRatio = 0.25f; } LLAvatarBridge::LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp) - : LLVolumeBridge(drawablep, regionp) + : LLVolumeBridge(drawablep, regionp) { - mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; - mPartitionType = LLViewerRegion::PARTITION_AVATAR; + mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; + mPartitionType = LLViewerRegion::PARTITION_AVATAR; } LLControlAVBridge::LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp) - : LLVolumeBridge(drawablep, regionp) + : LLVolumeBridge(drawablep, regionp) { - mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV; - mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV; + mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV; + mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV; } void LLControlAVBridge::updateSpatialExtents() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE - LLSpatialGroup* root = (LLSpatialGroup*)mOctree->getListener(0); + LLSpatialGroup* root = (LLSpatialGroup*)mOctree->getListener(0); - bool rootWasDirty = root->isDirty(); + bool rootWasDirty = root->isDirty(); - super::updateSpatialExtents(); // root becomes non-dirty here + super::updateSpatialExtents(); // root becomes non-dirty here - // SL-18251 "On-screen animesh characters using pelvis offset animations - // disappear when root goes off-screen" - // - // Expand extents to include Control Avatar placed outside of the bounds + // SL-18251 "On-screen animesh characters using pelvis offset animations + // disappear when root goes off-screen" + // + // Expand extents to include Control Avatar placed outside of the bounds LLControlAvatar* controlAvatar = getVObj() ? getVObj()->getControlAvatar() : NULL; if (controlAvatar && controlAvatar->mDrawable && controlAvatar->mDrawable->getEntry() && (rootWasDirty || controlAvatar->mPlaying)) - { - root->expandExtents(controlAvatar->mDrawable->getSpatialExtents(), *mDrawable->getXform()); - } + { + root->expandExtents(controlAvatar->mDrawable->getSpatialExtents(), *mDrawable->getXform()); + } } bool can_batch_texture(LLFace* facep) { - if (facep->getTextureEntry()->getBumpmap()) - { //bump maps aren't worked into texture batching yet - return false; - } - - if (facep->getTextureEntry()->getMaterialParams().notNull()) - { //materials don't work with texture batching yet - return false; - } - - if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA) - { //can't batch invisiprims - return false; - } - - if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) - { //texture animation breaks batches - return false; - } - + if (facep->getTextureEntry()->getBumpmap()) + { //bump maps aren't worked into texture batching yet + return false; + } + + if (facep->getTextureEntry()->getMaterialParams().notNull()) + { //materials don't work with texture batching yet + return false; + } + + if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA) + { //can't batch invisiprims + return false; + } + + if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) + { //texture animation breaks batches + return false; + } + if (facep->getTextureEntry()->getGLTFRenderMaterial() != nullptr) { // PBR materials break indexed texture batching return false; } - return true; + return true; } const static U32 MAX_FACE_COUNT = 4096U; @@ -5125,27 +5125,27 @@ LLFace** LLVolumeGeometryManager::sPbrFaces[2] = { NULL }; LLFace** LLVolumeGeometryManager::sAlphaFaces[2] = { NULL }; LLVolumeGeometryManager::LLVolumeGeometryManager() - : LLGeometryManager() + : LLGeometryManager() { - llassert(sInstanceCount >= 0); - if (sInstanceCount == 0) - { - allocateFaces(MAX_FACE_COUNT); - } + llassert(sInstanceCount >= 0); + if (sInstanceCount == 0) + { + allocateFaces(MAX_FACE_COUNT); + } - ++sInstanceCount; + ++sInstanceCount; } LLVolumeGeometryManager::~LLVolumeGeometryManager() { - llassert(sInstanceCount > 0); - --sInstanceCount; + llassert(sInstanceCount > 0); + --sInstanceCount; - if (sInstanceCount <= 0) - { - freeFaces(); - sInstanceCount = 0; - } + if (sInstanceCount <= 0) + { + freeFaces(); + sInstanceCount = 0; + } } void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount) @@ -5190,22 +5190,22 @@ void LLVolumeGeometryManager::freeFaces() void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - if ( type == LLRenderPass::PASS_ALPHA - && facep->getTextureEntry()->getMaterialParams().notNull() - && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT) - && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1) - { - LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; - } + if ( type == LLRenderPass::PASS_ALPHA + && facep->getTextureEntry()->getMaterialParams().notNull() + && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT) + && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1) + { + LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; + } - bool selected = facep->getViewerObject()->isSelected(); + bool selected = facep->getViewerObject()->isSelected(); - if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects) - { - return; - } + if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects) + { + return; + } - LL_LABEL_VERTEX_BUFFER(facep->getVertexBuffer(), LLRenderPass::lookupPassName(type)); + LL_LABEL_VERTEX_BUFFER(facep->getVertexBuffer(), LLRenderPass::lookupPassName(type)); U32 passType = type; @@ -5217,66 +5217,66 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, // See LLRenderPass PASS_foo enum passType += 1; } - //add face to drawmap - LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[passType]; + //add face to drawmap + LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[passType]; - S32 idx = draw_vec.size()-1; + S32 idx = draw_vec.size()-1; - bool fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || - (type == LLRenderPass::PASS_INVISIBLE) || - (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || - (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) || - (facep->getTextureEntry()->getFullbright()); - - if (!fullbright && - type != LLRenderPass::PASS_GLOW && + bool fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || + (type == LLRenderPass::PASS_INVISIBLE) || + (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || + (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) || + (facep->getTextureEntry()->getFullbright()); + + if (!fullbright && + type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL)) - { + { llassert(false); - LL_WARNS() << "Non fullbright face has no normals!" << LL_ENDL; - return; - } + LL_WARNS() << "Non fullbright face has no normals!" << LL_ENDL; + return; + } + + const LLMatrix4* tex_mat = NULL; + if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) + { + tex_mat = facep->mTextureMatrix; + } - const LLMatrix4* tex_mat = NULL; - if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) - { - tex_mat = facep->mTextureMatrix; - } + const LLMatrix4* model_mat = NULL; - const LLMatrix4* model_mat = NULL; + LLDrawable* drawable = facep->getDrawable(); - LLDrawable* drawable = facep->getDrawable(); - if (rigged) { // rigged meshes ignore their model matrix model_mat = nullptr; } - else if (drawable->isState(LLDrawable::ANIMATED_CHILD)) - { - model_mat = &drawable->getWorldMatrix(); - } - else if (drawable->isActive()) - { - model_mat = &drawable->getRenderMatrix(); - } - else - { - model_mat = &(drawable->getRegion()->mRenderMatrix); - } - - //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); + else if (drawable->isState(LLDrawable::ANIMATED_CHILD)) + { + model_mat = &drawable->getWorldMatrix(); + } + else if (drawable->isActive()) + { + model_mat = &drawable->getRenderMatrix(); + } + else + { + model_mat = &(drawable->getRegion()->mRenderMatrix); + } + + //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); const LLTextureEntry* te = facep->getTextureEntry(); - U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? te->getBumpmap() : 0; - U8 shiny = te->getShiny(); - - LLViewerTexture* tex = facep->getTexture(); + U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? te->getBumpmap() : 0; + U8 shiny = te->getShiny(); - U8 index = facep->getTextureIndex(); + LLViewerTexture* tex = facep->getTexture(); + + U8 index = facep->getTextureIndex(); LLMaterial* mat = nullptr; - + LLUUID mat_id; auto* gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial(); @@ -5298,110 +5298,110 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } } - bool batchable = false; - - U32 shader_mask = 0xFFFFFFFF; //no shader - - if (mat) - { - BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (te->getColor().mV[3] < 0.999f) ? TRUE : FALSE; - if (type == LLRenderPass::PASS_ALPHA) - { - shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND, is_alpha); - } - else - { - shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT, is_alpha); - } - } - - if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) - { - if (mat || gltf_mat || draw_vec[idx]->mMaterial) - { //can't batch textures when materials are present (yet) - batchable = false; - } - else if (index < draw_vec[idx]->mTextureList.size()) - { - if (draw_vec[idx]->mTextureList[index].isNull()) - { - batchable = true; - draw_vec[idx]->mTextureList[index] = tex; - } - else if (draw_vec[idx]->mTextureList[index] == tex) - { //this face's texture index can be used with this batch - batchable = true; - } - } - else - { //texture list can be expanded to fit this texture index - batchable = true; - } - } + bool batchable = false; + + U32 shader_mask = 0xFFFFFFFF; //no shader + + if (mat) + { + BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (te->getColor().mV[3] < 0.999f) ? TRUE : FALSE; + if (type == LLRenderPass::PASS_ALPHA) + { + shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND, is_alpha); + } + else + { + shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT, is_alpha); + } + } + + if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) + { + if (mat || gltf_mat || draw_vec[idx]->mMaterial) + { //can't batch textures when materials are present (yet) + batchable = false; + } + else if (index < draw_vec[idx]->mTextureList.size()) + { + if (draw_vec[idx]->mTextureList[index].isNull()) + { + batchable = true; + draw_vec[idx]->mTextureList[index] = tex; + } + else if (draw_vec[idx]->mTextureList[index] == tex) + { //this face's texture index can be used with this batch + batchable = true; + } + } + else + { //texture list can be expanded to fit this texture index + batchable = true; + } + } LLDrawInfo* info = idx >= 0 ? draw_vec[idx] : nullptr; - if (info && - info->mVertexBuffer == facep->getVertexBuffer() && - info->mEnd == facep->getGeomIndex()-1 && - (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) && + if (info && + info->mVertexBuffer == facep->getVertexBuffer() && + info->mEnd == facep->getGeomIndex()-1 && + (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) && #if LL_DARWIN - info->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && - info->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && + info->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && + info->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && #endif - info->mMaterialID == mat_id && - info->mFullbright == fullbright && - info->mBump == bump && - (!mat || (info->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different - info->mTextureMatrix == tex_mat && - info->mModelMatrix == model_mat && - info->mShaderMask == shader_mask && + info->mMaterialID == mat_id && + info->mFullbright == fullbright && + info->mBump == bump && + (!mat || (info->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different + info->mTextureMatrix == tex_mat && + info->mModelMatrix == model_mat && + info->mShaderMask == shader_mask && info->mAvatar == facep->mAvatar && info->getSkinHash() == facep->getSkinHash()) - { - info->mCount += facep->getIndicesCount(); - info->mEnd += facep->getGeomCount(); - - if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= info->mTextureList.size()) - { - info->mTextureList.resize(index+1); - info->mTextureList[index] = tex; - } - info->validate(); - } - else - { - U32 start = facep->getGeomIndex(); - U32 end = start + facep->getGeomCount()-1; - U32 offset = facep->getIndicesStart(); - U32 count = facep->getIndicesCount(); - LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex, - facep->getVertexBuffer(), fullbright, bump); + { + info->mCount += facep->getIndicesCount(); + info->mEnd += facep->getGeomCount(); + + if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= info->mTextureList.size()) + { + info->mTextureList.resize(index+1); + info->mTextureList[index] = tex; + } + info->validate(); + } + else + { + U32 start = facep->getGeomIndex(); + U32 end = start + facep->getGeomCount()-1; + U32 offset = facep->getIndicesStart(); + U32 count = facep->getIndicesCount(); + LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex, + facep->getVertexBuffer(), fullbright, bump); info = draw_info; - draw_vec.push_back(draw_info); - draw_info->mTextureMatrix = tex_mat; - draw_info->mModelMatrix = model_mat; - - draw_info->mBump = bump; - draw_info->mShiny = shiny; - - static const float alpha[4] = - { - 0.00f, - 0.25f, - 0.5f, - 0.75f - }; - float spec = alpha[shiny & TEM_SHINY_MASK]; - LLVector4 specColor(spec, spec, spec, spec); - draw_info->mSpecColor = specColor; - draw_info->mEnvIntensity = spec; - draw_info->mSpecularMap = NULL; - draw_info->mMaterial = mat; + draw_vec.push_back(draw_info); + draw_info->mTextureMatrix = tex_mat; + draw_info->mModelMatrix = model_mat; + + draw_info->mBump = bump; + draw_info->mShiny = shiny; + + static const float alpha[4] = + { + 0.00f, + 0.25f, + 0.5f, + 0.75f + }; + float spec = alpha[shiny & TEM_SHINY_MASK]; + LLVector4 specColor(spec, spec, spec, spec); + draw_info->mSpecColor = specColor; + draw_info->mEnvIntensity = spec; + draw_info->mSpecularMap = NULL; + draw_info->mMaterial = mat; draw_info->mGLTFMaterial = gltf_mat; - draw_info->mShaderMask = shader_mask; + draw_info->mShaderMask = shader_mask; draw_info->mAvatar = facep->mAvatar; draw_info->mSkinInfo = facep->mSkinInfo; @@ -5411,58 +5411,58 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mMaterialID = mat_id; } else if (mat) - { - draw_info->mMaterialID = mat_id; - - // We have a material. Update our draw info accordingly. - - if (!mat->getSpecularID().isNull()) - { - LLVector4 specColor; - specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f); - specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f); - specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f); - specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f); - draw_info->mSpecColor = specColor; - draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f); - draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset()); - } - - draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); - draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); - draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); - } - else - { - if (type == LLRenderPass::PASS_GRASS) - { - draw_info->mAlphaMaskCutoff = 0.5f; - } - else - { - draw_info->mAlphaMaskCutoff = 0.33f; - } - } - - // if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr - { //for alpha sorting - facep->setDrawInfo(draw_info); - } - - if (index < FACE_DO_NOT_BATCH_TEXTURES) - { //initialize texture list for texture batching - draw_info->mTextureList.resize(index+1); - draw_info->mTextureList[index] = tex; - } - draw_info->validate(); - } + { + draw_info->mMaterialID = mat_id; + + // We have a material. Update our draw info accordingly. + + if (!mat->getSpecularID().isNull()) + { + LLVector4 specColor; + specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f); + specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f); + specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f); + specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f); + draw_info->mSpecColor = specColor; + draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f); + draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset()); + } + + draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); + draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); + draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); + } + else + { + if (type == LLRenderPass::PASS_GRASS) + { + draw_info->mAlphaMaskCutoff = 0.5f; + } + else + { + draw_info->mAlphaMaskCutoff = 0.33f; + } + } + + // if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr + { //for alpha sorting + facep->setDrawInfo(draw_info); + } + + if (index < FACE_DO_NOT_BATCH_TEXTURES) + { //initialize texture list for texture batching + draw_info->mTextureList.resize(index+1); + draw_info->mTextureList[index] = tex; + } + draw_info->validate(); + } llassert(info->mGLTFMaterial == nullptr || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TANGENT) != 0); llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR || info->mGLTFMaterial != nullptr); llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_RIGGED || info->mGLTFMaterial != nullptr); llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK || info->mGLTFMaterial != nullptr); llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED || info->mGLTFMaterial != nullptr); - + llassert(type != LLRenderPass::PASS_BUMP || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TANGENT) != 0); llassert(type != LLRenderPass::PASS_NORMSPEC || info->mNormalMap.notNull()); llassert(type != LLRenderPass::PASS_SPECMAP || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TEXCOORD2) != 0); @@ -5505,93 +5505,93 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) return; } - if (group->changeLOD()) - { - group->mLastUpdateDistance = group->mDistance; - } + if (group->changeLOD()) + { + group->mLastUpdateDistance = group->mDistance; + } - group->mLastUpdateViewAngle = group->mViewAngle; + group->mLastUpdateViewAngle = group->mViewAngle; - if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY)) - { - if (group->hasState(LLSpatialGroup::MESH_DIRTY)) - { - rebuildMesh(group); - } - return; - } + if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY)) + { + if (group->hasState(LLSpatialGroup::MESH_DIRTY)) + { + rebuildMesh(group); + } + return; + } + + group->mBuilt = 1.f; - group->mBuilt = 1.f; - - LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); + LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); LLViewerObject *vobj = NULL; LLVOVolume *vol_obj = NULL; - if (bridge) - { + if (bridge) + { vobj = bridge->mDrawable->getVObj(); vol_obj = dynamic_cast<LLVOVolume*>(vobj); - } + } if (vol_obj) { vol_obj->updateVisualComplexity(); } - group->mGeometryBytes = 0; - group->mSurfaceArea = 0; - - //cache object box size since it might be used for determining visibility - const LLVector4a* bounds = group->getObjectBounds(); - group->mObjectBoxSize = bounds[1].getLength3().getF32(); + group->mGeometryBytes = 0; + group->mSurfaceArea = 0; - group->clearDrawMap(); + //cache object box size since it might be used for determining visibility + const LLVector4a* bounds = group->getObjectBounds(); + group->mObjectBoxSize = bounds[1].getLength3().getF32(); + + group->clearDrawMap(); U32 fullbright_count[2] = { 0 }; - U32 bump_count[2] = { 0 }; - U32 simple_count[2] = { 0 }; - U32 alpha_count[2] = { 0 }; - U32 norm_count[2] = { 0 }; - U32 spec_count[2] = { 0 }; - U32 normspec_count[2] = { 0 }; - U32 pbr_count[2] = { 0 }; - - static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); - static LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536); - U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - max_vertices = llmin(max_vertices, (U32) 65535); - - U32 cur_total = 0; - - bool emissive = false; - - //Determine if we've received skininfo that contains an - //alternate bind matrix - if it does then apply the translational component - //to the joints of the avatar. + U32 bump_count[2] = { 0 }; + U32 simple_count[2] = { 0 }; + U32 alpha_count[2] = { 0 }; + U32 norm_count[2] = { 0 }; + U32 spec_count[2] = { 0 }; + U32 normspec_count[2] = { 0 }; + U32 pbr_count[2] = { 0 }; + + static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); + static LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536); + U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); + U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); + max_vertices = llmin(max_vertices, (U32) 65535); + + U32 cur_total = 0; + + bool emissive = false; + + //Determine if we've received skininfo that contains an + //alternate bind matrix - if it does then apply the translational component + //to the joints of the avatar. #if 0 - bool pelvisGotSet = false; + bool pelvisGotSet = false; #endif - { + { LL_PROFILE_ZONE_NAMED("rebuildGeom - face list"); - //get all the faces into a list - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); + //get all the faces into a list + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - - if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) - { - continue; - } - - LLVOVolume* vobj = drawablep->getVOVolume(); - - if (!vobj || vobj->isDead()) - { - continue; - } + { + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + + if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) + { + continue; + } + + LLVOVolume* vobj = drawablep->getVOVolume(); + + if (!vobj || vobj->isDead()) + { + continue; + } // HACK -- brute force this check every time a drawable gets rebuilt for (S32 i = 0; i < drawablep->getNumFaces(); ++i) @@ -5621,24 +5621,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } - LLVolume* volume = vobj->getVolume(); - if (volume) - { - const LLVector3& scale = vobj->getScale(); - group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); - } + LLVolume* volume = vobj->getVolume(); + if (volume) + { + const LLVector3& scale = vobj->getScale(); + group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); + } + - F32 est_tris = vobj->getEstTrianglesMax(); vobj->updateControlAvatar(); - + LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment() << " is_mesh " << is_mesh << " est_tris " << est_tris << " is_animated " << vobj->isAnimatedObject() - << " can_animate " << vobj->canBeAnimatedObject() - << " cav " << vobj->getControlAvatar() + << " can_animate " << vobj->canBeAnimatedObject() + << " cav " << vobj->getControlAvatar() << " lod " << vobj->getLOD() << " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED)) << " drawable state " << drawablep->getState() @@ -5646,11 +5646,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) << " frame " << LLFrameTimer::getFrameCount() << LL_ENDL; - llassert_always(vobj); - vobj->updateTextureVirtualSize(true); - vobj->preRebuild(); + llassert_always(vobj); + vobj->updateTextureVirtualSize(true); + vobj->preRebuild(); - drawablep->clearState(LLDrawable::HAS_ALPHA); + drawablep->clearState(LLDrawable::HAS_ALPHA); LLVOAvatar* avatar = nullptr; const LLMeshSkinInfo* skinInfo = nullptr; @@ -5676,23 +5676,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) avatar->addAttachmentOverridesForObject(vobj, NULL, false); } - // Standard rigged mesh attachments: - bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); + // Standard rigged mesh attachments: + bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); // Animated objects. Have to check for isRiggedMesh() to // exclude static objects in animated object linksets. - rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() && + rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() && vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying); - bool any_rigged_face = false; + bool any_rigged_face = false; - //for each face - for (S32 i = 0; i < drawablep->getNumFaces(); i++) - { - LLFace* facep = drawablep->getFace(i); - if (!facep) - { - continue; - } + //for each face + for (S32 i = 0; i < drawablep->getNumFaces(); i++) + { + LLFace* facep = drawablep->getFace(i); + if (!facep) + { + continue; + } #if 0 #if LL_RELEASE_WITH_DEBUG_INFO const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" ); @@ -5706,12 +5706,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool is_pbr = gltf_mat != nullptr; #endif - //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render - // batch, it will recover its vertex buffer reference from the spatial group - facep->setVertexBuffer(NULL); - - //sum up face verts and indices - drawablep->updateFaceSize(i); + //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render + // batch, it will recover its vertex buffer reference from the spatial group + facep->setVertexBuffer(NULL); + + //sum up face verts and indices + drawablep->updateFaceSize(i); if (rigged) { @@ -5728,7 +5728,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) else { if (facep->isState(LLFace::RIGGED)) - { + { //face is not rigged but used to be, remove from rigged face pool LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool(); if (pool) @@ -5741,84 +5741,84 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } - if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) - { - facep->clearVertexBuffer(); - continue; - } + if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) + { + facep->clearVertexBuffer(); + continue; + } - if (facep->hasGeometry() && + if (facep->hasGeometry() && (rigged || // <-- HACK FIXME -- getPixelArea might be incorrect for rigged objects facep->getPixelArea() > FORCE_CULL_AREA)) // <-- don't render tiny faces - { + { cur_total += facep->getGeomCount(); - const LLTextureEntry* te = facep->getTextureEntry(); - LLViewerTexture* tex = facep->getTexture(); + const LLTextureEntry* te = facep->getTextureEntry(); + LLViewerTexture* tex = facep->getTexture(); - if (te->getGlow() > 0.f) - { - emissive = true; - } + if (te->getGlow() > 0.f) + { + emissive = true; + } - if (facep->isState(LLFace::TEXTURE_ANIM)) - { - if (!vobj->mTexAnimMode) - { - facep->clearState(LLFace::TEXTURE_ANIM); - } - } + if (facep->isState(LLFace::TEXTURE_ANIM)) + { + if (!vobj->mTexAnimMode) + { + facep->clearState(LLFace::TEXTURE_ANIM); + } + } - BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); - U32 type = gPipeline.getPoolTypeFromTE(te, tex); + BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); + U32 type = gPipeline.getPoolTypeFromTE(te, tex); if (is_pbr && gltf_mat && gltf_mat->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_BLEND) { type = LLDrawPool::POOL_GLTF_PBR; } else - if (type != LLDrawPool::POOL_ALPHA && force_simple) - { - type = LLDrawPool::POOL_SIMPLE; - } - facep->setPoolType(type); - - if (vobj->isHUDAttachment() && !is_pbr) - { - facep->setState(LLFace::FULLBRIGHT); - } - - if (vobj->mTextureAnimp && vobj->mTexAnimMode) - { - if (vobj->mTextureAnimp->mFace <= -1) - { - S32 face; - for (face = 0; face < vobj->getNumTEs(); face++) - { - LLFace * facep = drawablep->getFace(face); - if (facep) - { - facep->setState(LLFace::TEXTURE_ANIM); - } - } - } - else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) - { - LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace); - if (facep) - { - facep->setState(LLFace::TEXTURE_ANIM); - } - } - } - - if (type == LLDrawPool::POOL_ALPHA) - { - if (facep->canRenderAsMask()) - { //can be treated as alpha mask + if (type != LLDrawPool::POOL_ALPHA && force_simple) + { + type = LLDrawPool::POOL_SIMPLE; + } + facep->setPoolType(type); + + if (vobj->isHUDAttachment() && !is_pbr) + { + facep->setState(LLFace::FULLBRIGHT); + } + + if (vobj->mTextureAnimp && vobj->mTexAnimMode) + { + if (vobj->mTextureAnimp->mFace <= -1) + { + S32 face; + for (face = 0; face < vobj->getNumTEs(); face++) + { + LLFace * facep = drawablep->getFace(face); + if (facep) + { + facep->setState(LLFace::TEXTURE_ANIM); + } + } + } + else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) + { + LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace); + if (facep) + { + facep->setState(LLFace::TEXTURE_ANIM); + } + } + } + + if (type == LLDrawPool::POOL_ALPHA) + { + if (facep->canRenderAsMask()) + { //can be treated as alpha mask add_face(sSimpleFaces, simple_count, facep); - } - else - { + } + else + { F32 alpha; if (is_pbr) { @@ -5829,33 +5829,33 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) alpha = te->getColor().mV[3]; } if (alpha > 0.f || te->getGlow() > 0.f) - { //only treat as alpha in the pipeline if < 100% transparent - drawablep->setState(LLDrawable::HAS_ALPHA); - add_face(sAlphaFaces, alpha_count, facep); - } - else if (LLDrawPoolAlpha::sShowDebugAlpha || - (gPipeline.sRenderHighlight && !drawablep->getParent() && - //only root objects are highlighted with red color in this case - drawablep->getVObj() && drawablep->getVObj()->flagScripted() && - (LLPipeline::getRenderScriptedBeacons() || - (LLPipeline::getRenderScriptedTouchBeacons() && drawablep->getVObj()->flagHandleTouch())))) - { //draw the transparent face for debugging purposes using a custom texture - add_face(sAlphaFaces, alpha_count, facep); - } - } - } - else - { - if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) - { - facep->mLastUpdateTime = gFrameTimeSeconds; - } - - { + { //only treat as alpha in the pipeline if < 100% transparent + drawablep->setState(LLDrawable::HAS_ALPHA); + add_face(sAlphaFaces, alpha_count, facep); + } + else if (LLDrawPoolAlpha::sShowDebugAlpha || + (gPipeline.sRenderHighlight && !drawablep->getParent() && + //only root objects are highlighted with red color in this case + drawablep->getVObj() && drawablep->getVObj()->flagScripted() && + (LLPipeline::getRenderScriptedBeacons() || + (LLPipeline::getRenderScriptedTouchBeacons() && drawablep->getVObj()->flagHandleTouch())))) + { //draw the transparent face for debugging purposes using a custom texture + add_face(sAlphaFaces, alpha_count, facep); + } + } + } + else + { + if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) + { + facep->mLastUpdateTime = gFrameTimeSeconds; + } + + { LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); - if (gltf_mat != nullptr || (te->getMaterialParams().notNull())) - { + if (gltf_mat != nullptr || (te->getMaterialParams().notNull())) + { if (gltf_mat != nullptr) { add_face(sPbrFaces, pbr_count, facep); @@ -5884,91 +5884,91 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) add_face(sSimpleFaces, simple_count, facep); } } - } - else if (te->getBumpmap()) - { //needs normal + tangent + } + else if (te->getBumpmap()) + { //needs normal + tangent add_face(sBumpFaces, bump_count, facep); - } - else if (te->getShiny() || !te->getFullbright()) - { //needs normal + } + else if (te->getShiny() || !te->getFullbright()) + { //needs normal add_face(sSimpleFaces, simple_count, facep); - } - else - { //doesn't need normal - facep->setState(LLFace::FULLBRIGHT); + } + else + { //doesn't need normal + facep->setState(LLFace::FULLBRIGHT); add_face(sFullbrightFaces, fullbright_count, facep); - } - } - } - } - else - { //face has no renderable geometry - facep->clearVertexBuffer(); - } - } - - if (any_rigged_face) - { - if (!drawablep->isState(LLDrawable::RIGGED)) - { - drawablep->setState(LLDrawable::RIGGED); + } + } + } + } + else + { //face has no renderable geometry + facep->clearVertexBuffer(); + } + } + + if (any_rigged_face) + { + if (!drawablep->isState(LLDrawable::RIGGED)) + { + drawablep->setState(LLDrawable::RIGGED); LLDrawable* root = drawablep->getRoot(); if (root != drawablep) { root->setState(LLDrawable::RIGGED_CHILD); } - //first time this is drawable is being marked as rigged, - // do another LoD update to use avatar bounding box - vobj->updateLOD(); - } - } - else - { - drawablep->clearState(LLDrawable::RIGGED); + //first time this is drawable is being marked as rigged, + // do another LoD update to use avatar bounding box + vobj->updateLOD(); + } + } + else + { + drawablep->clearState(LLDrawable::RIGGED); vobj->updateRiggedVolume(false); - } - } - } - - //PROCESS NON-ALPHA FACES - U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; - U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO - U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; - U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; - - U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; - U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2; - U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2; - - U32 pbr_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TANGENT; - - if (emissive) - { //emissive faces are present, include emissive byte to preserve batching - simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE; - alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE; - bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE; - fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE; - norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE; - normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE; - spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE; + } + } + } + + //PROCESS NON-ALPHA FACES + U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; + U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO + U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; + U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; + + U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; + U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2; + U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2; + + U32 pbr_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TANGENT; + + if (emissive) + { //emissive faces are present, include emissive byte to preserve batching + simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE; + alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE; + bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE; + fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE; + norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE; + normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE; + spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE; pbr_mask = pbr_mask | LLVertexBuffer::MAP_EMISSIVE; - } + } - BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; + BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; // add extra vertex data for deferred rendering (not necessarily for batching textures) - if (batch_textures) - { - bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; - simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; - alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; - fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; - } + if (batch_textures) + { + bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT; + simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; + alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2; + fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX; + } - group->mGeometryBytes = 0; + group->mGeometryBytes = 0; - U32 geometryBytes = 0; + U32 geometryBytes = 0; // generate render batches for static geometry U32 extra_mask = LLVertexBuffer::MAP_TEXTURE_INDEX; @@ -5990,70 +5990,70 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) rigged = TRUE; } - group->mGeometryBytes = geometryBytes; + group->mGeometryBytes = geometryBytes; - { - //drawables have been rebuilt, clear rebuild status - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if(drawablep) - { + { + //drawables have been rebuilt, clear rebuild status + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) + { + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + if(drawablep) + { drawablep->clearState(LLDrawable::REBUILD_ALL); } } - } + } - group->mLastUpdateTime = gFrameTimeSeconds; - group->mBuilt = 1.f; - group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY); + group->mLastUpdateTime = gFrameTimeSeconds; + group->mBuilt = 1.f; + group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY); } void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - llassert(group); - if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY)) - { - { + llassert(group); + if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY)) + { + { LL_PROFILE_ZONE_NAMED("rebuildMesh - gen draw info"); group->mBuilt = 1.f; - - const U32 MAX_BUFFER_COUNT = 4096; - LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; - U32 buffer_count = 0; + const U32 MAX_BUFFER_COUNT = 4096; + LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; + + U32 buffer_count = 0; for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - - if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL)) - { - LLVOVolume* vobj = drawablep->getVOVolume(); - - if (!vobj) continue; - - if (vobj->isNoLOD()) continue; - - vobj->preRebuild(); - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(true); - } - - LLVolume* volume = vobj->getVolume(); - if (!volume) continue; - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) - { - LLFace* face = drawablep->getFace(i); - if (face) - { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff) - { + { + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL)) + { + LLVOVolume* vobj = drawablep->getVOVolume(); + + if (!vobj) continue; + + if (vobj->isNoLOD()) continue; + + vobj->preRebuild(); + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } + + LLVolume* volume = vobj->getVolume(); + if (!volume) continue; + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + { + LLFace* face = drawablep->getFace(i); + if (face) + { + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff) + { if (!face->getGeometryVolume(*volume, // volume face->getTEOffset(), // face_index vobj->getRelativeXform(), // mat_vert_in @@ -6068,72 +6068,72 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) } buff->unmapBuffer(); - } - } - } + } + } + } - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(); - } + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(); + } - drawablep->clearState(LLDrawable::REBUILD_ALL); - } - } + drawablep->clearState(LLDrawable::REBUILD_ALL); + } + } - { + { LL_PROFILE_ZONE_NAMED("rebuildMesh - flush"); - for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) - { - (*iter)->unmapBuffer(); - } - - // don't forget alpha - if(group != NULL && - !group->mVertexBuffer.isNull()) - { - group->mVertexBuffer->unmapBuffer(); - } - } - - group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); - } - } + for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) + { + (*iter)->unmapBuffer(); + } + + // don't forget alpha + if(group != NULL && + !group->mVertexBuffer.isNull()) + { + group->mVertexBuffer->unmapBuffer(); + } + } + + group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); + } + } } struct CompareBatchBreaker { - bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) - { - const LLTextureEntry* lte = lhs->getTextureEntry(); - const LLTextureEntry* rte = rhs->getTextureEntry(); + bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) + { + const LLTextureEntry* lte = lhs->getTextureEntry(); + const LLTextureEntry* rte = rhs->getTextureEntry(); if (lte->getBumpmap() != rte->getBumpmap()) - { - return lte->getBumpmap() < rte->getBumpmap(); - } - else if (lte->getFullbright() != rte->getFullbright()) - { - return lte->getFullbright() < rte->getFullbright(); - } + { + return lte->getBumpmap() < rte->getBumpmap(); + } + else if (lte->getFullbright() != rte->getFullbright()) + { + return lte->getFullbright() < rte->getFullbright(); + } else if (lte->getMaterialID() != rte->getMaterialID()) { return lte->getMaterialID() < rte->getMaterialID(); } - else if (lte->getShiny() != rte->getShiny()) - { - return lte->getShiny() < rte->getShiny(); - } + else if (lte->getShiny() != rte->getShiny()) + { + return lte->getShiny() < rte->getShiny(); + } else if (lhs->getTexture() != rhs->getTexture()) - { - return lhs->getTexture() < rhs->getTexture(); - } - else + { + return lhs->getTexture() < rhs->getTexture(); + } + else { // all else being equal, maintain consistent draw order return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex(); } - } + } }; struct CompareBatchBreakerRigged @@ -6161,16 +6161,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - U32 geometryBytes = 0; - - //calculate maximum number of vertices to store in a single buffer - static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); - U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - max_vertices = llmin(max_vertices, (U32) 65535); + U32 geometryBytes = 0; + + //calculate maximum number of vertices to store in a single buffer + static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); + U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); + max_vertices = llmin(max_vertices, (U32) 65535); - { + { LL_PROFILE_ZONE_NAMED("genDrawInfo - sort"); - + if (rigged) { if (!distance_sort) // <--- alpha "sort" rigged faces by maintaining original draw order @@ -6184,289 +6184,289 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace //sort faces by things that break batches, not including avatar and mesh id std::sort(faces, faces + face_count, CompareBatchBreaker()); } - else - { - //sort faces by distance - std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater()); - } - } - - bool hud_group = group->isHUDGroup() ; - LLFace** face_iter = faces; - LLFace** end_faces = faces+face_count; - - LLSpatialGroup::buffer_map_t buffer_map; - - LLViewerTexture* last_tex = NULL; - - S32 texture_index_channels = 1; - - if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) - { - texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity; - } - - if (distance_sort) - { - texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels; - } - - texture_index_channels = LLGLSLShader::sIndexedTextureChannels; - - bool flexi = false; - - while (face_iter != end_faces) - { - //pull off next face - LLFace* facep = *face_iter; - LLViewerTexture* tex = facep->getTexture(); + else + { + //sort faces by distance + std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater()); + } + } + + bool hud_group = group->isHUDGroup() ; + LLFace** face_iter = faces; + LLFace** end_faces = faces+face_count; + + LLSpatialGroup::buffer_map_t buffer_map; + + LLViewerTexture* last_tex = NULL; + + S32 texture_index_channels = 1; + + if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) + { + texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity; + } + + if (distance_sort) + { + texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels; + } + + texture_index_channels = LLGLSLShader::sIndexedTextureChannels; + + bool flexi = false; + + while (face_iter != end_faces) + { + //pull off next face + LLFace* facep = *face_iter; + LLViewerTexture* tex = facep->getTexture(); const LLTextureEntry* te = facep->getTextureEntry(); - LLMaterialPtr mat = te->getMaterialParams(); + LLMaterialPtr mat = te->getMaterialParams(); LLMaterialID matId = te->getMaterialID(); - if (distance_sort) - { - tex = NULL; - } + if (distance_sort) + { + tex = NULL; + } - if (last_tex != tex) - { - last_tex = tex; - } + if (last_tex != tex) + { + last_tex = tex; + } + + bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic(); + + U32 index_count = facep->getIndicesCount(); + U32 geom_count = facep->getGeomCount(); - bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic(); + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); - U32 index_count = facep->getIndicesCount(); - U32 geom_count = facep->getGeomCount(); + //sum up vertices needed for this render batch + LLFace** i = face_iter; + ++i; - flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + const U32 MAX_TEXTURE_COUNT = 32; + LLViewerTexture* texture_list[MAX_TEXTURE_COUNT]; - //sum up vertices needed for this render batch - LLFace** i = face_iter; - ++i; - - const U32 MAX_TEXTURE_COUNT = 32; - LLViewerTexture* texture_list[MAX_TEXTURE_COUNT]; - - U32 texture_count = 0; + U32 texture_count = 0; - { + { LL_PROFILE_ZONE_NAMED("genDrawInfo - face size"); - if (batch_textures) - { - U8 cur_tex = 0; - facep->setTextureIndex(cur_tex); - if (texture_count < MAX_TEXTURE_COUNT) - { - texture_list[texture_count++] = tex; - } - - if (can_batch_texture(facep)) - { //populate texture_list with any textures that can be batched - //move i to the next unbatchable face - while (i != end_faces) - { - facep = *i; - - if (!can_batch_texture(facep)) - { //face is bump mapped or has an animated texture matrix -- can't - //batch more than 1 texture at a time - facep->setTextureIndex(0); - break; - } - - if (facep->getTexture() != tex) - { - if (distance_sort) - { //textures might be out of order, see if texture exists in current batch - bool found = false; - for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx) - { - if (facep->getTexture() == texture_list[tex_idx]) - { - cur_tex = tex_idx; - found = true; - break; - } - } - - if (!found) - { - cur_tex = texture_count; - } - } - else - { - cur_tex++; - } - - if (cur_tex >= texture_index_channels) - { //cut batches when index channels are depleted - break; - } - - tex = facep->getTexture(); - - if (texture_count < MAX_TEXTURE_COUNT) - { - texture_list[texture_count++] = tex; - } - } - - if (geom_count + facep->getGeomCount() > max_vertices) - { //cut batches on geom count too big - break; - } - - ++i; - - flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); - - index_count += facep->getIndicesCount(); - geom_count += facep->getGeomCount(); - - facep->setTextureIndex(cur_tex); - } - } - else - { - facep->setTextureIndex(0); - } - - tex = texture_list[0]; - } - else - { - while (i != end_faces && - (LLPipeline::sTextureBindTest || - (distance_sort || - ((*i)->getTexture() == tex)))) - { - facep = *i; + if (batch_textures) + { + U8 cur_tex = 0; + facep->setTextureIndex(cur_tex); + if (texture_count < MAX_TEXTURE_COUNT) + { + texture_list[texture_count++] = tex; + } + + if (can_batch_texture(facep)) + { //populate texture_list with any textures that can be batched + //move i to the next unbatchable face + while (i != end_faces) + { + facep = *i; + + if (!can_batch_texture(facep)) + { //face is bump mapped or has an animated texture matrix -- can't + //batch more than 1 texture at a time + facep->setTextureIndex(0); + break; + } + + if (facep->getTexture() != tex) + { + if (distance_sort) + { //textures might be out of order, see if texture exists in current batch + bool found = false; + for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx) + { + if (facep->getTexture() == texture_list[tex_idx]) + { + cur_tex = tex_idx; + found = true; + break; + } + } + + if (!found) + { + cur_tex = texture_count; + } + } + else + { + cur_tex++; + } + + if (cur_tex >= texture_index_channels) + { //cut batches when index channels are depleted + break; + } + + tex = facep->getTexture(); + + if (texture_count < MAX_TEXTURE_COUNT) + { + texture_list[texture_count++] = tex; + } + } + + if (geom_count + facep->getGeomCount() > max_vertices) + { //cut batches on geom count too big + break; + } + + ++i; + + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + + index_count += facep->getIndicesCount(); + geom_count += facep->getGeomCount(); + + facep->setTextureIndex(cur_tex); + } + } + else + { + facep->setTextureIndex(0); + } + + tex = texture_list[0]; + } + else + { + while (i != end_faces && + (LLPipeline::sTextureBindTest || + (distance_sort || + ((*i)->getTexture() == tex)))) + { + facep = *i; const LLTextureEntry* nextTe = facep->getTextureEntry(); if (nextTe->getMaterialID() != matId) { break; } - //face has no texture index - facep->mDrawInfo = NULL; - facep->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES); + //face has no texture index + facep->mDrawInfo = NULL; + facep->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES); - if (geom_count + facep->getGeomCount() > max_vertices) - { //cut batches on geom count too big - break; - } + if (geom_count + facep->getGeomCount() > max_vertices) + { //cut batches on geom count too big + break; + } - ++i; - index_count += facep->getIndicesCount(); - geom_count += facep->getGeomCount(); + ++i; + index_count += facep->getIndicesCount(); + geom_count += facep->getGeomCount(); - flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); - } - } - } + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + } + } + } - //create vertex buffer - LLPointer<LLVertexBuffer> buffer; + //create vertex buffer + LLPointer<LLVertexBuffer> buffer; - { + { LL_PROFILE_ZONE_NAMED("genDrawInfo - allocate"); - buffer = new LLVertexBuffer(mask); - if(!buffer->allocateBuffer(geom_count, index_count)) - { - LL_WARNS() << "Failed to allocate group Vertex Buffer to " - << geom_count << " vertices and " - << index_count << " indices" << LL_ENDL; - buffer = NULL; - } - } - - if (buffer) - { - geometryBytes += buffer->getSize() + buffer->getIndicesSize(); - buffer_map[mask][*face_iter].push_back(buffer); - } - - //add face geometry - - U32 indices_index = 0; - U16 index_offset = 0; + buffer = new LLVertexBuffer(mask); + if(!buffer->allocateBuffer(geom_count, index_count)) + { + LL_WARNS() << "Failed to allocate group Vertex Buffer to " + << geom_count << " vertices and " + << index_count << " indices" << LL_ENDL; + buffer = NULL; + } + } + + if (buffer) + { + geometryBytes += buffer->getSize() + buffer->getIndicesSize(); + buffer_map[mask][*face_iter].push_back(buffer); + } + + //add face geometry + + U32 indices_index = 0; + U16 index_offset = 0; while (face_iter < i) - { - //update face indices for new buffer - facep = *face_iter; - - if (buffer.isNull()) - { - // Bulk allocation failed - facep->setVertexBuffer(buffer); - facep->setSize(0, 0); // mark as no geometry - ++face_iter; - continue; - } - facep->setIndicesIndex(indices_index); - facep->setGeomIndex(index_offset); - facep->setVertexBuffer(buffer); - - if (batch_textures && facep->getTextureIndex() == FACE_DO_NOT_BATCH_TEXTURES) - { - LL_ERRS() << "Invalid texture index." << LL_ENDL; - } - - { - //for debugging, set last time face was updated vs moved - facep->updateRebuildFlags(); - - { //copy face geometry into vertex buffer - LLDrawable* drawablep = facep->getDrawable(); - LLVOVolume* vobj = drawablep->getVOVolume(); - LLVolume* volume = vobj->getVolume(); - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(true); - } - - U32 te_idx = facep->getTEOffset(); - - if (!facep->getGeometryVolume(*volume, te_idx, - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true)) - { - LL_WARNS() << "Failed to get geometry for face!" << LL_ENDL; - } - - if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) - { - vobj->updateRelativeXform(false); - } - } - } - - index_offset += facep->getGeomCount(); - indices_index += facep->getIndicesCount(); - - //append face to appropriate render batch - - BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; - BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); - if ((mask & LLVertexBuffer::MAP_NORMAL) == 0) - { //paranoia check to make sure GL doesn't try to read non-existant normals - fullbright = TRUE; - } + { + //update face indices for new buffer + facep = *face_iter; + + if (buffer.isNull()) + { + // Bulk allocation failed + facep->setVertexBuffer(buffer); + facep->setSize(0, 0); // mark as no geometry + ++face_iter; + continue; + } + facep->setIndicesIndex(indices_index); + facep->setGeomIndex(index_offset); + facep->setVertexBuffer(buffer); + + if (batch_textures && facep->getTextureIndex() == FACE_DO_NOT_BATCH_TEXTURES) + { + LL_ERRS() << "Invalid texture index." << LL_ENDL; + } + + { + //for debugging, set last time face was updated vs moved + facep->updateRebuildFlags(); + + { //copy face geometry into vertex buffer + LLDrawable* drawablep = facep->getDrawable(); + LLVOVolume* vobj = drawablep->getVOVolume(); + LLVolume* volume = vobj->getVolume(); + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } + + U32 te_idx = facep->getTEOffset(); + + if (!facep->getGeometryVolume(*volume, te_idx, + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true)) + { + LL_WARNS() << "Failed to get geometry for face!" << LL_ENDL; + } + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(false); + } + } + } + + index_offset += facep->getGeomCount(); + indices_index += facep->getIndicesCount(); + + //append face to appropriate render batch + + BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA; + BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); + if ((mask & LLVertexBuffer::MAP_NORMAL) == 0) + { //paranoia check to make sure GL doesn't try to read non-existant normals + fullbright = TRUE; + } const LLTextureEntry* te = facep->getTextureEntry(); LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); - if (hud_group && gltf_mat == nullptr) - { //all hud attachments are fullbright - fullbright = TRUE; - } - - tex = facep->getTexture(); + if (hud_group && gltf_mat == nullptr) + { //all hud attachments are fullbright + fullbright = TRUE; + } - BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE; + tex = facep->getTexture(); + + BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE; LLMaterial* mat = nullptr; bool can_be_shiny = false; @@ -6486,8 +6486,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } F32 blinn_phong_alpha = te->getColor().mV[3]; - bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull()); - bool blinn_phong_opaque = blinn_phong_alpha >= 0.999f; + bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull()); + bool blinn_phong_opaque = blinn_phong_alpha >= 0.999f; bool blinn_phong_transparent = blinn_phong_alpha < 0.999f; if (!gltf_mat) @@ -6495,9 +6495,9 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace is_alpha = (is_alpha || blinn_phong_transparent) ? TRUE : FALSE; } - if (gltf_mat || (mat && !hud_group)) - { - bool material_pass = false; + if (gltf_mat || (mat && !hud_group)) + { + bool material_pass = false; if (gltf_mat) { // all other parameters ignored if gltf material is present @@ -6515,82 +6515,82 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } } else - // do NOT use 'fullbright' for this logic or you risk sending - // things without normals down the materials pipeline and will - // render poorly if not crash NORSPEC-240,314 - // - if (te->getFullbright()) - { - if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) - { - if (blinn_phong_opaque) - { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); - } - else - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - } - else if (is_alpha) - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - else - { - if (mat->getEnvironmentIntensity() > 0 || te->getShiny() > 0) - { - material_pass = true; - } - else - { + // do NOT use 'fullbright' for this logic or you risk sending + // things without normals down the materials pipeline and will + // render poorly if not crash NORSPEC-240,314 + // + if (te->getFullbright()) + { + if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { + if (blinn_phong_opaque) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + } + else if (is_alpha) + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + else + { + if (mat->getEnvironmentIntensity() > 0 || te->getShiny() > 0) + { + material_pass = true; + } + else + { if (blinn_phong_opaque) - { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); } else { registerFace(group, facep, LLRenderPass::PASS_ALPHA); } - } - } - } - else if (blinn_phong_transparent) - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - else if (use_legacy_bump) - { + } + } + } + else if (blinn_phong_transparent) + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + else if (use_legacy_bump) + { llassert(mask & LLVertexBuffer::MAP_TANGENT); - // we have a material AND legacy bump settings, but no normal map - registerFace(group, facep, LLRenderPass::PASS_BUMP); - } - else - { - material_pass = true; - } - - if (material_pass) - { - static const U32 pass[] = - { - LLRenderPass::PASS_MATERIAL, - LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA, - LLRenderPass::PASS_MATERIAL_ALPHA_MASK, - LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, - LLRenderPass::PASS_SPECMAP, - LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND, - LLRenderPass::PASS_SPECMAP_MASK, - LLRenderPass::PASS_SPECMAP_EMISSIVE, - LLRenderPass::PASS_NORMMAP, - LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND, - LLRenderPass::PASS_NORMMAP_MASK, - LLRenderPass::PASS_NORMMAP_EMISSIVE, - LLRenderPass::PASS_NORMSPEC, - LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND, - LLRenderPass::PASS_NORMSPEC_MASK, - LLRenderPass::PASS_NORMSPEC_EMISSIVE, - }; + // we have a material AND legacy bump settings, but no normal map + registerFace(group, facep, LLRenderPass::PASS_BUMP); + } + else + { + material_pass = true; + } + + if (material_pass) + { + static const U32 pass[] = + { + LLRenderPass::PASS_MATERIAL, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA, + LLRenderPass::PASS_MATERIAL_ALPHA_MASK, + LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, + LLRenderPass::PASS_SPECMAP, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND, + LLRenderPass::PASS_SPECMAP_MASK, + LLRenderPass::PASS_SPECMAP_EMISSIVE, + LLRenderPass::PASS_NORMMAP, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND, + LLRenderPass::PASS_NORMMAP_MASK, + LLRenderPass::PASS_NORMMAP_EMISSIVE, + LLRenderPass::PASS_NORMSPEC, + LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND, + LLRenderPass::PASS_NORMSPEC_MASK, + LLRenderPass::PASS_NORMSPEC_EMISSIVE, + }; U32 alpha_mode = mat->getDiffuseAlphaMode(); if (!distance_sort && alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) @@ -6601,180 +6601,180 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace U32 vb_mask = facep->getVertexBuffer()->getTypeMask(); - // HACK - this should also never happen, but sometimes we get here and the material thinks it has a specmap now + // HACK - this should also never happen, but sometimes we get here and the material thinks it has a specmap now // even though it didn't appear to have a specmap when the face was added to the list of faces if ((mask & 0x4) && !(vb_mask & LLVertexBuffer::MAP_TEXCOORD2)) { mask &= ~0x4; } - llassert(mask < sizeof(pass)/sizeof(U32)); + llassert(mask < sizeof(pass)/sizeof(U32)); - mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1)); + mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1)); // if this is going into alpha pool, distance sort MUST be true llassert(pass[mask] == LLRenderPass::PASS_ALPHA ? distance_sort : true); - registerFace(group, facep, pass[mask]); - } - } - else if (mat) - { - U8 mode = mat->getDiffuseAlphaMode(); + registerFace(group, facep, pass[mask]); + } + } + else if (mat) + { + U8 mode = mat->getDiffuseAlphaMode(); is_alpha = (is_alpha || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)); - if (is_alpha) - { - mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; - } - - if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) - { - registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK); - } - else if (is_alpha ) - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - else if (gPipeline.shadersLoaded() - && te->getShiny() - && can_be_shiny) - { - registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY); - } - else - { - registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE); - } - } - else if (is_alpha) - { - // can we safely treat this as an alpha mask? - if (facep->getFaceColor().mV[3] <= 0.f) - { //100% transparent, don't render unless we're highlighting transparent - registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE); - } - else if (facep->canRenderAsMask() && !hud_group) - { - if (te->getFullbright() || LLPipeline::sNoAlpha) - { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); - } - else - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); - } - } - else - { - registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - } - else if (gPipeline.shadersLoaded() - && te->getShiny() - && can_be_shiny) - { //shiny - if (tex->getPrimaryFormat() == GL_ALPHA) - { //invisiprim+shiny - registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); - registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); - } - else if (!hud_group) - { //deferred rendering - if (te->getFullbright()) - { //register in post deferred fullbright shiny pass - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); - if (te->getBumpmap()) - { //register in post deferred bump pass - registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); - } - } - else if (use_legacy_bump) - { //register in deferred bump pass + if (is_alpha) + { + mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + } + + if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { + registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK); + } + else if (is_alpha ) + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + else if (gPipeline.shadersLoaded() + && te->getShiny() + && can_be_shiny) + { + registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY); + } + else + { + registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE); + } + } + else if (is_alpha) + { + // can we safely treat this as an alpha mask? + if (facep->getFaceColor().mV[3] <= 0.f) + { //100% transparent, don't render unless we're highlighting transparent + registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE); + } + else if (facep->canRenderAsMask() && !hud_group) + { + if (te->getFullbright() || LLPipeline::sNoAlpha) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); + } + } + else + { + registerFace(group, facep, LLRenderPass::PASS_ALPHA); + } + } + else if (gPipeline.shadersLoaded() + && te->getShiny() + && can_be_shiny) + { //shiny + if (tex->getPrimaryFormat() == GL_ALPHA) + { //invisiprim+shiny + registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); + registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + } + else if (!hud_group) + { //deferred rendering + if (te->getFullbright()) + { //register in post deferred fullbright shiny pass + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); + if (te->getBumpmap()) + { //register in post deferred bump pass + registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); + } + } + else if (use_legacy_bump) + { //register in deferred bump pass llassert(mask& LLVertexBuffer::MAP_TANGENT); - registerFace(group, facep, LLRenderPass::PASS_BUMP); - } - else - { //register in deferred simple pass (deferred simple includes shiny) - llassert(mask & LLVertexBuffer::MAP_NORMAL); - registerFace(group, facep, LLRenderPass::PASS_SIMPLE); - } - } - else if (fullbright) - { //not deferred, register in standard fullbright shiny pass - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); - } - else - { //not deferred or fullbright, register in standard shiny pass - registerFace(group, facep, LLRenderPass::PASS_SHINY); - } - } - else - { //not alpha and not shiny - if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA) - { //invisiprim - registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); - } - else if (fullbright || bake_sunlight) - { //fullbright - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) - { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); - } - else - { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); - } - if (!hud_group && use_legacy_bump) - { //if this is the deferred render and a bump map is present, register in post deferred bump - registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); - } - } - else - { - if (use_legacy_bump) - { //non-shiny or fullbright deferred bump + registerFace(group, facep, LLRenderPass::PASS_BUMP); + } + else + { //register in deferred simple pass (deferred simple includes shiny) + llassert(mask & LLVertexBuffer::MAP_NORMAL); + registerFace(group, facep, LLRenderPass::PASS_SIMPLE); + } + } + else if (fullbright) + { //not deferred, register in standard fullbright shiny pass + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); + } + else + { //not deferred or fullbright, register in standard shiny pass + registerFace(group, facep, LLRenderPass::PASS_SHINY); + } + } + else + { //not alpha and not shiny + if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA) + { //invisiprim + registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + } + else if (fullbright || bake_sunlight) + { //fullbright + if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); + } + if (!hud_group && use_legacy_bump) + { //if this is the deferred render and a bump map is present, register in post deferred bump + registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); + } + } + else + { + if (use_legacy_bump) + { //non-shiny or fullbright deferred bump llassert(mask& LLVertexBuffer::MAP_TANGENT); - registerFace(group, facep, LLRenderPass::PASS_BUMP); - } - else - { //all around simple - llassert(mask & LLVertexBuffer::MAP_NORMAL); - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) - { //material alpha mask can be respected in non-deferred - registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); - } - else - { - registerFace(group, facep, LLRenderPass::PASS_SIMPLE); - } - } - } - - - if (!gPipeline.shadersLoaded() && - !is_alpha && - te->getShiny()) - { //shiny as an extra pass when shaders are disabled - registerFace(group, facep, LLRenderPass::PASS_SHINY); - } - } - - //not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010 - if (!is_alpha && hud_group) - { - llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); - facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); - - if (!force_simple && use_legacy_bump) - { + registerFace(group, facep, LLRenderPass::PASS_BUMP); + } + else + { //all around simple + llassert(mask & LLVertexBuffer::MAP_NORMAL); + if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + { //material alpha mask can be respected in non-deferred + registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_SIMPLE); + } + } + } + + + if (!gPipeline.shadersLoaded() && + !is_alpha && + te->getShiny()) + { //shiny as an extra pass when shaders are disabled + registerFace(group, facep, LLRenderPass::PASS_SHINY); + } + } + + //not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010 + if (!is_alpha && hud_group) + { + llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); + facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); + + if (!force_simple && use_legacy_bump) + { llassert(mask & LLVertexBuffer::MAP_TANGENT); - registerFace(group, facep, LLRenderPass::PASS_BUMP); - } - } + registerFace(group, facep, LLRenderPass::PASS_BUMP); + } + } - if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f) - { + if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f) + { if (gltf_mat) { registerFace(group, facep, LLRenderPass::PASS_GLTF_GLOW); @@ -6783,24 +6783,24 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace { registerFace(group, facep, LLRenderPass::PASS_GLOW); } - } - - ++face_iter; - } + } + + ++face_iter; + } - if (buffer) - { - buffer->unmapBuffer(); - } - } + if (buffer) + { + buffer->unmapBuffer(); + } + } - group->mBufferMap[mask].clear(); - for (LLSpatialGroup::buffer_texture_map_t::iterator i = buffer_map[mask].begin(); i != buffer_map[mask].end(); ++i) - { - group->mBufferMap[mask][i->first] = i->second; - } + group->mBufferMap[mask].clear(); + for (LLSpatialGroup::buffer_texture_map_t::iterator i = buffer_map[mask].begin(); i != buffer_map[mask].end(); ++i) + { + group->mBufferMap[mask][i->first] = i->second; + } - return geometryBytes; + return geometryBytes; } void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count) @@ -6818,57 +6818,57 @@ void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& verte } void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) -{ +{ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //clear off any old faces mFaceList.clear(); - //for each drawable - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - - if (!drawablep || drawablep->isDead()) - { - continue; - } - - //for each face - for (S32 i = 0; i < drawablep->getNumFaces(); i++) - { - //sum up face verts and indices - drawablep->updateFaceSize(i); - LLFace* facep = drawablep->getFace(i); - if (facep) - { - if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA && - facep->getGeomCount() + vertex_count <= 65536) - { - vertex_count += facep->getGeomCount(); - index_count += facep->getIndicesCount(); - - //remember face (for sorting) - mFaceList.push_back(facep); - } - else - { - facep->clearVertexBuffer(); - } - } - } - } + //for each drawable + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) + { + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + + if (!drawablep || drawablep->isDead()) + { + continue; + } + + //for each face + for (S32 i = 0; i < drawablep->getNumFaces(); i++) + { + //sum up face verts and indices + drawablep->updateFaceSize(i); + LLFace* facep = drawablep->getFace(i); + if (facep) + { + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA && + facep->getGeomCount() + vertex_count <= 65536) + { + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); + + //remember face (for sorting) + mFaceList.push_back(facep); + } + else + { + facep->clearVertexBuffer(); + } + } + } + } } LLHUDPartition::LLHUDPartition(LLViewerRegion* regionp) : LLBridgePartition(regionp) { - mPartitionType = LLViewerRegion::PARTITION_HUD; - mDrawableType = LLPipeline::RENDER_TYPE_HUD; - mSlopRatio = 0.f; - mLODPeriod = 1; + mPartitionType = LLViewerRegion::PARTITION_HUD; + mDrawableType = LLPipeline::RENDER_TYPE_HUD; + mSlopRatio = 0.f; + mLODPeriod = 1; } void LLHUDPartition::shift(const LLVector4a &offset) { - //HUD objects don't shift with region crossing. That would be silly. + //HUD objects don't shift with region crossing. That would be silly. } |