diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs | 190 |
1 files changed, 66 insertions, 124 deletions
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs index e23e355..e6aa7ef 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs | |||
@@ -258,9 +258,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
258 | 258 | ||
259 | public ContactData[] m_materialContactsData = new ContactData[8]; | 259 | public ContactData[] m_materialContactsData = new ContactData[8]; |
260 | 260 | ||
261 | private Dictionary<Vector3, IntPtr> RegionTerrain = new Dictionary<Vector3, IntPtr>(); | 261 | private IntPtr TerrainGeom; |
262 | private Dictionary<IntPtr, float[]> TerrainHeightFieldHeights = new Dictionary<IntPtr, float[]>(); | 262 | private float[] TerrainHeightFieldHeight; |
263 | private Dictionary<IntPtr, GCHandle> TerrainHeightFieldHeightsHandlers = new Dictionary<IntPtr, GCHandle>(); | 263 | private GCHandle TerrainHeightFieldHeightsHandler = new GCHandle(); |
264 | 264 | ||
265 | private int m_physicsiterations = 15; | 265 | private int m_physicsiterations = 15; |
266 | 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 |
@@ -302,9 +302,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
302 | public int physics_logging_interval = 0; | 302 | public int physics_logging_interval = 0; |
303 | public bool physics_logging_append_existing_logfile = false; | 303 | public bool physics_logging_append_existing_logfile = false; |
304 | 304 | ||
305 | private Vector3 m_worldOffset = Vector3.Zero; | ||
306 | public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); | 305 | public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); |
307 | private PhysicsScene m_parentScene = null; | ||
308 | 306 | ||
309 | private ODERayCastRequestManager m_rayCastManager; | 307 | private ODERayCastRequestManager m_rayCastManager; |
310 | public ODEMeshWorker m_meshWorker; | 308 | public ODEMeshWorker m_meshWorker; |
@@ -1931,24 +1929,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1931 | 1929 | ||
1932 | public float GetTerrainHeightAtXY(float x, float y) | 1930 | public float GetTerrainHeightAtXY(float x, float y) |
1933 | { | 1931 | { |
1934 | 1932 | if (TerrainGeom == IntPtr.Zero) | |
1935 | int offsetX = 0; | ||
1936 | int offsetY = 0; | ||
1937 | |||
1938 | // get region map | ||
1939 | IntPtr heightFieldGeom = IntPtr.Zero; | ||
1940 | if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom)) | ||
1941 | return 0f; | ||
1942 | |||
1943 | if (heightFieldGeom == IntPtr.Zero) | ||
1944 | return 0f; | 1933 | return 0f; |
1945 | 1934 | ||
1946 | if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom)) | 1935 | if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0) |
1947 | return 0f; | 1936 | return 0f; |
1948 | 1937 | ||
1949 | // TerrainHeightField for ODE as offset 1m | 1938 | // TerrainHeightField for ODE as offset 1m |
1950 | x += 1f - offsetX; | 1939 | x += 1f; |
1951 | y += 1f - offsetY; | 1940 | y += 1f; |
1952 | 1941 | ||
1953 | // make position fit into array | 1942 | // make position fit into array |
1954 | if (x < 0) | 1943 | if (x < 0) |
@@ -2027,7 +2016,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2027 | iy *= regsize; | 2016 | iy *= regsize; |
2028 | iy += ix; // all indexes have iy + ix | 2017 | iy += ix; // all indexes have iy + ix |
2029 | 2018 | ||
2030 | float[] heights = TerrainHeightFieldHeights[heightFieldGeom]; | 2019 | float[] heights = TerrainHeightFieldHeight; |
2031 | /* | 2020 | /* |
2032 | if ((dx + dy) <= 1.0f) | 2021 | if ((dx + dy) <= 1.0f) |
2033 | { | 2022 | { |
@@ -2064,25 +2053,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2064 | 2053 | ||
2065 | public Vector3 GetTerrainNormalAtXY(float x, float y) | 2054 | public Vector3 GetTerrainNormalAtXY(float x, float y) |
2066 | { | 2055 | { |
2067 | int offsetX = 0; | ||
2068 | int offsetY = 0; | ||
2069 | |||
2070 | // get region map | ||
2071 | IntPtr heightFieldGeom = IntPtr.Zero; | ||
2072 | Vector3 norm = new Vector3(0, 0, 1); | 2056 | Vector3 norm = new Vector3(0, 0, 1); |
2073 | 2057 | ||
2074 | if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom)) | 2058 | if (TerrainGeom == IntPtr.Zero) |
2075 | return norm; ; | ||
2076 | |||
2077 | if (heightFieldGeom == IntPtr.Zero) | ||
2078 | return norm; | 2059 | return norm; |
2079 | 2060 | ||
2080 | if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom)) | 2061 | if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0) |
2081 | return norm; | 2062 | return norm; |
2082 | 2063 | ||
2083 | // TerrainHeightField for ODE as offset 1m | 2064 | // TerrainHeightField for ODE as offset 1m |
2084 | x += 1f - offsetX; | 2065 | x += 1f; |
2085 | y += 1f - offsetY; | 2066 | y += 1f; |
2086 | 2067 | ||
2087 | // make position fit into array | 2068 | // make position fit into array |
2088 | if (x < 0) | 2069 | if (x < 0) |
@@ -2169,7 +2150,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2169 | iy *= regsize; | 2150 | iy *= regsize; |
2170 | iy += ix; // all indexes have iy + ix | 2151 | iy += ix; // all indexes have iy + ix |
2171 | 2152 | ||
2172 | float[] heights = TerrainHeightFieldHeights[heightFieldGeom]; | 2153 | float[] heights = TerrainHeightFieldHeight; |
2173 | 2154 | ||
2174 | if (firstTri) | 2155 | if (firstTri) |
2175 | { | 2156 | { |
@@ -2196,28 +2177,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2196 | 2177 | ||
2197 | public override void SetTerrain(float[] heightMap) | 2178 | public override void SetTerrain(float[] heightMap) |
2198 | { | 2179 | { |
2199 | if (m_worldOffset != Vector3.Zero && m_parentScene != null) | ||
2200 | { | ||
2201 | if (m_parentScene is ODEScene) | ||
2202 | { | ||
2203 | ((ODEScene)m_parentScene).SetTerrain(heightMap, m_worldOffset); | ||
2204 | } | ||
2205 | } | ||
2206 | else | ||
2207 | { | ||
2208 | SetTerrain(heightMap, m_worldOffset); | ||
2209 | } | ||
2210 | } | ||
2211 | |||
2212 | public void SetTerrain(float[] heightMap, Vector3 pOffset) | ||
2213 | { | ||
2214 | if (m_OSOdeLib) | 2180 | if (m_OSOdeLib) |
2215 | OSSetTerrain(heightMap, pOffset); | 2181 | OSSetTerrain(heightMap); |
2216 | else | 2182 | else |
2217 | OriSetTerrain(heightMap, pOffset); | 2183 | OriSetTerrain(heightMap); |
2218 | } | 2184 | } |
2219 | 2185 | ||
2220 | public void OriSetTerrain(float[] heightMap, Vector3 pOffset) | 2186 | public void OriSetTerrain(float[] heightMap) |
2221 | { | 2187 | { |
2222 | // assumes 1m size grid and constante size square regions | 2188 | // assumes 1m size grid and constante size square regions |
2223 | // needs to know about sims around in future | 2189 | // needs to know about sims around in future |
@@ -2282,45 +2248,40 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2282 | { | 2248 | { |
2283 | d.AllocateODEDataForThread(~0U); | 2249 | d.AllocateODEDataForThread(~0U); |
2284 | 2250 | ||
2285 | IntPtr GroundGeom = IntPtr.Zero; | 2251 | if (TerrainGeom != IntPtr.Zero) |
2286 | if (RegionTerrain.TryGetValue(pOffset, out GroundGeom)) | ||
2287 | { | 2252 | { |
2288 | RegionTerrain.Remove(pOffset); | 2253 | actor_name_map.Remove(TerrainGeom); |
2289 | if (GroundGeom != IntPtr.Zero) | 2254 | d.GeomDestroy(TerrainGeom); |
2290 | { | ||
2291 | actor_name_map.Remove(GroundGeom); | ||
2292 | d.GeomDestroy(GroundGeom); | ||
2293 | 2255 | ||
2294 | if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) | ||
2295 | { | ||
2296 | TerrainHeightFieldHeightsHandlers[GroundGeom].Free(); | ||
2297 | TerrainHeightFieldHeightsHandlers.Remove(GroundGeom); | ||
2298 | TerrainHeightFieldHeights.Remove(GroundGeom); | ||
2299 | } | ||
2300 | } | ||
2301 | } | 2256 | } |
2257 | |||
2258 | if (TerrainHeightFieldHeightsHandler.IsAllocated) | ||
2259 | TerrainHeightFieldHeightsHandler.Free(); | ||
2260 | |||
2302 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); | 2261 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); |
2303 | 2262 | ||
2304 | GCHandle _heightmaphandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); | 2263 | GC.Collect(1); |
2305 | 2264 | ||
2306 | d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmaphandler.AddrOfPinnedObject(), 0, | 2265 | TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); |
2266 | |||
2267 | d.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, | ||
2307 | heightmapHeight, heightmapWidth , | 2268 | heightmapHeight, heightmapWidth , |
2308 | (int)heightmapHeightSamples, (int)heightmapWidthSamples, scale, | 2269 | (int)heightmapHeightSamples, (int)heightmapWidthSamples, scale, |
2309 | offset, thickness, wrap); | 2270 | offset, thickness, wrap); |
2310 | 2271 | ||
2311 | d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); | 2272 | d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); |
2312 | 2273 | ||
2313 | GroundGeom = d.CreateHeightfield(GroundSpace, HeightmapData, 1); | 2274 | TerrainGeom = d.CreateHeightfield(GroundSpace, HeightmapData, 1); |
2314 | 2275 | ||
2315 | if (GroundGeom != IntPtr.Zero) | 2276 | if (TerrainGeom != IntPtr.Zero) |
2316 | { | 2277 | { |
2317 | d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land)); | 2278 | d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); |
2318 | d.GeomSetCollideBits(GroundGeom, 0); | 2279 | d.GeomSetCollideBits(TerrainGeom, 0); |
2319 | 2280 | ||
2320 | PhysicsActor pa = new NullPhysicsActor(); | 2281 | PhysicsActor pa = new NullPhysicsActor(); |
2321 | pa.Name = "Terrain"; | 2282 | pa.Name = "Terrain"; |
2322 | pa.PhysicsActorType = (int)ActorTypes.Ground; | 2283 | pa.PhysicsActorType = (int)ActorTypes.Ground; |
2323 | actor_name_map[GroundGeom] = pa; | 2284 | actor_name_map[TerrainGeom] = pa; |
2324 | 2285 | ||
2325 | // geom_name_map[GroundGeom] = "Terrain"; | 2286 | // geom_name_map[GroundGeom] = "Terrain"; |
2326 | 2287 | ||
@@ -2330,16 +2291,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2330 | q.Z = 0.5f; | 2291 | q.Z = 0.5f; |
2331 | q.W = 0.5f; | 2292 | q.W = 0.5f; |
2332 | 2293 | ||
2333 | d.GeomSetQuaternion(GroundGeom, ref q); | 2294 | d.GeomSetQuaternion(TerrainGeom, ref q); |
2334 | d.GeomSetPosition(GroundGeom, pOffset.X + m_regionWidth * 0.5f, pOffset.Y + m_regionHeight * 0.5f, 0.0f); | 2295 | d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); |
2335 | RegionTerrain.Add(pOffset, GroundGeom); | 2296 | TerrainHeightFieldHeight = _heightmap; |
2336 | TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); | ||
2337 | TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler); | ||
2338 | } | 2297 | } |
2298 | else | ||
2299 | TerrainHeightFieldHeightsHandler.Free(); | ||
2339 | } | 2300 | } |
2340 | } | 2301 | } |
2341 | 2302 | ||
2342 | public void OSSetTerrain(float[] heightMap, Vector3 pOffset) | 2303 | public void OSSetTerrain(float[] heightMap) |
2343 | { | 2304 | { |
2344 | // assumes 1m size grid and constante size square regions | 2305 | // assumes 1m size grid and constante size square regions |
2345 | // needs to know about sims around in future | 2306 | // needs to know about sims around in future |
@@ -2393,26 +2354,20 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2393 | } | 2354 | } |
2394 | yt += heightmapWidthSamples; | 2355 | yt += heightmapWidthSamples; |
2395 | } | 2356 | } |
2357 | |||
2396 | lock (OdeLock) | 2358 | lock (OdeLock) |
2397 | { | 2359 | { |
2398 | IntPtr GroundGeom = IntPtr.Zero; | 2360 | if (TerrainGeom != IntPtr.Zero) |
2399 | if (RegionTerrain.TryGetValue(pOffset, out GroundGeom)) | ||
2400 | { | 2361 | { |
2401 | RegionTerrain.Remove(pOffset); | 2362 | actor_name_map.Remove(TerrainGeom); |
2402 | if (GroundGeom != IntPtr.Zero) | 2363 | d.GeomDestroy(TerrainGeom); |
2403 | { | ||
2404 | actor_name_map.Remove(GroundGeom); | ||
2405 | d.GeomDestroy(GroundGeom); | ||
2406 | |||
2407 | if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) | ||
2408 | { | ||
2409 | if (TerrainHeightFieldHeightsHandlers[GroundGeom].IsAllocated) | ||
2410 | TerrainHeightFieldHeightsHandlers[GroundGeom].Free(); | ||
2411 | TerrainHeightFieldHeightsHandlers.Remove(GroundGeom); | ||
2412 | TerrainHeightFieldHeights.Remove(GroundGeom); | ||
2413 | } | ||
2414 | } | ||
2415 | } | 2364 | } |
2365 | |||
2366 | if (TerrainHeightFieldHeightsHandler.IsAllocated) | ||
2367 | TerrainHeightFieldHeightsHandler.Free(); | ||
2368 | |||
2369 | TerrainHeightFieldHeight = null; | ||
2370 | |||
2416 | IntPtr HeightmapData = d.GeomOSTerrainDataCreate(); | 2371 | IntPtr HeightmapData = d.GeomOSTerrainDataCreate(); |
2417 | 2372 | ||
2418 | const int wrap = 0; | 2373 | const int wrap = 0; |
@@ -2420,32 +2375,31 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2420 | if (thickness < 0) | 2375 | if (thickness < 0) |
2421 | thickness = 1; | 2376 | thickness = 1; |
2422 | 2377 | ||
2423 | GCHandle _heightmaphandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); | 2378 | TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); |
2424 | 2379 | ||
2425 | d.GeomOSTerrainDataBuild(HeightmapData, _heightmaphandler.AddrOfPinnedObject(), 0, 1.0f, | 2380 | d.GeomOSTerrainDataBuild(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, 1.0f, |
2426 | (int)heightmapWidthSamples, (int)heightmapHeightSamples, | 2381 | (int)heightmapWidthSamples, (int)heightmapHeightSamples, |
2427 | thickness, wrap); | 2382 | thickness, wrap); |
2428 | 2383 | ||
2429 | // d.GeomOSTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); | 2384 | // d.GeomOSTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); |
2430 | GroundGeom = d.CreateOSTerrain(GroundSpace, HeightmapData, 1); | 2385 | TerrainGeom = d.CreateOSTerrain(GroundSpace, HeightmapData, 1); |
2431 | if (GroundGeom != IntPtr.Zero) | 2386 | if (TerrainGeom != IntPtr.Zero) |
2432 | { | 2387 | { |
2433 | d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land)); | 2388 | d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); |
2434 | d.GeomSetCollideBits(GroundGeom, 0); | 2389 | d.GeomSetCollideBits(TerrainGeom, 0); |
2435 | |||
2436 | 2390 | ||
2437 | PhysicsActor pa = new NullPhysicsActor(); | 2391 | PhysicsActor pa = new NullPhysicsActor(); |
2438 | pa.Name = "Terrain"; | 2392 | pa.Name = "Terrain"; |
2439 | pa.PhysicsActorType = (int)ActorTypes.Ground; | 2393 | pa.PhysicsActorType = (int)ActorTypes.Ground; |
2440 | actor_name_map[GroundGeom] = pa; | 2394 | actor_name_map[TerrainGeom] = pa; |
2441 | 2395 | ||
2442 | // geom_name_map[GroundGeom] = "Terrain"; | 2396 | // geom_name_map[GroundGeom] = "Terrain"; |
2443 | 2397 | ||
2444 | d.GeomSetPosition(GroundGeom, pOffset.X + m_regionWidth * 0.5f, pOffset.Y + m_regionHeight * 0.5f, 0.0f); | 2398 | d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); |
2445 | RegionTerrain.Add(pOffset, GroundGeom); | 2399 | TerrainHeightFieldHeight = _heightmap; |
2446 | TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); | 2400 | } |
2447 | TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler); | 2401 | else |
2448 | } | 2402 | TerrainHeightFieldHeightsHandler.Free(); |
2449 | } | 2403 | } |
2450 | } | 2404 | } |
2451 | 2405 | ||
@@ -2504,26 +2458,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
2504 | foreach (OdeCharacter ch in chtorem) | 2458 | foreach (OdeCharacter ch in chtorem) |
2505 | ch.DoAChange(changes.Remove, null); | 2459 | ch.DoAChange(changes.Remove, null); |
2506 | 2460 | ||
2461 | if (TerrainGeom != IntPtr.Zero) | ||
2462 | d.GeomDestroy(TerrainGeom); | ||
2463 | TerrainGeom = IntPtr.Zero; | ||
2507 | 2464 | ||
2508 | foreach (IntPtr GroundGeom in RegionTerrain.Values) | 2465 | if (TerrainHeightFieldHeightsHandler.IsAllocated) |
2509 | { | 2466 | TerrainHeightFieldHeightsHandler.Free(); |
2510 | if (GroundGeom != IntPtr.Zero) | ||
2511 | d.GeomDestroy(GroundGeom); | ||
2512 | } | ||
2513 | |||
2514 | RegionTerrain.Clear(); | ||
2515 | |||
2516 | if (TerrainHeightFieldHeightsHandlers.Count > 0) | ||
2517 | { | ||
2518 | foreach (GCHandle gch in TerrainHeightFieldHeightsHandlers.Values) | ||
2519 | { | ||
2520 | if (gch.IsAllocated) | ||
2521 | gch.Free(); | ||
2522 | } | ||
2523 | } | ||
2524 | 2467 | ||
2525 | TerrainHeightFieldHeightsHandlers.Clear(); | 2468 | TerrainHeightFieldHeight = null; |
2526 | TerrainHeightFieldHeights.Clear(); | ||
2527 | 2469 | ||
2528 | if (ContactgeomsArray != IntPtr.Zero) | 2470 | if (ContactgeomsArray != IntPtr.Zero) |
2529 | { | 2471 | { |