aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs163
-rw-r--r--OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs28
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs110
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs321
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs1
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs514
6 files changed, 496 insertions, 641 deletions
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
index 80c1277..0a4ebe4 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
@@ -704,6 +704,8 @@ namespace OpenSim.Region.Physics.OdePlugin
704 if (m_isphysical) 704 if (m_isphysical)
705 m_targetSpace = _parent_scene.space; 705 m_targetSpace = _parent_scene.space;
706 706
707 _triMeshData = IntPtr.Zero;
708
707 m_primName = primName; 709 m_primName = primName;
708 m_taintserial = null; 710 m_taintserial = null;
709 m_taintadd = true; 711 m_taintadd = true;
@@ -773,6 +775,8 @@ namespace OpenSim.Region.Physics.OdePlugin
773 m_targetSpace = _parent_scene.space; 775 m_targetSpace = _parent_scene.space;
774 } 776 }
775 777
778 _triMeshData = IntPtr.Zero;
779
776 m_taintserial = null; 780 m_taintserial = null;
777 m_primName = primName; 781 m_primName = primName;
778 m_taintadd = true; 782 m_taintadd = true;
@@ -1762,7 +1766,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1762 1766
1763 private static Dictionary<IMesh, IntPtr> m_MeshToTriMeshMap = new Dictionary<IMesh, IntPtr>(); 1767 private static Dictionary<IMesh, IntPtr> m_MeshToTriMeshMap = new Dictionary<IMesh, IntPtr>();
1764 1768
1765 public void setMesh(OdeScene parent_scene, IMesh mesh) 1769 public bool setMesh(OdeScene parent_scene, IMesh mesh)
1766 { 1770 {
1767 // This sleeper is there to moderate how long it takes between 1771 // This sleeper is there to moderate how long it takes between
1768 // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object 1772 // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
@@ -1785,24 +1789,48 @@ namespace OpenSim.Region.Physics.OdePlugin
1785 disableBody(); 1789 disableBody();
1786 } 1790 }
1787 } 1791 }
1792
1793// do it on caller instead
1794/*
1795 if (_triMeshData != IntPtr.Zero)
1796 {
1797 d.GeomTriMeshDataDestroy(_triMeshData);
1798 _triMeshData = IntPtr.Zero;
1799 }
1800*/
1788 IntPtr vertices, indices; 1801 IntPtr vertices, indices;
1789 int vertexCount, indexCount; 1802 int vertexCount, indexCount;
1790 int vertexStride, triStride; 1803 int vertexStride, triStride;
1791 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap 1804 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
1792 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage 1805 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
1793 1806
1807 // warning this destroys the mesh for eventual future use. Only pinned float arrays stay valid
1794 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory 1808 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
1809
1810 if (vertexCount == 0 || indexCount == 0)
1811 {
1812 m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. It can be a sculp with alpha channel in map. Replacing it by a small box.", Name, _position.X, _position.Y, _position.Z);
1813 _size.X = 0.05f;
1814 _size.Y = 0.05f;
1815 _size.Z = 0.05f;
1816 return false;
1817 }
1818
1819/*
1795 if (m_MeshToTriMeshMap.ContainsKey(mesh)) 1820 if (m_MeshToTriMeshMap.ContainsKey(mesh))
1796 { 1821 {
1797 _triMeshData = m_MeshToTriMeshMap[mesh]; 1822 _triMeshData = m_MeshToTriMeshMap[mesh];
1798 } 1823 }
1799 else 1824 else
1825*/
1826
1827
1800 { 1828 {
1801 _triMeshData = d.GeomTriMeshDataCreate(); 1829 _triMeshData = d.GeomTriMeshDataCreate();
1802 1830
1803 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 1831 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
1804 d.GeomTriMeshDataPreprocess(_triMeshData); 1832 d.GeomTriMeshDataPreprocess(_triMeshData);
1805 m_MeshToTriMeshMap[mesh] = _triMeshData; 1833// m_MeshToTriMeshMap[mesh] = _triMeshData;
1806 } 1834 }
1807 1835
1808 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1836 _parent_scene.waitForSpaceUnlock(m_targetSpace);
@@ -1810,13 +1838,23 @@ namespace OpenSim.Region.Physics.OdePlugin
1810 { 1838 {
1811 // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer 1839 // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer
1812 // { 1840 // {
1813 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); 1841 // SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
1842 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null));
1814 // } 1843 // }
1815 } 1844 }
1816 catch (AccessViolationException) 1845 catch (Exception e)
1817 { 1846 {
1818 m_log.Error("[PHYSICS]: MESH LOCKED"); 1847 m_log.ErrorFormat("[PHYSICS]: Create trimesh failed on prim {0} : {1}",Name,e.Message);
1819 return; 1848
1849 if (_triMeshData != IntPtr.Zero)
1850 {
1851 d.GeomTriMeshDataDestroy(_triMeshData);
1852 _triMeshData = IntPtr.Zero;
1853 }
1854 _size.X = 0.05f;
1855 _size.Y = 0.05f;
1856 _size.Z = 0.05f;
1857 return false;
1820 } 1858 }
1821 1859
1822 1860
@@ -1828,6 +1866,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1828 1866
1829 // enableBody(); 1867 // enableBody();
1830 // } 1868 // }
1869 return true;
1831 } 1870 }
1832 1871
1833 public void ProcessTaints(float timestep) //============================================================================= 1872 public void ProcessTaints(float timestep) //=============================================================================
@@ -1837,6 +1876,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1837 changeadd(timestep); 1876 changeadd(timestep);
1838 } 1877 }
1839 1878
1879 if (m_taintremove)
1880 return;
1881
1840 if (prim_geom != IntPtr.Zero) 1882 if (prim_geom != IntPtr.Zero)
1841 { 1883 {
1842 if (!_position.ApproxEquals(m_taintposition, 0f)) 1884 if (!_position.ApproxEquals(m_taintposition, 0f))
@@ -2286,75 +2328,62 @@ namespace OpenSim.Region.Physics.OdePlugin
2286 2328
2287 public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) 2329 public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh)
2288 { 2330 {
2331 bool gottrimesh = false;
2332
2333 if (_triMeshData != IntPtr.Zero)
2334 {
2335 d.GeomTriMeshDataDestroy(_triMeshData);
2336 _triMeshData = IntPtr.Zero;
2337 }
2338
2289 if (_mesh != null) // Special - make mesh 2339 if (_mesh != null) // Special - make mesh
2290 { 2340 {
2291 setMesh(_parent_scene, _mesh); 2341 gottrimesh = setMesh(_parent_scene, _mesh);
2292 } 2342 }
2293 else // not a mesh 2343
2344 if (!gottrimesh) // not a mesh
2294 { 2345 {
2295 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) // special profile?? 2346 IntPtr geo = IntPtr.Zero;
2347
2348 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
2349 && _size.X == _size.Y && _size.X == _size.Z)
2296 { 2350 {
2297 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) // Equi-size 2351 // its a sphere
2352 _parent_scene.waitForSpaceUnlock(m_targetSpace);
2353 try
2298 { 2354 {
2299 if (((_size.X / 2f) > 0f)) // Has size 2355 geo = d.CreateSphere(m_targetSpace, _size.X * 0.5f);
2300 {
2301 _parent_scene.waitForSpaceUnlock(m_targetSpace);
2302 try
2303 {
2304 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
2305 }
2306 catch (AccessViolationException)
2307 {
2308 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
2309 ode.dunlock(_parent_scene.world);
2310 return;
2311 }
2312 }
2313 else
2314 {
2315 _parent_scene.waitForSpaceUnlock(m_targetSpace);
2316 try
2317 {
2318 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
2319 }
2320 catch (AccessViolationException)
2321 {
2322 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
2323 ode.dunlock(_parent_scene.world);
2324 return;
2325 }
2326 }
2327 } 2356 }
2328 else // not equi-size 2357 catch (Exception e)
2329 { 2358 {
2330 _parent_scene.waitForSpaceUnlock(m_targetSpace); 2359 m_log.WarnFormat("[PHYSICS]: Unable to create basic sphere for object {0}", e.Message);
2331 try 2360 geo = IntPtr.Zero;
2332 { 2361 ode.dunlock(_parent_scene.world);
2333 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
2334 }
2335 catch (AccessViolationException)
2336 {
2337 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
2338 ode.dunlock(_parent_scene.world);
2339 return;
2340 }
2341 } 2362 }
2342 } 2363 }
2343 2364 else // make it a box
2344 else // not special profile
2345 { 2365 {
2346 _parent_scene.waitForSpaceUnlock(m_targetSpace); 2366 _parent_scene.waitForSpaceUnlock(m_targetSpace);
2347 try 2367 try
2348 { 2368 {
2349 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 2369 geo = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
2350 } 2370 }
2351 catch (AccessViolationException) 2371 catch (Exception e)
2352 { 2372 {
2353 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object"); 2373 m_log.WarnFormat("[PHYSICS]: Unable to create basic sphere for object {0}", e.Message);
2374 geo = IntPtr.Zero;
2354 ode.dunlock(_parent_scene.world); 2375 ode.dunlock(_parent_scene.world);
2355 return;
2356 } 2376 }
2357 } 2377 }
2378
2379 if (geo == IntPtr.Zero)
2380 {
2381 m_taintremove = true;
2382 _parent_scene.AddPhysicsActorTaint(this);
2383 return;
2384 }
2385
2386 SetGeom(geo);
2358 } 2387 }
2359 } 2388 }
2360 2389
@@ -2372,18 +2401,17 @@ namespace OpenSim.Region.Physics.OdePlugin
2372 { 2401 {
2373 if (_parent_scene.needsMeshing(_pbs)) 2402 if (_parent_scene.needsMeshing(_pbs))
2374 { 2403 {
2375 // Don't need to re-enable body.. it's done in SetMesh
2376 try 2404 try
2377 { 2405 {
2378 _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); 2406 _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, (int)LevelOfDetail.High, true);
2379 } 2407 }
2380 catch 2408 catch
2381 { 2409 {
2382 //Don't continuously try to mesh prims when meshing has failed 2410 //Don't continuously try to mesh prims when meshing has failed
2383 m_meshfailed = true; 2411 m_meshfailed = true;
2412 _mesh = null;
2413 m_log.WarnFormat("[PHYSICS]: changeAdd CreateMesh fail on prim {0} at <{1},{2},{3}>", Name, _position.X, _position.Y, _position.Z);
2384 } 2414 }
2385 // createmesh returns null when it's a shape that isn't a cube.
2386 // m_log.Debug(m_localID);
2387 } 2415 }
2388 } 2416 }
2389 2417
@@ -2630,17 +2658,17 @@ namespace OpenSim.Region.Physics.OdePlugin
2630 try 2658 try
2631 { 2659 {
2632 if (_parent_scene.needsMeshing(_pbs)) 2660 if (_parent_scene.needsMeshing(_pbs))
2633 mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 2661 mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, (int)LevelOfDetail.High, true);
2634 } 2662 }
2635 catch 2663 catch
2636 { 2664 {
2637 m_meshfailed = true; 2665 m_meshfailed = true;
2666 mesh = null;
2667 m_log.WarnFormat("[PHYSICS]: changeSize CreateMesh fail on prim {0} at <{1},{2},{3}>", Name, _position.X, _position.Y, _position.Z);
2638 } 2668 }
2639 2669
2640 //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 2670 //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical);
2641 CreateGeom(m_targetSpace, mesh); 2671 CreateGeom(m_targetSpace, mesh);
2642
2643
2644 } 2672 }
2645 else 2673 else
2646 { 2674 {
@@ -2732,18 +2760,23 @@ namespace OpenSim.Region.Physics.OdePlugin
2732 { 2760 {
2733 // Don't need to re-enable body.. it's done in SetMesh 2761 // Don't need to re-enable body.. it's done in SetMesh
2734 float meshlod = _parent_scene.meshSculptLOD; 2762 float meshlod = _parent_scene.meshSculptLOD;
2763 IMesh mesh;
2735 2764
2736 if (IsPhysical) 2765 if (IsPhysical)
2737 meshlod = _parent_scene.MeshSculptphysicalLOD; 2766 meshlod = _parent_scene.MeshSculptphysicalLOD;
2738 try 2767 try
2739 { 2768 {
2740 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 2769 mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, (int)LevelOfDetail.High, true);
2741 CreateGeom(m_targetSpace, mesh);
2742 } 2770 }
2743 catch 2771 catch
2744 { 2772 {
2773 mesh = null;
2745 m_meshfailed = true; 2774 m_meshfailed = true;
2775 m_log.WarnFormat("[PHYSICS]: changeAdd CreateMesh fail on prim {0} at <{1},{2},{3}>", Name, _position.X, _position.Y, _position.Z);
2746 } 2776 }
2777
2778 CreateGeom(m_targetSpace, mesh);
2779
2747 // createmesh returns null when it doesn't mesh. 2780 // createmesh returns null when it doesn't mesh.
2748 } 2781 }
2749 else 2782 else
diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
index 61fb2d0..7a1e671 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
@@ -1772,7 +1772,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1772 IMesh mesh = null; 1772 IMesh mesh = null;
1773 1773
1774 if (needsMeshing(pbs)) 1774 if (needsMeshing(pbs))
1775 mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); 1775 mesh = mesher.CreateMesh(primName, pbs, size, (int)LevelOfDetail.High, true);
1776 1776
1777 result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, localid); 1777 result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, localid);
1778 1778
@@ -2174,6 +2174,16 @@ namespace OpenSim.Region.Physics.OdePlugin
2174 { 2174 {
2175 prim.ResetTaints(); 2175 prim.ResetTaints();
2176 2176
2177 try
2178 {
2179 if (prim._triMeshData != IntPtr.Zero)
2180 {
2181 d.GeomTriMeshDataDestroy(prim._triMeshData);
2182 prim._triMeshData = IntPtr.Zero;
2183 }
2184 }
2185 catch { };
2186
2177 if (prim.IsPhysical) 2187 if (prim.IsPhysical)
2178 { 2188 {
2179 prim.disableBody(); 2189 prim.disableBody();
@@ -2185,7 +2195,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2185 prim.IsPhysical = false; 2195 prim.IsPhysical = false;
2186 } 2196 }
2187 2197
2188
2189 } 2198 }
2190 // we don't want to remove the main space 2199 // we don't want to remove the main space
2191 2200
@@ -2505,7 +2514,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2505 } 2514 }
2506 2515
2507 // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim 2516 // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim
2508 if (!forceSimplePrimMeshing) 2517 if (!forceSimplePrimMeshing && !pbs.SculptEntry)
2509 { 2518 {
2510 if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) 2519 if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
2511 || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 2520 || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
@@ -2528,6 +2537,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2528 } 2537 }
2529 } 2538 }
2530 2539
2540 if (forceSimplePrimMeshing)
2541 return true;
2542
2531 if (pbs.ProfileHollow != 0) 2543 if (pbs.ProfileHollow != 0)
2532 iPropertiesNotSupportedDefault++; 2544 iPropertiesNotSupportedDefault++;
2533 2545
@@ -2592,6 +2604,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2592 } 2604 }
2593 } 2605 }
2594 2606
2607 if (pbs.SculptEntry && meshSculptedPrim)
2608 iPropertiesNotSupportedDefault++;
2595 2609
2596 if (iPropertiesNotSupportedDefault == 0) 2610 if (iPropertiesNotSupportedDefault == 0)
2597 { 2611 {
@@ -3443,8 +3457,8 @@ namespace OpenSim.Region.Physics.OdePlugin
3443 int heightmapWidth = regionsize + 2; // ODE map size 257 x 257 (Meters) (1 extra 3457 int heightmapWidth = regionsize + 2; // ODE map size 257 x 257 (Meters) (1 extra
3444 int heightmapHeight = regionsize + 2; 3458 int heightmapHeight = regionsize + 2;
3445 3459
3446 int heightmapWidthSamples = (int)regionsize + 3; // Sample file size, 258 x 258 samples 3460 int heightmapWidthSamples = (int)regionsize + 2; // Sample file size, 258 x 258 samples
3447 int heightmapHeightSamples = (int)regionsize + 3; 3461 int heightmapHeightSamples = (int)regionsize + 2;
3448 3462
3449 // Array of height samples for ODE 3463 // Array of height samples for ODE
3450 float[] _heightmap; 3464 float[] _heightmap;
@@ -3481,7 +3495,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3481 // Output x = 0 1 2 3 ..... 255 256 257 258 total out 3495 // Output x = 0 1 2 3 ..... 255 256 257 258 total out
3482 float val= heightMap[(yy * regionsize) + xx]; // input from heightMap, <0-255 * 256> <0-255> 3496 float val= heightMap[(yy * regionsize) + xx]; // input from heightMap, <0-255 * 256> <0-255>
3483 if (val < minele) val = minele; 3497 if (val < minele) val = minele;
3484 _heightmap[x * (heightmapHeightSamples) + y] = val; // samples output to _heightmap, <0-257 * 258> <0-257> 3498 _heightmap[x * (regionsize + 2) + y] = val; // samples output to _heightmap, <0-257 * 258> <0-257>
3485 hfmin = (val < hfmin) ? val : hfmin; 3499 hfmin = (val < hfmin) ? val : hfmin;
3486 hfmax = (val > hfmax) ? val : hfmax; 3500 hfmax = (val > hfmax) ? val : hfmax;
3487 } 3501 }
@@ -3531,8 +3545,6 @@ namespace OpenSim.Region.Physics.OdePlugin
3531 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); 3545 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
3532 d.GeomSetRotation(GroundGeom, ref R); 3546 d.GeomSetRotation(GroundGeom, ref R);
3533 d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)) - 0.5f, (pOffset.Y + (regionsize * 0.5f)) - 0.5f, 0); 3547 d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)) - 0.5f, (pOffset.Y + (regionsize * 0.5f)) - 0.5f, 0);
3534 // having nsamples = size + 1 center is actually at size/2
3535 d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)), (pOffset.Y + (regionsize * 0.5f)), 0);
3536 IntPtr testGround = IntPtr.Zero; 3548 IntPtr testGround = IntPtr.Zero;
3537 if (RegionTerrain.TryGetValue(pOffset, out testGround)) 3549 if (RegionTerrain.TryGetValue(pOffset, out testGround))
3538 { 3550 {
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
index 80218e7..c9d0909 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
@@ -83,7 +83,6 @@ namespace OpenSim.Region.Physics.OdePlugin
83 private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); 83 private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
84 private float m_linearMotorDecayTimescale = 120; 84 private float m_linearMotorDecayTimescale = 120;
85 private float m_linearMotorTimescale = 1000; 85 private float m_linearMotorTimescale = 1000;
86 private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
87 private Vector3 m_linearMotorOffset = Vector3.Zero; 86 private Vector3 m_linearMotorOffset = Vector3.Zero;
88 87
89 //Angular properties 88 //Angular properties
@@ -91,7 +90,6 @@ namespace OpenSim.Region.Physics.OdePlugin
91 private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate 90 private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate
92 private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate 91 private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate
93 private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate 92 private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate
94 private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
95 93
96 //Deflection properties 94 //Deflection properties
97 private float m_angularDeflectionEfficiency = 0; 95 private float m_angularDeflectionEfficiency = 0;
@@ -102,7 +100,7 @@ namespace OpenSim.Region.Physics.OdePlugin
102 //Banking properties 100 //Banking properties
103 private float m_bankingEfficiency = 0; 101 private float m_bankingEfficiency = 0;
104 private float m_bankingMix = 0; 102 private float m_bankingMix = 0;
105 private float m_bankingTimescale = 0; 103 private float m_bankingTimescale = 1000;
106 104
107 //Hover and Buoyancy properties 105 //Hover and Buoyancy properties
108 private float m_VhoverHeight = 0f; 106 private float m_VhoverHeight = 0f;
@@ -117,9 +115,8 @@ namespace OpenSim.Region.Physics.OdePlugin
117 private float m_verticalAttractionEfficiency = 1.0f; // damped 115 private float m_verticalAttractionEfficiency = 1.0f; // damped
118 private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor. 116 private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor.
119 117
120 // auxiliar
121 private Vector3 m_dir = Vector3.Zero; // velocity applied to body
122 118
119 // auxiliar
123 private float m_lmEfect = 0; // current linear motor eficiency 120 private float m_lmEfect = 0; // current linear motor eficiency
124 private float m_amEfect = 0; // current angular motor eficiency 121 private float m_amEfect = 0; // current angular motor eficiency
125 122
@@ -130,6 +127,82 @@ namespace OpenSim.Region.Physics.OdePlugin
130 _pParentScene = rootPrim._parent_scene; 127 _pParentScene = rootPrim._parent_scene;
131 } 128 }
132 129
130
131 public void DoSetVehicle(VehicleData vd)
132 {
133
134 float timestep = _pParentScene.ODE_STEPSIZE;
135 float invtimestep = 1.0f / timestep;
136
137 m_type = vd.m_type;
138 m_flags = vd.m_flags;
139
140 // Linear properties
141 m_linearMotorDirection = vd.m_linearMotorDirection;
142
143 m_linearFrictionTimescale = vd.m_linearFrictionTimescale;
144 if (m_linearFrictionTimescale.X < timestep) m_linearFrictionTimescale.X = timestep;
145 if (m_linearFrictionTimescale.Y < timestep) m_linearFrictionTimescale.Y = timestep;
146 if (m_linearFrictionTimescale.Z < timestep) m_linearFrictionTimescale.Z = timestep;
147
148 m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale;
149 if (m_linearMotorDecayTimescale < 0.5f) m_linearMotorDecayTimescale = 0.5f;
150 m_linearMotorDecayTimescale *= invtimestep;
151
152 m_linearMotorTimescale = vd.m_linearMotorTimescale;
153 if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep;
154
155 m_linearMotorOffset = vd.m_linearMotorOffset;
156
157 //Angular properties
158 m_angularMotorDirection = vd.m_angularMotorDirection;
159 m_angularMotorTimescale = vd.m_angularMotorTimescale;
160 if (m_angularMotorTimescale < timestep) m_angularMotorTimescale = timestep;
161
162 m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale;
163 if (m_angularMotorDecayTimescale < 0.5f) m_angularMotorDecayTimescale = 0.5f;
164 m_angularMotorDecayTimescale *= invtimestep;
165
166 m_angularFrictionTimescale = vd.m_angularFrictionTimescale;
167 if (m_angularFrictionTimescale.X < timestep) m_angularFrictionTimescale.X = timestep;
168 if (m_angularFrictionTimescale.Y < timestep) m_angularFrictionTimescale.Y = timestep;
169 if (m_angularFrictionTimescale.Z < timestep) m_angularFrictionTimescale.Z = timestep;
170
171 //Deflection properties
172 m_angularDeflectionEfficiency = vd.m_angularDeflectionEfficiency;
173 m_angularDeflectionTimescale = vd.m_angularDeflectionTimescale;
174 if (m_angularDeflectionTimescale < timestep) m_angularDeflectionTimescale = timestep;
175
176 m_linearDeflectionEfficiency = vd.m_linearDeflectionEfficiency;
177 m_linearDeflectionTimescale = vd.m_linearDeflectionTimescale;
178 if (m_linearDeflectionTimescale < timestep) m_linearDeflectionTimescale = timestep;
179
180 //Banking properties
181 m_bankingEfficiency = vd.m_bankingEfficiency;
182 m_bankingMix = vd.m_bankingMix;
183 m_bankingTimescale = vd.m_bankingTimescale;
184 if (m_bankingTimescale < timestep) m_bankingTimescale = timestep;
185
186 //Hover and Buoyancy properties
187 m_VhoverHeight = vd.m_VhoverHeight;
188 m_VhoverEfficiency = vd.m_VhoverEfficiency;
189 m_VhoverTimescale = vd.m_VhoverTimescale;
190 if (m_VhoverTimescale < timestep) m_VhoverTimescale = timestep;
191
192 m_VehicleBuoyancy = vd.m_VehicleBuoyancy;
193
194 //Attractor properties
195 m_verticalAttractionEfficiency = vd.m_verticalAttractionEfficiency;
196 m_verticalAttractionTimescale = vd.m_verticalAttractionTimescale;
197 if (m_verticalAttractionTimescale < timestep) m_verticalAttractionTimescale = timestep;
198
199 // Axis
200 m_referenceFrame = vd.m_referenceFrame;
201
202 m_lmEfect = 0;
203 m_amEfect = 0;
204 }
205
133 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) 206 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
134 { 207 {
135 float len; 208 float len;
@@ -231,6 +304,9 @@ namespace OpenSim.Region.Physics.OdePlugin
231 if (len > 12.566f) 304 if (len > 12.566f)
232 m_angularMotorDirection *= (12.566f / len); 305 m_angularMotorDirection *= (12.566f / len);
233 m_amEfect = 1.0f; // turn it on 306 m_amEfect = 1.0f; // turn it on
307 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
308 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
309 d.BodyEnable(rootPrim.Body);
234 break; 310 break;
235 case Vehicle.LINEAR_FRICTION_TIMESCALE: 311 case Vehicle.LINEAR_FRICTION_TIMESCALE:
236 if (pValue < timestep) pValue = timestep; 312 if (pValue < timestep) pValue = timestep;
@@ -242,6 +318,9 @@ namespace OpenSim.Region.Physics.OdePlugin
242 if (len > 30.0f) 318 if (len > 30.0f)
243 m_linearMotorDirection *= (30.0f / len); 319 m_linearMotorDirection *= (30.0f / len);
244 m_lmEfect = 1.0f; // turn it on 320 m_lmEfect = 1.0f; // turn it on
321 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
322 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
323 d.BodyEnable(rootPrim.Body);
245 break; 324 break;
246 case Vehicle.LINEAR_MOTOR_OFFSET: 325 case Vehicle.LINEAR_MOTOR_OFFSET:
247 m_linearMotorOffset = new Vector3(pValue, pValue, pValue); 326 m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
@@ -273,6 +352,9 @@ namespace OpenSim.Region.Physics.OdePlugin
273 if (len > 12.566f) 352 if (len > 12.566f)
274 m_angularMotorDirection *= (12.566f / len); 353 m_angularMotorDirection *= (12.566f / len);
275 m_amEfect = 1.0f; // turn it on 354 m_amEfect = 1.0f; // turn it on
355 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
356 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
357 d.BodyEnable(rootPrim.Body);
276 break; 358 break;
277 case Vehicle.LINEAR_FRICTION_TIMESCALE: 359 case Vehicle.LINEAR_FRICTION_TIMESCALE:
278 if (pValue.X < timestep) pValue.X = timestep; 360 if (pValue.X < timestep) pValue.X = timestep;
@@ -286,6 +368,9 @@ namespace OpenSim.Region.Physics.OdePlugin
286 if (len > 30.0f) 368 if (len > 30.0f)
287 m_linearMotorDirection *= (30.0f / len); 369 m_linearMotorDirection *= (30.0f / len);
288 m_lmEfect = 1.0f; // turn it on 370 m_lmEfect = 1.0f; // turn it on
371 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
372 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
373 d.BodyEnable(rootPrim.Body);
289 break; 374 break;
290 case Vehicle.LINEAR_MOTOR_OFFSET: 375 case Vehicle.LINEAR_MOTOR_OFFSET:
291 m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); 376 m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
@@ -347,12 +432,23 @@ namespace OpenSim.Region.Physics.OdePlugin
347 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); 432 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
348 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); 433 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
349 m_linearMotorTimescale = 1000; 434 m_linearMotorTimescale = 1000;
350 m_linearMotorDecayTimescale = 120 * invtimestep; 435 m_linearMotorDecayTimescale = 120;
351 m_angularMotorTimescale = 1000; 436 m_angularMotorTimescale = 1000;
352 m_angularMotorDecayTimescale = 1000 * invtimestep; 437 m_angularMotorDecayTimescale = 1000;
353 m_VhoverHeight = 0; 438 m_VhoverHeight = 0;
439 m_VhoverEfficiency = 1;
354 m_VhoverTimescale = 1000; 440 m_VhoverTimescale = 1000;
355 m_VehicleBuoyancy = 0; 441 m_VehicleBuoyancy = 0;
442 m_linearDeflectionEfficiency = 0;
443 m_linearDeflectionTimescale = 1000;
444 m_angularDeflectionEfficiency = 0;
445 m_angularDeflectionTimescale = 1000;
446 m_bankingEfficiency = 0;
447 m_bankingMix = 1;
448 m_bankingTimescale = 1000;
449 m_verticalAttractionEfficiency = 0;
450 m_verticalAttractionTimescale = 1000;
451
356 m_flags = (VehicleFlag)0; 452 m_flags = (VehicleFlag)0;
357 break; 453 break;
358 454
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index 3b7f562..0ccdbc0 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -111,7 +111,7 @@ namespace OpenSim.Region.Physics.OdePlugin
111 | CollisionCategories.Body 111 | CollisionCategories.Body
112 | CollisionCategories.Character 112 | CollisionCategories.Character
113 ); 113 );
114 private bool m_collidesLand = true; 114// private bool m_collidesLand = true;
115 private bool m_collidesWater; 115 private bool m_collidesWater;
116 public bool m_returnCollisions; 116 public bool m_returnCollisions;
117 117
@@ -122,7 +122,7 @@ namespace OpenSim.Region.Physics.OdePlugin
122 private CollisionCategories m_collisionFlags = m_default_collisionFlags; 122 private CollisionCategories m_collisionFlags = m_default_collisionFlags;
123 123
124 public bool m_disabled; 124 public bool m_disabled;
125 public bool m_taintselected; 125
126 126
127 public uint m_localID; 127 public uint m_localID;
128 128
@@ -142,20 +142,19 @@ namespace OpenSim.Region.Physics.OdePlugin
142 private List<OdePrim> childrenPrim = new List<OdePrim>(); 142 private List<OdePrim> childrenPrim = new List<OdePrim>();
143 143
144 private bool m_iscolliding; 144 private bool m_iscolliding;
145 private bool m_wascolliding; 145
146 private bool m_isSelected; 146 public bool m_isSelected;
147 private bool m_delaySelect;
148 private bool m_lastdoneSelected;
149 public bool m_outbounds;
147 150
148 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively 151 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
149 152
150 private bool m_throttleUpdates; 153 private bool m_throttleUpdates;
151 private int throttleCounter; 154 private int throttleCounter;
152 public int m_interpenetrationcount;
153 public float m_collisionscore; 155 public float m_collisionscore;
154 int m_colliderfilter = 0; 156 int m_colliderfilter = 0;
155 public int m_roundsUnderMotionThreshold;
156 private int m_crossingfailures;
157 157
158 public bool outofBounds;
159 private float m_density = 10.000006836f; // Aluminum g/cm3; 158 private float m_density = 10.000006836f; // Aluminum g/cm3;
160 159
161 public bool _zeroFlag; 160 public bool _zeroFlag;
@@ -166,12 +165,11 @@ namespace OpenSim.Region.Physics.OdePlugin
166 private Vector3 _target_velocity; 165 private Vector3 _target_velocity;
167 166
168 public Vector3 primOOBsize; // prim real dimensions from mesh 167 public Vector3 primOOBsize; // prim real dimensions from mesh
169 public Vector3 primOOBoffset; // is centroid out of mesh or rest aabb 168 public Vector3 primOOBoffset; // its centroid out of mesh or rest aabb
170 public float primOOBradiusSQ; 169 public float primOOBradiusSQ;
171 public d.Mass primdMass; // prim inertia information on it's own referencial 170 public d.Mass primdMass; // prim inertia information on it's own referencial
172 float primMass; // prim own mass 171 float primMass; // prim own mass
173 float _mass; // object mass acording to case 172 float _mass; // object mass acording to case
174 public d.Mass objectpMass; // object last computed inertia
175 private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb 173 private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb
176 174
177 public int givefakepos = 0; 175 public int givefakepos = 0;
@@ -182,9 +180,6 @@ namespace OpenSim.Region.Physics.OdePlugin
182 public int m_eventsubscription; 180 public int m_eventsubscription;
183 private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); 181 private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate();
184 182
185 private IntPtr m_linkJoint = IntPtr.Zero;
186 private IntPtr _linkJointGroup = IntPtr.Zero;
187
188 public volatile bool childPrim; 183 public volatile bool childPrim;
189 184
190 public ODEDynamics m_vehicle; 185 public ODEDynamics m_vehicle;
@@ -264,7 +259,7 @@ namespace OpenSim.Region.Physics.OdePlugin
264 set 259 set
265 { 260 {
266 if (value) 261 if (value)
267 m_isSelected = value; 262 m_isSelected = value; // if true set imediatly to stop moves etc
268 AddChange(changes.Selected, value); 263 AddChange(changes.Selected, value);
269 } 264 }
270 } 265 }
@@ -298,13 +293,6 @@ namespace OpenSim.Region.Physics.OdePlugin
298 m_iscolliding = false; 293 m_iscolliding = false;
299 else 294 else
300 m_iscolliding = true; 295 m_iscolliding = true;
301
302 if (m_wascolliding != m_iscolliding)
303 {
304 if (m_wascolliding && !m_isSelected && Body != IntPtr.Zero)
305 d.BodyEnable(Body);
306 m_wascolliding = m_iscolliding;
307 }
308 } 296 }
309 } 297 }
310 298
@@ -665,19 +653,21 @@ namespace OpenSim.Region.Physics.OdePlugin
665 strVehicleQuatParam fp = new strVehicleQuatParam(); 653 strVehicleQuatParam fp = new strVehicleQuatParam();
666 fp.param = param; 654 fp.param = param;
667 fp.value = value; 655 fp.value = value;
668 AddChange(changes.VehicleVectorParam, fp); 656 AddChange(changes.VehicleRotationParam, fp);
669 } 657 }
670 658
671 public override void VehicleFlags(int param, bool value) 659 public override void VehicleFlags(int param, bool value)
672 { 660 {
673 if (m_vehicle == null)
674 return;
675 strVehicleBoolParam bp = new strVehicleBoolParam(); 661 strVehicleBoolParam bp = new strVehicleBoolParam();
676 bp.param = param; 662 bp.param = param;
677 bp.value = value; 663 bp.value = value;
678 AddChange(changes.VehicleFlags, bp); 664 AddChange(changes.VehicleFlags, bp);
679 } 665 }
680 666
667 public override void SetVehicle(object vdata)
668 {
669 AddChange(changes.SetVehicle, vdata);
670 }
681 public void SetAcceleration(Vector3 accel) 671 public void SetAcceleration(Vector3 accel)
682 { 672 {
683 _acceleration = accel; 673 _acceleration = accel;
@@ -710,8 +700,30 @@ namespace OpenSim.Region.Physics.OdePlugin
710 700
711 public override void CrossingFailure() 701 public override void CrossingFailure()
712 { 702 {
713 m_crossingfailures++; 703 if (m_outbounds)
714 changeDisable(false); 704 {
705 _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f);
706 _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f);
707 _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f);
708
709 m_lastposition = _position;
710 _velocity.X = 0;
711 _velocity.Y = 0;
712 _velocity.Z = 0;
713
714 m_lastVelocity = _velocity;
715 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
716 m_vehicle.Stop();
717
718 if(Body != IntPtr.Zero)
719 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
720 if (prim_geom != IntPtr.Zero)
721 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
722
723 m_outbounds = false;
724 changeDisable(false);
725 base.RequestPhysicsterseUpdate();
726 }
715 } 727 }
716 728
717 public override void SetMomentum(Vector3 momentum) 729 public override void SetMomentum(Vector3 momentum)
@@ -865,12 +877,14 @@ namespace OpenSim.Region.Physics.OdePlugin
865 m_force = Vector3.Zero; 877 m_force = Vector3.Zero;
866 878
867 m_iscolliding = false; 879 m_iscolliding = false;
868 m_wascolliding = false;
869 m_colliderfilter = 0; 880 m_colliderfilter = 0;
870 881
871 hasOOBoffsetFromMesh = false; 882 hasOOBoffsetFromMesh = false;
872 _triMeshData = IntPtr.Zero; 883 _triMeshData = IntPtr.Zero;
873 884
885 m_lastdoneSelected = false;
886 m_isSelected = false;
887 m_delaySelect = false;
874 888
875 primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; 889 primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu;
876 primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; 890 primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
@@ -885,8 +899,6 @@ namespace OpenSim.Region.Physics.OdePlugin
885 private void resetCollisionAccounting() 899 private void resetCollisionAccounting()
886 { 900 {
887 m_collisionscore = 0; 901 m_collisionscore = 0;
888 m_interpenetrationcount = 0;
889 m_disabled = false;
890 } 902 }
891 903
892 private void createAMotor(Vector3 axis) 904 private void createAMotor(Vector3 axis)
@@ -926,9 +938,6 @@ namespace OpenSim.Region.Physics.OdePlugin
926 curr.W = dcur.W; 938 curr.W = dcur.W;
927 Vector3 ax; 939 Vector3 ax;
928 940
929 const int StopERP = 7;
930 const int StopCFM = 8;
931
932 int i = 0; 941 int i = 0;
933 int j = 0; 942 int j = 0;
934 if (axis.X == 0) 943 if (axis.X == 0)
@@ -943,10 +952,10 @@ namespace OpenSim.Region.Physics.OdePlugin
943 d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f); 952 d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f);
944 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f); 953 d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f);
945 d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f); 954 d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f);
946 d.JointSetAMotorParam(Amotor, (int)StopCFM, 0f); 955 d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f);
947 d.JointSetAMotorParam(Amotor, (int)StopERP, 0.8f); 956 d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f);
948 i++; 957 i++;
949 j = 256; // odeplugin.cs doesn't have all parameters so this moves to next axis set 958 j = 256; // move to next axis set
950 } 959 }
951 960
952 if (axis.Y == 0) 961 if (axis.Y == 0)
@@ -960,8 +969,8 @@ namespace OpenSim.Region.Physics.OdePlugin
960 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); 969 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f);
961 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); 970 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f);
962 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); 971 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f);
963 d.JointSetAMotorParam(Amotor, j + (int)StopCFM, 0f); 972 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f);
964 d.JointSetAMotorParam(Amotor, j + (int)StopERP, 0.8f); 973 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f);
965 i++; 974 i++;
966 j += 256; 975 j += 256;
967 } 976 }
@@ -977,8 +986,8 @@ namespace OpenSim.Region.Physics.OdePlugin
977 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); 986 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f);
978 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); 987 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f);
979 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); 988 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f);
980 d.JointSetAMotorParam(Amotor, j + (int)StopCFM, 0f); 989 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f);
981 d.JointSetAMotorParam(Amotor, j + (int)StopERP, 0.8f); 990 d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f);
982 } 991 }
983 } 992 }
984 993
@@ -1186,24 +1195,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1186 1195
1187 public void enableBodySoft() 1196 public void enableBodySoft()
1188 { 1197 {
1189 if (!childPrim) 1198 if (!childPrim && !m_isSelected)
1190 { 1199 {
1191 if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) 1200 if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero)
1192 { 1201 {
1193 if (m_targetSpace != _parent_scene.ActiveSpace)
1194 {
1195 m_targetSpace = _parent_scene.ActiveSpace;
1196
1197 foreach (OdePrim prm in childrenPrim)
1198 {
1199 if (prm.prim_geom != IntPtr.Zero)
1200 {
1201 d.SpaceAdd(m_targetSpace, prm.prim_geom);
1202 prm.m_targetSpace = m_targetSpace;
1203 }
1204 }
1205 d.SpaceAdd(m_targetSpace, prim_geom);
1206 }
1207 d.GeomEnable(prim_geom); 1202 d.GeomEnable(prim_geom);
1208 foreach (OdePrim prm in childrenPrim) 1203 foreach (OdePrim prm in childrenPrim)
1209 d.GeomEnable(prm.prim_geom); 1204 d.GeomEnable(prm.prim_geom);
@@ -1211,6 +1206,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1211 d.BodyEnable(Body); 1206 d.BodyEnable(Body);
1212 } 1207 }
1213 } 1208 }
1209 m_disabled = false;
1214 resetCollisionAccounting(); // this sets m_disable to false 1210 resetCollisionAccounting(); // this sets m_disable to false
1215 } 1211 }
1216 1212
@@ -1221,19 +1217,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1221 { 1217 {
1222 if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) 1218 if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero)
1223 { 1219 {
1224 if (m_targetSpace == _parent_scene.ActiveSpace)
1225 {
1226 foreach (OdePrim prm in childrenPrim)
1227 {
1228 if (prm.m_targetSpace != IntPtr.Zero && prm.prim_geom != IntPtr.Zero)
1229 {
1230 d.SpaceRemove(prm.m_targetSpace, prm.prim_geom);
1231 prm.m_targetSpace = IntPtr.Zero;
1232 }
1233 }
1234 d.SpaceRemove(m_targetSpace, prim_geom);
1235 m_targetSpace = IntPtr.Zero;
1236 }
1237 d.GeomDisable(prim_geom); 1220 d.GeomDisable(prim_geom);
1238 foreach (OdePrim prm in childrenPrim) 1221 foreach (OdePrim prm in childrenPrim)
1239 d.GeomDisable(prm.prim_geom); 1222 d.GeomDisable(prm.prim_geom);
@@ -1369,9 +1352,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1369 d.BodySetMass(Body, ref objdmass); 1352 d.BodySetMass(Body, ref objdmass);
1370 _mass = objdmass.mass; 1353 _mass = objdmass.mass;
1371 1354
1372 m_collisionCategories |= CollisionCategories.Body;
1373 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1374
1375 // disconnect from world gravity so we can apply buoyancy 1355 // disconnect from world gravity so we can apply buoyancy
1376 d.BodySetGravityMode(Body, false); 1356 d.BodySetGravityMode(Body, false);
1377 1357
@@ -1379,16 +1359,14 @@ namespace OpenSim.Region.Physics.OdePlugin
1379 d.BodySetAutoDisableSteps(Body, body_autodisable_frames); 1359 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
1380 // d.BodySetLinearDampingThreshold(Body, 0.01f); 1360 // d.BodySetLinearDampingThreshold(Body, 0.01f);
1381 // d.BodySetAngularDampingThreshold(Body, 0.001f); 1361 // d.BodySetAngularDampingThreshold(Body, 0.001f);
1382 d.BodySetDamping(Body, .001f, .0002f); 1362 d.BodySetDamping(Body, .002f, .002f);
1383 1363
1364 m_collisionCategories |= CollisionCategories.Body;
1365 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1384 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1366 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1385 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1367 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1386
1387 m_interpenetrationcount = 0;
1388 m_collisionscore = 0; 1368 m_collisionscore = 0;
1389 1369
1390 m_disabled = false;
1391
1392 if (m_targetSpace != _parent_scene.ActiveSpace) 1370 if (m_targetSpace != _parent_scene.ActiveSpace)
1393 { 1371 {
1394 if (m_targetSpace != IntPtr.Zero) 1372 if (m_targetSpace != IntPtr.Zero)
@@ -1416,6 +1394,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1416 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 1394 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1417 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); 1395 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
1418 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); 1396 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
1397 prm.m_collisionscore = 0;
1419 1398
1420 if (prm.m_targetSpace != _parent_scene.ActiveSpace) 1399 if (prm.m_targetSpace != _parent_scene.ActiveSpace)
1421 { 1400 {
@@ -1428,10 +1407,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1428 prm.m_targetSpace = _parent_scene.ActiveSpace; 1407 prm.m_targetSpace = _parent_scene.ActiveSpace;
1429 d.SpaceAdd(m_targetSpace, prm.prim_geom); 1408 d.SpaceAdd(m_targetSpace, prm.prim_geom);
1430 } 1409 }
1431 d.GeomEnable(prm.prim_geom); 1410
1411 if (m_isSelected || m_disabled)
1412 d.GeomDisable(prm.prim_geom);
1413
1432 prm.m_disabled = false; 1414 prm.m_disabled = false;
1433 prm.m_interpenetrationcount = 0;
1434 prm.m_collisionscore = 0;
1435 _parent_scene.addActivePrim(prm); 1415 _parent_scene.addActivePrim(prm);
1436 } 1416 }
1437 } 1417 }
@@ -1442,8 +1422,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1442 createAMotor(m_angularlock); 1422 createAMotor(m_angularlock);
1443 } 1423 }
1444 1424
1445 d.GeomEnable(prim_geom); 1425 if (m_isSelected || m_disabled)
1446 m_disabled = false; 1426 {
1427 d.GeomDisable(prim_geom);
1428 d.BodyDisable(Body);
1429 }
1430
1447 _parent_scene.addActivePrim(this); 1431 _parent_scene.addActivePrim(this);
1448 } 1432 }
1449 1433
@@ -1484,12 +1468,16 @@ namespace OpenSim.Region.Physics.OdePlugin
1484 prm.m_collisionscore = 0; 1468 prm.m_collisionscore = 0;
1485 } 1469 }
1486 } 1470 }
1471 if (Amotor != IntPtr.Zero)
1472 {
1473 d.JointDestroy(Amotor);
1474 Amotor = IntPtr.Zero;
1475 }
1487 d.BodyDestroy(Body); 1476 d.BodyDestroy(Body);
1488 } 1477 }
1489 Body = IntPtr.Zero; 1478 Body = IntPtr.Zero;
1490 } 1479 }
1491 _mass = primMass; 1480 _mass = primMass;
1492 m_disabled = true;
1493 m_collisionscore = 0; 1481 m_collisionscore = 0;
1494 } 1482 }
1495 1483
@@ -2115,49 +2103,72 @@ namespace OpenSim.Region.Physics.OdePlugin
2115 d.BodySetTorque(Body, 0f, 0f, 0f); 2103 d.BodySetTorque(Body, 0f, 0f, 0f);
2116 d.BodySetLinearVel(Body, 0f, 0f, 0f); 2104 d.BodySetLinearVel(Body, 0f, 0f, 0f);
2117 d.BodySetAngularVel(Body, 0f, 0f, 0f); 2105 d.BodySetAngularVel(Body, 0f, 0f, 0f);
2118
2119 } 2106 }
2120 } 2107 }
2121 2108
2122 private void changeSelectedStatus(bool newval) 2109 private void changeSelectedStatus(bool newval)
2123 { 2110 {
2111 if (m_lastdoneSelected == newval)
2112 return;
2113
2114 m_lastdoneSelected = newval;
2115 DoSelectedStatus(newval);
2116 }
2117
2118 private void CheckDelaySelect()
2119 {
2120 if (m_delaySelect)
2121 {
2122 DoSelectedStatus(m_isSelected);
2123 }
2124 }
2125
2126 private void DoSelectedStatus(bool newval)
2127 {
2124 m_isSelected = newval; 2128 m_isSelected = newval;
2125 Stop(); 2129 Stop();
2126 2130
2127 if (newval) 2131 if (newval)
2128 { 2132 {
2129 m_collisionCategories = CollisionCategories.Selected; 2133 if (!childPrim && Body != IntPtr.Zero)
2130 m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); 2134 d.BodyDisable(Body);
2131 2135
2132 if (prim_geom != IntPtr.Zero) 2136 if (m_delaySelect)
2133 { 2137 {
2134 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 2138 if (!childPrim)
2135 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 2139 {
2140 foreach (OdePrim prm in childrenPrim)
2141 {
2142 d.GeomDisable(prm.prim_geom);
2143 prm.m_delaySelect = false;
2144 }
2145 }
2146 d.GeomDisable(prim_geom);
2147 m_delaySelect = false;
2148 }
2149 else
2150 {
2151 m_delaySelect = true;
2136 } 2152 }
2137
2138 disableBodySoft();
2139 } 2153 }
2140 else 2154 else
2141 { 2155 {
2142 m_collisionCategories = CollisionCategories.Geom; 2156 if (!childPrim && Body != IntPtr.Zero && !m_disabled)
2143 2157 d.BodyEnable(Body);
2144 if (m_isphysical)
2145 m_collisionCategories |= CollisionCategories.Body;
2146
2147 m_collisionFlags = m_default_collisionFlags;
2148
2149 if (m_collidesLand)
2150 m_collisionFlags |= CollisionCategories.Land;
2151 if (m_collidesWater)
2152 m_collisionFlags |= CollisionCategories.Water;
2153 2158
2154 if (prim_geom != IntPtr.Zero) 2159 if (!childPrim)
2155 { 2160 {
2156 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 2161 foreach (OdePrim prm in childrenPrim)
2157 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 2162 {
2163 if(!prm.m_disabled)
2164 d.GeomEnable(prm.prim_geom);
2165 prm.m_delaySelect = false;
2166 }
2158 } 2167 }
2168 if(!m_disabled)
2169 d.GeomEnable(prim_geom);
2159 2170
2160 enableBodySoft(); 2171 m_delaySelect = false;
2161 } 2172 }
2162 2173
2163 resetCollisionAccounting(); 2174 resetCollisionAccounting();
@@ -2165,6 +2176,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2165 2176
2166 private void changePosition(Vector3 newPos) 2177 private void changePosition(Vector3 newPos)
2167 { 2178 {
2179 CheckDelaySelect();
2168 if (m_isphysical) 2180 if (m_isphysical)
2169 { 2181 {
2170 if (childPrim) // inertia is messed, must rebuild 2182 if (childPrim) // inertia is messed, must rebuild
@@ -2207,6 +2219,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2207 2219
2208 private void changeOrientation(Quaternion newOri) 2220 private void changeOrientation(Quaternion newOri)
2209 { 2221 {
2222 CheckDelaySelect();
2210 if (m_isphysical) 2223 if (m_isphysical)
2211 { 2224 {
2212 if (childPrim) // inertia is messed, must rebuild 2225 if (childPrim) // inertia is messed, must rebuild
@@ -2258,6 +2271,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2258 2271
2259 private void changePositionAndOrientation(Vector3 newPos, Quaternion newOri) 2272 private void changePositionAndOrientation(Vector3 newPos, Quaternion newOri)
2260 { 2273 {
2274 CheckDelaySelect();
2261 if (m_isphysical) 2275 if (m_isphysical)
2262 { 2276 {
2263 if (childPrim && m_building) // inertia is messed, must rebuild 2277 if (childPrim && m_building) // inertia is messed, must rebuild
@@ -2342,6 +2356,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2342 2356
2343 private void changePhysicsStatus(bool NewStatus) 2357 private void changePhysicsStatus(bool NewStatus)
2344 { 2358 {
2359 CheckDelaySelect();
2360
2345 m_isphysical = NewStatus; 2361 m_isphysical = NewStatus;
2346 2362
2347 if (!childPrim) 2363 if (!childPrim)
@@ -2384,6 +2400,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2384 2400
2385 private void changeprimsizeshape() 2401 private void changeprimsizeshape()
2386 { 2402 {
2403 CheckDelaySelect();
2404
2387 OdePrim parent = (OdePrim)_parent; 2405 OdePrim parent = (OdePrim)_parent;
2388 2406
2389 bool chp = childPrim; 2407 bool chp = childPrim;
@@ -2508,7 +2526,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2508 } 2526 }
2509 2527
2510 m_collisionscore = 0; 2528 m_collisionscore = 0;
2511 m_interpenetrationcount = 0;
2512 } 2529 }
2513 } 2530 }
2514 2531
@@ -2528,7 +2545,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2528 } 2545 }
2529 } 2546 }
2530 m_collisionscore = 0; 2547 m_collisionscore = 0;
2531 m_interpenetrationcount = 0;
2532 } 2548 }
2533 } 2549 }
2534 2550
@@ -2565,6 +2581,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2565 else 2581 else
2566 { 2582 {
2567 m_building = false; 2583 m_building = false;
2584 CheckDelaySelect();
2568 if (!childPrim) 2585 if (!childPrim)
2569 MakeBody(); 2586 MakeBody();
2570 } 2587 }
@@ -2575,18 +2592,26 @@ namespace OpenSim.Region.Physics.OdePlugin
2575 } 2592 }
2576 } 2593 }
2577 2594
2578 private void changeVehicleType(int value) 2595 public void changeSetVehicle(VehicleData vdata)
2579 { 2596 {
2580 if (m_vehicle == null) 2597 if (m_vehicle == null)
2598 m_vehicle = new ODEDynamics(this);
2599 m_vehicle.DoSetVehicle(vdata);
2600 }
2601 private void changeVehicleType(int value)
2602 {
2603 if (value == (int)Vehicle.TYPE_NONE)
2581 { 2604 {
2582 if (value != (int)Vehicle.TYPE_NONE) 2605 if (m_vehicle != null)
2583 { 2606 m_vehicle = null;
2584 m_vehicle = new ODEDynamics(this);
2585 m_vehicle.ProcessTypeChange((Vehicle)value);
2586 }
2587 } 2607 }
2588 else 2608 else
2609 {
2610 if (m_vehicle == null)
2611 m_vehicle = new ODEDynamics(this);
2612
2589 m_vehicle.ProcessTypeChange((Vehicle)value); 2613 m_vehicle.ProcessTypeChange((Vehicle)value);
2614 }
2590 } 2615 }
2591 2616
2592 private void changeVehicleFloatParam(strVehicleFloatParam fp) 2617 private void changeVehicleFloatParam(strVehicleFloatParam fp)
@@ -2595,8 +2620,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2595 return; 2620 return;
2596 2621
2597 m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value); 2622 m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value);
2598 if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
2599 d.BodyEnable(Body);
2600 } 2623 }
2601 2624
2602 private void changeVehicleVectorParam(strVehicleVectorParam vp) 2625 private void changeVehicleVectorParam(strVehicleVectorParam vp)
@@ -2604,8 +2627,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2604 if (m_vehicle == null) 2627 if (m_vehicle == null)
2605 return; 2628 return;
2606 m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value); 2629 m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value);
2607 if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
2608 d.BodyEnable(Body);
2609 } 2630 }
2610 2631
2611 private void changeVehicleRotationParam(strVehicleQuatParam qp) 2632 private void changeVehicleRotationParam(strVehicleQuatParam qp)
@@ -2613,8 +2634,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2613 if (m_vehicle == null) 2634 if (m_vehicle == null)
2614 return; 2635 return;
2615 m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value); 2636 m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value);
2616 if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
2617 d.BodyEnable(Body);
2618 } 2637 }
2619 2638
2620 private void changeVehicleFlags(strVehicleBoolParam bp) 2639 private void changeVehicleFlags(strVehicleBoolParam bp)
@@ -2622,8 +2641,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2622 if (m_vehicle == null) 2641 if (m_vehicle == null)
2623 return; 2642 return;
2624 m_vehicle.ProcessVehicleFlags(bp.param, bp.value); 2643 m_vehicle.ProcessVehicleFlags(bp.param, bp.value);
2625 if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
2626 d.BodyEnable(Body);
2627 } 2644 }
2628 2645
2629 #endregion 2646 #endregion
@@ -2849,41 +2866,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2849 { 2866 {
2850 if (Body != IntPtr.Zero) 2867 if (Body != IntPtr.Zero)
2851 { 2868 {
2852 if (m_crossingfailures != 0 && m_crossingfailures < 5)
2853 {
2854 _position.X = Util.Clip(_position.X, 0.4f, _parent_scene.WorldExtents.X - 0.4f);
2855 _position.Y = Util.Clip(_position.Y, 0.4f, _parent_scene.WorldExtents.Y - 0.4f);
2856 _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f);
2857
2858 float tmp = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y);
2859 if (_position.Z < tmp)
2860 _position.Z = tmp + 0.2f;
2861
2862 m_lastposition = _position;
2863 m_lastorientation = _orientation;
2864 _velocity.X = 0;
2865 _velocity.Y = 0;
2866 _velocity.Z = 0;
2867
2868 m_lastVelocity = _velocity;
2869 m_rotationalVelocity = _velocity;
2870 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
2871 m_vehicle.Stop();
2872
2873 m_crossingfailures = 0; // do this only once
2874 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
2875 d.BodySetAngularVel(Body, 0, 0, 0);
2876 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2877 enableBodySoft();
2878 base.RequestPhysicsterseUpdate();
2879 return;
2880 }
2881
2882 else if (m_crossingfailures != 0)
2883 {
2884 return;
2885 }
2886
2887 Vector3 pv = Vector3.Zero; 2869 Vector3 pv = Vector3.Zero;
2888 bool lastZeroFlag = _zeroFlag; 2870 bool lastZeroFlag = _zeroFlag;
2889 2871
@@ -2899,24 +2881,21 @@ namespace OpenSim.Region.Physics.OdePlugin
2899 // we can't let it keeping moving and having colisions 2881 // we can't let it keeping moving and having colisions
2900 // since it can be stucked between something like terrain and edge 2882 // since it can be stucked between something like terrain and edge
2901 // so lets stop and disable it until something else kicks it 2883 // so lets stop and disable it until something else kicks it
2902 if (m_crossingfailures == 0)
2903 {
2904 2884
2905 _position.X = Util.Clip(lpos.X, -0.5f, _parent_scene.WorldExtents.X + 0.5f); 2885 _position.X = Util.Clip(lpos.X, -0.2f, _parent_scene.WorldExtents.X + 0.2f);
2906 _position.Y = Util.Clip(lpos.Y, -0.5f, _parent_scene.WorldExtents.Y + 0.5f); 2886 _position.Y = Util.Clip(lpos.Y, -0.2f, _parent_scene.WorldExtents.Y + 0.2f);
2907 _position.Z = Util.Clip(lpos.Z, -100f, 50000f); 2887 _position.Z = Util.Clip(lpos.Z, -100f, 50000f);
2908 2888
2909 m_lastposition = _position; 2889 m_lastposition = _position;
2910 m_lastorientation = _orientation; 2890// m_lastorientation = _orientation;
2911 2891
2912 d.BodySetLinearVel(Body, 0, 0, 0); // stop it 2892 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
2913 d.BodySetAngularVel(Body, 0, 0, 0); 2893// d.BodySetAngularVel(Body, 0, 0, 0);
2914 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 2894 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2915 disableBodySoft(); // stop collisions 2895 disableBodySoft(); // stop collisions
2916 m_crossingfailures++; // do this only once 2896 m_outbounds = true;
2917 base.RequestPhysicsterseUpdate(); 2897 base.RequestPhysicsterseUpdate();
2918 return; 2898 return;
2919 }
2920 } 2899 }
2921 2900
2922 if (lpos.Z < -100 || lpos.Z > 100000f) 2901 if (lpos.Z < -100 || lpos.Z > 100000f)
@@ -3159,6 +3138,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3159 else 3138 else
3160 ChildRemove(this, false); 3139 ChildRemove(this, false);
3161 3140
3141 m_vehicle = null;
3162 RemoveGeom(); 3142 RemoveGeom();
3163 m_targetSpace = IntPtr.Zero; 3143 m_targetSpace = IntPtr.Zero;
3164 if (m_eventsubscription > 0) 3144 if (m_eventsubscription > 0)
@@ -3273,6 +3253,9 @@ namespace OpenSim.Region.Physics.OdePlugin
3273 changeVehicleRotationParam((strVehicleQuatParam) arg); 3253 changeVehicleRotationParam((strVehicleQuatParam) arg);
3274 break; 3254 break;
3275 3255
3256 case changes.SetVehicle:
3257 changeSetVehicle((VehicleData) arg);
3258 break;
3276 case changes.Null: 3259 case changes.Null:
3277 donullchange(); 3260 donullchange();
3278 break; 3261 break;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
index e62746e..2b6bc59 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
@@ -1,4 +1,3 @@
1
2/* 1/*
3 * based on: 2 * based on:
4 * Ode.NET - .NET bindings for ODE 3 * Ode.NET - .NET bindings for ODE
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 56f3786..6e4c373 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -137,6 +137,7 @@ namespace OpenSim.Region.Physics.OdePlugin
137 VehicleVectorParam, 137 VehicleVectorParam,
138 VehicleRotationParam, 138 VehicleRotationParam,
139 VehicleFlags, 139 VehicleFlags,
140 SetVehicle,
140 141
141 Null //keep this last used do dim the methods array. does nothing but pulsing the prim 142 Null //keep this last used do dim the methods array. does nothing but pulsing the prim
142 } 143 }
@@ -166,8 +167,8 @@ namespace OpenSim.Region.Physics.OdePlugin
166 167
167 float frictionMovementMult = 0.3f; 168 float frictionMovementMult = 0.3f;
168 169
169 float TerrainBounce = 0.3f; 170 float TerrainBounce = 0.1f;
170 float TerrainFriction = 0.3f; 171 float TerrainFriction = 0.1f;
171 172
172 public float AvatarBounce = 0.3f; 173 public float AvatarBounce = 0.3f;
173 public float AvatarFriction = 0;// 0.9f * 0.5f; 174 public float AvatarFriction = 0;// 0.9f * 0.5f;
@@ -989,145 +990,62 @@ namespace OpenSim.Region.Physics.OdePlugin
989 /// <param name="timeStep"></param> 990 /// <param name="timeStep"></param>
990 private void collision_optimized() 991 private void collision_optimized()
991 { 992 {
992// _perloopContact.Clear();
993// clear characts IsColliding until we do it some other way
994
995 lock (_characters) 993 lock (_characters)
996 { 994 {
997 foreach (OdeCharacter chr in _characters) 995 try
996 {
997 foreach (OdeCharacter chr in _characters)
998 { 998 {
999 // this are odd checks if they are needed something is wrong elsewhere 999 if (chr == null || chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
1000 // keep for now 1000 continue;
1001 if (chr == null) 1001
1002 continue; 1002 chr.IsColliding = false;
1003 1003 // chr.CollidingGround = false; not done here
1004 if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) 1004 chr.CollidingObj = false;
1005 continue; 1005 // do colisions with static space
1006 1006 d.SpaceCollide2(StaticSpace, chr.Shell, IntPtr.Zero, nearCallback);
1007 chr.IsColliding = false;
1008 // chr.CollidingGround = false; not done here
1009 chr.CollidingObj = false;
1010 } 1007 }
1011 } 1008 }
1012 1009 catch (AccessViolationException)
1013 // now let ode do its job
1014 // colide active things amoung them
1015
1016 int st = Util.EnvironmentTickCount();
1017 int ta;
1018 int ts;
1019 try
1020 {
1021 d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback);
1022 }
1023 catch (AccessViolationException)
1024 { 1010 {
1025 m_log.Warn("[PHYSICS]: Unable to Active space collide"); 1011 m_log.Warn("[PHYSICS]: Unable to collide Character to static space");
1026 } 1012 }
1027 ta = Util.EnvironmentTickCountSubtract(st); 1013
1028 // then active things with static enviroment 1014 }
1029 try 1015
1016 // collide active prims with static enviroment
1017 lock (_activeprims)
1018 {
1019 try
1030 { 1020 {
1031 d.SpaceCollide2(ActiveSpace,StaticSpace, IntPtr.Zero, nearCallback); 1021 foreach (OdePrim prm in _activeprims)
1022 {
1023 if (d.BodyIsEnabled(prm.Body))
1024 d.SpaceCollide2(StaticSpace, prm.prim_geom, IntPtr.Zero, nearCallback);
1025 }
1032 } 1026 }
1033 catch (AccessViolationException) 1027 catch (AccessViolationException)
1034 { 1028 {
1035 m_log.Warn("[PHYSICS]: Unable to Active to static space collide"); 1029 m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space");
1036 } 1030 }
1037 ts = Util.EnvironmentTickCountSubtract(st);
1038// _perloopContact.Clear();
1039 }
1040
1041 #endregion
1042
1043
1044 public float GetTerrainHeightAtXY(float x, float y)
1045 {
1046 // assumes 1m size grid and constante size square regions
1047 // region offset in mega position
1048
1049 int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
1050 int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
1051
1052 IntPtr heightFieldGeom = IntPtr.Zero;
1053
1054 // get region map
1055 if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom))
1056 return 0f;
1057
1058 if (heightFieldGeom == IntPtr.Zero)
1059 return 0f;
1060
1061 if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
1062 return 0f;
1063
1064 // TerrainHeightField for ODE as offset 1m
1065 x += 1f - offsetX;
1066 y += 1f - offsetY;
1067
1068 // make position fit into array
1069 if (x < 0)
1070 x = 0;
1071 if (y < 0)
1072 y = 0;
1073
1074 // integer indexs
1075 int ix;
1076 int iy;
1077 // interpolators offset
1078 float dx;
1079 float dy;
1080
1081 int regsize = (int)Constants.RegionSize + 2; // map size see setterrain
1082
1083 // we still have square fixed size regions
1084 // also flip x and y because of how map is done for ODE fliped axis
1085 // so ix,iy,dx and dy are inter exchanged
1086 if (x < regsize - 1)
1087 {
1088 iy = (int)x;
1089 dy = x - (float)iy;
1090 }
1091 else // out world use external height
1092 {
1093 iy = regsize - 1;
1094 dy = 0;
1095 } 1031 }
1096 if (y < regsize - 1) 1032
1033 // finally colide active things amoung them
1034 try
1097 { 1035 {
1098 ix = (int)y; 1036 d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback);
1099 dx = y - (float)ix;
1100 } 1037 }
1101 else 1038 catch (AccessViolationException)
1102 { 1039 {
1103 ix = regsize - 1; 1040 m_log.Warn("[PHYSICS]: Unable to collide in Active space");
1104 dx = 0;
1105 } 1041 }
1106 1042
1107 float h0; 1043// _perloopContact.Clear();
1108 float h1; 1044 }
1109 float h2;
1110
1111 iy *= regsize;
1112 iy += ix; // all indexes have iy + ix
1113 1045
1114 float[] heights = TerrainHeightFieldHeights[heightFieldGeom]; 1046 #endregion
1115 1047
1116 if ((dx + dy) <= 1.0f)
1117 {
1118 h0 = ((float)heights[iy]); // 0,0 vertice
1119 h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0
1120 h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0
1121 }
1122 else
1123 {
1124 h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice
1125 h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0
1126 h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1
1127 }
1128 1048
1129 return h0 + h1 + h2;
1130 }
1131 1049
1132 /// <summary> 1050 /// <summary>
1133 /// Add actor to the list that should receive collision events in the simulate loop. 1051 /// Add actor to the list that should receive collision events in the simulate loop.
@@ -1835,273 +1753,94 @@ namespace OpenSim.Region.Physics.OdePlugin
1835 get { return (false); } 1753 get { return (false); }
1836 } 1754 }
1837 1755
1838 #region ODE Specific Terrain Fixes 1756 public float GetTerrainHeightAtXY(float x, float y)
1839 public float[] ResizeTerrain512NearestNeighbour(float[] heightMap)
1840 { 1757 {
1841 float[] returnarr = new float[262144]; 1758 // assumes 1m size grid and constante size square regions
1842 float[,] resultarr = new float[(int)WorldExtents.X, (int)WorldExtents.Y]; 1759 // needs to know about sims around in future
1760 // region offset in mega position
1843 1761
1844 // Filling out the array into its multi-dimensional components 1762 int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
1845 for (int y = 0; y < WorldExtents.Y; y++) 1763 int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
1846 {
1847 for (int x = 0; x < WorldExtents.X; x++)
1848 {
1849 resultarr[y, x] = heightMap[y * (int)WorldExtents.Y + x];
1850 }
1851 }
1852 1764
1853 // Resize using Nearest Neighbour 1765 IntPtr heightFieldGeom = IntPtr.Zero;
1854
1855 // This particular way is quick but it only works on a multiple of the original
1856
1857 // The idea behind this method can be described with the following diagrams
1858 // second pass and third pass happen in the same loop really.. just separated
1859 // them to show what this does.
1860
1861 // First Pass
1862 // ResultArr:
1863 // 1,1,1,1,1,1
1864 // 1,1,1,1,1,1
1865 // 1,1,1,1,1,1
1866 // 1,1,1,1,1,1
1867 // 1,1,1,1,1,1
1868 // 1,1,1,1,1,1
1869
1870 // Second Pass
1871 // ResultArr2:
1872 // 1,,1,,1,,1,,1,,1,
1873 // ,,,,,,,,,,
1874 // 1,,1,,1,,1,,1,,1,
1875 // ,,,,,,,,,,
1876 // 1,,1,,1,,1,,1,,1,
1877 // ,,,,,,,,,,
1878 // 1,,1,,1,,1,,1,,1,
1879 // ,,,,,,,,,,
1880 // 1,,1,,1,,1,,1,,1,
1881 // ,,,,,,,,,,
1882 // 1,,1,,1,,1,,1,,1,
1883
1884 // Third pass fills in the blanks
1885 // ResultArr2:
1886 // 1,1,1,1,1,1,1,1,1,1,1,1
1887 // 1,1,1,1,1,1,1,1,1,1,1,1
1888 // 1,1,1,1,1,1,1,1,1,1,1,1
1889 // 1,1,1,1,1,1,1,1,1,1,1,1
1890 // 1,1,1,1,1,1,1,1,1,1,1,1
1891 // 1,1,1,1,1,1,1,1,1,1,1,1
1892 // 1,1,1,1,1,1,1,1,1,1,1,1
1893 // 1,1,1,1,1,1,1,1,1,1,1,1
1894 // 1,1,1,1,1,1,1,1,1,1,1,1
1895 // 1,1,1,1,1,1,1,1,1,1,1,1
1896 // 1,1,1,1,1,1,1,1,1,1,1,1
1897
1898 // X,Y = .
1899 // X+1,y = ^
1900 // X,Y+1 = *
1901 // X+1,Y+1 = #
1902
1903 // Filling in like this;
1904 // .*
1905 // ^#
1906 // 1st .
1907 // 2nd *
1908 // 3rd ^
1909 // 4th #
1910 // on single loop.
1911
1912 float[,] resultarr2 = new float[512, 512];
1913 for (int y = 0; y < WorldExtents.Y; y++)
1914 {
1915 for (int x = 0; x < WorldExtents.X; x++)
1916 {
1917 resultarr2[y * 2, x * 2] = resultarr[y, x];
1918 1766
1919 if (y < WorldExtents.Y) 1767 // get region map
1920 { 1768 if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom))
1921 resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x]; 1769 return 0f;
1922 }
1923 if (x < WorldExtents.X)
1924 {
1925 resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x];
1926 }
1927 if (x < WorldExtents.X && y < WorldExtents.Y)
1928 {
1929 resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x];
1930 }
1931 }
1932 }
1933 1770
1934 //Flatten out the array 1771 if (heightFieldGeom == IntPtr.Zero)
1935 int i = 0; 1772 return 0f;
1936 for (int y = 0; y < 512; y++)
1937 {
1938 for (int x = 0; x < 512; x++)
1939 {
1940 if (resultarr2[y, x] <= 0)
1941 returnarr[i] = 0.0000001f;
1942 else
1943 returnarr[i] = resultarr2[y, x];
1944 1773
1945 i++; 1774 if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
1946 } 1775 return 0f;
1947 }
1948 1776
1949 return returnarr; 1777 // TerrainHeightField for ODE as offset 1m
1950 } 1778 x += 1f - offsetX;
1779 y += 1f - offsetY;
1951 1780
1952 public float[] ResizeTerrain512Interpolation(float[] heightMap) 1781 // make position fit into array
1953 { 1782 if (x < 0)
1954 float[] returnarr = new float[262144]; 1783 x = 0;
1955 float[,] resultarr = new float[512,512]; 1784 if (y < 0)
1785 y = 0;
1786
1787 // integer indexs
1788 int ix;
1789 int iy;
1790 // interpolators offset
1791 float dx;
1792 float dy;
1793
1794 int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples
1956 1795
1957 // Filling out the array into its multi-dimensional components 1796 // we still have square fixed size regions
1958 for (int y = 0; y < 256; y++) 1797 // also flip x and y because of how map is done for ODE fliped axis
1798 // so ix,iy,dx and dy are inter exchanged
1799 if (x < regsize - 1)
1959 { 1800 {
1960 for (int x = 0; x < 256; x++) 1801 iy = (int)x;
1961 { 1802 dy = x - (float)iy;
1962 resultarr[y, x] = heightMap[y * 256 + x];
1963 }
1964 } 1803 }
1965 1804 else // out world use external height
1966 // Resize using interpolation
1967
1968 // This particular way is quick but it only works on a multiple of the original
1969
1970 // The idea behind this method can be described with the following diagrams
1971 // second pass and third pass happen in the same loop really.. just separated
1972 // them to show what this does.
1973
1974 // First Pass
1975 // ResultArr:
1976 // 1,1,1,1,1,1
1977 // 1,1,1,1,1,1
1978 // 1,1,1,1,1,1
1979 // 1,1,1,1,1,1
1980 // 1,1,1,1,1,1
1981 // 1,1,1,1,1,1
1982
1983 // Second Pass
1984 // ResultArr2:
1985 // 1,,1,,1,,1,,1,,1,
1986 // ,,,,,,,,,,
1987 // 1,,1,,1,,1,,1,,1,
1988 // ,,,,,,,,,,
1989 // 1,,1,,1,,1,,1,,1,
1990 // ,,,,,,,,,,
1991 // 1,,1,,1,,1,,1,,1,
1992 // ,,,,,,,,,,
1993 // 1,,1,,1,,1,,1,,1,
1994 // ,,,,,,,,,,
1995 // 1,,1,,1,,1,,1,,1,
1996
1997 // Third pass fills in the blanks
1998 // ResultArr2:
1999 // 1,1,1,1,1,1,1,1,1,1,1,1
2000 // 1,1,1,1,1,1,1,1,1,1,1,1
2001 // 1,1,1,1,1,1,1,1,1,1,1,1
2002 // 1,1,1,1,1,1,1,1,1,1,1,1
2003 // 1,1,1,1,1,1,1,1,1,1,1,1
2004 // 1,1,1,1,1,1,1,1,1,1,1,1
2005 // 1,1,1,1,1,1,1,1,1,1,1,1
2006 // 1,1,1,1,1,1,1,1,1,1,1,1
2007 // 1,1,1,1,1,1,1,1,1,1,1,1
2008 // 1,1,1,1,1,1,1,1,1,1,1,1
2009 // 1,1,1,1,1,1,1,1,1,1,1,1
2010
2011 // X,Y = .
2012 // X+1,y = ^
2013 // X,Y+1 = *
2014 // X+1,Y+1 = #
2015
2016 // Filling in like this;
2017 // .*
2018 // ^#
2019 // 1st .
2020 // 2nd *
2021 // 3rd ^
2022 // 4th #
2023 // on single loop.
2024
2025 float[,] resultarr2 = new float[512,512];
2026 for (int y = 0; y < (int)Constants.RegionSize; y++)
2027 { 1805 {
2028 for (int x = 0; x < (int)Constants.RegionSize; x++) 1806 iy = regsize - 1;
2029 { 1807 dy = 0;
2030 resultarr2[y*2, x*2] = resultarr[y, x];
2031
2032 if (y < (int)Constants.RegionSize)
2033 {
2034 if (y + 1 < (int)Constants.RegionSize)
2035 {
2036 if (x + 1 < (int)Constants.RegionSize)
2037 {
2038 resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] +
2039 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
2040 }
2041 else
2042 {
2043 resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x])/2);
2044 }
2045 }
2046 else
2047 {
2048 resultarr2[(y*2) + 1, x*2] = resultarr[y, x];
2049 }
2050 }
2051 if (x < (int)Constants.RegionSize)
2052 {
2053 if (x + 1 < (int)Constants.RegionSize)
2054 {
2055 if (y + 1 < (int)Constants.RegionSize)
2056 {
2057 resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
2058 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
2059 }
2060 else
2061 {
2062 resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y, x + 1])/2);
2063 }
2064 }
2065 else
2066 {
2067 resultarr2[y*2, (x*2) + 1] = resultarr[y, x];
2068 }
2069 }
2070 if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize)
2071 {
2072 if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize))
2073 {
2074 resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
2075 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
2076 }
2077 else
2078 {
2079 resultarr2[(y*2) + 1, (x*2) + 1] = resultarr[y, x];
2080 }
2081 }
2082 }
2083 } 1808 }
2084 //Flatten out the array 1809 if (y < regsize - 1)
2085 int i = 0;
2086 for (int y = 0; y < 512; y++)
2087 { 1810 {
2088 for (int x = 0; x < 512; x++) 1811 ix = (int)y;
2089 { 1812 dx = y - (float)ix;
2090 if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x])) 1813 }
2091 { 1814 else
2092 m_log.Warn("[PHYSICS]: Non finite heightfield element detected. Setting it to 0"); 1815 {
2093 resultarr2[y, x] = 0; 1816 ix = regsize - 1;
2094 } 1817 dx = 0;
2095 returnarr[i] = resultarr2[y, x];
2096 i++;
2097 }
2098 } 1818 }
2099 1819
2100 return returnarr; 1820 float h0;
2101 } 1821 float h1;
1822 float h2;
2102 1823
2103 #endregion 1824 iy *= regsize;
1825 iy += ix; // all indexes have iy + ix
2104 1826
1827 float[] heights = TerrainHeightFieldHeights[heightFieldGeom];
1828
1829 if ((dx + dy) <= 1.0f)
1830 {
1831 h0 = ((float)heights[iy]); // 0,0 vertice
1832 h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0
1833 h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0
1834 }
1835 else
1836 {
1837 h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice
1838 h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0
1839 h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1
1840 }
1841
1842 return h0 + h1 + h2;
1843 }
2105 public override void SetTerrain(float[] heightMap) 1844 public override void SetTerrain(float[] heightMap)
2106 { 1845 {
2107 if (m_worldOffset != Vector3.Zero && m_parentScene != null) 1846 if (m_worldOffset != Vector3.Zero && m_parentScene != null)
@@ -2124,48 +1863,47 @@ namespace OpenSim.Region.Physics.OdePlugin
2124 1863
2125 public void SetTerrain(float[] heightMap, Vector3 pOffset) 1864 public void SetTerrain(float[] heightMap, Vector3 pOffset)
2126 { 1865 {
1866 // assumes 1m size grid and constante size square regions
1867 // needs to know about sims around in future
2127 1868
2128 float[] _heightmap; 1869 float[] _heightmap;
2129 _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))];
2130 1870
2131 uint heightmapWidth = Constants.RegionSize + 2; 1871 uint heightmapWidth = Constants.RegionSize + 2;
2132 uint heightmapHeight = Constants.RegionSize + 2; 1872 uint heightmapHeight = Constants.RegionSize + 2;
2133 1873
2134 uint heightmapWidthSamples; 1874 uint heightmapWidthSamples = heightmapWidth + 1;
1875 uint heightmapHeightSamples = heightmapHeight + 1;
2135 1876
2136 uint heightmapHeightSamples; 1877 _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples];
2137
2138 heightmapWidthSamples = (uint)Constants.RegionSize + 2;
2139 heightmapHeightSamples = (uint)Constants.RegionSize + 2;
2140 1878
2141 const float scale = 1.0f; 1879 const float scale = 1.0f;
2142 const float offset = 0.0f; 1880 const float offset = 0.0f;
2143 const float thickness = 10f; 1881 const float thickness = 10f;
2144 const int wrap = 0; 1882 const int wrap = 0;
2145 1883
2146 int regionsize = (int) Constants.RegionSize + 2; 1884 uint regionsize = Constants.RegionSize;
2147 1885
2148 float hfmin = float.MaxValue; 1886 float hfmin = float.MaxValue;
2149 float hfmax = float.MinValue; 1887 float hfmax = float.MinValue;
2150 float val; 1888 float val;
2151 int xx; 1889 uint xx;
2152 int yy; 1890 uint yy;
2153 1891
2154 int maxXXYY = regionsize - 3; 1892 uint maxXXYY = regionsize - 1;
2155 // flipping map adding one margin all around so things don't fall in edges 1893 // flipping map adding one margin all around so things don't fall in edges
2156 1894
2157 int xt = 0; 1895 uint xt = 0;
2158 xx = 0; 1896 xx = 0;
2159 1897
2160 for (int x = 0; x < heightmapWidthSamples; x++) 1898 for (uint x = 0; x < heightmapWidthSamples; x++)
2161 { 1899 {
2162 if (x > 1 && xx < maxXXYY) 1900 if (x > 1 && xx < maxXXYY)
2163 xx++; 1901 xx++;
2164 yy = 0; 1902 yy = 0;
2165 for (int y = 0; y < heightmapHeightSamples; y++) 1903 for (uint y = 0; y < heightmapHeightSamples; y++)
2166 { 1904 {
2167 if (y > 1 && y < maxXXYY) 1905 if (y > 1 && y < maxXXYY)
2168 yy += (int)Constants.RegionSize; 1906 yy += regionsize;
2169 1907
2170 val = heightMap[yy + xx]; 1908 val = heightMap[yy + xx];
2171 _heightmap[xt + y] = val; 1909 _heightmap[xt + y] = val;
@@ -2176,8 +1914,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2176 hfmax = val; 1914 hfmax = val;
2177 1915
2178 } 1916 }
2179 1917 xt += heightmapHeightSamples;
2180 xt += regionsize;
2181 } 1918 }
2182 lock (OdeLock) 1919 lock (OdeLock)
2183 { 1920 {
@@ -2230,11 +1967,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2230 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); 1967 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
2231 d.GeomSetRotation(GroundGeom, ref R); 1968 d.GeomSetRotation(GroundGeom, ref R);
2232 d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0); 1969 d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0);
2233 IntPtr testGround = IntPtr.Zero;
2234 if (RegionTerrain.TryGetValue(pOffset, out testGround))
2235 {
2236 RegionTerrain.Remove(pOffset);
2237 }
2238 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); 1970 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
2239// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap); 1971// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
2240 TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); 1972 TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);