aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules/ubOde
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/PhysicsModules/ubOde')
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs9
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs12
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs417
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 {