A bunch of supersize sculpty fixes by Thickbrick

This commit is contained in:
Siana Gearz
2011-02-16 20:59:00 +01:00
parent da61fc8195
commit 94c13d3131
5 changed files with 208 additions and 34 deletions

View File

@@ -106,6 +106,9 @@ public:
F32 getVirtualSize() const { return mVSize; } F32 getVirtualSize() const { return mVSize; }
F32 getPixelArea() const { return mPixelArea; } F32 getPixelArea() const { return mPixelArea; }
S32 getIndexInTex() const {return mIndexInTex ;}
void setIndexInTex(S32 index) { mIndexInTex = index ;}
void renderSetColor() const; void renderSetColor() const;
S32 renderElements(const U16 *index_array) const; S32 renderElements(const U16 *index_array) const;
S32 renderIndexed (); S32 renderIndexed ();
@@ -226,6 +229,7 @@ private:
U16 mGeomIndex; // index into draw pool U16 mGeomIndex; // index into draw pool
U32 mIndicesCount; U32 mIndicesCount;
U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!) U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!)
S32 mIndexInTex ;
//previous rebuild's geometry info //previous rebuild's geometry info
U16 mLastGeomCount; U16 mLastGeomCount;

View File

@@ -61,6 +61,7 @@
#include "llappviewer.h" #include "llappviewer.h"
#include "llface.h" #include "llface.h"
#include "llviewercamera.h" #include "llviewercamera.h"
#include "llvovolume.h"
// <edit> // <edit>
#include "llimagemetadatareader.h" #include "llimagemetadatareader.h"
@@ -357,6 +358,11 @@ void LLViewerImage::init(bool firstinit)
mDesiredSavedRawDiscardLevel = -1 ; mDesiredSavedRawDiscardLevel = -1 ;
mCanUseHTTP = true; //default on if cap/settings allows us mCanUseHTTP = true; //default on if cap/settings allows us
mNumFaces = 0 ;
mNumVolumes = 0;
mFaceList.clear() ;
mVolumeList.clear();
} }
// virtual // virtual
@@ -393,6 +399,7 @@ LLViewerImage::~LLViewerImage()
void LLViewerImage::cleanup() void LLViewerImage::cleanup()
{ {
mFaceList.clear() ; mFaceList.clear() ;
mVolumeList.clear();
for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
iter != mLoadedCallbackList.end(); ) iter != mLoadedCallbackList.end(); )
{ {
@@ -753,19 +760,19 @@ void LLViewerImage::updateVirtualSize()
{ {
addTextureStats(0.f, FALSE) ;//reset addTextureStats(0.f, FALSE) ;//reset
} }
if(mFaceList.size() > 0) for(U32 i = 0 ; i < mNumFaces ; i++)
{ {
for(std::list<LLFace*>::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) LLFace* facep = mFaceList[i] ;
if(facep->getDrawable()->isRecentlyVisible())
{ {
LLFace* facep = *iter ; addTextureStats(facep->getVirtualSize()) ;
if(facep->getDrawable()->isRecentlyVisible()) setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
{
addTextureStats(facep->getVirtualSize()) ;
setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
}
} }
} }
mNeedsResetMaxVirtualSize = TRUE ; mNeedsResetMaxVirtualSize = TRUE ;
reorganizeFaceList();
reorganizeVolumeList();
#endif #endif
} }
void LLViewerImage::scaleDown() void LLViewerImage::scaleDown()
@@ -1755,13 +1762,19 @@ void LLViewerImage::setCachedRawImage()
if(mForSculpt) if(mForSculpt)
{ {
max_size = MAX_CACHED_RAW_SCULPT_IMAGE_AREA ; max_size = MAX_CACHED_RAW_SCULPT_IMAGE_AREA ;
// Even though we don't use the full pixel size, we want to decode up to discard 0,
// because some legacy sculpts are weird like that.
mCachedRawImageReady = !mRawDiscardLevel ;
}
else
{
mCachedRawImageReady = (!mRawDiscardLevel || ((w * h) >= max_size)) ;
} }
while(((w >> i) * (h >> i)) > max_size) while(((w >> i) * (h >> i)) > max_size)
{ {
++i ; ++i ;
} }
mCachedRawImageReady = (!mRawDiscardLevel || ((w * h) >= max_size)) ;
if(i) if(i)
{ {
@@ -1772,7 +1785,8 @@ void LLViewerImage::setCachedRawImage()
mRawImage->scale(w >> i, h >> i) ; mRawImage->scale(w >> i, h >> i) ;
} }
mCachedRawImage = mRawImage ; mCachedRawImage = mRawImage ;
mCachedRawDiscardLevel = mRawDiscardLevel + i ; mRawDiscardLevel += i ;
mCachedRawDiscardLevel = mRawDiscardLevel ;
} }
} }
@@ -1780,7 +1794,7 @@ void LLViewerImage::checkCachedRawSculptImage()
{ {
if(mCachedRawImageReady && mCachedRawDiscardLevel > 0) if(mCachedRawImageReady && mCachedRawDiscardLevel > 0)
{ {
if(mCachedRawImage->getWidth() * mCachedRawImage->getHeight() < MAX_CACHED_RAW_SCULPT_IMAGE_AREA) if(getDiscardLevel() != 0)
{ {
mCachedRawImageReady = FALSE ; mCachedRawImageReady = FALSE ;
} }
@@ -1806,11 +1820,111 @@ void LLViewerImage::setForSculpt()
checkCachedRawSculptImage() ; checkCachedRawSculptImage() ;
} }
//virtual
void LLViewerImage::addFace(LLFace* facep) void LLViewerImage::addFace(LLFace* facep)
{ {
mFaceList.push_back(facep) ; if(mNumFaces >= mFaceList.size())
{
mFaceList.resize(2 * mNumFaces + 1) ;
}
mFaceList[mNumFaces] = facep ;
facep->setIndexInTex(mNumFaces) ;
mNumFaces++ ;
mLastFaceListUpdateTimer.reset() ;
} }
//virtual
void LLViewerImage::removeFace(LLFace* facep) void LLViewerImage::removeFace(LLFace* facep)
{ {
mFaceList.remove(facep) ; if(mNumFaces > 1)
{
S32 index = facep->getIndexInTex() ;
mFaceList[index] = mFaceList[--mNumFaces] ;
mFaceList[index]->setIndexInTex(index) ;
}
else
{
mFaceList.clear() ;
mNumFaces = 0 ;
}
mLastFaceListUpdateTimer.reset() ;
}
S32 LLViewerImage::getNumFaces() const
{
return mNumFaces ;
}
//virtual
void LLViewerImage::addVolume(LLVOVolume* volumep)
{
if( mNumVolumes >= mVolumeList.size())
{
mVolumeList.resize(2 * mNumVolumes + 1) ;
}
mVolumeList[mNumVolumes] = volumep ;
volumep->setIndexInTex(mNumVolumes) ;
mNumVolumes++ ;
mLastVolumeListUpdateTimer.reset() ;
}
//virtual
void LLViewerImage::removeVolume(LLVOVolume* volumep)
{
if(mNumVolumes > 1)
{
S32 index = volumep->getIndexInTex() ;
mVolumeList[index] = mVolumeList[--mNumVolumes] ;
mVolumeList[index]->setIndexInTex(index) ;
}
else
{
mVolumeList.clear() ;
mNumVolumes = 0 ;
}
mLastVolumeListUpdateTimer.reset() ;
}
S32 LLViewerImage::getNumVolumes() const
{
return mNumVolumes ;
}
void LLViewerImage::reorganizeFaceList()
{
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
if(mNumFaces + MAX_EXTRA_BUFFER_SIZE > mFaceList.size())
{
return ;
}
if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
{
return ;
}
mLastFaceListUpdateTimer.reset() ;
mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end());
}
void LLViewerImage::reorganizeVolumeList()
{
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
if(mNumVolumes + MAX_EXTRA_BUFFER_SIZE > mVolumeList.size())
{
return ;
}
if(mLastVolumeListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
{
return ;
}
mLastVolumeListUpdateTimer.reset() ;
mVolumeList.erase(mVolumeList.begin() + mNumVolumes, mVolumeList.end());
} }

View File

@@ -51,6 +51,7 @@ typedef void (*loaded_callback_func)( BOOL success, LLViewerImage *src_vi, LLIma
class LLVFile; class LLVFile;
class LLMessageSystem; class LLMessageSystem;
class LLVOVolume;
class LLLoadedCallbackEntry class LLLoadedCallbackEntry
{ {
@@ -209,6 +210,9 @@ public:
INVALID_DISCARD_LEVEL = 0x7fff INVALID_DISCARD_LEVEL = 0x7fff
}; };
typedef std::vector<LLFace*> ll_face_list_t;
typedef std::vector<LLVOVolume*> ll_volume_list_t;
protected: protected:
/*virtual*/ ~LLViewerImage(); /*virtual*/ ~LLViewerImage();
@@ -317,8 +321,17 @@ public:
BOOL isSameTexture(const LLViewerImage* tex) const ; BOOL isSameTexture(const LLViewerImage* tex) const ;
void addFace(LLFace* facep) ; virtual void addFace(LLFace* facep) ;
void removeFace(LLFace* facep) ; virtual void removeFace(LLFace* facep) ;
S32 getNumFaces() const;
const ll_face_list_t* getFaceList() const {return &mFaceList;}
void reorganizeFaceList() ;
virtual void addVolume(LLVOVolume* volumep);
virtual void removeVolume(LLVOVolume* volumep);
S32 getNumVolumes() const;
const ll_volume_list_t* getVolumeList() const { return &mVolumeList; }
void reorganizeVolumeList() ;
void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}; void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;};
@@ -424,8 +437,13 @@ private:
BOOL mForSculpt ; //a flag if the texture is used for a sculpt data. BOOL mForSculpt ; //a flag if the texture is used for a sculpt data.
mutable BOOL mNeedsResetMaxVirtualSize ; mutable BOOL mNeedsResetMaxVirtualSize ;
typedef std::list<LLFace*> ll_face_list_t ; ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture U32 mNumFaces ;
LLFrameTimer mLastFaceListUpdateTimer ;
ll_volume_list_t mVolumeList;
U32 mNumVolumes;
LLFrameTimer mLastVolumeListUpdateTimer;
bool mCanUseHTTP; // can this image be fetched by http bool mCanUseHTTP; // can this image be fetched by http

View File

@@ -88,12 +88,12 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mRelativeXformInvTrans.setIdentity(); mRelativeXformInvTrans.setIdentity();
mLOD = MIN_LOD; mLOD = MIN_LOD;
mSculptLevel = -2;
mTextureAnimp = NULL; mTextureAnimp = NULL;
mVObjRadius = LLVector3(1,1,0.5f).length(); mVObjRadius = LLVector3(1,1,0.5f).length();
mNumFaces = 0; mNumFaces = 0;
mLODChanged = FALSE; mLODChanged = FALSE;
mSculptChanged = FALSE; mSculptChanged = FALSE;
mIndexInTex = 0;
} }
LLVOVolume::~LLVOVolume() LLVOVolume::~LLVOVolume()
@@ -513,9 +513,8 @@ void LLVOVolume::updateTextureVirtualSize()
if (isSculpted()) if (isSculpted())
{ {
LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); updateSculptTexture();
LLUUID id = sculpt_params->getSculptTexture();
mSculptTexture = gImageList.getImage(id);
if (mSculptTexture.notNull()) if (mSculptTexture.notNull())
{ {
mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
@@ -538,8 +537,8 @@ void LLVOVolume::updateTextureVirtualSize()
} }
} }
S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture
S32 current_discard = mSculptLevel; S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ;
if (texture_discard >= 0 && //texture has some data available if (texture_discard >= 0 && //texture has some data available
(texture_discard < current_discard || //texture has more data than last rebuild (texture_discard < current_discard || //texture has more data than last rebuild
@@ -692,25 +691,52 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail
mVolumeImpl->onSetVolume(volume_params, detail); mVolumeImpl->onSetVolume(volume_params, detail);
} }
updateSculptTexture();
if (isSculpted()) if (isSculpted())
{ {
mSculptTexture = gImageList.getImage(volume_params.getSculptID());
if (mSculptTexture.notNull()) if (mSculptTexture.notNull())
{ {
sculpt(); sculpt();
mSculptLevel = getVolume()->getSculptLevel();
} }
} }
else
{
mSculptTexture = NULL;
}
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
void LLVOVolume::updateSculptTexture()
{
LLPointer<LLViewerImage> old_sculpt = mSculptTexture;
if (isSculpted())
{
LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
LLUUID id = sculpt_params->getSculptTexture();
if (id.notNull())
{
mSculptTexture = gImageList.getImage(id);
}
}
else
{
mSculptTexture = NULL;
}
if (mSculptTexture != old_sculpt)
{
if (old_sculpt.notNull())
{
old_sculpt->removeVolume(this);
}
if (mSculptTexture.notNull())
{
mSculptTexture->addVolume(this);
}
}
}
// sculpt replaces generate() for sculpted surfaces // sculpt replaces generate() for sculpted surfaces
void LLVOVolume::sculpt() void LLVOVolume::sculpt()
{ {
@@ -721,7 +747,7 @@ void LLVOVolume::sculpt()
S8 sculpt_components = 0; S8 sculpt_components = 0;
const U8* sculpt_data = NULL; const U8* sculpt_data = NULL;
S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; S32 discard_level = mSculptTexture->getDiscardLevel();
LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ;
S32 max_discard = mSculptTexture->getMaxDiscardLevel(); S32 max_discard = mSculptTexture->getMaxDiscardLevel();
@@ -764,6 +790,16 @@ void LLVOVolume::sculpt()
sculpt_data = raw_image->getData(); sculpt_data = raw_image->getData();
} }
getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level); getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level);
//notify rebuild any other VOVolumes that reference this sculpty volume
for (S32 i = 0; i < mSculptTexture->getNumVolumes(); ++i)
{
LLVOVolume* volume = (*(mSculptTexture->getVolumeList()))[i];
if (volume != this && volume->getVolume() == getVolume())
{
gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY, FALSE);
}
}
} }
} }

