aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/llvolume.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:34 -0500
committerJacek Antonelli2008-08-15 23:45:34 -0500
commitcd17687f01420952712a500107e0f93e7ab8d5f8 (patch)
treece48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/llmath/llvolume.cpp
parentSecond Life viewer sources 1.19.0.5 (diff)
downloadmeta-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.cpp546
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 &params, const F32 detail, const BOOL ge
1639 } 1639 }
1640} 1640}
1641 1641
1642void LLVolume::resizePath(S32 length)
1643{
1644 mPathp->resizePath(length);
1645 if (mVolumeFaces != NULL)
1646 {
1647 delete[] mVolumeFaces;
1648 mVolumeFaces = NULL;
1649 }
1650}
1651
1642void LLVolume::regen() 1652void LLVolume::regen()
1643{ 1653{
1644 generate(); 1654 generate();
1645 createVolumeFaces(); 1655 createVolumeFaces();
1646} 1656}
1647 1657
1658void LLVolume::genBinormals(S32 face)
1659{
1660 mVolumeFaces[face].createBinormals();
1661}
1662
1648LLVolume::~LLVolume() 1663LLVolume::~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
1857inline 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.
1845void 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
1868inline 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); 1877inline 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
1884inline 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
1891inline 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
1899F32 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
1934void 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
1965void 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
2034void 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
3973BOOL LLVolumeFace::create() 4055BOOL 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
4003BOOL LLVolumeFace::createUnCutCubeCap() 4085BOOL 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
4100BOOL LLVolumeFace::createCap() 4191BOOL 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
4483BOOL LLVolumeFace::createSide() 4589void 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
4632BOOL 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