diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs | 9 | ||||
-rw-r--r-- | OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs | 12 | ||||
-rw-r--r-- | OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs | 417 |
3 files changed, 127 insertions, 311 deletions
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs index 42ad391..ee22a70 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs | |||
@@ -743,10 +743,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
743 | return CreateiOSTerrain(space, data, bPlaceable); | 743 | return CreateiOSTerrain(space, data, bPlaceable); |
744 | } | 744 | } |
745 | 745 | ||
746 | |||
747 | |||
748 | |||
749 | |||
750 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity] | 746 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity] |
751 | internal static extern IntPtr CreateiGeom(int classnum); | 747 | internal static extern IntPtr CreateiGeom(int classnum); |
752 | internal static IntPtr CreateGeom(int classnum) | 748 | internal static IntPtr CreateGeom(int classnum) |
@@ -794,8 +790,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
794 | NTotalGeoms++; | 790 | NTotalGeoms++; |
795 | return CreateiTriMesh(space, data, callback, arrayCallback, rayCallback); | 791 | return CreateiTriMesh(space, data, callback, arrayCallback, rayCallback); |
796 | } | 792 | } |
797 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity] | ||
798 | internal static extern dReal Dot(ref dReal X0, ref dReal X1, int n); | ||
799 | 793 | ||
800 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDQfromW"), SuppressUnmanagedCodeSecurity] | 794 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDQfromW"), SuppressUnmanagedCodeSecurity] |
801 | internal static extern void DQfromW(dReal[] dq, ref Vector3 w, ref Quaternion q); | 795 | internal static extern void DQfromW(dReal[] dq, ref Vector3 w, ref Quaternion q); |
@@ -884,9 +878,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
884 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity] | 878 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity] |
885 | internal static extern void GeomGetAABB(IntPtr geom, out AABB aabb); | 879 | internal static extern void GeomGetAABB(IntPtr geom, out AABB aabb); |
886 | 880 | ||
887 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity] | ||
888 | internal static extern void GeomGetAABB(IntPtr geom, out dReal minX); | ||
889 | |||
890 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetBody"), SuppressUnmanagedCodeSecurity] | 881 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetBody"), SuppressUnmanagedCodeSecurity] |
891 | internal static extern IntPtr GeomGetBody(IntPtr geom); | 882 | internal static extern IntPtr GeomGetBody(IntPtr geom); |
892 | 883 | ||
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs index 90560fd..7ef4d27 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs | |||
@@ -55,15 +55,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
55 | SafeNativeMethods.InitODE(); | 55 | SafeNativeMethods.InitODE(); |
56 | 56 | ||
57 | string ode_config = SafeNativeMethods.GetConfiguration(); | 57 | string ode_config = SafeNativeMethods.GetConfiguration(); |
58 | if (ode_config != null && ode_config != "") | 58 | if (ode_config == null || ode_config == "" || !ode_config.Contains("ODE_OPENSIM")) |
59 | { | 59 | { |
60 | m_log.InfoFormat("[ubODE] ode library configuration: {0}", ode_config); | 60 | m_log.Error("[ubODE] Native ode library version not supported"); |
61 | 61 | m_Enabled = false; | |
62 | if (ode_config.Contains("ODE_OPENSIM")) | 62 | return; |
63 | { | ||
64 | OSOdeLib = true; | ||
65 | } | ||
66 | } | 63 | } |
64 | m_log.InfoFormat("[ubODE] ode library configuration: {0}", ode_config); | ||
67 | } | 65 | } |
68 | } | 66 | } |
69 | } | 67 | } |
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs index fe11505..cdade00 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs | |||
@@ -190,8 +190,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
190 | // this netx dimensions are only relevant for terrain partition (mega regions) | 190 | // this netx dimensions are only relevant for terrain partition (mega regions) |
191 | // WorldExtents below has the simulation dimensions | 191 | // WorldExtents below has the simulation dimensions |
192 | // they should be identical except on mega regions | 192 | // they should be identical except on mega regions |
193 | private uint m_regionWidth = Constants.RegionSize; | 193 | private int m_regionWidth = (int)Constants.RegionSize; |
194 | private uint m_regionHeight = Constants.RegionSize; | 194 | private int m_regionHeight = (int)Constants.RegionSize; |
195 | 195 | ||
196 | public float ODE_STEPSIZE = 0.020f; | 196 | public float ODE_STEPSIZE = 0.020f; |
197 | public float HalfOdeStep = 0.01f; | 197 | public float HalfOdeStep = 0.01f; |
@@ -255,9 +255,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
255 | 255 | ||
256 | public ContactData[] m_materialContactsData = new ContactData[8]; | 256 | public ContactData[] m_materialContactsData = new ContactData[8]; |
257 | 257 | ||
258 | private IntPtr TerrainGeom; | 258 | private IntPtr m_terrainGeom; |
259 | private float[] TerrainHeightFieldHeight; | 259 | private float[] m_terrainHeights; |
260 | private GCHandle TerrainHeightFieldHeightsHandler = new GCHandle(); | 260 | private GCHandle m_terrainHeightsHandler = new GCHandle(); |
261 | private IntPtr HeightmapData; | ||
262 | private int m_lastRegionWidth; | ||
263 | private int m_lastRegionHeight; | ||
261 | 264 | ||
262 | private int m_physicsiterations = 15; | 265 | private int m_physicsiterations = 15; |
263 | private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag | 266 | private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag |
@@ -326,10 +329,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
326 | m_frameWorkScene.RegisterModuleInterface<PhysicsScene>(this); | 329 | m_frameWorkScene.RegisterModuleInterface<PhysicsScene>(this); |
327 | 330 | ||
328 | Initialization(); | 331 | Initialization(); |
329 | |||
330 | base.Initialise(m_frameWorkScene.PhysicsRequestAsset, | ||
331 | (m_frameWorkScene.Heightmap != null ? m_frameWorkScene.Heightmap.GetFloatsSerialised() : new float[m_frameWorkScene.RegionInfo.RegionSizeX * m_frameWorkScene.RegionInfo.RegionSizeY]), | ||
332 | (float)m_frameWorkScene.RegionInfo.RegionSettings.WaterHeight); | ||
333 | } | 332 | } |
334 | 333 | ||
335 | public void RegionLoaded() | 334 | public void RegionLoaded() |
@@ -360,9 +359,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
360 | m_rayCastManager = new ODERayCastRequestManager(this); | 359 | m_rayCastManager = new ODERayCastRequestManager(this); |
361 | 360 | ||
362 | WorldExtents.X = m_frameWorkScene.RegionInfo.RegionSizeX; | 361 | WorldExtents.X = m_frameWorkScene.RegionInfo.RegionSizeX; |
363 | m_regionWidth = (uint)WorldExtents.X; | 362 | m_regionWidth = (int)WorldExtents.X; |
364 | WorldExtents.Y = m_frameWorkScene.RegionInfo.RegionSizeY; | 363 | WorldExtents.Y = m_frameWorkScene.RegionInfo.RegionSizeY; |
365 | m_regionHeight = (uint)WorldExtents.Y; | 364 | m_regionHeight = (int)WorldExtents.Y; |
366 | 365 | ||
367 | lock (OdeLock) | 366 | lock (OdeLock) |
368 | { | 367 | { |
@@ -549,6 +548,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
549 | m_lastframe = Util.GetTimeStamp(); | 548 | m_lastframe = Util.GetTimeStamp(); |
550 | m_lastMeshExpire = m_lastframe; | 549 | m_lastMeshExpire = m_lastframe; |
551 | step_time = -1; | 550 | step_time = -1; |
551 | |||
552 | |||
553 | base.Initialise(m_frameWorkScene.PhysicsRequestAsset, | ||
554 | (m_frameWorkScene.Heightmap != null ? m_frameWorkScene.Heightmap.GetFloatsSerialised() : new float[m_frameWorkScene.RegionInfo.RegionSizeX * m_frameWorkScene.RegionInfo.RegionSizeY]), | ||
555 | (float)m_frameWorkScene.RegionInfo.RegionSettings.WaterHeight); | ||
552 | } | 556 | } |
553 | 557 | ||
554 | internal void waitForSpaceUnlock(IntPtr space) | 558 | internal void waitForSpaceUnlock(IntPtr space) |
@@ -1867,10 +1871,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1867 | 1871 | ||
1868 | public float GetTerrainHeightAtXY(float x, float y) | 1872 | public float GetTerrainHeightAtXY(float x, float y) |
1869 | { | 1873 | { |
1870 | if (TerrainGeom == IntPtr.Zero) | 1874 | if (m_terrainGeom == IntPtr.Zero) |
1871 | return 0f; | 1875 | return 0f; |
1872 | 1876 | ||
1873 | if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0) | 1877 | if (m_terrainHeights == null || m_terrainHeights.Length == 0) |
1874 | return 0f; | 1878 | return 0f; |
1875 | 1879 | ||
1876 | // TerrainHeightField for ODE as offset 1m | 1880 | // TerrainHeightField for ODE as offset 1m |
@@ -1894,57 +1898,25 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1894 | int regsizeY = (int)m_regionHeight + 3; // map size see setterrain number of samples | 1898 | int regsizeY = (int)m_regionHeight + 3; // map size see setterrain number of samples |
1895 | int regsize = regsizeX; | 1899 | int regsize = regsizeX; |
1896 | 1900 | ||
1897 | if (m_OSOdeLib) | 1901 | if (x < regsizeX - 1) |
1898 | { | 1902 | { |
1899 | if (x < regsizeX - 1) | 1903 | ix = (int)x; |
1900 | { | 1904 | dx = x - (float)ix; |
1901 | ix = (int)x; | 1905 | } |
1902 | dx = x - (float)ix; | 1906 | else // out world use external height |
1903 | } | 1907 | { |
1904 | else // out world use external height | 1908 | ix = regsizeX - 2; |
1905 | { | 1909 | dx = 0; |
1906 | ix = regsizeX - 2; | 1910 | } |
1907 | dx = 0; | 1911 | if (y < regsizeY - 1) |
1908 | } | 1912 | { |
1909 | if (y < regsizeY - 1) | 1913 | iy = (int)y; |
1910 | { | 1914 | dy = y - (float)iy; |
1911 | iy = (int)y; | ||
1912 | dy = y - (float)iy; | ||
1913 | } | ||
1914 | else | ||
1915 | { | ||
1916 | iy = regsizeY - 2; | ||
1917 | dy = 0; | ||
1918 | } | ||
1919 | } | 1915 | } |
1920 | else | 1916 | else |
1921 | { | 1917 | { |
1922 | // we still have square fixed size regions | 1918 | iy = regsizeY - 2; |
1923 | // also flip x and y because of how map is done for ODE fliped axis | 1919 | dy = 0; |
1924 | // so ix,iy,dx and dy are inter exchanged | ||
1925 | |||
1926 | regsize = regsizeY; | ||
1927 | |||
1928 | if (x < regsizeX - 1) | ||
1929 | { | ||
1930 | iy = (int)x; | ||
1931 | dy = x - (float)iy; | ||
1932 | } | ||
1933 | else // out world use external height | ||
1934 | { | ||
1935 | iy = regsizeX - 2; | ||
1936 | dy = 0; | ||
1937 | } | ||
1938 | if (y < regsizeY - 1) | ||
1939 | { | ||
1940 | ix = (int)y; | ||
1941 | dx = y - (float)ix; | ||
1942 | } | ||
1943 | else | ||
1944 | { | ||
1945 | ix = regsizeY - 2; | ||
1946 | dx = 0; | ||
1947 | } | ||
1948 | } | 1920 | } |
1949 | 1921 | ||
1950 | float h0; | 1922 | float h0; |
@@ -1954,7 +1926,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1954 | iy *= regsize; | 1926 | iy *= regsize; |
1955 | iy += ix; // all indexes have iy + ix | 1927 | iy += ix; // all indexes have iy + ix |
1956 | 1928 | ||
1957 | float[] heights = TerrainHeightFieldHeight; | 1929 | float[] heights = m_terrainHeights; |
1958 | /* | 1930 | /* |
1959 | if ((dx + dy) <= 1.0f) | 1931 | if ((dx + dy) <= 1.0f) |
1960 | { | 1932 | { |
@@ -1993,10 +1965,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1993 | { | 1965 | { |
1994 | Vector3 norm = new Vector3(0, 0, 1); | 1966 | Vector3 norm = new Vector3(0, 0, 1); |
1995 | 1967 | ||
1996 | if (TerrainGeom == IntPtr.Zero) | 1968 | if (m_terrainGeom == IntPtr.Zero) |
1997 | return norm; | 1969 | return norm; |
1998 | 1970 | ||
1999 | if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0) | 1971 | if (m_terrainHeights == null || m_terrainHeights.Length == 0) |
2000 | return norm; | 1972 | return norm; |
2001 | 1973 | ||
2002 | // TerrainHeightField for ODE as offset 1m | 1974 | // TerrainHeightField for ODE as offset 1m |
@@ -2024,62 +1996,27 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2024 | int ystep = regsizeX; | 1996 | int ystep = regsizeX; |
2025 | bool firstTri = false; | 1997 | bool firstTri = false; |
2026 | 1998 | ||
2027 | if (m_OSOdeLib) | 1999 | if (x < regsizeX - 1) |
2028 | { | 2000 | { |
2029 | if (x < regsizeX - 1) | 2001 | ix = (int)x; |
2030 | { | 2002 | dx = x - (float)ix; |
2031 | ix = (int)x; | 2003 | } |
2032 | dx = x - (float)ix; | 2004 | else // out world use external height |
2033 | } | 2005 | { |
2034 | else // out world use external height | 2006 | ix = regsizeX - 2; |
2035 | { | 2007 | dx = 0; |
2036 | ix = regsizeX - 2; | 2008 | } |
2037 | dx = 0; | 2009 | if (y < regsizeY - 1) |
2038 | } | 2010 | { |
2039 | if (y < regsizeY - 1) | 2011 | iy = (int)y; |
2040 | { | 2012 | dy = y - (float)iy; |
2041 | iy = (int)y; | ||
2042 | dy = y - (float)iy; | ||
2043 | } | ||
2044 | else | ||
2045 | { | ||
2046 | iy = regsizeY - 2; | ||
2047 | dy = 0; | ||
2048 | } | ||
2049 | firstTri = dy > dx; | ||
2050 | } | 2013 | } |
2051 | |||
2052 | else | 2014 | else |
2053 | { | 2015 | { |
2054 | xstep = regsizeY; | 2016 | iy = regsizeY - 2; |
2055 | ystep = 1; | 2017 | dy = 0; |
2056 | regsize = regsizeY; | ||
2057 | |||
2058 | // we still have square fixed size regions | ||
2059 | // also flip x and y because of how map is done for ODE fliped axis | ||
2060 | // so ix,iy,dx and dy are inter exchanged | ||
2061 | if (x < regsizeX - 1) | ||
2062 | { | ||
2063 | iy = (int)x; | ||
2064 | dy = x - (float)iy; | ||
2065 | } | ||
2066 | else // out world use external height | ||
2067 | { | ||
2068 | iy = regsizeX - 2; | ||
2069 | dy = 0; | ||
2070 | } | ||
2071 | if (y < regsizeY - 1) | ||
2072 | { | ||
2073 | ix = (int)y; | ||
2074 | dx = y - (float)ix; | ||
2075 | } | ||
2076 | else | ||
2077 | { | ||
2078 | ix = regsizeY - 2; | ||
2079 | dx = 0; | ||
2080 | } | ||
2081 | firstTri = dx > dy; | ||
2082 | } | 2018 | } |
2019 | firstTri = dy > dx; | ||
2083 | 2020 | ||
2084 | float h0; | 2021 | float h0; |
2085 | float h1; | 2022 | float h1; |
@@ -2088,7 +2025,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2088 | iy *= regsize; | 2025 | iy *= regsize; |
2089 | iy += ix; // all indexes have iy + ix | 2026 | iy += ix; // all indexes have iy + ix |
2090 | 2027 | ||
2091 | float[] heights = TerrainHeightFieldHeight; | 2028 | float[] heights = m_terrainHeights; |
2092 | 2029 | ||
2093 | if (firstTri) | 2030 | if (firstTri) |
2094 | { | 2031 | { |
@@ -2113,229 +2050,117 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2113 | return norm; | 2050 | return norm; |
2114 | } | 2051 | } |
2115 | 2052 | ||
2116 | public override void SetTerrain(float[] heightMap) | 2053 | private void InitTerrain() |
2117 | { | ||
2118 | if (m_OSOdeLib) | ||
2119 | OSSetTerrain(heightMap); | ||
2120 | else | ||
2121 | OriSetTerrain(heightMap); | ||
2122 | } | ||
2123 | |||
2124 | public void OriSetTerrain(float[] heightMap) | ||
2125 | { | 2054 | { |
2126 | // assumes 1m size grid and constante size square regions | ||
2127 | // needs to know about sims around in future | ||
2128 | |||
2129 | float[] _heightmap; | ||
2130 | |||
2131 | uint regionsizeX = m_regionWidth; | ||
2132 | uint regionsizeY = m_regionHeight; | ||
2133 | |||
2134 | // map is rotated | ||
2135 | uint heightmapWidth = regionsizeY + 2; | ||
2136 | uint heightmapHeight = regionsizeX + 2; | ||
2137 | |||
2138 | uint heightmapWidthSamples = heightmapWidth + 1; | ||
2139 | uint heightmapHeightSamples = heightmapHeight + 1; | ||
2140 | |||
2141 | _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples]; | ||
2142 | |||
2143 | const float scale = 1.0f; | ||
2144 | const float offset = 0.0f; | ||
2145 | const float thickness = 10f; | ||
2146 | const int wrap = 0; | ||
2147 | |||
2148 | |||
2149 | float hfmin = float.MaxValue; | ||
2150 | float hfmax = float.MinValue; | ||
2151 | float val; | ||
2152 | uint xx; | ||
2153 | uint yy; | ||
2154 | |||
2155 | uint maxXX = regionsizeX - 1; | ||
2156 | uint maxYY = regionsizeY - 1; | ||
2157 | // flipping map adding one margin all around so things don't fall in edges | ||
2158 | |||
2159 | uint xt = 0; | ||
2160 | xx = 0; | ||
2161 | |||
2162 | for (uint x = 0; x < heightmapWidthSamples; x++) | ||
2163 | { | ||
2164 | if (x > 1 && xx < maxXX) | ||
2165 | xx++; | ||
2166 | yy = 0; | ||
2167 | for (uint y = 0; y < heightmapHeightSamples; y++) | ||
2168 | { | ||
2169 | if (y > 1 && y < maxYY) | ||
2170 | yy += regionsizeX; | ||
2171 | |||
2172 | val = heightMap[yy + xx]; | ||
2173 | if (val < -100.0f) | ||
2174 | val = -100.0f; | ||
2175 | _heightmap[xt + y] = val; | ||
2176 | |||
2177 | if (hfmin > val) | ||
2178 | hfmin = val; | ||
2179 | if (hfmax < val) | ||
2180 | hfmax = val; | ||
2181 | } | ||
2182 | xt += heightmapHeightSamples; | ||
2183 | } | ||
2184 | |||
2185 | lock (OdeLock) | 2055 | lock (OdeLock) |
2186 | { | 2056 | { |
2187 | SafeNativeMethods.AllocateODEDataForThread(~0U); | 2057 | SafeNativeMethods.AllocateODEDataForThread(~0U); |
2188 | 2058 | ||
2189 | if (TerrainGeom != IntPtr.Zero) | 2059 | if (m_terrainGeom != IntPtr.Zero) |
2190 | { | 2060 | { |
2191 | actor_name_map.Remove(TerrainGeom); | 2061 | actor_name_map.Remove(m_terrainGeom); |
2192 | SafeNativeMethods.GeomDestroy(TerrainGeom); | 2062 | SafeNativeMethods.GeomDestroy(m_terrainGeom); |
2193 | |||
2194 | } | 2063 | } |
2195 | 2064 | ||
2196 | if (TerrainHeightFieldHeightsHandler.IsAllocated) | 2065 | if (m_terrainHeightsHandler.IsAllocated) |
2197 | TerrainHeightFieldHeightsHandler.Free(); | 2066 | m_terrainHeightsHandler.Free(); |
2198 | 2067 | m_terrainHeights = null; | |
2199 | IntPtr HeightmapData = SafeNativeMethods.GeomHeightfieldDataCreate(); | ||
2200 | 2068 | ||
2201 | TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); | 2069 | int heightmapWidthSamples = m_regionWidth + 3; |
2070 | int heightmapHeightSamples = m_regionHeight + 3; | ||
2202 | 2071 | ||
2203 | SafeNativeMethods.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, | 2072 | m_terrainHeights = new float[heightmapWidthSamples * heightmapHeightSamples]; |
2204 | heightmapHeight, heightmapWidth , | 2073 | m_terrainHeightsHandler = GCHandle.Alloc(m_terrainHeights, GCHandleType.Pinned); |
2205 | (int)heightmapHeightSamples, (int)heightmapWidthSamples, scale, | ||
2206 | offset, thickness, wrap); | ||
2207 | 2074 | ||
2208 | SafeNativeMethods.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); | 2075 | m_lastRegionWidth = m_regionWidth; |
2209 | 2076 | ||
2210 | TerrainGeom = SafeNativeMethods.CreateHeightfield(GroundSpace, HeightmapData, 1); | 2077 | HeightmapData = SafeNativeMethods.GeomOSTerrainDataCreate(); |
2078 | SafeNativeMethods.GeomOSTerrainDataBuild(HeightmapData, m_terrainHeightsHandler.AddrOfPinnedObject(), 0, 1.0f, | ||
2079 | heightmapWidthSamples, heightmapHeightSamples, | ||
2080 | 1, 0); | ||
2211 | 2081 | ||
2212 | if (TerrainGeom != IntPtr.Zero) | 2082 | m_terrainGeom = SafeNativeMethods.CreateOSTerrain(GroundSpace, HeightmapData, 1); |
2083 | if (m_terrainGeom != IntPtr.Zero) | ||
2213 | { | 2084 | { |
2214 | SafeNativeMethods.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); | 2085 | SafeNativeMethods.GeomSetCategoryBits(m_terrainGeom, (uint)(CollisionCategories.Land)); |
2215 | SafeNativeMethods.GeomSetCollideBits(TerrainGeom, 0); | 2086 | SafeNativeMethods.GeomSetCollideBits(m_terrainGeom, 0); |
2216 | 2087 | ||
2217 | PhysicsActor pa = new NullPhysicsActor(); | 2088 | PhysicsActor pa = new NullPhysicsActor(); |
2218 | pa.Name = "Terrain"; | 2089 | pa.Name = "Terrain"; |
2219 | pa.PhysicsActorType = (int)ActorTypes.Ground; | 2090 | pa.PhysicsActorType = (int)ActorTypes.Ground; |
2220 | actor_name_map[TerrainGeom] = pa; | 2091 | actor_name_map[m_terrainGeom] = pa; |
2221 | 2092 | ||
2222 | // geom_name_map[GroundGeom] = "Terrain"; | 2093 | //geom_name_map[GroundGeom] = "Terrain"; |
2223 | 2094 | ||
2224 | SafeNativeMethods.Quaternion q = new SafeNativeMethods.Quaternion(); | 2095 | SafeNativeMethods.GeomSetPosition(m_terrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); |
2225 | q.X = 0.5f; | ||
2226 | q.Y = 0.5f; | ||
2227 | q.Z = 0.5f; | ||
2228 | q.W = 0.5f; | ||
2229 | |||
2230 | SafeNativeMethods.GeomSetQuaternion(TerrainGeom, ref q); | ||
2231 | SafeNativeMethods.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); | ||
2232 | TerrainHeightFieldHeight = _heightmap; | ||
2233 | } | 2096 | } |
2234 | else | 2097 | else |
2235 | TerrainHeightFieldHeightsHandler.Free(); | 2098 | m_terrainHeightsHandler.Free(); |
2236 | } | 2099 | } |
2237 | } | 2100 | } |
2238 | 2101 | ||
2239 | public void OSSetTerrain(float[] heightMap) | 2102 | public override void SetTerrain(float[] heightMap) |
2240 | { | 2103 | { |
2241 | // assumes 1m size grid and constante size square regions | 2104 | // assumes 1m size grid and constante size square regions |
2242 | // needs to know about sims around in future | 2105 | // needs to know about sims around in future |
2243 | 2106 | ||
2244 | float[] _heightmap; | 2107 | if(m_regionWidth != m_lastRegionWidth || |
2108 | m_regionHeight != m_lastRegionHeight || | ||
2109 | !m_terrainHeightsHandler.IsAllocated || | ||
2110 | m_terrainGeom == IntPtr.Zero) | ||
2111 | InitTerrain(); | ||
2245 | 2112 | ||
2246 | uint regionsizeX = m_regionWidth; | 2113 | int regionsizeX = m_regionWidth; |
2247 | uint regionsizeY = m_regionHeight; | 2114 | int regionsizeY = m_regionHeight; |
2248 | 2115 | ||
2249 | uint heightmapWidth = regionsizeX + 2; | 2116 | int heightmapWidth = regionsizeX + 2; |
2250 | uint heightmapHeight = regionsizeY + 2; | 2117 | int heightmapHeight = regionsizeY + 2; |
2251 | 2118 | ||
2252 | uint heightmapWidthSamples = heightmapWidth + 1; | 2119 | int heightmapWidthSamples = heightmapWidth + 1; |
2253 | uint heightmapHeightSamples = heightmapHeight + 1; | 2120 | int heightmapHeightSamples = heightmapHeight + 1; |
2254 | 2121 | ||
2255 | _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples]; | ||
2256 | |||
2257 | |||
2258 | float hfmin = float.MaxValue; | ||
2259 | // float hfmax = float.MinValue; | ||
2260 | float val; | 2122 | float val; |
2261 | 2123 | ||
2262 | 2124 | int maxXX = regionsizeX + 1; | |
2263 | uint maxXX = regionsizeX + 1; | 2125 | int maxYY = regionsizeY + 1; |
2264 | uint maxYY = regionsizeY + 1; | ||
2265 | // adding one margin all around so things don't fall in edges | 2126 | // adding one margin all around so things don't fall in edges |
2266 | 2127 | ||
2267 | uint xx; | 2128 | int xx; |
2268 | uint yy = 0; | 2129 | int yy = 0; |
2269 | uint yt = 0; | 2130 | int yt = 0; |
2131 | float minH = float.MaxValue; | ||
2132 | float maxH = float.MinValue; | ||
2270 | 2133 | ||
2271 | for (uint y = 0; y < heightmapHeightSamples; y++) | 2134 | for (int y = 0; y < heightmapHeightSamples; y++) |
2272 | { | 2135 | { |
2273 | if (y > 1 && y < maxYY) | 2136 | if (y > 1 && y < maxYY) |
2274 | yy += regionsizeX; | 2137 | yy += regionsizeX; |
2275 | xx = 0; | 2138 | xx = 0; |
2276 | for (uint x = 0; x < heightmapWidthSamples; x++) | 2139 | |
2140 | lock(OdeLock) | ||
2277 | { | 2141 | { |
2278 | if (x > 1 && x < maxXX) | 2142 | for (int x = 0; x < heightmapWidthSamples; x++) |
2279 | xx++; | 2143 | { |
2280 | 2144 | if (x > 1 && x < maxXX) | |
2281 | val = heightMap[yy + xx]; | 2145 | xx++; |
2282 | if (val < -100.0f) | 2146 | |
2283 | val = -100.0f; | 2147 | val = heightMap[yy + xx]; |
2284 | _heightmap[yt + x] = val; | 2148 | if (val < -100.0f) |
2285 | 2149 | val = -100.0f; | |
2286 | if (hfmin > val) | 2150 | if(val > maxH) |
2287 | hfmin = val; | 2151 | maxH = val; |
2288 | // if (hfmax < val) | 2152 | if(val < minH) |
2289 | // hfmax = val; | 2153 | minH = val; |
2154 | m_terrainHeights[yt + x] = val; | ||
2155 | } | ||
2290 | } | 2156 | } |
2291 | yt += heightmapWidthSamples; | 2157 | yt += heightmapWidthSamples; |
2292 | } | 2158 | } |
2293 | 2159 | ||
2294 | lock (OdeLock) | 2160 | lock (OdeLock) |
2295 | { | 2161 | { |
2296 | if (TerrainGeom != IntPtr.Zero) | 2162 | SafeNativeMethods.GeomOSTerrainDataSetBounds(HeightmapData, minH, maxH); |
2297 | { | 2163 | SafeNativeMethods.GeomSetPosition(m_terrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); |
2298 | actor_name_map.Remove(TerrainGeom); | ||
2299 | SafeNativeMethods.GeomDestroy(TerrainGeom); | ||
2300 | } | ||
2301 | |||
2302 | if (TerrainHeightFieldHeightsHandler.IsAllocated) | ||
2303 | TerrainHeightFieldHeightsHandler.Free(); | ||
2304 | |||
2305 | TerrainHeightFieldHeight = null; | ||
2306 | |||
2307 | IntPtr HeightmapData = SafeNativeMethods.GeomOSTerrainDataCreate(); | ||
2308 | |||
2309 | const int wrap = 0; | ||
2310 | float thickness = hfmin; | ||
2311 | if (thickness < 0) | ||
2312 | thickness = 1; | ||
2313 | |||
2314 | TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); | ||
2315 | |||
2316 | SafeNativeMethods.GeomOSTerrainDataBuild(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, 1.0f, | ||
2317 | (int)heightmapWidthSamples, (int)heightmapHeightSamples, | ||
2318 | thickness, wrap); | ||
2319 | |||
2320 | // d.GeomOSTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); | ||
2321 | TerrainGeom = SafeNativeMethods.CreateOSTerrain(GroundSpace, HeightmapData, 1); | ||
2322 | if (TerrainGeom != IntPtr.Zero) | ||
2323 | { | ||
2324 | SafeNativeMethods.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); | ||
2325 | SafeNativeMethods.GeomSetCollideBits(TerrainGeom, 0); | ||
2326 | |||
2327 | PhysicsActor pa = new NullPhysicsActor(); | ||
2328 | pa.Name = "Terrain"; | ||
2329 | pa.PhysicsActorType = (int)ActorTypes.Ground; | ||
2330 | actor_name_map[TerrainGeom] = pa; | ||
2331 | |||
2332 | // geom_name_map[GroundGeom] = "Terrain"; | ||
2333 | |||
2334 | SafeNativeMethods.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); | ||
2335 | TerrainHeightFieldHeight = _heightmap; | ||
2336 | } | ||
2337 | else | ||
2338 | TerrainHeightFieldHeightsHandler.Free(); | ||
2339 | } | 2164 | } |
2340 | } | 2165 | } |
2341 | 2166 | ||
@@ -2394,14 +2219,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2394 | foreach (OdeCharacter ch in chtorem) | 2219 | foreach (OdeCharacter ch in chtorem) |
2395 | ch.DoAChange(changes.Remove, null); | 2220 | ch.DoAChange(changes.Remove, null); |
2396 | 2221 | ||
2397 | if (TerrainGeom != IntPtr.Zero) | 2222 | if (m_terrainGeom != IntPtr.Zero) |
2398 | SafeNativeMethods.GeomDestroy(TerrainGeom); | 2223 | SafeNativeMethods.GeomDestroy(m_terrainGeom); |
2399 | TerrainGeom = IntPtr.Zero; | 2224 | m_terrainGeom = IntPtr.Zero; |
2400 | 2225 | ||
2401 | if (TerrainHeightFieldHeightsHandler.IsAllocated) | 2226 | if (m_terrainHeightsHandler.IsAllocated) |
2402 | TerrainHeightFieldHeightsHandler.Free(); | 2227 | m_terrainHeightsHandler.Free(); |
2403 | 2228 | ||
2404 | TerrainHeightFieldHeight = null; | 2229 | m_terrainHeights = null; |
2230 | m_lastRegionWidth = 0; | ||
2231 | m_lastRegionHeight = 0; | ||
2405 | 2232 | ||
2406 | if (ContactgeomsArray != IntPtr.Zero) | 2233 | if (ContactgeomsArray != IntPtr.Zero) |
2407 | { | 2234 | { |