View File

@@ -169,8 +169,10 @@ public:
/*virtual*/ BOOL setMaterial(const U8 material); /*virtual*/ BOOL setMaterial(const U8 material);
void setTexture(const S32 face); void setTexture(const S32 face);
S32 getIndexInTex() const {return mIndexInTex ;}
/*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false); /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
void updateSculptTexture();
void setIndexInTex(S32 index) { mIndexInTex = index ;}
void sculpt(); void sculpt();
void updateRelativeXform(); void updateRelativeXform();
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
@@ -228,7 +230,6 @@ private:
LLFrameTimer mTextureUpdateTimer; LLFrameTimer mTextureUpdateTimer;
S32 mLOD; S32 mLOD;
BOOL mLODChanged; BOOL mLODChanged;
S32 mSculptLevel;
BOOL mSculptChanged; BOOL mSculptChanged;
LLMatrix4 mRelativeXform; LLMatrix4 mRelativeXform;
LLMatrix3 mRelativeXformInvTrans; LLMatrix3 mRelativeXformInvTrans;
@@ -236,6 +237,7 @@ private:
F32 mVObjRadius; F32 mVObjRadius;
LLVolumeInterface *mVolumeImpl; LLVolumeInterface *mVolumeImpl;
LLPointer<LLViewerImage> mSculptTexture; LLPointer<LLViewerImage> mSculptTexture;
S32 mIndexInTex;
// statics // statics
public: public: