diff options
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r-- | OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 163 | ||||
-rw-r--r-- | OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs | 28 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | 110 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 321 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | 1 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 514 |
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); |