Changeset 1012 for GTP/trunk/Lib/Vis
- Timestamp:
- 06/13/06 08:03:35 (19 years ago)
- Location:
- GTP/trunk/Lib/Vis
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp
r1006 r1012 2126 2126 const float value, 2127 2127 AxisAlignedBox3 &left, 2128 AxisAlignedBox3 &right) 2128 AxisAlignedBox3 &right) const 2129 2129 { 2130 2130 if ( (value >= mMin[axis]) && (value <= mMax[axis]) ) -
GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h
r1006 r1012 391 391 void ExtractPolys(PolygonContainer &polys) const; 392 392 393 /** Splits the box into two separate boxes accordingto the split plane394 */ 395 void Split(const int axis, const float value, AxisAlignedBox3 &left, AxisAlignedBox3 &right) ;393 /** Splits the box into two separate boxes with respect to the split plane 394 */ 395 void Split(const int axis, const float value, AxisAlignedBox3 &left, AxisAlignedBox3 &right) const; 396 396 397 397 #define __EXTENT_HACK -
GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h
r1008 r1012 1084 1084 { 1085 1085 VssRay *vssRay; 1086 1087 1086 std::vector<BspIntersection> intersections; 1088 1089 1087 BspRay(VssRay *ray): vssRay(ray) {} 1090 1088 }; -
GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
r1011 r1012 2388 2388 Intersectable::NewMail(); 2389 2389 ViewCell::NewMail(); 2390 2390 2391 Vector3 entp = ray.Extrap(mint); 2391 2392 Vector3 extp = ray.Extrap(maxt); … … 2424 2425 else // ray and plane are coincident 2425 2426 { 2426 // WHAT TO DO IN THIS CASE ?2427 // matt: WHAT TO DO IN THIS CASE ? 2427 2428 //break; 2428 2429 node = in->GetFront(); -
GTP/trunk/Lib/Vis/Preprocessing/src/VspKdTree.cpp
r1011 r1012 1903 1903 } 1904 1904 1905 1905 1906 AxisAlignedBox3 VspKdTree::GetBBox(VspKdNode *node) const 1906 1907 { … … 1930 1931 } 1931 1932 1933 1932 1934 int VspKdTree::GetRootPvsSize() const 1933 1935 { … … 1935 1937 } 1936 1938 1939 1937 1940 const VspKdStatistics &VspKdTree::GetStatistics() const 1938 1941 { 1939 1942 return mStat; 1940 1943 } 1944 1941 1945 1942 1946 void VspKdTree::AddRays(VssRayContainer &add) … … 1955 1959 mStat.rayRefs * sizeof(RayInfo)) / (1024.0f * 1024.0f); 1956 1960 } 1961 1957 1962 1958 1963 float VspKdTree::GetRayMemUsage() const -
GTP/trunk/Lib/Vis/Preprocessing/src/VspKdTree.h
r1004 r1012 592 592 593 593 LineTraversalData () {} 594 LineTraversalData (VspKdNode *n, 595 const Vector3 &p, 596 const float maxt): 594 LineTraversalData (VspKdNode *n, const Vector3 &p, const float maxt): 597 595 mNode(n), mExitPoint(p), mMaxT(maxt) {} 598 596 }; -
GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
r1011 r1012 156 156 157 157 158 float VspInterior::GetPosition() const 159 { 160 return mPlane.mPosition; 161 } 162 163 164 int VspInterior::GetAxis() const 165 { 166 return mPlane.mAxis; 167 } 168 169 158 170 void VspInterior::ReplaceChildLink(VspNode *oldChild, VspNode *newChild) 159 171 { … … 172 184 173 185 186 AxisAlignedBox3 VspInterior::GetBox() const 187 { 188 return mBox; 189 } 190 191 192 void VspInterior::SetBox(const AxisAlignedBox3 &box) 193 { 194 mBox = box; 195 } 196 197 198 int VspInterior::Type() const 199 { 200 return Interior; 201 } 202 174 203 /****************************************************************/ 175 204 /* class VspLeaf implementation */ … … 186 215 DEL_PTR(mPvs); 187 216 } 217 218 int VspLeaf::Type() const 219 { 220 return Leaf; 221 } 222 188 223 189 224 … … 1381 1416 1382 1417 1383 int VspOspTree::CastRay(Ray &ray) 1384 { 1385 int hits = 0; 1386 #if TODO 1387 stack<BspRayTraversalData> tQueue; 1388 1389 float maxt, mint; 1390 1391 if (!mBox.GetRaySegment(ray, mint, maxt)) 1392 return 0; 1393 1394 Intersectable::NewMail(); 1418 void VspOspTree::CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const 1419 { 1395 1420 ViewCell::NewMail(); 1396 1397 Vector3 entp = ray.Extrap(mint);1398 Vector3 extp = ray.Extrap(maxt);1399 1400 VspNode *node = mRoot;1401 VspNode *farChild = NULL;1402 1403 while (1)1404 {1405 if (!node->IsLeaf())1406 {1407 VspInterior *in = dynamic_cast<VspInterior *>(node);1408 1409 Plane3 splitPlane = in->GetPlane();1410 const int entSide = splitPlane.Side(entp);1411 const int extSide = splitPlane.Side(extp);1412 1413 if (entSide < 0)1414 {1415 node = in->GetBack();1416 1417 if(extSide <= 0) // plane does not split ray => no far child1418 continue;1419 1420 farChild = in->GetFront(); // plane splits ray1421 1422 } else if (entSide > 0)1423 {1424 node = in->GetFront();1425 1426 if (extSide >= 0) // plane does not split ray => no far child1427 continue;1428 1429 farChild = in->GetBack(); // plane splits ray1430 }1431 else // ray and plane are coincident1432 {1433 // WHAT TO DO IN THIS CASE ?1434 //break;1435 node = in->GetFront();1436 continue;1437 }1438 1439 // push data for far child1440 tQueue.push(VspRayTraversalData(farChild, extp, maxt));1441 1442 // find intersection of ray segment with plane1443 float t;1444 extp = splitPlane.FindIntersection(ray.GetLoc(), extp, &t);1445 maxt *= t;1446 1447 } else // reached leaf => intersection with view cell1448 {1449 VspLeaf *leaf = dynamic_cast<VspLeaf *>(node);1450 1451 if (!leaf->GetViewCell()->Mailed())1452 {1453 //ray.bspIntersections.push_back(Ray::VspOspIntersection(maxt, leaf));1454 leaf->GetViewCell()->Mail();1455 ++ hits;1456 }1457 1458 //-- fetch the next far child from the stack1459 if (tQueue.empty())1460 break;1461 1462 entp = extp;1463 mint = maxt; // NOTE: need this?1464 1465 if (ray.GetType() == Ray::LINE_SEGMENT && mint > 1.0f)1466 break;1467 1468 BspRayTraversalData &s = tQueue.top();1469 1470 node = s.mNode;1471 extp = s.mExitPoint;1472 maxt = s.mMaxT;1473 1474 tQueue.pop();1475 }1476 }1477 #endif1478 return hits;1479 }1480 1481 1482 void VspOspTree::CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const1483 {1484 ViewCell::NewMail();1485 1486 1421 CollectViewCells(mRoot, onlyValid, viewCells, true); 1487 1422 } … … 1647 1582 1648 1583 1649 int VspOspTree::FindNeighbors(VspNode *n, vector<VspLeaf *> &neighbors, 1584 int VspOspTree::FindNeighbors(VspLeaf *n, 1585 vector<VspLeaf *> &neighbors, 1650 1586 const bool onlyUnmailed) const 1651 1587 { 1652 // TODO 1653 return 0; 1654 } 1655 1656 1657 VspLeaf *VspOspTree::GetRandomLeaf(const Plane3 &halfspace) 1658 { 1659 #if TODO 1660 stack<VspNode *> nodeStack; 1661 nodeStack.push(mRoot); 1662 1663 int mask = rand(); 1588 stack<VspNode *> nodeStack; 1589 1590 nodeStack.push(mRoot); 1591 1592 const AxisAlignedBox3 box = GetBBox(n); 1664 1593 1665 1594 while (!nodeStack.empty()) … … 1670 1599 if (node->IsLeaf()) 1671 1600 { 1601 VspLeaf *leaf = dynamic_cast<VspLeaf *>(node); 1602 1603 if (leaf != n && (!onlyUnmailed || !leaf->Mailed())) 1604 neighbors.push_back(leaf); 1605 } 1606 else 1607 { 1608 VspInterior *interior = dynamic_cast<VspInterior *>(node); 1609 1610 if (interior->GetPosition() > box.Max(interior->GetAxis())) 1611 nodeStack.push(interior->GetBack()); 1612 else 1613 { 1614 if (interior->GetPosition() < box.Min(interior->GetAxis())) 1615 nodeStack.push(interior->GetFront()); 1616 else 1617 { 1618 // random decision 1619 nodeStack.push(interior->GetBack()); 1620 nodeStack.push(interior->GetFront()); 1621 } 1622 } 1623 } 1624 } 1625 1626 return (int)neighbors.size(); 1627 } 1628 1629 1630 // Find random neighbor which was not mailed 1631 VspLeaf *VspOspTree::GetRandomLeaf(const Plane3 &plane) 1632 { 1633 stack<VspNode *> nodeStack; 1634 nodeStack.push(mRoot); 1635 1636 int mask = rand(); 1637 1638 while (!nodeStack.empty()) 1639 { 1640 VspNode *node = nodeStack.top(); 1641 1642 nodeStack.pop(); 1643 1644 if (node->IsLeaf()) 1645 { 1672 1646 return dynamic_cast<VspLeaf *>(node); 1673 } 1674 else 1647 } 1648 else 1675 1649 { 1676 1650 VspInterior *interior = dynamic_cast<VspInterior *>(node); 1677 1651 VspNode *next; 1678 BspNodeGeometry geom; 1679 1680 // todo: not very efficient: constructs full cell everytime 1681 ConstructGeometry(interior, geom); 1682 1683 const int cf = 1684 Polygon3::ClassifyPlane(geom.GetPolys(), halfspace, mEpsilon); 1685 1686 if (cf == Polygon3::BACK_SIDE) 1652 1653 if (GetBBox(interior->GetBack()).Side(plane) < 0) 1687 1654 next = interior->GetFront(); 1688 else 1689 if (cf == Polygon3::FRONT_SIDE) 1690 next = interior->GetFront(); 1691 else 1692 { 1693 // random decision 1694 if (mask & 1) 1655 else 1656 if (GetBBox(interior->GetFront()).Side(plane) < 0) 1695 1657 next = interior->GetBack(); 1696 else 1697 next = interior->GetFront(); 1698 mask = mask >> 1; 1699 } 1700 1701 nodeStack.push(next); 1702 } 1703 } 1704 #endif 1658 else 1659 { 1660 // random decision 1661 if (mask & 1) 1662 next = interior->GetBack(); 1663 else 1664 next = interior->GetFront(); 1665 mask = mask >> 1; 1666 } 1667 1668 nodeStack.push(next); 1669 } 1670 } 1671 1705 1672 return NULL; 1706 1673 } … … 1783 1750 1784 1751 1785 1786 1752 int VspOspTree::CastLineSegment(const Vector3 &origin, 1787 1753 const Vector3 &termination, … … 1789 1755 { 1790 1756 int hits = 0; 1791 #if TODO1792 stack<VspRayTraversalData> tStack;1793 1757 1794 1758 float mint = 0.0f, maxt = 1.0f; 1759 const Vector3 dir = termination - origin; 1760 1761 stack<LineTraversalData> tStack; 1795 1762 1796 1763 Intersectable::NewMail(); … … 1801 1768 1802 1769 VspNode *node = mRoot; 1803 VspNode *farChild = NULL;1804 1805 float t;1806 const float thresh = 1e-6f; // matt: change this to adjustable value1807 1770 VspNode *farChild; 1771 1772 float position; 1773 int axis; 1774 1808 1775 while (1) 1809 1776 { … … 1811 1778 { 1812 1779 VspInterior *in = dynamic_cast<VspInterior *>(node); 1813 1814 Plane3 splitPlane = in->GetPlane(); 1815 1816 const int entSide = splitPlane.Side(entp, thresh); 1817 const int extSide = splitPlane.Side(extp, thresh); 1818 1819 if (entSide < 0) 1820 { 1821 node = in->GetBack(); 1822 1823 // plane does not split ray => no far child 1824 if (extSide <= 0) 1780 position = in->GetPosition(); 1781 axis = in->GetAxis(); 1782 1783 if (entp[axis] <= position) 1784 { 1785 if (extp[axis] <= position) 1786 { 1787 node = in->GetBack(); 1788 // cases N1,N2,N3,P5,Z2,Z3 1825 1789 continue; 1826 1827 farChild = in->GetFront(); // plane splits ray 1828 } 1829 else if (entSide > 0) 1830 { 1831 node = in->GetFront(); 1832 1833 if (extSide >= 0) // plane does not split ray => no far child 1790 } else 1791 { 1792 // case N4 1793 node = in->GetBack(); 1794 farChild = in->GetFront(); 1795 } 1796 } 1797 else 1798 { 1799 if (position <= extp[axis]) 1800 { 1801 node = in->GetFront(); 1802 // cases P1,P2,P3,N5,Z1 1834 1803 continue; 1835 1836 farChild = in->GetBack(); // plane splits ray 1837 } 1838 else // one of the ray end points is on the plane 1839 { // NOTE: what to do if ray is coincident with plane? 1840 if (extSide < 0) 1841 node = in->GetBack(); 1842 else //if (extSide > 0) 1804 } 1805 else 1806 { 1843 1807 node = in->GetFront(); 1844 //else break; // coincident => count no intersections 1845 1846 continue; // no far child 1847 } 1848 1849 // push data for far child 1850 tStack.push(VspRayTraversalData(farChild, extp)); 1851 1852 // find intersection of ray segment with plane 1853 extp = splitPlane.FindIntersection(origin, extp, &t); 1854 } 1808 farChild = in->GetBack(); 1809 // case P4 1810 } 1811 } 1812 1813 // $$ modification 3.5.2004 - hints from Kamil Ghais 1814 // case N4 or P4 1815 const float tdist = (position - origin[axis]) / dir[axis]; 1816 tStack.push(LineTraversalData(farChild, extp, maxt)); //TODO 1817 1818 extp = origin + dir * tdist; 1819 maxt = tdist; 1820 } 1855 1821 else 1856 1822 { 1857 // reached leaf => intersection with view cell1823 // compute intersection with all objects in this leaf 1858 1824 VspLeaf *leaf = dynamic_cast<VspLeaf *>(node); 1859 ViewCell *viewCell; 1860 1861 if (0) 1862 viewCell = mViewCellsTree->GetActiveViewCell(leaf->GetViewCell()); 1863 else 1864 viewCell = leaf->GetViewCell(); 1865 1866 if (!viewCell->Mailed()) 1867 { 1868 viewcells.push_back(viewCell); 1869 viewCell->Mail(); 1825 ViewCell *vc = leaf->GetViewCell(); 1826 1827 if (!vc->Mailed()) 1828 { 1829 vc->Mail(); 1830 viewcells.push_back(vc); 1870 1831 ++ hits; 1871 1832 } 1872 1873 //-- fetch the next far child from the stack 1833 #if 0 1834 leaf->mRays.push_back(RayInfo(new VssRay(origin, termination, NULL, NULL, 0))); 1835 #endif 1836 // get the next node from the stack 1874 1837 if (tStack.empty()) 1875 1838 break; 1876 1839 1877 1840 entp = extp; 1841 mint = maxt; 1878 1842 1879 const BspRayTraversalData &s = tStack.top(); 1880 1843 LineTraversalData &s = tStack.top(); 1881 1844 node = s.mNode; 1882 1845 extp = s.mExitPoint; 1883 1846 maxt = s.mMaxT; 1884 1847 tStack.pop(); 1885 1848 } 1886 1849 } 1850 1851 return hits; 1852 } 1853 1854 1855 int VspOspTree::CastRay(Ray &ray) 1856 { 1857 int hits = 0; 1858 1859 stack<LineTraversalData> tStack; 1860 const Vector3 dir = ray.GetDir(); 1861 1862 float maxt, mint; 1863 1864 if (!mBox.GetRaySegment(ray, mint, maxt)) 1865 return 0; 1866 1867 Intersectable::NewMail(); 1868 ViewCell::NewMail(); 1869 1870 Vector3 entp = ray.Extrap(mint); 1871 Vector3 extp = ray.Extrap(maxt); 1872 1873 const Vector3 origin = entp; 1874 1875 VspNode *node = mRoot; 1876 VspNode *farChild = NULL; 1877 1878 float position; 1879 int axis; 1880 1881 while (1) 1882 { 1883 if (!node->IsLeaf()) 1884 { 1885 VspInterior *in = dynamic_cast<VspInterior *>(node); 1886 position = in->GetPosition(); 1887 axis = in->GetAxis(); 1888 1889 if (entp[axis] <= position) 1890 { 1891 if (extp[axis] <= position) 1892 { 1893 node = in->GetBack(); 1894 // cases N1,N2,N3,P5,Z2,Z3 1895 continue; 1896 } else 1897 { 1898 // case N4 1899 node = in->GetBack(); 1900 farChild = in->GetFront(); 1901 } 1902 } 1903 else 1904 { 1905 if (position <= extp[axis]) 1906 { 1907 node = in->GetFront(); 1908 // cases P1,P2,P3,N5,Z1 1909 continue; 1910 } 1911 else 1912 { 1913 node = in->GetFront(); 1914 farChild = in->GetBack(); 1915 // case P4 1916 } 1917 } 1918 1919 // $$ modification 3.5.2004 - hints from Kamil Ghais 1920 // case N4 or P4 1921 const float tdist = (position - origin[axis]) / dir[axis]; 1922 tStack.push(LineTraversalData(farChild, extp, maxt)); //TODO 1923 extp = origin + dir * tdist; 1924 maxt = tdist; 1925 } 1926 else 1927 { 1928 // compute intersection with all objects in this leaf 1929 VspLeaf *leaf = dynamic_cast<VspLeaf *>(node); 1930 ViewCell *vc = leaf->GetViewCell(); 1931 1932 if (!vc->Mailed()) 1933 { 1934 vc->Mail(); 1935 // todo: add view cells to ray 1936 ++ hits; 1937 } 1938 1939 #if 0 1940 leaf->mRays.push_back(RayInfo(new VssRay(origin, termination, NULL, NULL, 0))); 1887 1941 #endif 1942 // get the next node from the stack 1943 if (tStack.empty()) 1944 break; 1945 1946 entp = extp; 1947 mint = maxt; 1948 1949 LineTraversalData &s = tStack.top(); 1950 node = s.mNode; 1951 extp = s.mExitPoint; 1952 maxt = s.mMaxT; 1953 tStack.pop(); 1954 } 1955 } 1956 1888 1957 return hits; 1889 1958 } 1890 1891 1959 1892 1960 … … 2014 2082 { 2015 2083 VspInterior *interior = dynamic_cast<VspInterior *>(node); 2016 #if TODO2084 2017 2085 // random decision 2018 if (interior->GetP lane().Side(point)< 0)2086 if (interior->GetPosition() - point[interior->GetAxis()] < 0) 2019 2087 nodeStack.push(interior->GetBack()); 2020 2088 else 2021 2089 nodeStack.push(interior->GetFront()); 2022 #endif2023 2090 } 2024 2091 } … … 2033 2100 bool VspOspTree::ViewPointValid(const Vector3 &viewPoint) const 2034 2101 { 2035 #if TODO2036 2102 VspNode *node = mRoot; 2037 2103 … … 2047 2113 VspInterior *in = dynamic_cast<VspInterior *>(node); 2048 2114 2049 if (in->GetP lane().Side(viewPoint)<= 0)2115 if (in->GetPosition() - viewPoint[in->GetAxis()] <= 0) 2050 2116 { 2051 2117 node = in->GetBack(); … … 2056 2122 } 2057 2123 } 2058 #endif 2124 2059 2125 // should never come here 2060 2126 return false; … … 2120 2186 } 2121 2187 else 2122 { 2123 #if TODO 2188 { 2124 2189 VspInterior *interior = dynamic_cast<VspInterior *>(node); 2125 2190 2126 Plane3 plane = interior->GetPlane(); 2127 stream << "<Interior plane=\"" << plane.mNormal.x << " " 2128 << plane.mNormal.y << " " << plane.mNormal.z << " " 2129 << plane.mD << "\">" << endl; 2191 AxisAlignedPlane plane = interior->GetPlane(); 2192 stream << "<Interior plane=\"" << plane.mPosition << " " 2193 << plane.mAxis << "\">" << endl; 2130 2194 2131 2195 ExportNode(interior->GetBack(), stream); 2132 2196 ExportNode(interior->GetFront(), stream); 2133 #endif 2197 2134 2198 stream << "</Interior>" << endl; 2135 2199 } … … 2186 2250 } 2187 2251 2188 } 2252 2253 AxisAlignedBox3 VspOspTree::GetBBox(VspNode *node) const 2254 { 2255 if (!node->GetParent()) 2256 return mBox; 2257 2258 if (!node->IsLeaf()) 2259 { 2260 return (dynamic_cast<VspInterior *>(node))->GetBox(); 2261 } 2262 2263 VspInterior *parent = dynamic_cast<VspInterior *>(node->GetParent()); 2264 2265 AxisAlignedBox3 box(parent->GetBox()); 2266 2267 if (parent->GetFront() == node) 2268 box.SetMin(parent->GetAxis(), parent->GetPosition()); 2269 else 2270 box.SetMax(parent->GetAxis(), parent->GetPosition()); 2271 2272 return box; 2273 } 2274 2275 2276 } -
GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h
r1011 r1012 144 144 class VspNode 145 145 { 146 147 146 public: 147 148 // types of vsp nodes 149 enum {Interior, Leaf}; 150 148 151 VspNode(); 149 152 virtual ~VspNode(){}; … … 154 157 */ 155 158 virtual bool IsLeaf() const = 0; 159 160 virtual int Type() const; 156 161 157 162 /** Determines whether this node is a root … … 215 220 bool IsLeaf() const; 216 221 222 int Type() const; 223 217 224 VspNode *GetBack(); 218 225 VspNode *GetFront(); … … 221 228 */ 222 229 AxisAlignedPlane GetPlane() const; 230 231 /** Returns position of split plane. 232 */ 233 float GetPosition() const; 234 235 /** Returns split axis. 236 */ 237 int GetAxis() const; 223 238 224 239 /** Replace front or back child with new child. … … 234 249 } 235 250 251 AxisAlignedBox3 GetBox() const; 252 void SetBox(const AxisAlignedBox3 &box); 253 236 254 protected: 255 256 AxisAlignedBox3 mBox; 237 257 238 258 /// Splitting plane corresponding to this node … … 263 283 bool IsLeaf() const; 264 284 285 virtual int Type() const; 286 265 287 /** Returns pointer of view cell. 266 288 */ … … 414 436 415 437 438 /** Struct for traversing line segment. 439 */ 440 struct LineTraversalData 441 { 442 VspNode *mNode; 443 Vector3 mExitPoint; 444 445 float mMaxT; 446 447 LineTraversalData () {} 448 LineTraversalData (VspNode *n, const Vector3 &p, const float maxt): 449 mNode(n), mExitPoint(p), mMaxT(maxt) {} 450 }; 451 416 452 typedef std::priority_queue<VspOspTraversalData> VspOspTraversalQueue; 417 453 418 454 /** candidate for a view space split 455 */ 419 456 struct VspOspSplitCandidate 420 457 { … … 466 503 const VspTreeStatistics &GetStatistics() const; 467 504 505 /** Returns bounding box of the specified node. 506 */ 507 AxisAlignedBox3 GetBBox(VspNode *node) const; 468 508 469 509 /** Constructs the tree from a given set of rays. … … 506 546 /** finds neighbouring leaves of this tree node. 507 547 */ 508 int FindNeighbors(Vsp Node*n,548 int FindNeighbors(VspLeaf *n, 509 549 vector<VspLeaf *> &neighbors, 510 550 const bool onlyUnmailed) const; … … 594 634 @returns number of view cells found 595 635 */ 596 int ComputeBoxIntersections(const AxisAlignedBox3 &box, ViewCellContainer &viewCells) const; 636 int ComputeBoxIntersections(const AxisAlignedBox3 &box, 637 ViewCellContainer &viewCells) const; 597 638 598 639 // pointer to the hierarchy of view cells
Note: See TracChangeset
for help on using the changeset viewer.