diff options
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 215 |
1 files changed, 109 insertions, 106 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 9ca2d3f..cf74f14 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | |||
@@ -189,9 +189,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
189 | private const uint m_regionHeight = Constants.RegionSize; | 189 | private const uint m_regionHeight = Constants.RegionSize; |
190 | 190 | ||
191 | public float ODE_STEPSIZE = 0.020f; | 191 | public float ODE_STEPSIZE = 0.020f; |
192 | public float HalfOdeStep = 0.01f; | ||
192 | private float metersInSpace = 25.6f; | 193 | private float metersInSpace = 25.6f; |
193 | private float m_timeDilation = 1.0f; | 194 | private float m_timeDilation = 1.0f; |
194 | 195 | ||
196 | DateTime m_lastframe; | ||
197 | |||
195 | public float gravityx = 0f; | 198 | public float gravityx = 0f; |
196 | public float gravityy = 0f; | 199 | public float gravityy = 0f; |
197 | public float gravityz = -9.8f; | 200 | public float gravityz = -9.8f; |
@@ -485,6 +488,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
485 | } | 488 | } |
486 | } | 489 | } |
487 | 490 | ||
491 | HalfOdeStep = ODE_STEPSIZE * 0.5f; | ||
492 | |||
488 | ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); | 493 | ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); |
489 | GlobalContactsArray = GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf); | 494 | GlobalContactsArray = GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf); |
490 | 495 | ||
@@ -521,7 +526,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
521 | d.WorldSetAngularDamping(world, 0.001f); | 526 | d.WorldSetAngularDamping(world, 0.001f); |
522 | d.WorldSetAngularDampingThreshold(world, 0f); | 527 | d.WorldSetAngularDampingThreshold(world, 0f); |
523 | d.WorldSetLinearDampingThreshold(world, 0f); | 528 | d.WorldSetLinearDampingThreshold(world, 0f); |
524 | d.WorldSetMaxAngularSpeed(world, 256f); | 529 | d.WorldSetMaxAngularSpeed(world, 100f); |
525 | 530 | ||
526 | d.WorldSetCFM(world,1e-6f); // a bit harder than default | 531 | d.WorldSetCFM(world,1e-6f); // a bit harder than default |
527 | //d.WorldSetCFM(world, 1e-4f); // a bit harder than default | 532 | //d.WorldSetCFM(world, 1e-4f); // a bit harder than default |
@@ -564,6 +569,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
564 | // let this now be real maximum values | 569 | // let this now be real maximum values |
565 | spaceGridMaxX--; | 570 | spaceGridMaxX--; |
566 | spaceGridMaxY--; | 571 | spaceGridMaxY--; |
572 | m_lastframe = DateTime.UtcNow; | ||
567 | } | 573 | } |
568 | 574 | ||
569 | internal void waitForSpaceUnlock(IntPtr space) | 575 | internal void waitForSpaceUnlock(IntPtr space) |
@@ -1685,35 +1691,30 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1685 | /// <returns></returns> | 1691 | /// <returns></returns> |
1686 | public override float Simulate(float timeStep) | 1692 | public override float Simulate(float timeStep) |
1687 | { | 1693 | { |
1688 | int statstart; | ||
1689 | int statchanges = 0; | ||
1690 | int statchmove = 0; | ||
1691 | int statactmove = 0; | ||
1692 | int statray = 0; | ||
1693 | int statcol = 0; | ||
1694 | int statstep = 0; | ||
1695 | int statmovchar = 0; | ||
1696 | int statmovprim; | ||
1697 | int totjcontact = 0; | ||
1698 | 1694 | ||
1695 | DateTime now = DateTime.UtcNow; | ||
1696 | TimeSpan SinceLastFrame = now - m_lastframe; | ||
1697 | m_lastframe = now; | ||
1698 | timeStep = (float)SinceLastFrame.TotalSeconds; | ||
1699 | |||
1699 | // acumulate time so we can reduce error | 1700 | // acumulate time so we can reduce error |
1700 | step_time += timeStep; | 1701 | step_time += timeStep; |
1701 | 1702 | ||
1702 | if (step_time < ODE_STEPSIZE) | 1703 | if (step_time < HalfOdeStep) |
1703 | return 0; | 1704 | return 0; |
1704 | 1705 | ||
1705 | if (framecount >= int.MaxValue) | 1706 | if (framecount < 0) |
1706 | framecount = 0; | 1707 | framecount = 0; |
1707 | 1708 | ||
1708 | framecount++; | 1709 | framecount++; |
1709 | 1710 | ||
1710 | int curphysiteractions = m_physicsiterations; | 1711 | int curphysiteractions; |
1711 | 1712 | ||
1713 | // if in trouble reduce step resolution | ||
1712 | if (step_time >= m_SkipFramesAtms) | 1714 | if (step_time >= m_SkipFramesAtms) |
1713 | { | 1715 | curphysiteractions = m_physicsiterations / 2; |
1714 | // if in trouble reduce step resolution | 1716 | else |
1715 | curphysiteractions /= 2; | 1717 | curphysiteractions = m_physicsiterations; |
1716 | } | ||
1717 | 1718 | ||
1718 | int nodeframes = 0; | 1719 | int nodeframes = 0; |
1719 | 1720 | ||
@@ -1733,13 +1734,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1733 | base.TriggerPhysicsBasedRestart(); | 1734 | base.TriggerPhysicsBasedRestart(); |
1734 | } | 1735 | } |
1735 | 1736 | ||
1736 | 1737 | while (step_time >= HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever | |
1737 | while (step_time >= ODE_STEPSIZE && nodeframes < 10) //limit number of steps so we don't say here for ever | ||
1738 | { | 1738 | { |
1739 | try | 1739 | try |
1740 | { | 1740 | { |
1741 | statstart = Util.EnvironmentTickCount(); | ||
1742 | |||
1743 | // clear pointer/counter to contacts to pass into joints | 1741 | // clear pointer/counter to contacts to pass into joints |
1744 | m_global_contactcount = 0; | 1742 | m_global_contactcount = 0; |
1745 | 1743 | ||
@@ -1778,17 +1776,39 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1778 | 1776 | ||
1779 | } | 1777 | } |
1780 | 1778 | ||
1781 | statchanges += Util.EnvironmentTickCountSubtract(statstart); | 1779 | // Move characters |
1780 | lock (_characters) | ||
1781 | { | ||
1782 | List<OdeCharacter> defects = new List<OdeCharacter>(); | ||
1783 | foreach (OdeCharacter actor in _characters) | ||
1784 | { | ||
1785 | if (actor != null) | ||
1786 | actor.Move(ODE_STEPSIZE, defects); | ||
1787 | } | ||
1788 | if (defects.Count != 0) | ||
1789 | { | ||
1790 | foreach (OdeCharacter defect in defects) | ||
1791 | { | ||
1792 | RemoveCharacter(defect); | ||
1793 | } | ||
1794 | } | ||
1795 | } | ||
1796 | |||
1797 | // Move other active objects | ||
1798 | lock (_activegroups) | ||
1799 | { | ||
1800 | foreach (OdePrim aprim in _activegroups) | ||
1801 | { | ||
1802 | aprim.Move(); | ||
1803 | } | ||
1804 | } | ||
1782 | 1805 | ||
1783 | statactmove += Util.EnvironmentTickCountSubtract(statstart); | ||
1784 | //if ((framecount % m_randomizeWater) == 0) | 1806 | //if ((framecount % m_randomizeWater) == 0) |
1785 | // randomizeWater(waterlevel); | 1807 | // randomizeWater(waterlevel); |
1786 | 1808 | ||
1787 | m_rayCastManager.ProcessQueuedRequests(); | 1809 | m_rayCastManager.ProcessQueuedRequests(); |
1788 | 1810 | ||
1789 | statray += Util.EnvironmentTickCountSubtract(statstart); | ||
1790 | collision_optimized(); | 1811 | collision_optimized(); |
1791 | statcol += Util.EnvironmentTickCountSubtract(statstart); | ||
1792 | 1812 | ||
1793 | lock (_collisionEventPrim) | 1813 | lock (_collisionEventPrim) |
1794 | { | 1814 | { |
@@ -1813,38 +1833,39 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1813 | } | 1833 | } |
1814 | } | 1834 | } |
1815 | 1835 | ||
1836 | // do a ode simulation step | ||
1816 | d.WorldQuickStep(world, ODE_STEPSIZE); | 1837 | d.WorldQuickStep(world, ODE_STEPSIZE); |
1817 | statstep += Util.EnvironmentTickCountSubtract(statstart); | 1838 | d.JointGroupEmpty(contactgroup); |
1839 | |||
1840 | // update managed ideia of physical data and do updates to core | ||
1841 | /* | ||
1842 | lock (_characters) | ||
1843 | { | ||
1844 | foreach (OdeCharacter actor in _characters) | ||
1845 | { | ||
1846 | if (actor != null) | ||
1847 | { | ||
1848 | if (actor.bad) | ||
1849 | m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); | ||
1850 | |||
1851 | actor.UpdatePositionAndVelocity(); | ||
1852 | } | ||
1853 | } | ||
1854 | } | ||
1855 | */ | ||
1818 | 1856 | ||
1819 | // Move characters | 1857 | lock (_activegroups) |
1820 | lock (_characters) | ||
1821 | { | 1858 | { |
1822 | List<OdeCharacter> defects = new List<OdeCharacter>(); | ||
1823 | foreach (OdeCharacter actor in _characters) | ||
1824 | { | ||
1825 | if (actor != null) | ||
1826 | actor.Move(ODE_STEPSIZE, defects); | ||
1827 | } | ||
1828 | if (defects.Count != 0) | ||
1829 | { | 1859 | { |
1830 | foreach (OdeCharacter defect in defects) | 1860 | foreach (OdePrim actor in _activegroups) |
1831 | { | 1861 | { |
1832 | RemoveCharacter(defect); | 1862 | if (actor.IsPhysical) |
1863 | { | ||
1864 | actor.UpdatePositionAndVelocity(); | ||
1865 | } | ||
1833 | } | 1866 | } |
1834 | } | 1867 | } |
1835 | } | 1868 | } |
1836 | statchmove += Util.EnvironmentTickCountSubtract(statstart); | ||
1837 | |||
1838 | // Move other active objects | ||
1839 | lock (_activegroups) | ||
1840 | { | ||
1841 | foreach (OdePrim aprim in _activegroups) | ||
1842 | { | ||
1843 | aprim.Move(); | ||
1844 | } | ||
1845 | } | ||
1846 | |||
1847 | //ode.dunlock(world); | ||
1848 | } | 1869 | } |
1849 | catch (Exception e) | 1870 | catch (Exception e) |
1850 | { | 1871 | { |
@@ -1852,32 +1873,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1852 | // ode.dunlock(world); | 1873 | // ode.dunlock(world); |
1853 | } | 1874 | } |
1854 | 1875 | ||
1855 | d.JointGroupEmpty(contactgroup); | ||
1856 | totjcontact += m_global_contactcount; | ||
1857 | 1876 | ||
1858 | step_time -= ODE_STEPSIZE; | 1877 | step_time -= ODE_STEPSIZE; |
1859 | nodeframes++; | 1878 | nodeframes++; |
1860 | } | 1879 | } |
1861 | 1880 | ||
1862 | statstart = Util.EnvironmentTickCount(); | ||
1863 | |||
1864 | /* | ||
1865 | // now included in characters move() and done at ode rate | ||
1866 | // maybe be needed later if we need to do any extra work at hearbeat rate | ||
1867 | lock (_characters) | ||
1868 | { | ||
1869 | foreach (OdeCharacter actor in _characters) | ||
1870 | { | ||
1871 | if (actor != null) | ||
1872 | { | ||
1873 | if (actor.bad) | ||
1874 | m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); | ||
1875 | |||
1876 | actor.UpdatePositionAndVelocity(); | ||
1877 | } | ||
1878 | } | ||
1879 | } | ||
1880 | */ | ||
1881 | lock (_badCharacter) | 1881 | lock (_badCharacter) |
1882 | { | 1882 | { |
1883 | if (_badCharacter.Count > 0) | 1883 | if (_badCharacter.Count > 0) |
@@ -1890,22 +1890,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1890 | _badCharacter.Clear(); | 1890 | _badCharacter.Clear(); |
1891 | } | 1891 | } |
1892 | } | 1892 | } |
1893 | statmovchar = Util.EnvironmentTickCountSubtract(statstart); | ||
1894 | |||
1895 | lock (_activegroups) | ||
1896 | { | ||
1897 | { | ||
1898 | foreach (OdePrim actor in _activegroups) | ||
1899 | { | ||
1900 | if (actor.IsPhysical) | ||
1901 | { | ||
1902 | actor.UpdatePositionAndVelocity((float)nodeframes * ODE_STEPSIZE); | ||
1903 | } | ||
1904 | } | ||
1905 | } | ||
1906 | } | ||
1907 | |||
1908 | statmovprim = Util.EnvironmentTickCountSubtract(statstart); | ||
1909 | 1893 | ||
1910 | int nactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); | 1894 | int nactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); |
1911 | int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); | 1895 | int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); |
@@ -1932,15 +1916,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1932 | d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); | 1916 | d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); |
1933 | } | 1917 | } |
1934 | 1918 | ||
1935 | // think time dilation is not a physics issue alone.. but ok let's fake something | 1919 | // think time dilation as to do with dinamic step size that we dont' have |
1936 | if (step_time < ODE_STEPSIZE) // we did the required loops | 1920 | // even so tell something to world |
1921 | if (nodeframes < 10) // we did the requested loops | ||
1937 | m_timeDilation = 1.0f; | 1922 | m_timeDilation = 1.0f; |
1938 | else | 1923 | else if (step_time > 0) |
1939 | { // we didn't forget the lost ones and let user know something | 1924 | { |
1940 | m_timeDilation = 1 - step_time / timeStep; | 1925 | m_timeDilation = timeStep / step_time; |
1941 | if (m_timeDilation < 0) | 1926 | if (m_timeDilation > 1) |
1942 | m_timeDilation = 0; | 1927 | m_timeDilation = 1; |
1943 | step_time = 0; | 1928 | if (step_time > m_SkipFramesAtms) |
1929 | step_time = 0; | ||
1944 | } | 1930 | } |
1945 | } | 1931 | } |
1946 | 1932 | ||
@@ -2007,7 +1993,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2007 | } | 1993 | } |
2008 | else // out world use external height | 1994 | else // out world use external height |
2009 | { | 1995 | { |
2010 | ix = regsize - 1; | 1996 | ix = regsize - 2; |
2011 | dx = 0; | 1997 | dx = 0; |
2012 | } | 1998 | } |
2013 | if (y < regsize - 1) | 1999 | if (y < regsize - 1) |
@@ -2017,7 +2003,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2017 | } | 2003 | } |
2018 | else | 2004 | else |
2019 | { | 2005 | { |
2020 | iy = regsize - 1; | 2006 | iy = regsize - 2; |
2021 | dy = 0; | 2007 | dy = 0; |
2022 | } | 2008 | } |
2023 | } | 2009 | } |
@@ -2034,7 +2020,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2034 | } | 2020 | } |
2035 | else // out world use external height | 2021 | else // out world use external height |
2036 | { | 2022 | { |
2037 | iy = regsize - 1; | 2023 | iy = regsize - 2; |
2038 | dy = 0; | 2024 | dy = 0; |
2039 | } | 2025 | } |
2040 | if (y < regsize - 1) | 2026 | if (y < regsize - 1) |
@@ -2044,7 +2030,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2044 | } | 2030 | } |
2045 | else | 2031 | else |
2046 | { | 2032 | { |
2047 | ix = regsize - 1; | 2033 | ix = regsize - 2; |
2048 | dx = 0; | 2034 | dx = 0; |
2049 | } | 2035 | } |
2050 | } | 2036 | } |
@@ -2057,18 +2043,35 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2057 | iy += ix; // all indexes have iy + ix | 2043 | iy += ix; // all indexes have iy + ix |
2058 | 2044 | ||
2059 | float[] heights = TerrainHeightFieldHeights[heightFieldGeom]; | 2045 | float[] heights = TerrainHeightFieldHeights[heightFieldGeom]; |
2046 | /* | ||
2047 | if ((dx + dy) <= 1.0f) | ||
2048 | { | ||
2049 | h0 = ((float)heights[iy]); // 0,0 vertice | ||
2050 | h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0 | ||
2051 | h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0 | ||
2052 | } | ||
2053 | else | ||
2054 | { | ||
2055 | h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice | ||
2056 | h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0 | ||
2057 | h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1 | ||
2058 | } | ||
2059 | */ | ||
2060 | h0 = ((float)heights[iy]); // 0,0 vertice | ||
2060 | 2061 | ||
2061 | if ((dx + dy) <= 1.0f) | 2062 | if ((dy > dx)) |
2062 | { | 2063 | { |
2063 | h0 = ((float)heights[iy]); // 0,0 vertice | 2064 | iy += regsize; |
2064 | h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0 | 2065 | h2 = (float)heights[iy]; // 0,1 vertice |
2065 | h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0 | 2066 | h1 = (h2 - h0) * dy; // 0,1 vertice minus 0,0 |
2067 | h2 = ((float)heights[iy + 1] - h2) * dx; // 1,1 vertice minus 0,1 | ||
2066 | } | 2068 | } |
2067 | else | 2069 | else |
2068 | { | 2070 | { |
2069 | h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice | 2071 | iy++; |
2070 | h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0 | 2072 | h2 = (float)heights[iy]; // vertice 1,0 |
2071 | h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1 | 2073 | h1 = (h2 - h0) * dx; // 1,0 vertice minus 0,0 |
2074 | h2 = (((float)heights[iy + regsize]) - h2) * dy; // 1,1 vertice minus 1,0 | ||
2072 | } | 2075 | } |
2073 | 2076 | ||
2074 | return h0 + h1 + h2; | 2077 | return h0 + h1 + h2; |