diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/PhysicsModules/Ode/OdeScene.cs (renamed from OpenSim/Region/Physics/OdePlugin/OdeScene.cs) | 686 |
1 files changed, 240 insertions, 446 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs index d53bd90..8cc7f28 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs | |||
@@ -25,6 +25,12 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | // changes for varsize regions | ||
29 | // note that raycasts need to have limited range | ||
30 | // (even in normal regions) | ||
31 | // or application thread stack may just blowup | ||
32 | // see RayCast(ODERayCastRequest req) | ||
33 | |||
28 | //#define USE_DRAWSTUFF | 34 | //#define USE_DRAWSTUFF |
29 | //#define SPAM | 35 | //#define SPAM |
30 | 36 | ||
@@ -38,15 +44,19 @@ using System.Runtime.InteropServices; | |||
38 | using System.Threading; | 44 | using System.Threading; |
39 | using log4net; | 45 | using log4net; |
40 | using Nini.Config; | 46 | using Nini.Config; |
47 | using Mono.Addins; | ||
41 | using Ode.NET; | 48 | using Ode.NET; |
42 | using OpenMetaverse; | 49 | using OpenMetaverse; |
43 | #if USE_DRAWSTUFF | 50 | #if USE_DRAWSTUFF |
44 | using Drawstuff.NET; | 51 | using Drawstuff.NET; |
45 | #endif | 52 | #endif |
46 | using OpenSim.Framework; | 53 | using OpenSim.Framework; |
47 | using OpenSim.Region.Physics.Manager; | 54 | using OpenSim.Region.PhysicsModules.SharedBase; |
55 | using OpenSim.Region.Framework.Scenes; | ||
56 | using OpenSim.Region.Framework.Interfaces; | ||
57 | |||
48 | 58 | ||
49 | namespace OpenSim.Region.Physics.OdePlugin | 59 | namespace OpenSim.Region.PhysicsModule.ODE |
50 | { | 60 | { |
51 | public enum StatusIndicators : int | 61 | public enum StatusIndicators : int |
52 | { | 62 | { |
@@ -101,9 +111,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
101 | Rubber = 6 | 111 | Rubber = 6 |
102 | } | 112 | } |
103 | 113 | ||
104 | public class OdeScene : PhysicsScene | 114 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ODEPhysicsScene")] |
115 | public class OdeScene : PhysicsScene, INonSharedRegionModule | ||
105 | { | 116 | { |
106 | private readonly ILog m_log; | 117 | private readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString()); |
118 | private bool m_Enabled = false; | ||
119 | |||
107 | // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); | 120 | // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); |
108 | 121 | ||
109 | /// <summary> | 122 | /// <summary> |
@@ -263,8 +276,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
263 | 276 | ||
264 | private Random fluidRandomizer = new Random(Environment.TickCount); | 277 | private Random fluidRandomizer = new Random(Environment.TickCount); |
265 | 278 | ||
266 | private const uint m_regionWidth = Constants.RegionSize; | 279 | public bool m_suportCombine = true; |
267 | private const uint m_regionHeight = Constants.RegionSize; | 280 | |
281 | private uint m_regionWidth = Constants.RegionSize; | ||
282 | private uint m_regionHeight = Constants.RegionSize; | ||
268 | 283 | ||
269 | private float ODE_STEPSIZE = 0.0178f; | 284 | private float ODE_STEPSIZE = 0.0178f; |
270 | private float metersInSpace = 29.9f; | 285 | private float metersInSpace = 29.9f; |
@@ -288,9 +303,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
288 | private int framecount = 0; | 303 | private int framecount = 0; |
289 | //private int m_returncollisions = 10; | 304 | //private int m_returncollisions = 10; |
290 | 305 | ||
291 | private readonly IntPtr contactgroup; | 306 | private IntPtr contactgroup; |
292 | 307 | ||
293 | internal IntPtr WaterGeom; | 308 | // internal IntPtr WaterGeom; |
294 | 309 | ||
295 | private float nmTerrainContactFriction = 255.0f; | 310 | private float nmTerrainContactFriction = 255.0f; |
296 | private float nmTerrainContactBounce = 0.1f; | 311 | private float nmTerrainContactBounce = 0.1f; |
@@ -507,31 +522,116 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
507 | public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); | 522 | public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); |
508 | public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); | 523 | public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); |
509 | 524 | ||
510 | // TODO: unused: private uint heightmapWidth = m_regionWidth + 1; | ||
511 | // TODO: unused: private uint heightmapHeight = m_regionHeight + 1; | ||
512 | // TODO: unused: private uint heightmapWidthSamples; | ||
513 | // TODO: unused: private uint heightmapHeightSamples; | ||
514 | |||
515 | private volatile int m_global_contactcount = 0; | 525 | private volatile int m_global_contactcount = 0; |
516 | 526 | ||
517 | private Vector3 m_worldOffset = Vector3.Zero; | 527 | private Vector3 m_worldOffset = Vector3.Zero; |
518 | public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); | 528 | public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); |
519 | private PhysicsScene m_parentScene = null; | 529 | private PhysicsScene m_parentScene = null; |
520 | 530 | ||
531 | float spacesPerMeterX; | ||
532 | float spacesPerMeterY; | ||
533 | int spaceGridMaxX; | ||
534 | int spaceGridMaxY; | ||
535 | |||
521 | private ODERayCastRequestManager m_rayCastManager; | 536 | private ODERayCastRequestManager m_rayCastManager; |
522 | 537 | ||
538 | |||
539 | #region INonSharedRegionModule | ||
540 | public string Name | ||
541 | { | ||
542 | get { return "OpenDynamicsEngine"; } | ||
543 | } | ||
544 | |||
545 | public Type ReplaceableInterface | ||
546 | { | ||
547 | get { return null; } | ||
548 | } | ||
549 | |||
550 | public void Initialise(IConfigSource source) | ||
551 | { | ||
552 | // TODO: Move this out of Startup | ||
553 | IConfig config = source.Configs["Startup"]; | ||
554 | if (config != null) | ||
555 | { | ||
556 | string physics = config.GetString("physics", string.Empty); | ||
557 | if (physics == Name) | ||
558 | { | ||
559 | m_Enabled = true; | ||
560 | m_config = source; | ||
561 | |||
562 | // We do this so that OpenSimulator on Windows loads the correct native ODE library depending on whether | ||
563 | // it's running as a 32-bit process or a 64-bit one. By invoking LoadLibary here, later DLLImports | ||
564 | // will find it already loaded later on. | ||
565 | // | ||
566 | // This isn't necessary for other platforms (e.g. Mac OSX and Linux) since the DLL used can be | ||
567 | // controlled in Ode.NET.dll.config | ||
568 | if (Util.IsWindows()) | ||
569 | Util.LoadArchSpecificWindowsDll("ode.dll"); | ||
570 | |||
571 | // Initializing ODE only when a scene is created allows alternative ODE plugins to co-habit (according to | ||
572 | // http://opensimulator.org/mantis/view.php?id=2750). | ||
573 | d.InitODE(); | ||
574 | |||
575 | } | ||
576 | } | ||
577 | |||
578 | } | ||
579 | |||
580 | public void Close() | ||
581 | { | ||
582 | } | ||
583 | |||
584 | public void AddRegion(Scene scene) | ||
585 | { | ||
586 | if (!m_Enabled) | ||
587 | return; | ||
588 | |||
589 | EngineType = Name; | ||
590 | PhysicsSceneName = EngineType + "/" + scene.RegionInfo.RegionName; | ||
591 | |||
592 | scene.RegisterModuleInterface<PhysicsScene>(this); | ||
593 | Vector3 extent = new Vector3(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, scene.RegionInfo.RegionSizeZ); | ||
594 | Initialise(extent); | ||
595 | InitialiseFromConfig(m_config); | ||
596 | |||
597 | // This may not be that good since terrain may not be avaiable at this point | ||
598 | base.Initialise(scene.PhysicsRequestAsset, | ||
599 | (scene.Heightmap != null ? scene.Heightmap.GetFloatsSerialised() : new float[(int)(extent.X * extent.Y)]), | ||
600 | (float)scene.RegionInfo.RegionSettings.WaterHeight); | ||
601 | |||
602 | } | ||
603 | |||
604 | public void RemoveRegion(Scene scene) | ||
605 | { | ||
606 | if (!m_Enabled) | ||
607 | return; | ||
608 | } | ||
609 | |||
610 | public void RegionLoaded(Scene scene) | ||
611 | { | ||
612 | if (!m_Enabled) | ||
613 | return; | ||
614 | |||
615 | mesher = scene.RequestModuleInterface<IMesher>(); | ||
616 | if (mesher == null) | ||
617 | m_log.WarnFormat("[ODE SCENE]: No mesher in {0}. Things will not work well.", PhysicsSceneName); | ||
618 | } | ||
619 | #endregion | ||
620 | |||
523 | /// <summary> | 621 | /// <summary> |
524 | /// Initiailizes the scene | 622 | /// Initiailizes the scene |
525 | /// Sets many properties that ODE requires to be stable | 623 | /// Sets many properties that ODE requires to be stable |
526 | /// These settings need to be tweaked 'exactly' right or weird stuff happens. | 624 | /// These settings need to be tweaked 'exactly' right or weird stuff happens. |
527 | /// </summary> | 625 | /// </summary> |
528 | /// <param value="name">Name of the scene. Useful in debug messages.</param> | 626 | private void Initialise(Vector3 regionExtent) |
529 | public OdeScene(string name) | ||
530 | { | 627 | { |
531 | m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name); | 628 | WorldExtents.X = regionExtent.X; |
532 | 629 | m_regionWidth = (uint)regionExtent.X; | |
533 | Name = name; | 630 | WorldExtents.Y = regionExtent.Y; |
534 | 631 | m_regionHeight = (uint)regionExtent.Y; | |
632 | |||
633 | m_suportCombine = false; | ||
634 | |||
535 | nearCallback = near; | 635 | nearCallback = near; |
536 | triCallback = TriCallback; | 636 | triCallback = TriCallback; |
537 | triArrayCallback = TriArrayCallback; | 637 | triArrayCallback = TriArrayCallback; |
@@ -550,7 +650,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
550 | viewthread.Start(); | 650 | viewthread.Start(); |
551 | #endif | 651 | #endif |
552 | 652 | ||
553 | _watermap = new float[258 * 258]; | 653 | // _watermap = new float[258 * 258]; |
554 | 654 | ||
555 | // Zero out the prim spaces array (we split our space into smaller spaces so | 655 | // Zero out the prim spaces array (we split our space into smaller spaces so |
556 | // we can hit test less. | 656 | // we can hit test less. |
@@ -571,12 +671,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
571 | } | 671 | } |
572 | #endif | 672 | #endif |
573 | 673 | ||
574 | // Initialize the mesh plugin | 674 | // Initialize from configs |
575 | public override void Initialise(IMesher meshmerizer, IConfigSource config) | 675 | private void InitialiseFromConfig(IConfigSource config) |
576 | { | 676 | { |
577 | InitializeExtraStats(); | 677 | InitializeExtraStats(); |
578 | 678 | ||
579 | mesher = meshmerizer; | ||
580 | m_config = config; | 679 | m_config = config; |
581 | // Defaults | 680 | // Defaults |
582 | 681 | ||
@@ -698,7 +797,31 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
698 | 797 | ||
699 | contacts = new d.ContactGeom[contactsPerCollision]; | 798 | contacts = new d.ContactGeom[contactsPerCollision]; |
700 | 799 | ||
701 | staticPrimspace = new IntPtr[(int)(300 / metersInSpace), (int)(300 / metersInSpace)]; | 800 | spacesPerMeterX = 1.0f / metersInSpace; |
801 | spacesPerMeterY = 1.0f / metersInSpace; | ||
802 | |||
803 | spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeterX); | ||
804 | spaceGridMaxY = (int)(WorldExtents.Y * spacesPerMeterY); | ||
805 | |||
806 | // note: limit number of spaces | ||
807 | if (spaceGridMaxX > 24) | ||
808 | { | ||
809 | spaceGridMaxX = 24; | ||
810 | spacesPerMeterX = spaceGridMaxX / WorldExtents.X; | ||
811 | } | ||
812 | if (spaceGridMaxY > 24) | ||
813 | { | ||
814 | spaceGridMaxY = 24; | ||
815 | spacesPerMeterY = spaceGridMaxY / WorldExtents.Y ; | ||
816 | } | ||
817 | |||
818 | staticPrimspace = new IntPtr[spaceGridMaxX, spaceGridMaxY]; | ||
819 | |||
820 | // make this index limits | ||
821 | spaceGridMaxX--; | ||
822 | spaceGridMaxY--; | ||
823 | |||
824 | |||
702 | 825 | ||
703 | // Centeral contact friction and bounce | 826 | // Centeral contact friction and bounce |
704 | // ckrinke 11/10/08 Enabling soft_erp but not soft_cfm until I figure out why | 827 | // ckrinke 11/10/08 Enabling soft_erp but not soft_cfm until I figure out why |
@@ -1817,7 +1940,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1817 | } | 1940 | } |
1818 | catch (AccessViolationException) | 1941 | catch (AccessViolationException) |
1819 | { | 1942 | { |
1820 | m_log.ErrorFormat("[ODE SCENE]: Unable to space collide {0}", Name); | 1943 | m_log.ErrorFormat("[ODE SCENE]: Unable to space collide {0}", PhysicsSceneName); |
1821 | } | 1944 | } |
1822 | 1945 | ||
1823 | //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y); | 1946 | //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y); |
@@ -1882,6 +2005,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1882 | 2005 | ||
1883 | public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) | 2006 | public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) |
1884 | { | 2007 | { |
2008 | if (!m_suportCombine) | ||
2009 | return; | ||
1885 | m_worldOffset = offset; | 2010 | m_worldOffset = offset; |
1886 | WorldExtents = new Vector2(extents.X, extents.Y); | 2011 | WorldExtents = new Vector2(extents.X, extents.Y); |
1887 | m_parentScene = pScene; | 2012 | m_parentScene = pScene; |
@@ -1890,12 +2015,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1890 | // Recovered for use by fly height. Kitto Flora | 2015 | // Recovered for use by fly height. Kitto Flora |
1891 | internal float GetTerrainHeightAtXY(float x, float y) | 2016 | internal float GetTerrainHeightAtXY(float x, float y) |
1892 | { | 2017 | { |
1893 | int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize; | ||
1894 | int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize; | ||
1895 | |||
1896 | IntPtr heightFieldGeom = IntPtr.Zero; | 2018 | IntPtr heightFieldGeom = IntPtr.Zero; |
2019 | int offsetX = 0; | ||
2020 | int offsetY = 0; | ||
2021 | |||
2022 | if (m_suportCombine) | ||
2023 | { | ||
2024 | offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize; | ||
2025 | offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize; | ||
2026 | } | ||
1897 | 2027 | ||
1898 | if (RegionTerrain.TryGetValue(new Vector3(offsetX,offsetY,0), out heightFieldGeom)) | 2028 | if(RegionTerrain.TryGetValue(new Vector3(offsetX,offsetY,0), out heightFieldGeom)) |
1899 | { | 2029 | { |
1900 | if (heightFieldGeom != IntPtr.Zero) | 2030 | if (heightFieldGeom != IntPtr.Zero) |
1901 | { | 2031 | { |
@@ -1909,10 +2039,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1909 | (int)x < 0.001f || (int)y < 0.001f) | 2039 | (int)x < 0.001f || (int)y < 0.001f) |
1910 | return 0; | 2040 | return 0; |
1911 | 2041 | ||
1912 | x = x - offsetX; | 2042 | x = x - offsetX + 1f; |
1913 | y = y - offsetY; | 2043 | y = y - offsetY + 1f; |
1914 | 2044 | ||
1915 | index = (int)((int)x * ((int)Constants.RegionSize + 2) + (int)y); | 2045 | index = (int)((int)x * ((int)m_regionHeight +3) + (int)y); |
1916 | 2046 | ||
1917 | if (index < TerrainHeightFieldHeights[heightFieldGeom].Length) | 2047 | if (index < TerrainHeightFieldHeights[heightFieldGeom].Length) |
1918 | { | 2048 | { |
@@ -1968,16 +2098,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1968 | 2098 | ||
1969 | #region Add/Remove Entities | 2099 | #region Add/Remove Entities |
1970 | 2100 | ||
1971 | public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) | 2101 | public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) |
1972 | { | 2102 | { |
1973 | Vector3 pos; | ||
1974 | pos.X = position.X; | ||
1975 | pos.Y = position.Y; | ||
1976 | pos.Z = position.Z; | ||
1977 | |||
1978 | OdeCharacter newAv | 2103 | OdeCharacter newAv |
1979 | = new OdeCharacter( | 2104 | = new OdeCharacter( |
1980 | avName, this, pos, size, avPIDD, avPIDP, | 2105 | avName, this, position, velocity, size, avPIDD, avPIDP, |
1981 | avCapRadius, avStandupTensor, avDensity, | 2106 | avCapRadius, avStandupTensor, avDensity, |
1982 | avMovementDivisorWalk, avMovementDivisorRun); | 2107 | avMovementDivisorWalk, avMovementDivisorRun); |
1983 | 2108 | ||
@@ -2751,16 +2876,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2751 | { | 2876 | { |
2752 | int[] returnint = new int[2]; | 2877 | int[] returnint = new int[2]; |
2753 | 2878 | ||
2754 | returnint[0] = (int) (pos.X/metersInSpace); | 2879 | returnint[0] = (int) (pos.X * spacesPerMeterX); |
2755 | 2880 | ||
2756 | if (returnint[0] > ((int) (259f/metersInSpace))) | 2881 | if (returnint[0] > spaceGridMaxX) |
2757 | returnint[0] = ((int) (259f/metersInSpace)); | 2882 | returnint[0] = spaceGridMaxX; |
2758 | if (returnint[0] < 0) | 2883 | if (returnint[0] < 0) |
2759 | returnint[0] = 0; | 2884 | returnint[0] = 0; |
2760 | 2885 | ||
2761 | returnint[1] = (int) (pos.Y/metersInSpace); | 2886 | returnint[1] = (int)(pos.Y * spacesPerMeterY); |
2762 | if (returnint[1] > ((int) (259f/metersInSpace))) | 2887 | if (returnint[1] > spaceGridMaxY) |
2763 | returnint[1] = ((int) (259f/metersInSpace)); | 2888 | returnint[1] = spaceGridMaxY; |
2764 | if (returnint[1] < 0) | 2889 | if (returnint[1] < 0) |
2765 | returnint[1] = 0; | 2890 | returnint[1] = 0; |
2766 | 2891 | ||
@@ -3086,7 +3211,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3086 | { | 3211 | { |
3087 | m_log.ErrorFormat( | 3212 | m_log.ErrorFormat( |
3088 | "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2} due to defect found when moving", | 3213 | "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2} due to defect found when moving", |
3089 | actor.Name, actor.LocalID, Name); | 3214 | actor.Name, actor.LocalID, PhysicsSceneName); |
3090 | 3215 | ||
3091 | RemoveCharacter(actor); | 3216 | RemoveCharacter(actor); |
3092 | actor.DestroyOdeStructures(); | 3217 | actor.DestroyOdeStructures(); |
@@ -3202,7 +3327,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3202 | { | 3327 | { |
3203 | m_log.ErrorFormat( | 3328 | m_log.ErrorFormat( |
3204 | "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2} due to defect found when updating position and velocity", | 3329 | "[ODE SCENE]: Removing physics character {0} {1} from physics scene {2} due to defect found when updating position and velocity", |
3205 | actor.Name, actor.LocalID, Name); | 3330 | actor.Name, actor.LocalID, PhysicsSceneName); |
3206 | 3331 | ||
3207 | RemoveCharacter(actor); | 3332 | RemoveCharacter(actor); |
3208 | actor.DestroyOdeStructures(); | 3333 | actor.DestroyOdeStructures(); |
@@ -3514,273 +3639,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3514 | get { return false; } | 3639 | get { return false; } |
3515 | } | 3640 | } |
3516 | 3641 | ||
3517 | #region ODE Specific Terrain Fixes | ||
3518 | private float[] ResizeTerrain512NearestNeighbour(float[] heightMap) | ||
3519 | { | ||
3520 | float[] returnarr = new float[262144]; | ||
3521 | float[,] resultarr = new float[(int)WorldExtents.X, (int)WorldExtents.Y]; | ||
3522 | |||
3523 | // Filling out the array into its multi-dimensional components | ||
3524 | for (int y = 0; y < WorldExtents.Y; y++) | ||
3525 | { | ||
3526 | for (int x = 0; x < WorldExtents.X; x++) | ||
3527 | { | ||
3528 | resultarr[y, x] = heightMap[y * (int)WorldExtents.Y + x]; | ||
3529 | } | ||
3530 | } | ||
3531 | |||
3532 | // Resize using Nearest Neighbour | ||
3533 | |||
3534 | // This particular way is quick but it only works on a multiple of the original | ||
3535 | |||
3536 | // The idea behind this method can be described with the following diagrams | ||
3537 | // second pass and third pass happen in the same loop really.. just separated | ||
3538 | // them to show what this does. | ||
3539 | |||
3540 | // First Pass | ||
3541 | // ResultArr: | ||
3542 | // 1,1,1,1,1,1 | ||
3543 | // 1,1,1,1,1,1 | ||
3544 | // 1,1,1,1,1,1 | ||
3545 | // 1,1,1,1,1,1 | ||
3546 | // 1,1,1,1,1,1 | ||
3547 | // 1,1,1,1,1,1 | ||
3548 | |||
3549 | // Second Pass | ||
3550 | // ResultArr2: | ||
3551 | // 1,,1,,1,,1,,1,,1, | ||
3552 | // ,,,,,,,,,, | ||
3553 | // 1,,1,,1,,1,,1,,1, | ||
3554 | // ,,,,,,,,,, | ||
3555 | // 1,,1,,1,,1,,1,,1, | ||
3556 | // ,,,,,,,,,, | ||
3557 | // 1,,1,,1,,1,,1,,1, | ||
3558 | // ,,,,,,,,,, | ||
3559 | // 1,,1,,1,,1,,1,,1, | ||
3560 | // ,,,,,,,,,, | ||
3561 | // 1,,1,,1,,1,,1,,1, | ||
3562 | |||
3563 | // Third pass fills in the blanks | ||
3564 | // ResultArr2: | ||
3565 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3566 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3567 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3568 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3569 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3570 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3571 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3572 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3573 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3574 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3575 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3576 | |||
3577 | // X,Y = . | ||
3578 | // X+1,y = ^ | ||
3579 | // X,Y+1 = * | ||
3580 | // X+1,Y+1 = # | ||
3581 | |||
3582 | // Filling in like this; | ||
3583 | // .* | ||
3584 | // ^# | ||
3585 | // 1st . | ||
3586 | // 2nd * | ||
3587 | // 3rd ^ | ||
3588 | // 4th # | ||
3589 | // on single loop. | ||
3590 | |||
3591 | float[,] resultarr2 = new float[512, 512]; | ||
3592 | for (int y = 0; y < WorldExtents.Y; y++) | ||
3593 | { | ||
3594 | for (int x = 0; x < WorldExtents.X; x++) | ||
3595 | { | ||
3596 | resultarr2[y * 2, x * 2] = resultarr[y, x]; | ||
3597 | |||
3598 | if (y < WorldExtents.Y) | ||
3599 | { | ||
3600 | resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x]; | ||
3601 | } | ||
3602 | if (x < WorldExtents.X) | ||
3603 | { | ||
3604 | resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x]; | ||
3605 | } | ||
3606 | if (x < WorldExtents.X && y < WorldExtents.Y) | ||
3607 | { | ||
3608 | resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x]; | ||
3609 | } | ||
3610 | } | ||
3611 | } | ||
3612 | |||
3613 | //Flatten out the array | ||
3614 | int i = 0; | ||
3615 | for (int y = 0; y < 512; y++) | ||
3616 | { | ||
3617 | for (int x = 0; x < 512; x++) | ||
3618 | { | ||
3619 | if (resultarr2[y, x] <= 0) | ||
3620 | returnarr[i] = 0.0000001f; | ||
3621 | else | ||
3622 | returnarr[i] = resultarr2[y, x]; | ||
3623 | |||
3624 | i++; | ||
3625 | } | ||
3626 | } | ||
3627 | |||
3628 | return returnarr; | ||
3629 | } | ||
3630 | |||
3631 | private float[] ResizeTerrain512Interpolation(float[] heightMap) | ||
3632 | { | ||
3633 | float[] returnarr = new float[262144]; | ||
3634 | float[,] resultarr = new float[512,512]; | ||
3635 | |||
3636 | // Filling out the array into its multi-dimensional components | ||
3637 | for (int y = 0; y < 256; y++) | ||
3638 | { | ||
3639 | for (int x = 0; x < 256; x++) | ||
3640 | { | ||
3641 | resultarr[y, x] = heightMap[y * 256 + x]; | ||
3642 | } | ||
3643 | } | ||
3644 | |||
3645 | // Resize using interpolation | ||
3646 | |||
3647 | // This particular way is quick but it only works on a multiple of the original | ||
3648 | |||
3649 | // The idea behind this method can be described with the following diagrams | ||
3650 | // second pass and third pass happen in the same loop really.. just separated | ||
3651 | // them to show what this does. | ||
3652 | |||
3653 | // First Pass | ||
3654 | // ResultArr: | ||
3655 | // 1,1,1,1,1,1 | ||
3656 | // 1,1,1,1,1,1 | ||
3657 | // 1,1,1,1,1,1 | ||
3658 | // 1,1,1,1,1,1 | ||
3659 | // 1,1,1,1,1,1 | ||
3660 | // 1,1,1,1,1,1 | ||
3661 | |||
3662 | // Second Pass | ||
3663 | // ResultArr2: | ||
3664 | // 1,,1,,1,,1,,1,,1, | ||
3665 | // ,,,,,,,,,, | ||
3666 | // 1,,1,,1,,1,,1,,1, | ||
3667 | // ,,,,,,,,,, | ||
3668 | // 1,,1,,1,,1,,1,,1, | ||
3669 | // ,,,,,,,,,, | ||
3670 | // 1,,1,,1,,1,,1,,1, | ||
3671 | // ,,,,,,,,,, | ||
3672 | // 1,,1,,1,,1,,1,,1, | ||
3673 | // ,,,,,,,,,, | ||
3674 | // 1,,1,,1,,1,,1,,1, | ||
3675 | |||
3676 | // Third pass fills in the blanks | ||
3677 | // ResultArr2: | ||
3678 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3679 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3680 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3681 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3682 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3683 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3684 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3685 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3686 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3687 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3688 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
3689 | |||
3690 | // X,Y = . | ||
3691 | // X+1,y = ^ | ||
3692 | // X,Y+1 = * | ||
3693 | // X+1,Y+1 = # | ||
3694 | |||
3695 | // Filling in like this; | ||
3696 | // .* | ||
3697 | // ^# | ||
3698 | // 1st . | ||
3699 | // 2nd * | ||
3700 | // 3rd ^ | ||
3701 | // 4th # | ||
3702 | // on single loop. | ||
3703 | |||
3704 | float[,] resultarr2 = new float[512,512]; | ||
3705 | for (int y = 0; y < (int)Constants.RegionSize; y++) | ||
3706 | { | ||
3707 | for (int x = 0; x < (int)Constants.RegionSize; x++) | ||
3708 | { | ||
3709 | resultarr2[y*2, x*2] = resultarr[y, x]; | ||
3710 | |||
3711 | if (y < (int)Constants.RegionSize) | ||
3712 | { | ||
3713 | if (y + 1 < (int)Constants.RegionSize) | ||
3714 | { | ||
3715 | if (x + 1 < (int)Constants.RegionSize) | ||
3716 | { | ||
3717 | resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] + | ||
3718 | resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); | ||
3719 | } | ||
3720 | else | ||
3721 | { | ||
3722 | resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x])/2); | ||
3723 | } | ||
3724 | } | ||
3725 | else | ||
3726 | { | ||
3727 | resultarr2[(y*2) + 1, x*2] = resultarr[y, x]; | ||
3728 | } | ||
3729 | } | ||
3730 | if (x < (int)Constants.RegionSize) | ||
3731 | { | ||
3732 | if (x + 1 < (int)Constants.RegionSize) | ||
3733 | { | ||
3734 | if (y + 1 < (int)Constants.RegionSize) | ||
3735 | { | ||
3736 | resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + | ||
3737 | resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); | ||
3738 | } | ||
3739 | else | ||
3740 | { | ||
3741 | resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y, x + 1])/2); | ||
3742 | } | ||
3743 | } | ||
3744 | else | ||
3745 | { | ||
3746 | resultarr2[y*2, (x*2) + 1] = resultarr[y, x]; | ||
3747 | } | ||
3748 | } | ||
3749 | if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize) | ||
3750 | { | ||
3751 | if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize)) | ||
3752 | { | ||
3753 | resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + | ||
3754 | resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); | ||
3755 | } | ||
3756 | else | ||
3757 | { | ||
3758 | resultarr2[(y*2) + 1, (x*2) + 1] = resultarr[y, x]; | ||
3759 | } | ||
3760 | } | ||
3761 | } | ||
3762 | } | ||
3763 | //Flatten out the array | ||
3764 | int i = 0; | ||
3765 | for (int y = 0; y < 512; y++) | ||
3766 | { | ||
3767 | for (int x = 0; x < 512; x++) | ||
3768 | { | ||
3769 | if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x])) | ||
3770 | { | ||
3771 | m_log.Warn("[ODE SCENE]: Non finite heightfield element detected. Setting it to 0"); | ||
3772 | resultarr2[y, x] = 0; | ||
3773 | } | ||
3774 | returnarr[i] = resultarr2[y, x]; | ||
3775 | i++; | ||
3776 | } | ||
3777 | } | ||
3778 | |||
3779 | return returnarr; | ||
3780 | } | ||
3781 | |||
3782 | #endregion | ||
3783 | |||
3784 | public override void SetTerrain(float[] heightMap) | 3642 | public override void SetTerrain(float[] heightMap) |
3785 | { | 3643 | { |
3786 | if (m_worldOffset != Vector3.Zero && m_parentScene != null) | 3644 | if (m_worldOffset != Vector3.Zero && m_parentScene != null) |
@@ -3799,73 +3657,67 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3799 | private void SetTerrain(float[] heightMap, Vector3 pOffset) | 3657 | private void SetTerrain(float[] heightMap, Vector3 pOffset) |
3800 | { | 3658 | { |
3801 | int startTime = Util.EnvironmentTickCount(); | 3659 | int startTime = Util.EnvironmentTickCount(); |
3802 | m_log.DebugFormat("[ODE SCENE]: Setting terrain for {0} with offset {1}", Name, pOffset); | 3660 | m_log.DebugFormat("[ODE SCENE]: Setting terrain for {0} with offset {1}", PhysicsSceneName, pOffset); |
3803 | 3661 | ||
3804 | // this._heightmap[i] = (double)heightMap[i]; | 3662 | |
3805 | // dbm (danx0r) -- creating a buffer zone of one extra sample all around | ||
3806 | //_origheightmap = heightMap; | ||
3807 | |||
3808 | float[] _heightmap; | 3663 | float[] _heightmap; |
3809 | 3664 | ||
3810 | // zero out a heightmap array float array (single dimension [flattened])) | 3665 | // ok im lasy this are just a aliases |
3811 | //if ((int)Constants.RegionSize == 256) | 3666 | uint regionsizeX = m_regionWidth; |
3812 | // _heightmap = new float[514 * 514]; | 3667 | uint regionsizeY = m_regionHeight; |
3813 | //else | ||
3814 | 3668 | ||
3815 | _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))]; | 3669 | // map is rotated |
3670 | uint heightmapWidth = regionsizeY + 2; | ||
3671 | uint heightmapHeight = regionsizeX + 2; | ||
3816 | 3672 | ||
3817 | uint heightmapWidth = Constants.RegionSize + 1; | 3673 | uint heightmapWidthSamples = heightmapWidth + 1; |
3818 | uint heightmapHeight = Constants.RegionSize + 1; | 3674 | uint heightmapHeightSamples = heightmapHeight + 1; |
3819 | 3675 | ||
3820 | uint heightmapWidthSamples; | 3676 | _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples]; |
3821 | 3677 | ||
3822 | uint heightmapHeightSamples; | ||
3823 | |||
3824 | //if (((int)Constants.RegionSize) == 256) | ||
3825 | //{ | ||
3826 | // heightmapWidthSamples = 2 * (uint)Constants.RegionSize + 2; | ||
3827 | // heightmapHeightSamples = 2 * (uint)Constants.RegionSize + 2; | ||
3828 | // heightmapWidth++; | ||
3829 | // heightmapHeight++; | ||
3830 | //} | ||
3831 | //else | ||
3832 | //{ | ||
3833 | |||
3834 | heightmapWidthSamples = (uint)Constants.RegionSize + 1; | ||
3835 | heightmapHeightSamples = (uint)Constants.RegionSize + 1; | ||
3836 | //} | ||
3837 | 3678 | ||
3838 | const float scale = 1.0f; | 3679 | const float scale = 1.0f; |
3839 | const float offset = 0.0f; | 3680 | const float offset = 0.0f; |
3840 | const float thickness = 0.2f; | 3681 | const float thickness = 10f; |
3841 | const int wrap = 0; | 3682 | const int wrap = 0; |
3842 | 3683 | ||
3843 | int regionsize = (int) Constants.RegionSize + 2; | ||
3844 | //Double resolution | ||
3845 | //if (((int)Constants.RegionSize) == 256) | ||
3846 | // heightMap = ResizeTerrain512Interpolation(heightMap); | ||
3847 | 3684 | ||
3685 | float hfmin = float.MaxValue; | ||
3686 | float hfmax = float.MinValue; | ||
3687 | float val; | ||
3688 | uint xx; | ||
3689 | uint yy; | ||
3848 | 3690 | ||
3849 | // if (((int)Constants.RegionSize) == 256 && (int)Constants.RegionSize == 256) | 3691 | uint maxXX = regionsizeX - 1; |
3850 | // regionsize = 512; | 3692 | uint maxYY = regionsizeY - 1; |
3851 | 3693 | ||
3852 | float hfmin = 2000; | 3694 | // flipping map adding one margin all around so things don't fall in edges |
3853 | float hfmax = -2000; | 3695 | |
3854 | 3696 | uint xt = 0; | |
3855 | for (int x = 0; x < heightmapWidthSamples; x++) | 3697 | xx = 0; |
3698 | |||
3699 | |||
3700 | for (uint x = 0; x < heightmapWidthSamples; x++) | ||
3856 | { | 3701 | { |
3857 | for (int y = 0; y < heightmapHeightSamples; y++) | 3702 | if (x > 1 && xx < maxXX) |
3703 | xx++; | ||
3704 | yy = 0; | ||
3705 | for (uint y = 0; y < heightmapHeightSamples; y++) | ||
3858 | { | 3706 | { |
3859 | int xx = Util.Clip(x - 1, 0, regionsize - 1); | 3707 | if (y > 1 && y < maxYY) |
3860 | int yy = Util.Clip(y - 1, 0, regionsize - 1); | 3708 | yy += regionsizeX; |
3861 | 3709 | ||
3862 | 3710 | val = heightMap[yy + xx]; | |
3863 | float val= heightMap[yy * (int)Constants.RegionSize + xx]; | 3711 | if (val < 0.0f) |
3864 | _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; | 3712 | val = 0.0f; |
3865 | 3713 | _heightmap[xt + y] = val; | |
3866 | hfmin = (val < hfmin) ? val : hfmin; | 3714 | |
3867 | hfmax = (val > hfmax) ? val : hfmax; | 3715 | if (hfmin > val) |
3716 | hfmin = val; | ||
3717 | if (hfmax < val) | ||
3718 | hfmax = val; | ||
3868 | } | 3719 | } |
3720 | xt += heightmapHeightSamples; | ||
3869 | } | 3721 | } |
3870 | 3722 | ||
3871 | lock (OdeLock) | 3723 | lock (OdeLock) |
@@ -3886,9 +3738,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3886 | 3738 | ||
3887 | } | 3739 | } |
3888 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); | 3740 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); |
3889 | d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth + 1, heightmapHeight + 1, | 3741 | d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, |
3890 | (int)heightmapWidthSamples + 1, (int)heightmapHeightSamples + 1, scale, | 3742 | heightmapWidth, heightmapHeight, |
3891 | offset, thickness, wrap); | 3743 | (int)heightmapWidthSamples, (int)heightmapHeightSamples, |
3744 | scale, offset, thickness, wrap); | ||
3745 | |||
3892 | d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); | 3746 | d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); |
3893 | GroundGeom = d.CreateHeightfield(space, HeightmapData, 1); | 3747 | GroundGeom = d.CreateHeightfield(space, HeightmapData, 1); |
3894 | if (GroundGeom != IntPtr.Zero) | 3748 | if (GroundGeom != IntPtr.Zero) |
@@ -3903,17 +3757,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3903 | 3757 | ||
3904 | Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); | 3758 | Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); |
3905 | Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); | 3759 | Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); |
3906 | //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1)); | ||
3907 | 3760 | ||
3908 | q1 = q1 * q2; | 3761 | q1 = q1 * q2; |
3909 | //q1 = q1 * q3; | ||
3910 | Vector3 v3; | 3762 | Vector3 v3; |
3911 | float angle; | 3763 | float angle; |
3912 | q1.GetAxisAngle(out v3, out angle); | 3764 | q1.GetAxisAngle(out v3, out angle); |
3913 | 3765 | ||
3914 | d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); | 3766 | d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); |
3915 | d.GeomSetRotation(GroundGeom, ref R); | 3767 | d.GeomSetRotation(GroundGeom, ref R); |
3916 | d.GeomSetPosition(GroundGeom, (pOffset.X + ((int)Constants.RegionSize * 0.5f)), (pOffset.Y + ((int)Constants.RegionSize * 0.5f)), 0); | 3768 | d.GeomSetPosition(GroundGeom, pOffset.X + regionsizeX * 0.5f, pOffset.Y + regionsizeY * 0.5f, 0f); |
3917 | IntPtr testGround = IntPtr.Zero; | 3769 | IntPtr testGround = IntPtr.Zero; |
3918 | if (RegionTerrain.TryGetValue(pOffset, out testGround)) | 3770 | if (RegionTerrain.TryGetValue(pOffset, out testGround)) |
3919 | { | 3771 | { |
@@ -3924,7 +3776,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3924 | } | 3776 | } |
3925 | 3777 | ||
3926 | m_log.DebugFormat( | 3778 | m_log.DebugFormat( |
3927 | "[ODE SCENE]: Setting terrain for {0} took {1}ms", Name, Util.EnvironmentTickCountSubtract(startTime)); | 3779 | "[ODE SCENE]: Setting terrain for {0} took {1}ms", PhysicsSceneName, Util.EnvironmentTickCountSubtract(startTime)); |
3928 | } | 3780 | } |
3929 | 3781 | ||
3930 | public override void DeleteTerrain() | 3782 | public override void DeleteTerrain() |
@@ -3938,89 +3790,31 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3938 | 3790 | ||
3939 | public override bool SupportsCombining() | 3791 | public override bool SupportsCombining() |
3940 | { | 3792 | { |
3941 | return true; | 3793 | return m_suportCombine; |
3942 | } | 3794 | } |
3943 | 3795 | ||
3944 | // public override void UnCombine(PhysicsScene pScene) | ||
3945 | // { | ||
3946 | // IntPtr localGround = IntPtr.Zero; | ||
3947 | //// float[] localHeightfield; | ||
3948 | // bool proceed = false; | ||
3949 | // List<IntPtr> geomDestroyList = new List<IntPtr>(); | ||
3950 | // | ||
3951 | // lock (OdeLock) | ||
3952 | // { | ||
3953 | // if (RegionTerrain.TryGetValue(Vector3.Zero, out localGround)) | ||
3954 | // { | ||
3955 | // foreach (IntPtr geom in TerrainHeightFieldHeights.Keys) | ||
3956 | // { | ||
3957 | // if (geom == localGround) | ||
3958 | // { | ||
3959 | //// localHeightfield = TerrainHeightFieldHeights[geom]; | ||
3960 | // proceed = true; | ||
3961 | // } | ||
3962 | // else | ||
3963 | // { | ||
3964 | // geomDestroyList.Add(geom); | ||
3965 | // } | ||
3966 | // } | ||
3967 | // | ||
3968 | // if (proceed) | ||
3969 | // { | ||
3970 | // m_worldOffset = Vector3.Zero; | ||
3971 | // WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); | ||
3972 | // m_parentScene = null; | ||
3973 | // | ||
3974 | // foreach (IntPtr g in geomDestroyList) | ||
3975 | // { | ||
3976 | // // removingHeightField needs to be done or the garbage collector will | ||
3977 | // // collect the terrain data before we tell ODE to destroy it causing | ||
3978 | // // memory corruption | ||
3979 | // if (TerrainHeightFieldHeights.ContainsKey(g)) | ||
3980 | // { | ||
3981 | //// float[] removingHeightField = TerrainHeightFieldHeights[g]; | ||
3982 | // TerrainHeightFieldHeights.Remove(g); | ||
3983 | // | ||
3984 | // if (RegionTerrain.ContainsKey(g)) | ||
3985 | // { | ||
3986 | // RegionTerrain.Remove(g); | ||
3987 | // } | ||
3988 | // | ||
3989 | // d.GeomDestroy(g); | ||
3990 | // //removingHeightField = new float[0]; | ||
3991 | // } | ||
3992 | // } | ||
3993 | // | ||
3994 | // } | ||
3995 | // else | ||
3996 | // { | ||
3997 | // m_log.Warn("[PHYSICS]: Couldn't proceed with UnCombine. Region has inconsistant data."); | ||
3998 | // } | ||
3999 | // } | ||
4000 | // } | ||
4001 | // } | ||
4002 | |||
4003 | public override void SetWaterLevel(float baseheight) | 3796 | public override void SetWaterLevel(float baseheight) |
4004 | { | 3797 | { |
4005 | waterlevel = baseheight; | 3798 | waterlevel = baseheight; |
4006 | randomizeWater(waterlevel); | 3799 | // randomizeWater(waterlevel); |
4007 | } | 3800 | } |
4008 | 3801 | ||
3802 | /* | ||
4009 | private void randomizeWater(float baseheight) | 3803 | private void randomizeWater(float baseheight) |
4010 | { | 3804 | { |
4011 | const uint heightmapWidth = m_regionWidth + 2; | 3805 | uint heightmapWidth = m_regionWidth + 2; |
4012 | const uint heightmapHeight = m_regionHeight + 2; | 3806 | uint heightmapHeight = m_regionHeight + 2; |
4013 | const uint heightmapWidthSamples = m_regionWidth + 2; | 3807 | uint heightmapWidthSamples = m_regionWidth + 2; |
4014 | const uint heightmapHeightSamples = m_regionHeight + 2; | 3808 | uint heightmapHeightSamples = m_regionHeight + 2; |
4015 | const float scale = 1.0f; | 3809 | float scale = 1.0f; |
4016 | const float offset = 0.0f; | 3810 | float offset = 0.0f; |
4017 | const float thickness = 2.9f; | 3811 | float thickness = 2.9f; |
4018 | const int wrap = 0; | 3812 | int wrap = 0; |
4019 | 3813 | ||
4020 | for (int i = 0; i < (258 * 258); i++) | 3814 | for (int i = 0; i < (258 * 258); i++) |
4021 | { | 3815 | { |
4022 | _watermap[i] = (baseheight-0.1f) + ((float)fluidRandomizer.Next(1,9) / 10f); | 3816 | _watermap[i] = (baseheight-0.1f) + ((float)fluidRandomizer.Next(1,9) / 10f); |
4023 | // m_log.Info((baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f)); | 3817 | // m_log.Info((baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f)); |
4024 | } | 3818 | } |
4025 | 3819 | ||
4026 | lock (OdeLock) | 3820 | lock (OdeLock) |
@@ -4031,8 +3825,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
4031 | } | 3825 | } |
4032 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); | 3826 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); |
4033 | d.GeomHeightfieldDataBuildSingle(HeightmapData, _watermap, 0, heightmapWidth, heightmapHeight, | 3827 | d.GeomHeightfieldDataBuildSingle(HeightmapData, _watermap, 0, heightmapWidth, heightmapHeight, |
4034 | (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale, | 3828 | (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale, |
4035 | offset, thickness, wrap); | 3829 | offset, thickness, wrap); |
4036 | d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight); | 3830 | d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight); |
4037 | WaterGeom = d.CreateHeightfield(space, HeightmapData, 1); | 3831 | WaterGeom = d.CreateHeightfield(space, HeightmapData, 1); |
4038 | if (WaterGeom != IntPtr.Zero) | 3832 | if (WaterGeom != IntPtr.Zero) |
@@ -4060,7 +3854,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
4060 | d.GeomSetPosition(WaterGeom, 128, 128, 0); | 3854 | d.GeomSetPosition(WaterGeom, 128, 128, 0); |
4061 | } | 3855 | } |
4062 | } | 3856 | } |
4063 | 3857 | */ | |
4064 | public override void Dispose() | 3858 | public override void Dispose() |
4065 | { | 3859 | { |
4066 | _worldInitialized = false; | 3860 | _worldInitialized = false; |
@@ -4095,8 +3889,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
4095 | lock (_prims) | 3889 | lock (_prims) |
4096 | { | 3890 | { |
4097 | List<OdePrim> orderedPrims = new List<OdePrim>(_prims); | 3891 | List<OdePrim> orderedPrims = new List<OdePrim>(_prims); |
4098 | orderedPrims.OrderByDescending(p => p.CollisionScore).Take(25); | 3892 | orderedPrims.OrderByDescending(p => p.CollisionScore); |
4099 | topColliders = orderedPrims.ToDictionary(p => p.LocalID, p => p.CollisionScore); | 3893 | topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore); |
4100 | 3894 | ||
4101 | foreach (OdePrim p in _prims) | 3895 | foreach (OdePrim p in _prims) |
4102 | p.CollisionScore = 0; | 3896 | p.CollisionScore = 0; |