diff options
author | thickbrick | 2011-01-24 19:40:13 +0200 |
---|---|---|
committer | thickbrick | 2011-01-24 19:40:13 +0200 |
commit | 981e88b92549cae661a077490df693f1d207c808 (patch) | |
tree | a5021efb71a6216e33317019a18803cc40bfc27a /linden/indra/newview | |
parent | Partial fix #772: Large sculpt maps are deformed (diff) | |
download | meta-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.h | 4 | ||||
-rw-r--r-- | linden/indra/newview/llviewerimage.cpp | 131 | ||||
-rw-r--r-- | linden/indra/newview/llviewerimage.h | 26 | ||||
-rw-r--r-- | linden/indra/newview/llvovolume.cpp | 56 | ||||
-rw-r--r-- | linden/indra/newview/llvovolume.h | 6 |
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() | |||
388 | void LLViewerImage::cleanup() | 394 | void 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 | } |
772 | void LLViewerImage::scaleDown() | 779 | void LLViewerImage::scaleDown() |
@@ -1817,11 +1824,111 @@ void LLViewerImage::setForSculpt() | |||
1817 | checkCachedRawSculptImage() ; | 1824 | checkCachedRawSculptImage() ; |
1818 | } | 1825 | } |
1819 | 1826 | ||
1827 | //virtual | ||
1820 | void LLViewerImage::addFace(LLFace* facep) | 1828 | void 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 | ||
1841 | void 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 | |||
1857 | S32 LLViewerImage::getNumFaces() const | ||
1858 | { | ||
1859 | return mNumFaces ; | ||
1860 | } | ||
1861 | |||
1862 | |||
1863 | //virtual | ||
1864 | void 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 | } |
1824 | void LLViewerImage::removeFace(LLFace* facep) | 1875 | |
1876 | //virtual | ||
1877 | void 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 | |||
1893 | S32 LLViewerImage::getNumVolumes() const | ||
1894 | { | ||
1895 | return mNumVolumes ; | ||
1896 | } | ||
1897 | |||
1898 | void 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 | |||
1917 | void 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 | ||
52 | class LLVFile; | 52 | class LLVFile; |
53 | class LLMessageSystem; | 53 | class LLMessageSystem; |
54 | class LLVOVolume; | ||
54 | 55 | ||
55 | class LLLoadedCallbackEntry | 56 | class 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 | |||
212 | protected: | 216 | protected: |
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 | ||
100 | LLVOVolume::~LLVOVolume() | 100 | LLVOVolume::~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 | ||
699 | void 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 |
705 | void LLVOVolume::sculpt() | 731 | void 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 |
244 | public: | 246 | public: |