aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview
diff options
context:
space:
mode:
authorthickbrick2011-01-24 19:40:13 +0200
committerthickbrick2011-01-24 19:40:13 +0200
commit981e88b92549cae661a077490df693f1d207c808 (patch)
treea5021efb71a6216e33317019a18803cc40bfc27a /linden/indra/newview
parentPartial fix #772: Large sculpt maps are deformed (diff)
downloadmeta-impy-981e88b92549cae661a077490df693f1d207c808.zip
meta-impy-981e88b92549cae661a077490df693f1d207c808.tar.gz
meta-impy-981e88b92549cae661a077490df693f1d207c808.tar.bz2
meta-impy-981e88b92549cae661a077490df693f1d207c808.tar.xz
Additional Fix #772 and other sculpt problems
Port from V2 (Snowglobe2) that adds to each texture a list of faces and sculpt volumes that use that texture, and rebuild all sculpts when the texture is decoded. This is needed so that we don't depend on LOD changes which may never/rarely happen for some megaprim sculpts.
Diffstat (limited to 'linden/indra/newview')
-rw-r--r--linden/indra/newview/llface.h4
-rw-r--r--linden/indra/newview/llviewerimage.cpp131
-rw-r--r--linden/indra/newview/llviewerimage.h26
-rw-r--r--linden/indra/newview/llvovolume.cpp56
-rw-r--r--linden/indra/newview/llvovolume.h6
5 files changed, 195 insertions, 28 deletions
diff --git a/linden/indra/newview/llface.h b/linden/indra/newview/llface.h
index 4893e82..e31b93f 100644
--- a/linden/indra/newview/llface.h
+++ b/linden/indra/newview/llface.h
@@ -106,6 +106,9 @@ public:
106 F32 getVirtualSize() const { return mVSize; } 106 F32 getVirtualSize() const { return mVSize; }
107 F32 getPixelArea() const { return mPixelArea; } 107 F32 getPixelArea() const { return mPixelArea; }
108 108
109 S32 getIndexInTex() const {return mIndexInTex ;}
110 void setIndexInTex(S32 index) { mIndexInTex = index ;}
111
109 void renderSetColor() const; 112 void renderSetColor() const;
110 S32 renderElements(const U16 *index_array) const; 113 S32 renderElements(const U16 *index_array) const;
111 S32 renderIndexed (); 114 S32 renderIndexed ();
@@ -225,6 +228,7 @@ private:
225 U16 mGeomIndex; // index into draw pool 228 U16 mGeomIndex; // index into draw pool
226 U32 mIndicesCount; 229 U32 mIndicesCount;
227 U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!) 230 U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!)
231 S32 mIndexInTex ;
228 232
229 //previous rebuild's geometry info 233 //previous rebuild's geometry info
230 U16 mLastGeomCount; 234 U16 mLastGeomCount;
diff --git a/linden/indra/newview/llviewerimage.cpp b/linden/indra/newview/llviewerimage.cpp
index a600dc5..28561ed 100644
--- a/linden/indra/newview/llviewerimage.cpp
+++ b/linden/indra/newview/llviewerimage.cpp
@@ -61,6 +61,7 @@
61#include "llappviewer.h" 61#include "llappviewer.h"
62#include "llface.h" 62#include "llface.h"
63#include "llviewercamera.h" 63#include "llviewercamera.h"
64#include "llvovolume.h"
64/////////////////////////////////////////////////////////////////////////////// 65///////////////////////////////////////////////////////////////////////////////
65 66
66// statics 67// statics
@@ -352,6 +353,11 @@ void LLViewerImage::init(bool firstinit)
352 mDesiredSavedRawDiscardLevel = -1 ; 353 mDesiredSavedRawDiscardLevel = -1 ;
353 354
354 mCanUseHTTP = true; //default on if cap/settings allows us 355 mCanUseHTTP = true; //default on if cap/settings allows us
356
357 mNumFaces = 0 ;
358 mNumVolumes = 0;
359 mFaceList.clear() ;
360 mVolumeList.clear();
355} 361}
356 362
357// virtual 363// virtual
@@ -388,6 +394,7 @@ LLViewerImage::~LLViewerImage()
388void LLViewerImage::cleanup() 394void LLViewerImage::cleanup()
389{ 395{
390 mFaceList.clear() ; 396 mFaceList.clear() ;
397 mVolumeList.clear();
391 for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); 398 for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
392 iter != mLoadedCallbackList.end(); ) 399 iter != mLoadedCallbackList.end(); )
393 { 400 {
@@ -754,19 +761,19 @@ void LLViewerImage::updateVirtualSize()
754 { 761 {
755 addTextureStats(0.f, FALSE) ;//reset 762 addTextureStats(0.f, FALSE) ;//reset
756 } 763 }
757 if(mFaceList.size() > 0) 764 for(U32 i = 0 ; i < mNumFaces ; i++)
758 { 765 {
759 for(std::list<LLFace*>::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) 766 LLFace* facep = mFaceList[i] ;
767 if(facep->getDrawable()->isRecentlyVisible())
760 { 768 {
761 LLFace* facep = *iter ; 769 addTextureStats(facep->getVirtualSize()) ;
762 if(facep->getDrawable()->isRecentlyVisible()) 770 setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
763 { 771 }
764 addTextureStats(facep->getVirtualSize()) ;
765 setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
766 }
767 }
768 } 772 }
773
769 mNeedsResetMaxVirtualSize = TRUE ; 774 mNeedsResetMaxVirtualSize = TRUE ;
775 reorganizeFaceList();
776 reorganizeVolumeList();
770#endif 777#endif
771} 778}
772void LLViewerImage::scaleDown() 779void LLViewerImage::scaleDown()
@@ -1817,11 +1824,111 @@ void LLViewerImage::setForSculpt()
1817 checkCachedRawSculptImage() ; 1824 checkCachedRawSculptImage() ;
1818} 1825}
1819 1826
1827//virtual
1820void LLViewerImage::addFace(LLFace* facep) 1828void LLViewerImage::addFace(LLFace* facep)
1821{ 1829{
1822 mFaceList.push_back(facep) ; 1830 if(mNumFaces >= mFaceList.size())
1831 {
1832 mFaceList.resize(2 * mNumFaces + 1) ;
1833 }
1834 mFaceList[mNumFaces] = facep ;
1835 facep->setIndexInTex(mNumFaces) ;
1836 mNumFaces++ ;
1837 mLastFaceListUpdateTimer.reset() ;
1838}
1839
1840//virtual
1841void LLViewerImage::removeFace(LLFace* facep)
1842{
1843 if(mNumFaces > 1)
1844 {
1845 S32 index = facep->getIndexInTex() ;
1846 mFaceList[index] = mFaceList[--mNumFaces] ;
1847 mFaceList[index]->setIndexInTex(index) ;
1848 }
1849 else
1850 {
1851 mFaceList.clear() ;
1852 mNumFaces = 0 ;
1853 }
1854 mLastFaceListUpdateTimer.reset() ;
1855}
1856
1857S32 LLViewerImage::getNumFaces() const
1858{
1859 return mNumFaces ;
1860}
1861
1862
1863//virtual
1864void LLViewerImage::addVolume(LLVOVolume* volumep)
1865{
1866 if( mNumVolumes >= mVolumeList.size())
1867 {
1868 mVolumeList.resize(2 * mNumVolumes + 1) ;
1869 }
1870 mVolumeList[mNumVolumes] = volumep ;
1871 volumep->setIndexInTex(mNumVolumes) ;
1872 mNumVolumes++ ;
1873 mLastVolumeListUpdateTimer.reset() ;
1823} 1874}
1824void LLViewerImage::removeFace(LLFace* facep) 1875
1876//virtual
1877void LLViewerImage::removeVolume(LLVOVolume* volumep)
1825{ 1878{
1826 mFaceList.remove(facep) ; 1879 if(mNumVolumes > 1)
1880 {
1881 S32 index = volumep->getIndexInTex() ;
1882 mVolumeList[index] = mVolumeList[--mNumVolumes] ;
1883 mVolumeList[index]->setIndexInTex(index) ;
1884 }
1885 else
1886 {
1887 mVolumeList.clear() ;
1888 mNumVolumes = 0 ;
1889 }
1890 mLastVolumeListUpdateTimer.reset() ;
1891}
1892
1893S32 LLViewerImage::getNumVolumes() const
1894{
1895 return mNumVolumes ;
1896}
1897
1898void LLViewerImage::reorganizeFaceList()
1899{
1900 static const F32 MAX_WAIT_TIME = 20.f; // seconds
1901 static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
1902
1903 if(mNumFaces + MAX_EXTRA_BUFFER_SIZE > mFaceList.size())
1904 {
1905 return ;
1906 }
1907
1908 if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
1909 {
1910 return ;
1911 }
1912
1913 mLastFaceListUpdateTimer.reset() ;
1914 mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end());
1915}
1916
1917void LLViewerImage::reorganizeVolumeList()
1918{
1919 static const F32 MAX_WAIT_TIME = 20.f; // seconds
1920 static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
1921
1922 if(mNumVolumes + MAX_EXTRA_BUFFER_SIZE > mVolumeList.size())
1923 {
1924 return ;
1925 }
1926
1927 if(mLastVolumeListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
1928 {
1929 return ;
1930 }
1931
1932 mLastVolumeListUpdateTimer.reset() ;
1933 mVolumeList.erase(mVolumeList.begin() + mNumVolumes, mVolumeList.end());
1827} 1934}
diff --git a/linden/indra/newview/llviewerimage.h b/linden/indra/newview/llviewerimage.h
index 3bee51c..c2e3303 100644
--- a/linden/indra/newview/llviewerimage.h
+++ b/linden/indra/newview/llviewerimage.h
@@ -51,6 +51,7 @@ typedef void (*loaded_callback_func)( BOOL success, LLViewerImage *src_vi, LLIma
51 51
52class LLVFile; 52class LLVFile;
53class LLMessageSystem; 53class LLMessageSystem;
54class LLVOVolume;
54 55
55class LLLoadedCallbackEntry 56class LLLoadedCallbackEntry
56{ 57{
@@ -209,6 +210,9 @@ public:
209 INVALID_DISCARD_LEVEL = 0x7fff 210 INVALID_DISCARD_LEVEL = 0x7fff
210 }; 211 };
211 212
213 typedef std::vector<LLFace*> ll_face_list_t;
214 typedef std::vector<LLVOVolume*> ll_volume_list_t;
215
212protected: 216protected:
213 /*virtual*/ ~LLViewerImage(); 217 /*virtual*/ ~LLViewerImage();
214 218
@@ -311,8 +315,17 @@ public:
311 315
312 BOOL isSameTexture(const LLViewerImage* tex) const ; 316 BOOL isSameTexture(const LLViewerImage* tex) const ;
313 317
314 void addFace(LLFace* facep) ; 318 virtual void addFace(LLFace* facep) ;
315 void removeFace(LLFace* facep) ; 319 virtual void removeFace(LLFace* facep) ;
320 S32 getNumFaces() const;
321 const ll_face_list_t* getFaceList() const {return &mFaceList;}
322 void reorganizeFaceList() ;
323
324 virtual void addVolume(LLVOVolume* volumep);
325 virtual void removeVolume(LLVOVolume* volumep);
326 S32 getNumVolumes() const;
327 const ll_volume_list_t* getVolumeList() const { return &mVolumeList; }
328 void reorganizeVolumeList() ;
316 329
317 void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}; 330 void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;};
318 331
@@ -417,8 +430,13 @@ private:
417 BOOL mForSculpt ; //a flag if the texture is used for a sculpt data. 430 BOOL mForSculpt ; //a flag if the texture is used for a sculpt data.
418 mutable BOOL mNeedsResetMaxVirtualSize ; 431 mutable BOOL mNeedsResetMaxVirtualSize ;
419 432
420 typedef std::list<LLFace*> ll_face_list_t ; 433 ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
421 ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture 434 U32 mNumFaces ;
435 LLFrameTimer mLastFaceListUpdateTimer ;
436
437 ll_volume_list_t mVolumeList;
438 U32 mNumVolumes;
439 LLFrameTimer mLastVolumeListUpdateTimer;
422 440
423 bool mCanUseHTTP; // can this image be fetched by http 441 bool mCanUseHTTP; // can this image be fetched by http
424 442
diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp
index 632bca2..e4a0d0c 100644
--- a/linden/indra/newview/llvovolume.cpp
+++ b/linden/indra/newview/llvovolume.cpp
@@ -89,12 +89,12 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
89 mRelativeXformInvTrans.setIdentity(); 89 mRelativeXformInvTrans.setIdentity();
90 90
91 mLOD = MIN_LOD; 91 mLOD = MIN_LOD;
92 mSculptLevel = -2;
93 mTextureAnimp = NULL; 92 mTextureAnimp = NULL;
94 mVObjRadius = LLVector3(1,1,0.5f).length(); 93 mVObjRadius = LLVector3(1,1,0.5f).length();
95 mNumFaces = 0; 94 mNumFaces = 0;
96 mLODChanged = FALSE; 95 mLODChanged = FALSE;
97 mSculptChanged = FALSE; 96 mSculptChanged = FALSE;
97 mIndexInTex = 0;
98} 98}
99 99
100LLVOVolume::~LLVOVolume() 100LLVOVolume::~LLVOVolume()
@@ -502,9 +502,8 @@ void LLVOVolume::updateTextureVirtualSize()
502 502
503 if (isSculpted()) 503 if (isSculpted())
504 { 504 {
505 LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); 505 updateSculptTexture();
506 LLUUID id = sculpt_params->getSculptTexture(); 506
507 mSculptTexture = gImageList.getImage(id);
508 if (mSculptTexture.notNull()) 507 if (mSculptTexture.notNull())
509 { 508 {
510 mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), 509 mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
@@ -682,25 +681,52 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail
682 mVolumeImpl->onSetVolume(volume_params, detail); 681 mVolumeImpl->onSetVolume(volume_params, detail);
683 } 682 }
684 683
684 updateSculptTexture();
685
685 if (isSculpted()) 686 if (isSculpted())
686 { 687 {
687 mSculptTexture = gImageList.getImage(volume_params.getSculptID());
688 if (mSculptTexture.notNull()) 688 if (mSculptTexture.notNull())
689 { 689 {
690 sculpt(); 690 sculpt();
691 mSculptLevel = getVolume()->getSculptLevel();
692 } 691 }
693 } 692 }
694 else
695 {
696 mSculptTexture = NULL;
697 }
698 693
699 return TRUE; 694 return TRUE;
700 } 695 }
701 return FALSE; 696 return FALSE;
702} 697}
703 698
699void LLVOVolume::updateSculptTexture()
700{
701 LLPointer<LLViewerImage> old_sculpt = mSculptTexture;
702
703 if (isSculpted())
704 {
705 LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
706 LLUUID id = sculpt_params->getSculptTexture();
707 if (id.notNull())
708 {
709 mSculptTexture = gImageList::getImage(id);
710 }
711 }
712 else
713 {
714 mSculptTexture = NULL;
715 }
716
717 if (mSculptTexture != old_sculpt)
718 {
719 if (old_sculpt.notNull())
720 {
721 old_sculpt->removeVolume(this);
722 }
723 if (mSculptTexture.notNull())
724 {
725 mSculptTexture->addVolume(this);
726 }
727 }
728}
729
704// sculpt replaces generate() for sculpted surfaces 730// sculpt replaces generate() for sculpted surfaces
705void LLVOVolume::sculpt() 731void LLVOVolume::sculpt()
706{ 732{
@@ -754,6 +780,16 @@ void LLVOVolume::sculpt()
754 sculpt_data = raw_image->getData(); 780 sculpt_data = raw_image->getData();
755 } 781 }
756 getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level); 782 getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level);
783
784 //notify rebuild any other VOVolumes that reference this sculpty volume
785 for (S32 i = 0; i < mSculptTexture->getNumVolumes(); ++i)
786 {
787 LLVOVolume* volume = (*(mSculptTexture->getVolumeList()))[i];
788 if (volume != this && volume->getVolume() == getVolume())
789 {
790 gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY, FALSE);
791 }
792 }
757 } 793 }
758} 794}
759 795
diff --git a/linden/indra/newview/llvovolume.h b/linden/indra/newview/llvovolume.h
index a78aa37..7c8a68d 100644
--- a/linden/indra/newview/llvovolume.h
+++ b/linden/indra/newview/llvovolume.h
@@ -169,8 +169,10 @@ public:
169 /*virtual*/ BOOL setMaterial(const U8 material); 169 /*virtual*/ BOOL setMaterial(const U8 material);
170 170
171 void setTexture(const S32 face); 171 void setTexture(const S32 face);
172 172 S32 getIndexInTex() const {return mIndexInTex ;}
173 /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false); 173 /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
174 void updateSculptTexture();
175 void setIndexInTex(S32 index) { mIndexInTex = index ;}
174 void sculpt(); 176 void sculpt();
175 void updateRelativeXform(); 177 void updateRelativeXform();
176 /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); 178 /*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
@@ -231,7 +233,6 @@ private:
231 LLFrameTimer mTextureUpdateTimer; 233 LLFrameTimer mTextureUpdateTimer;
232 S32 mLOD; 234 S32 mLOD;
233 BOOL mLODChanged; 235 BOOL mLODChanged;
234 S32 mSculptLevel;
235 BOOL mSculptChanged; 236 BOOL mSculptChanged;
236 LLMatrix4 mRelativeXform; 237 LLMatrix4 mRelativeXform;
237 LLMatrix3 mRelativeXformInvTrans; 238 LLMatrix3 mRelativeXformInvTrans;
@@ -239,6 +240,7 @@ private:
239 F32 mVObjRadius; 240 F32 mVObjRadius;
240 LLVolumeInterface *mVolumeImpl; 241 LLVolumeInterface *mVolumeImpl;
241 LLPointer<LLViewerImage> mSculptTexture; 242 LLPointer<LLViewerImage> mSculptTexture;
243 S32 mIndexInTex;
242 244
243 // statics 245 // statics
244public: 246public: