diff options
author | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
commit | cd17687f01420952712a500107e0f93e7ab8d5f8 (patch) | |
tree | ce48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/llmath/llvolume.cpp | |
parent | Second Life viewer sources 1.19.0.5 (diff) | |
download | meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2 meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz |
Second Life viewer sources 1.19.1.0
Diffstat (limited to 'linden/indra/llmath/llvolume.cpp')
-rw-r--r-- | linden/indra/llmath/llvolume.cpp | 546 |
1 files changed, 344 insertions, 202 deletions
diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp index 3316168..266ec08 100644 --- a/linden/indra/llmath/llvolume.cpp +++ b/linden/indra/llmath/llvolume.cpp | |||
@@ -1639,12 +1639,27 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge | |||
1639 | } | 1639 | } |
1640 | } | 1640 | } |
1641 | 1641 | ||
1642 | void LLVolume::resizePath(S32 length) | ||
1643 | { | ||
1644 | mPathp->resizePath(length); | ||
1645 | if (mVolumeFaces != NULL) | ||
1646 | { | ||
1647 | delete[] mVolumeFaces; | ||
1648 | mVolumeFaces = NULL; | ||
1649 | } | ||
1650 | } | ||
1651 | |||
1642 | void LLVolume::regen() | 1652 | void LLVolume::regen() |
1643 | { | 1653 | { |
1644 | generate(); | 1654 | generate(); |
1645 | createVolumeFaces(); | 1655 | createVolumeFaces(); |
1646 | } | 1656 | } |
1647 | 1657 | ||
1658 | void LLVolume::genBinormals(S32 face) | ||
1659 | { | ||
1660 | mVolumeFaces[face].createBinormals(); | ||
1661 | } | ||
1662 | |||
1648 | LLVolume::~LLVolume() | 1663 | LLVolume::~LLVolume() |
1649 | { | 1664 | { |
1650 | sNumMeshPoints -= mMesh.size(); | 1665 | sNumMeshPoints -= mMesh.size(); |
@@ -1746,12 +1761,6 @@ void LLVolume::createVolumeFaces() | |||
1746 | { | 1761 | { |
1747 | S32 i; | 1762 | S32 i; |
1748 | 1763 | ||
1749 | if (mVolumeFaces != NULL) | ||
1750 | { | ||
1751 | delete[] mVolumeFaces; | ||
1752 | mVolumeFaces = NULL; | ||
1753 | } | ||
1754 | |||
1755 | if (mGenerateSingleFace) | 1764 | if (mGenerateSingleFace) |
1756 | { | 1765 | { |
1757 | mNumVolumeFaces = 0; | 1766 | mNumVolumeFaces = 0; |
@@ -1760,7 +1769,12 @@ void LLVolume::createVolumeFaces() | |||
1760 | { | 1769 | { |
1761 | S32 num_faces = getNumFaces(); | 1770 | S32 num_faces = getNumFaces(); |
1762 | mNumVolumeFaces = num_faces; | 1771 | mNumVolumeFaces = num_faces; |
1763 | mVolumeFaces = new LLVolumeFace[num_faces]; | 1772 | BOOL partial_build = TRUE; |
1773 | if (!mVolumeFaces) | ||
1774 | { | ||
1775 | partial_build = FALSE; | ||
1776 | mVolumeFaces = new LLVolumeFace[num_faces]; | ||
1777 | } | ||
1764 | // Initialize volume faces with parameter data | 1778 | // Initialize volume faces with parameter data |
1765 | for (i = 0; i < num_faces; i++) | 1779 | for (i = 0; i < num_faces; i++) |
1766 | { | 1780 | { |
@@ -1823,7 +1837,7 @@ void LLVolume::createVolumeFaces() | |||
1823 | 1837 | ||
1824 | for (i = 0; i < mNumVolumeFaces; i++) | 1838 | for (i = 0; i < mNumVolumeFaces; i++) |
1825 | { | 1839 | { |
1826 | mVolumeFaces[i].create(); | 1840 | mVolumeFaces[i].create(partial_build); |
1827 | } | 1841 | } |
1828 | } | 1842 | } |
1829 | } | 1843 | } |
@@ -1840,55 +1854,70 @@ inline LLVector3 sculpt_rgb_to_vector(U8 r, U8 g, U8 b) | |||
1840 | return value; | 1854 | return value; |
1841 | } | 1855 | } |
1842 | 1856 | ||
1857 | inline U32 sculpt_xy_to_index(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components) | ||
1858 | { | ||
1859 | U32 index = (x + y * sculpt_width) * sculpt_components; | ||
1843 | 1860 | ||
1844 | // sculpt replaces generate() for sculpted surfaces | 1861 | // attempt to resolve DEV-11158 - remove assert later. |
1845 | void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level) | 1862 | llassert(index < sculpt_width * sculpt_height * sculpt_components); |
1863 | |||
1864 | return index; | ||
1865 | } | ||
1866 | |||
1867 | |||
1868 | inline U32 sculpt_st_to_index(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components) | ||
1846 | { | 1869 | { |
1847 | U8 sculpt_type = mParams.getSculptType(); | 1870 | U32 x = (U32) ((F32)s/(size_s) * (F32) sculpt_width); |
1871 | U32 y = (U32) ((F32)t/(size_t) * (F32) sculpt_height); | ||
1848 | 1872 | ||
1849 | BOOL data_is_empty = FALSE; | 1873 | return sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); |
1874 | } | ||
1850 | 1875 | ||
1851 | if (sculpt_width == 0 || sculpt_height == 0 || sculpt_data == NULL) | ||
1852 | { | ||
1853 | sculpt_level = -1; | ||
1854 | data_is_empty = TRUE; | ||
1855 | } | ||
1856 | 1876 | ||
1857 | mPathp->generate(mDetail, 0, TRUE); | 1877 | inline LLVector3 sculpt_index_to_vector(U32 index, const U8* sculpt_data) |
1858 | mProfilep->generate(mPathp->isOpen(), mDetail, 0, TRUE); | 1878 | { |
1859 | 1879 | LLVector3 v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); | |
1880 | |||
1881 | return v; | ||
1882 | } | ||
1883 | |||
1884 | inline LLVector3 sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) | ||
1885 | { | ||
1886 | U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components); | ||
1887 | |||
1888 | return sculpt_index_to_vector(index, sculpt_data); | ||
1889 | } | ||
1890 | |||
1891 | inline LLVector3 sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) | ||
1892 | { | ||
1893 | U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); | ||
1894 | |||
1895 | return sculpt_index_to_vector(index, sculpt_data); | ||
1896 | } | ||
1897 | |||
1898 | |||
1899 | F32 LLVolume::sculptGetSurfaceArea(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) | ||
1900 | { | ||
1901 | // test to see if image has enough variation to create non-degenerate geometry | ||
1902 | |||
1860 | S32 sizeS = mPathp->mPath.size(); | 1903 | S32 sizeS = mPathp->mPath.size(); |
1861 | S32 sizeT = mProfilep->mProfile.size(); | 1904 | S32 sizeT = mProfilep->mProfile.size(); |
1862 | 1905 | ||
1863 | sNumMeshPoints -= mMesh.size(); | ||
1864 | mMesh.resize(sizeS * sizeT); | ||
1865 | sNumMeshPoints += mMesh.size(); | ||
1866 | |||
1867 | F32 area = 0; | 1906 | F32 area = 0; |
1868 | // first test to see if image has enough variation to create non-degenerate geometry | 1907 | |
1869 | if (!data_is_empty) | 1908 | if ((sculpt_width != 0) && |
1909 | (sculpt_height != 0) && | ||
1910 | (sculpt_components != 0) && | ||
1911 | (sculpt_data != NULL)) | ||
1870 | { | 1912 | { |
1871 | for (S32 s = 0; s < sizeS - 1; s++) | 1913 | for (S32 s = 0; s < sizeS - 1; s++) |
1872 | { | 1914 | { |
1873 | for (S32 t = 0; t < sizeT - 1; t++) | 1915 | for (S32 t = 0; t < sizeT - 1; t++) |
1874 | { | 1916 | { |
1875 | // first coordinate | ||
1876 | U32 x = (U32) ((F32)s/(sizeS) * (F32) sculpt_width); | ||
1877 | U32 y = (U32) ((F32)t/(sizeT) * (F32) sculpt_height); | ||
1878 | |||
1879 | // coordinate offset by 1 | ||
1880 | U32 x2 = (U32) ((F32)(s+1)/(sizeS) * (F32) sculpt_width); | ||
1881 | U32 y2 = (U32) ((F32)(t+1)/(sizeT) * (F32) sculpt_height); | ||
1882 | |||
1883 | // three points on a triagle - find the image indices first | ||
1884 | U32 p1_index = (x + y * sculpt_width) * sculpt_components; | ||
1885 | U32 p2_index = (x2 + y * sculpt_width) * sculpt_components; | ||
1886 | U32 p3_index = (x + y2 * sculpt_width) * sculpt_components; | ||
1887 | |||
1888 | // convert image data to vectors | 1917 | // convert image data to vectors |
1889 | LLVector3 p1 = sculpt_rgb_to_vector(sculpt_data[p1_index], sculpt_data[p1_index+1], sculpt_data[p1_index+2]); | 1918 | LLVector3 p1 = sculpt_st_to_vector(s, t, sizeS, sizeT, sculpt_width, sculpt_height, sculpt_components, sculpt_data); |
1890 | LLVector3 p2 = sculpt_rgb_to_vector(sculpt_data[p2_index], sculpt_data[p2_index+1], sculpt_data[p2_index+2]); | 1919 | LLVector3 p2 = sculpt_st_to_vector(s+1, t, sizeS, sizeT, sculpt_width, sculpt_height, sculpt_components, sculpt_data); |
1891 | LLVector3 p3 = sculpt_rgb_to_vector(sculpt_data[p3_index], sculpt_data[p3_index+1], sculpt_data[p3_index+2]); | 1920 | LLVector3 p3 = sculpt_st_to_vector(s, t+1, sizeS, sizeT, sculpt_width, sculpt_height, sculpt_components, sculpt_data); |
1892 | 1921 | ||
1893 | // compute the area of the parallelogram by taking the length of the cross product: | 1922 | // compute the area of the parallelogram by taking the length of the cross product: |
1894 | // (parallegram is an approximation of two triangles) | 1923 | // (parallegram is an approximation of two triangles) |
@@ -1896,99 +1925,151 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, | |||
1896 | area += cross.magVec(); | 1925 | area += cross.magVec(); |
1897 | } | 1926 | } |
1898 | } | 1927 | } |
1899 | if (area < SCULPT_MIN_AREA) | ||
1900 | data_is_empty = TRUE; | ||
1901 | } | 1928 | } |
1902 | 1929 | ||
1903 | //generate vertex positions | 1930 | return area; |
1904 | if (data_is_empty) // if empty, make a sphere | 1931 | } |
1905 | { | 1932 | |
1906 | S32 line = 0; | 1933 | // create placeholder shape |
1934 | void LLVolume::sculptGeneratePlaceholder() | ||
1935 | { | ||
1936 | S32 sizeS = mPathp->mPath.size(); | ||
1937 | S32 sizeT = mProfilep->mProfile.size(); | ||
1938 | |||
1939 | S32 line = 0; | ||
1907 | 1940 | ||
1908 | for (S32 s = 0; s < sizeS; s++) | 1941 | // for now, this is a sphere. |
1942 | for (S32 s = 0; s < sizeS; s++) | ||
1943 | { | ||
1944 | for (S32 t = 0; t < sizeT; t++) | ||
1909 | { | 1945 | { |
1910 | for (S32 t = 0; t < sizeT; t++) | 1946 | S32 i = t + line; |
1911 | { | 1947 | Point& pt = mMesh[i]; |
1912 | S32 i = t + line; | ||
1913 | Point& pt = mMesh[i]; | ||
1914 | 1948 | ||
1915 | 1949 | ||
1916 | F32 u = (F32)s/(sizeS-1); | 1950 | F32 u = (F32)s/(sizeS-1); |
1917 | F32 v = (F32)t/(sizeT-1); | 1951 | F32 v = (F32)t/(sizeT-1); |
1918 | 1952 | ||
1919 | const F32 RADIUS = (F32) 0.3; | 1953 | const F32 RADIUS = (F32) 0.3; |
1920 | 1954 | ||
1921 | pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); | 1955 | pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); |
1922 | pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); | 1956 | pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); |
1923 | pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS); | 1957 | pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS); |
1924 | 1958 | ||
1925 | } | ||
1926 | line += sizeT; | ||
1927 | } | 1959 | } |
1928 | } | 1960 | line += sizeT; |
1929 | else | 1961 | } |
1962 | } | ||
1963 | |||
1964 | // create the vertices from the map | ||
1965 | void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type) | ||
1966 | { | ||
1967 | S32 sizeS = mPathp->mPath.size(); | ||
1968 | S32 sizeT = mProfilep->mProfile.size(); | ||
1969 | |||
1970 | S32 line = 0; | ||
1971 | for (S32 s = 0; s < sizeS; s++) | ||
1930 | { | 1972 | { |
1931 | S32 line = 0; | 1973 | // Run along the profile. |
1932 | for (S32 s = 0; s < sizeS; s++) | 1974 | for (S32 t = 0; t < sizeT; t++) |
1933 | { | 1975 | { |
1934 | // Run along the profile. | 1976 | S32 i = t + line; |
1935 | for (S32 t = 0; t < sizeT; t++) | 1977 | Point& pt = mMesh[i]; |
1936 | { | ||
1937 | S32 i = t + line; | ||
1938 | Point& pt = mMesh[i]; | ||
1939 | 1978 | ||
1940 | U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); | 1979 | U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); |
1941 | U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); | 1980 | U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); |
1942 | 1981 | ||
1943 | if (y == 0) // top row stitching | 1982 | if (y == 0) // top row stitching |
1983 | { | ||
1984 | // pinch? | ||
1985 | if (sculpt_type == LL_SCULPT_TYPE_SPHERE) | ||
1944 | { | 1986 | { |
1945 | // pinch? | 1987 | x = sculpt_width / 2; |
1946 | if (sculpt_type == LL_SCULPT_TYPE_SPHERE) | ||
1947 | { | ||
1948 | x = sculpt_width / 2; | ||
1949 | } | ||
1950 | } | 1988 | } |
1989 | } | ||
1951 | 1990 | ||
1952 | if (y == sculpt_height) // bottom row stitching | 1991 | if (y == sculpt_height) // bottom row stitching |
1992 | { | ||
1993 | // wrap? | ||
1994 | if (sculpt_type == LL_SCULPT_TYPE_TORUS) | ||
1953 | { | 1995 | { |
1954 | // wrap? | 1996 | y = 0; |
1955 | if (sculpt_type == LL_SCULPT_TYPE_TORUS) | 1997 | } |
1956 | { | 1998 | else |
1957 | y = 0; | 1999 | { |
1958 | } | 2000 | y = sculpt_height - 1; |
1959 | else | 2001 | } |
1960 | { | ||
1961 | y = sculpt_height - 1; | ||
1962 | } | ||
1963 | 2002 | ||
1964 | // pinch? | 2003 | // pinch? |
1965 | if (sculpt_type == LL_SCULPT_TYPE_SPHERE) | 2004 | if (sculpt_type == LL_SCULPT_TYPE_SPHERE) |
1966 | { | 2005 | { |
1967 | x = sculpt_width / 2; | 2006 | x = sculpt_width / 2; |
1968 | } | ||
1969 | } | 2007 | } |
2008 | } | ||
1970 | 2009 | ||
1971 | if (x == sculpt_width) // side stitching | 2010 | if (x == sculpt_width) // side stitching |
2011 | { | ||
2012 | // wrap? | ||
2013 | if ((sculpt_type == LL_SCULPT_TYPE_SPHERE) || | ||
2014 | (sculpt_type == LL_SCULPT_TYPE_TORUS) || | ||
2015 | (sculpt_type == LL_SCULPT_TYPE_CYLINDER)) | ||
1972 | { | 2016 | { |
1973 | // wrap? | 2017 | x = 0; |
1974 | if ((sculpt_type == LL_SCULPT_TYPE_SPHERE) || | 2018 | } |
1975 | (sculpt_type == LL_SCULPT_TYPE_TORUS) || | ||
1976 | (sculpt_type == LL_SCULPT_TYPE_CYLINDER)) | ||
1977 | { | ||
1978 | x = 0; | ||
1979 | } | ||
1980 | 2019 | ||
1981 | else | 2020 | else |
1982 | { | 2021 | { |
1983 | x = sculpt_width - 1; | 2022 | x = sculpt_width - 1; |
1984 | } | ||
1985 | } | 2023 | } |
1986 | |||
1987 | U32 index = (x + y * sculpt_width) * sculpt_components; | ||
1988 | pt.mPos = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); | ||
1989 | } | 2024 | } |
1990 | line += sizeT; | 2025 | |
2026 | pt.mPos = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data); | ||
1991 | } | 2027 | } |
2028 | line += sizeT; | ||
2029 | } | ||
2030 | } | ||
2031 | |||
2032 | |||
2033 | // sculpt replaces generate() for sculpted surfaces | ||
2034 | void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level) | ||
2035 | { | ||
2036 | U8 sculpt_type = mParams.getSculptType(); | ||
2037 | |||
2038 | BOOL data_is_empty = FALSE; | ||
2039 | |||
2040 | if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components == 0 || sculpt_data == NULL) | ||
2041 | { | ||
2042 | sculpt_level = -1; | ||
2043 | data_is_empty = TRUE; | ||
2044 | } | ||
2045 | |||
2046 | mPathp->generate(mDetail, 0, TRUE); | ||
2047 | mProfilep->generate(mPathp->isOpen(), mDetail, 0, TRUE); | ||
2048 | |||
2049 | S32 sizeS = mPathp->mPath.size(); | ||
2050 | S32 sizeT = mProfilep->mProfile.size(); | ||
2051 | |||
2052 | // weird crash bug - DEV-11158 - trying to collect more data: | ||
2053 | if ((sizeS == 0) || (sizeT == 0)) | ||
2054 | { | ||
2055 | llwarns << "sculpt bad mesh size " << sizeS << " " << sizeT << llendl; | ||
2056 | } | ||
2057 | |||
2058 | sNumMeshPoints -= mMesh.size(); | ||
2059 | mMesh.resize(sizeS * sizeT); | ||
2060 | sNumMeshPoints += mMesh.size(); | ||
2061 | |||
2062 | if (sculptGetSurfaceArea(sculpt_width, sculpt_height, sculpt_components, sculpt_data) < SCULPT_MIN_AREA) | ||
2063 | data_is_empty = TRUE; | ||
2064 | |||
2065 | //generate vertex positions | ||
2066 | if (data_is_empty) // if empty, make a placeholder mesh | ||
2067 | { | ||
2068 | sculptGeneratePlaceholder(); | ||
2069 | } | ||
2070 | else | ||
2071 | { | ||
2072 | sculptGenerateMapVertices(sculpt_width, sculpt_height, sculpt_components, sculpt_data, sculpt_type); | ||
1992 | } | 2073 | } |
1993 | 2074 | ||
1994 | for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++) | 2075 | for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++) |
@@ -3967,18 +4048,19 @@ LLVolumeFace::LLVolumeFace() | |||
3967 | mBeginT = 0; | 4048 | mBeginT = 0; |
3968 | mNumS = 0; | 4049 | mNumS = 0; |
3969 | mNumT = 0; | 4050 | mNumT = 0; |
4051 | mHasBinormals = FALSE; | ||
3970 | } | 4052 | } |
3971 | 4053 | ||
3972 | 4054 | ||
3973 | BOOL LLVolumeFace::create() | 4055 | BOOL LLVolumeFace::create(BOOL partial_build) |
3974 | { | 4056 | { |
3975 | if (mTypeMask & CAP_MASK) | 4057 | if (mTypeMask & CAP_MASK) |
3976 | { | 4058 | { |
3977 | return createCap(); | 4059 | return createCap(partial_build); |
3978 | } | 4060 | } |
3979 | else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK)) | 4061 | else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK)) |
3980 | { | 4062 | { |
3981 | return createSide(); | 4063 | return createSide(partial_build); |
3982 | } | 4064 | } |
3983 | else | 4065 | else |
3984 | { | 4066 | { |
@@ -4000,7 +4082,7 @@ void LerpPlanarVertex(LLVolumeFace::VertexData& v0, | |||
4000 | vout.mBinormal = v0.mBinormal; | 4082 | vout.mBinormal = v0.mBinormal; |
4001 | } | 4083 | } |
4002 | 4084 | ||
4003 | BOOL LLVolumeFace::createUnCutCubeCap() | 4085 | BOOL LLVolumeFace::createUnCutCubeCap(BOOL partial_build) |
4004 | { | 4086 | { |
4005 | const std::vector<LLVolume::Point>& mesh = mVolumep->getMesh(); | 4087 | const std::vector<LLVolume::Point>& mesh = mVolumep->getMesh(); |
4006 | const std::vector<LLVector3>& profile = mVolumep->getProfile().mProfile; | 4088 | const std::vector<LLVector3>& profile = mVolumep->getProfile().mProfile; |
@@ -4055,6 +4137,12 @@ BOOL LLVolumeFace::createUnCutCubeCap() | |||
4055 | corners[t].mBinormal = baseVert.mBinormal; | 4137 | corners[t].mBinormal = baseVert.mBinormal; |
4056 | corners[t].mNormal = baseVert.mNormal; | 4138 | corners[t].mNormal = baseVert.mNormal; |
4057 | } | 4139 | } |
4140 | mHasBinormals = TRUE; | ||
4141 | |||
4142 | if (partial_build) | ||
4143 | { | ||
4144 | mVertices.clear(); | ||
4145 | } | ||
4058 | 4146 | ||
4059 | S32 vtop = mVertices.size(); | 4147 | S32 vtop = mVertices.size(); |
4060 | for(int gx = 0;gx<grid_size+1;gx++){ | 4148 | for(int gx = 0;gx<grid_size+1;gx++){ |
@@ -4082,22 +4170,25 @@ BOOL LLVolumeFace::createUnCutCubeCap() | |||
4082 | 4170 | ||
4083 | mCenter = (min + max) * 0.5f; | 4171 | mCenter = (min + max) * 0.5f; |
4084 | 4172 | ||
4085 | int idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0}; | 4173 | if (!partial_build) |
4086 | for(int gx = 0;gx<grid_size;gx++){ | 4174 | { |
4087 | for(int gy = 0;gy<grid_size;gy++){ | 4175 | int idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0}; |
4088 | if (mTypeMask & TOP_MASK){ | 4176 | for(int gx = 0;gx<grid_size;gx++){ |
4089 | for(int i=5;i>=0;i--)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); | 4177 | for(int gy = 0;gy<grid_size;gy++){ |
4090 | }else{ | 4178 | if (mTypeMask & TOP_MASK){ |
4091 | for(int i=0;i<6;i++)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); | 4179 | for(int i=5;i>=0;i--)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); |
4180 | }else{ | ||
4181 | for(int i=0;i<6;i++)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); | ||
4182 | } | ||
4092 | } | 4183 | } |
4093 | } | 4184 | } |
4094 | } | 4185 | } |
4095 | 4186 | ||
4096 | return TRUE; | 4187 | return TRUE; |
4097 | } | 4188 | } |
4098 | 4189 | ||
4099 | 4190 | ||
4100 | BOOL LLVolumeFace::createCap() | 4191 | BOOL LLVolumeFace::createCap(BOOL partial_build) |
4101 | { | 4192 | { |
4102 | if (!(mTypeMask & HOLLOW_MASK) && | 4193 | if (!(mTypeMask & HOLLOW_MASK) && |
4103 | !(mTypeMask & OPEN_MASK) && | 4194 | !(mTypeMask & OPEN_MASK) && |
@@ -4106,7 +4197,7 @@ BOOL LLVolumeFace::createCap() | |||
4106 | (mVolumep->getProfile().mParams.getCurveType()==LL_PCODE_PROFILE_SQUARE && | 4197 | (mVolumep->getProfile().mParams.getCurveType()==LL_PCODE_PROFILE_SQUARE && |
4107 | mVolumep->getPath().mParams.getCurveType()==LL_PCODE_PATH_LINE) | 4198 | mVolumep->getPath().mParams.getCurveType()==LL_PCODE_PATH_LINE) |
4108 | ){ | 4199 | ){ |
4109 | return createUnCutCubeCap(); | 4200 | return createUnCutCubeCap(partial_build); |
4110 | } | 4201 | } |
4111 | 4202 | ||
4112 | S32 i; | 4203 | S32 i; |
@@ -4118,8 +4209,13 @@ BOOL LLVolumeFace::createCap() | |||
4118 | // All types of caps have the same number of vertices and indices | 4209 | // All types of caps have the same number of vertices and indices |
4119 | num_vertices = profile.size(); | 4210 | num_vertices = profile.size(); |
4120 | num_indices = (profile.size() - 2)*3; | 4211 | num_indices = (profile.size() - 2)*3; |
4121 | vector_append(mVertices,num_vertices); | 4212 | |
4122 | vector_append(mIndices,num_indices); | 4213 | mVertices.resize(num_vertices); |
4214 | |||
4215 | if (!partial_build) | ||
4216 | { | ||
4217 | mIndices.resize(num_indices); | ||
4218 | } | ||
4123 | 4219 | ||
4124 | S32 max_s = mVolumep->getProfile().getTotal(); | 4220 | S32 max_s = mVolumep->getProfile().getTotal(); |
4125 | S32 max_t = mVolumep->getPath().mPath.size(); | 4221 | S32 max_t = mVolumep->getPath().mPath.size(); |
@@ -4203,7 +4299,10 @@ BOOL LLVolumeFace::createCap() | |||
4203 | { | 4299 | { |
4204 | mVertices.push_back(vd); | 4300 | mVertices.push_back(vd); |
4205 | num_vertices++; | 4301 | num_vertices++; |
4206 | vector_append(mIndices, 3); | 4302 | if (!partial_build) |
4303 | { | ||
4304 | vector_append(mIndices, 3); | ||
4305 | } | ||
4207 | } | 4306 | } |
4208 | 4307 | ||
4209 | 4308 | ||
@@ -4213,6 +4312,13 @@ BOOL LLVolumeFace::createCap() | |||
4213 | mVertices[i].mNormal = normal; | 4312 | mVertices[i].mNormal = normal; |
4214 | } | 4313 | } |
4215 | 4314 | ||
4315 | mHasBinormals = TRUE; | ||
4316 | |||
4317 | if (partial_build) | ||
4318 | { | ||
4319 | return TRUE; | ||
4320 | } | ||
4321 | |||
4216 | if (mTypeMask & HOLLOW_MASK) | 4322 | if (mTypeMask & HOLLOW_MASK) |
4217 | { | 4323 | { |
4218 | if (mTypeMask & TOP_MASK) | 4324 | if (mTypeMask & TOP_MASK) |
@@ -4480,7 +4586,50 @@ BOOL LLVolumeFace::createCap() | |||
4480 | return TRUE; | 4586 | return TRUE; |
4481 | } | 4587 | } |
4482 | 4588 | ||
4483 | BOOL LLVolumeFace::createSide() | 4589 | void LLVolumeFace::createBinormals() |
4590 | { | ||
4591 | if (!mHasBinormals) | ||
4592 | { | ||
4593 | //generate binormals | ||
4594 | for (U32 i = 0; i < mIndices.size()/3; i++) | ||
4595 | { //for each triangle | ||
4596 | const VertexData& v0 = mVertices[mIndices[i*3+0]]; | ||
4597 | const VertexData& v1 = mVertices[mIndices[i*3+1]]; | ||
4598 | const VertexData& v2 = mVertices[mIndices[i*3+2]]; | ||
4599 | |||
4600 | //calculate binormal | ||
4601 | LLVector3 binorm = calc_binormal_from_triangle(v0.mPosition, v0.mTexCoord, | ||
4602 | v1.mPosition, v1.mTexCoord, | ||
4603 | v2.mPosition, v2.mTexCoord); | ||
4604 | |||
4605 | for (U32 j = 0; j < 3; j++) | ||
4606 | { //add triangle normal to vertices | ||
4607 | mVertices[mIndices[i*3+j]].mBinormal += binorm; // * (weight_sum - d[j])/weight_sum; | ||
4608 | } | ||
4609 | |||
4610 | //even out quad contributions | ||
4611 | if (i % 2 == 0) | ||
4612 | { | ||
4613 | mVertices[mIndices[i*3+2]].mBinormal += binorm; | ||
4614 | } | ||
4615 | else | ||
4616 | { | ||
4617 | mVertices[mIndices[i*3+1]].mBinormal += binorm; | ||
4618 | } | ||
4619 | } | ||
4620 | |||
4621 | //normalize binormals | ||
4622 | for (U32 i = 0; i < mVertices.size(); i++) | ||
4623 | { | ||
4624 | mVertices[i].mBinormal.normVec(); | ||
4625 | mVertices[i].mNormal.normVec(); | ||
4626 | } | ||
4627 | |||
4628 | mHasBinormals = TRUE; | ||
4629 | } | ||
4630 | } | ||
4631 | |||
4632 | BOOL LLVolumeFace::createSide(BOOL partial_build) | ||
4484 | { | 4633 | { |
4485 | BOOL flat = mTypeMask & FLAT_MASK; | 4634 | BOOL flat = mTypeMask & FLAT_MASK; |
4486 | S32 num_vertices, num_indices; | 4635 | S32 num_vertices, num_indices; |
@@ -4496,9 +4645,14 @@ BOOL LLVolumeFace::createSide() | |||
4496 | 4645 | ||
4497 | num_vertices = mNumS*mNumT; | 4646 | num_vertices = mNumS*mNumT; |
4498 | num_indices = (mNumS-1)*(mNumT-1)*6; | 4647 | num_indices = (mNumS-1)*(mNumT-1)*6; |
4499 | vector_append(mVertices,num_vertices); | 4648 | |
4500 | vector_append(mIndices,num_indices); | 4649 | mVertices.resize(num_vertices); |
4501 | vector_append(mEdge, num_indices); | 4650 | |
4651 | if (!partial_build) | ||
4652 | { | ||
4653 | mIndices.resize(num_indices); | ||
4654 | mEdge.resize(num_indices); | ||
4655 | } | ||
4502 | 4656 | ||
4503 | LLVector3& face_min = mExtents[0]; | 4657 | LLVector3& face_min = mExtents[0]; |
4504 | LLVector3& face_max = mExtents[1]; | 4658 | LLVector3& face_max = mExtents[1]; |
@@ -4609,61 +4763,63 @@ BOOL LLVolumeFace::createSide() | |||
4609 | S32 cur_edge = 0; | 4763 | S32 cur_edge = 0; |
4610 | BOOL flat_face = mTypeMask & FLAT_MASK; | 4764 | BOOL flat_face = mTypeMask & FLAT_MASK; |
4611 | 4765 | ||
4612 | // Now we generate the indices. | 4766 | if (!partial_build) |
4613 | for (t = 0; t < (mNumT-1); t++) | 4767 | { |
4614 | { | 4768 | // Now we generate the indices. |
4615 | for (s = 0; s < (mNumS-1); s++) | 4769 | for (t = 0; t < (mNumT-1); t++) |
4616 | { | 4770 | { |
4617 | mIndices[cur_index++] = s + mNumS*t; //bottom left | 4771 | for (s = 0; s < (mNumS-1); s++) |
4618 | mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right | 4772 | { |
4619 | mIndices[cur_index++] = s + mNumS*(t+1); //top left | 4773 | mIndices[cur_index++] = s + mNumS*t; //bottom left |
4620 | mIndices[cur_index++] = s + mNumS*t; //bottom left | 4774 | mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right |
4621 | mIndices[cur_index++] = s+1 + mNumS*t; //bottom right | 4775 | mIndices[cur_index++] = s + mNumS*(t+1); //top left |
4622 | mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right | 4776 | mIndices[cur_index++] = s + mNumS*t; //bottom left |
4623 | 4777 | mIndices[cur_index++] = s+1 + mNumS*t; //bottom right | |
4624 | mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face | 4778 | mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right |
4625 | if (t < mNumT-2) { //top right/top left neighbor face | 4779 | |
4626 | mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; | 4780 | mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face |
4627 | } | 4781 | if (t < mNumT-2) { //top right/top left neighbor face |
4628 | else if (mNumT <= 3 || mVolumep->getPath().isOpen() == TRUE) { //no neighbor | 4782 | mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; |
4629 | mEdge[cur_edge++] = -1; | 4783 | } |
4630 | } | 4784 | else if (mNumT <= 3 || mVolumep->getPath().isOpen() == TRUE) { //no neighbor |
4631 | else { //wrap on T | 4785 | mEdge[cur_edge++] = -1; |
4632 | mEdge[cur_edge++] = s*2+1; | 4786 | } |
4633 | } | 4787 | else { //wrap on T |
4634 | if (s > 0) { //top left/bottom left neighbor face | 4788 | mEdge[cur_edge++] = s*2+1; |
4635 | mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1; | 4789 | } |
4636 | } | 4790 | if (s > 0) { //top left/bottom left neighbor face |
4637 | else if (flat_face || mVolumep->getProfile().isOpen() == TRUE) { //no neighbor | 4791 | mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1; |
4638 | mEdge[cur_edge++] = -1; | 4792 | } |
4639 | } | 4793 | else if (flat_face || mVolumep->getProfile().isOpen() == TRUE) { //no neighbor |
4640 | else { //wrap on S | 4794 | mEdge[cur_edge++] = -1; |
4641 | mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1; | 4795 | } |
4642 | } | 4796 | else { //wrap on S |
4643 | 4797 | mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1; | |
4644 | if (t > 0) { //bottom left/bottom right neighbor face | 4798 | } |
4645 | mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2; | 4799 | |
4646 | } | 4800 | if (t > 0) { //bottom left/bottom right neighbor face |
4647 | else if (mNumT <= 3 || mVolumep->getPath().isOpen() == TRUE) { //no neighbor | 4801 | mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2; |
4648 | mEdge[cur_edge++] = -1; | 4802 | } |
4649 | } | 4803 | else if (mNumT <= 3 || mVolumep->getPath().isOpen() == TRUE) { //no neighbor |
4650 | else { //wrap on T | 4804 | mEdge[cur_edge++] = -1; |
4651 | mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2; | 4805 | } |
4652 | } | 4806 | else { //wrap on T |
4653 | if (s < mNumS-2) { //bottom right/top right neighbor face | 4807 | mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2; |
4654 | mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2; | 4808 | } |
4655 | } | 4809 | if (s < mNumS-2) { //bottom right/top right neighbor face |
4656 | else if (flat_face || mVolumep->getProfile().isOpen() == TRUE) { //no neighbor | 4810 | mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2; |
4657 | mEdge[cur_edge++] = -1; | 4811 | } |
4658 | } | 4812 | else if (flat_face || mVolumep->getProfile().isOpen() == TRUE) { //no neighbor |
4659 | else { //wrap on S | 4813 | mEdge[cur_edge++] = -1; |
4660 | mEdge[cur_edge++] = (mNumS-1)*2*t; | 4814 | } |
4815 | else { //wrap on S | ||
4816 | mEdge[cur_edge++] = (mNumS-1)*2*t; | ||
4817 | } | ||
4818 | mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face | ||
4661 | } | 4819 | } |
4662 | mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face | ||
4663 | } | 4820 | } |
4664 | } | 4821 | } |
4665 | 4822 | ||
4666 | |||
4667 | //generate normals | 4823 | //generate normals |
4668 | for (U32 i = 0; i < mIndices.size()/3; i++) { //for each triangle | 4824 | for (U32 i = 0; i < mIndices.size()/3; i++) { //for each triangle |
4669 | const VertexData& v0 = mVertices[mIndices[i*3+0]]; | 4825 | const VertexData& v0 = mVertices[mIndices[i*3+0]]; |
@@ -4674,27 +4830,22 @@ BOOL LLVolumeFace::createSide() | |||
4674 | LLVector3 norm = (v0.mPosition-v1.mPosition)% | 4830 | LLVector3 norm = (v0.mPosition-v1.mPosition)% |
4675 | (v0.mPosition-v2.mPosition); | 4831 | (v0.mPosition-v2.mPosition); |
4676 | 4832 | ||
4677 | //calculate binormal | 4833 | for (U32 j = 0; j < 3; j++) |
4678 | LLVector3 binorm = calc_binormal_from_triangle(v0.mPosition, v0.mTexCoord, | 4834 | { //add triangle normal to vertices |
4679 | v1.mPosition, v1.mTexCoord, | ||
4680 | v2.mPosition, v2.mTexCoord); | ||
4681 | |||
4682 | for (U32 j = 0; j < 3; j++) { //add triangle normal to vertices | ||
4683 | mVertices[mIndices[i*3+j]].mNormal += norm; // * (weight_sum - d[j])/weight_sum; | 4835 | mVertices[mIndices[i*3+j]].mNormal += norm; // * (weight_sum - d[j])/weight_sum; |
4684 | mVertices[mIndices[i*3+j]].mBinormal += binorm; // * (weight_sum - d[j])/weight_sum; | ||
4685 | } | 4836 | } |
4686 | 4837 | ||
4687 | //even out quad contributions | 4838 | //even out quad contributions |
4688 | if (i % 2 == 0) { | 4839 | if (i % 2 == 0) |
4840 | { | ||
4689 | mVertices[mIndices[i*3+2]].mNormal += norm; | 4841 | mVertices[mIndices[i*3+2]].mNormal += norm; |
4690 | mVertices[mIndices[i*3+2]].mBinormal += binorm; | ||
4691 | } | 4842 | } |
4692 | else { | 4843 | else |
4844 | { | ||
4693 | mVertices[mIndices[i*3+1]].mNormal += norm; | 4845 | mVertices[mIndices[i*3+1]].mNormal += norm; |
4694 | mVertices[mIndices[i*3+1]].mBinormal += binorm; | ||
4695 | } | 4846 | } |
4696 | } | 4847 | } |
4697 | 4848 | ||
4698 | // adjust normals based on wrapping and stitching | 4849 | // adjust normals based on wrapping and stitching |
4699 | 4850 | ||
4700 | BOOL s_bottom_converges = ((mVertices[0].mPosition - mVertices[mNumS*(mNumT-2)].mPosition).magVecSquared() < 0.000001f); | 4851 | BOOL s_bottom_converges = ((mVertices[0].mPosition - mVertices[mNumS*(mNumT-2)].mPosition).magVecSquared() < 0.000001f); |
@@ -4820,15 +4971,6 @@ BOOL LLVolumeFace::createSide() | |||
4820 | 4971 | ||
4821 | } | 4972 | } |
4822 | 4973 | ||
4823 | |||
4824 | //normalize normals and binormals here so the meshes that reference | ||
4825 | //this volume data don't have to | ||
4826 | for (U32 i = 0; i < mVertices.size(); i++) | ||
4827 | { | ||
4828 | mVertices[i].mNormal.normVec(); | ||
4829 | mVertices[i].mBinormal.normVec(); | ||
4830 | } | ||
4831 | |||
4832 | return TRUE; | 4974 | return TRUE; |
4833 | } | 4975 | } |
4834 | 4976 | ||