aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorUbitUmarov2015-10-17 14:42:04 +0100
committerUbitUmarov2015-10-17 14:42:04 +0100
commit8dcb4de53ced95cd1dfea0931b1b65d4e752709b (patch)
treea34e76fb8e45ea8556d2299ce49a9d0e89ef8be9
parentbug fix. Some rare meshs reported as having +-infinity dimensions (diff)
downloadopensim-SC-8dcb4de53ced95cd1dfea0931b1b65d4e752709b.zip
opensim-SC-8dcb4de53ced95cd1dfea0931b1b65d4e752709b.tar.gz
opensim-SC-8dcb4de53ced95cd1dfea0931b1b65d4e752709b.tar.bz2
opensim-SC-8dcb4de53ced95cd1dfea0931b1b65d4e752709b.tar.xz
fix GetTerrainHeightAtXY for large regions. Also change ode dispose()
-rw-r--r--OpenSim/Region/PhysicsModules/Ode/OdeScene.cs416
1 files changed, 30 insertions, 386 deletions
diff --git a/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs
index a85d11a..f245a3b 100644
--- a/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs
+++ b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs
@@ -1988,8 +1988,9 @@ namespace OpenSim.Region.PhysicsModule.ODE
1988 1988
1989 x = x - offsetX + 1f; 1989 x = x - offsetX + 1f;
1990 y = y - offsetY + 1f; 1990 y = y - offsetY + 1f;
1991 // map is rotated
1991 1992
1992 index = (int)((int)x * ((int)Constants.RegionSize + 2) + (int)y); 1993 index = (int)x * ((int)m_regionHeight + 3) + (int)y;
1993 1994
1994 if (index < TerrainHeightFieldHeights[heightFieldGeom].Length) 1995 if (index < TerrainHeightFieldHeights[heightFieldGeom].Length)
1995 { 1996 {
@@ -2567,59 +2568,13 @@ namespace OpenSim.Region.PhysicsModule.ODE
2567 2568
2568 2569
2569 } 2570 }
2570 // we don't want to remove the main space
2571
2572 // If the geometry is in the targetspace, remove it from the target space
2573 //m_log.Warn(prim.m_targetSpace);
2574
2575 //if (prim.m_targetSpace != IntPtr.Zero)
2576 //{
2577 //if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom))
2578 //{
2579
2580 //if (d.GeomIsSpace(prim.m_targetSpace))
2581 //{
2582 //waitForSpaceUnlock(prim.m_targetSpace);
2583 //d.SpaceRemove(prim.m_targetSpace, prim.prim_geom);
2584 prim.m_targetSpace = IntPtr.Zero; 2571 prim.m_targetSpace = IntPtr.Zero;
2585 //}
2586 //else
2587 //{
2588 // m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
2589 //((OdePrim)prim).m_targetSpace.ToString());
2590 //}
2591
2592 //}
2593 //}
2594 //m_log.Warn(prim.prim_geom);
2595
2596 if (!prim.RemoveGeom()) 2572 if (!prim.RemoveGeom())
2597 m_log.Warn("[ODE SCENE]: Unable to remove prim from physics scene"); 2573 m_log.Warn("[ODE SCENE]: Unable to remove prim from physics scene");
2598 2574
2599 lock (_prims) 2575 lock (_prims)
2600 _prims.Remove(prim); 2576 _prims.Remove(prim);
2601 2577
2602 //If there are no more geometries in the sub-space, we don't need it in the main space anymore
2603 //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0)
2604 //{
2605 //if (prim.m_targetSpace != null)
2606 //{
2607 //if (d.GeomIsSpace(prim.m_targetSpace))
2608 //{
2609 //waitForSpaceUnlock(prim.m_targetSpace);
2610 //d.SpaceRemove(space, prim.m_targetSpace);
2611 // free up memory used by the space.
2612 //d.SpaceDestroy(prim.m_targetSpace);
2613 //int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position);
2614 //resetSpaceArrayItemToZero(xyspace[0], xyspace[1]);
2615 //}
2616 //else
2617 //{
2618 //m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
2619 //((OdePrim) prim).m_targetSpace.ToString());
2620 //}
2621 //}
2622 //}
2623 2578
2624 if (SupportsNINJAJoints) 2579 if (SupportsNINJAJoints)
2625 RemoveAllJointsConnectedToActorThreadLocked(prim); 2580 RemoveAllJointsConnectedToActorThreadLocked(prim);
@@ -2715,12 +2670,9 @@ namespace OpenSim.Region.PhysicsModule.ODE
2715 { 2670 {
2716 if (d.GeomIsSpace(currentspace)) 2671 if (d.GeomIsSpace(currentspace))
2717 { 2672 {
2718// waitForSpaceUnlock(currentspace);
2719// waitForSpaceUnlock(space);
2720 d.SpaceRemove(space, currentspace); 2673 d.SpaceRemove(space, currentspace);
2721 // free up memory used by the space. 2674 // free up memory used by the space.
2722 2675
2723 //d.SpaceDestroy(currentspace);
2724 resetSpaceArrayItemToZero(currentspace); 2676 resetSpaceArrayItemToZero(currentspace);
2725 } 2677 }
2726 else 2678 else
@@ -3574,274 +3526,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
3574 get { return false; } 3526 get { return false; }
3575 } 3527 }
3576 3528
3577/* godd try.. but not a fix
3578 #region ODE Specific Terrain Fixes
3579 private float[] ResizeTerrain512NearestNeighbour(float[] heightMap)
3580 {
3581 float[] returnarr = new float[262144];
3582 float[,] resultarr = new float[(int)WorldExtents.X, (int)WorldExtents.Y];
3583
3584 // Filling out the array into its multi-dimensional components
3585 for (int y = 0; y < WorldExtents.Y; y++)
3586 {
3587 for (int x = 0; x < WorldExtents.X; x++)
3588 {
3589 resultarr[y, x] = heightMap[y * (int)WorldExtents.Y + x];
3590 }
3591 }
3592
3593 // Resize using Nearest Neighbour
3594
3595 // This particular way is quick but it only works on a multiple of the original
3596
3597 // The idea behind this method can be described with the following diagrams
3598 // second pass and third pass happen in the same loop really.. just separated
3599 // them to show what this does.
3600
3601 // First Pass
3602 // ResultArr:
3603 // 1,1,1,1,1,1
3604 // 1,1,1,1,1,1
3605 // 1,1,1,1,1,1
3606 // 1,1,1,1,1,1
3607 // 1,1,1,1,1,1
3608 // 1,1,1,1,1,1
3609
3610 // Second Pass
3611 // ResultArr2:
3612 // 1,,1,,1,,1,,1,,1,
3613 // ,,,,,,,,,,
3614 // 1,,1,,1,,1,,1,,1,
3615 // ,,,,,,,,,,
3616 // 1,,1,,1,,1,,1,,1,
3617 // ,,,,,,,,,,
3618 // 1,,1,,1,,1,,1,,1,
3619 // ,,,,,,,,,,
3620 // 1,,1,,1,,1,,1,,1,
3621 // ,,,,,,,,,,
3622 // 1,,1,,1,,1,,1,,1,
3623
3624 // Third pass fills in the blanks
3625 // ResultArr2:
3626 // 1,1,1,1,1,1,1,1,1,1,1,1
3627 // 1,1,1,1,1,1,1,1,1,1,1,1
3628 // 1,1,1,1,1,1,1,1,1,1,1,1
3629 // 1,1,1,1,1,1,1,1,1,1,1,1
3630 // 1,1,1,1,1,1,1,1,1,1,1,1
3631 // 1,1,1,1,1,1,1,1,1,1,1,1
3632 // 1,1,1,1,1,1,1,1,1,1,1,1
3633 // 1,1,1,1,1,1,1,1,1,1,1,1
3634 // 1,1,1,1,1,1,1,1,1,1,1,1
3635 // 1,1,1,1,1,1,1,1,1,1,1,1
3636 // 1,1,1,1,1,1,1,1,1,1,1,1
3637
3638 // X,Y = .
3639 // X+1,y = ^
3640 // X,Y+1 = *
3641 // X+1,Y+1 = #
3642
3643 // Filling in like this;
3644 // .*
3645 // ^#
3646 // 1st .
3647 // 2nd *
3648 // 3rd ^
3649 // 4th #
3650 // on single loop.
3651
3652 float[,] resultarr2 = new float[512, 512];
3653 for (int y = 0; y < WorldExtents.Y; y++)
3654 {
3655 for (int x = 0; x < WorldExtents.X; x++)
3656 {
3657 resultarr2[y * 2, x * 2] = resultarr[y, x];
3658
3659 if (y < WorldExtents.Y)
3660 {
3661 resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x];
3662 }
3663 if (x < WorldExtents.X)
3664 {
3665 resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x];
3666 }
3667 if (x < WorldExtents.X && y < WorldExtents.Y)
3668 {
3669 resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x];
3670 }
3671 }
3672 }
3673
3674 //Flatten out the array
3675 int i = 0;
3676 for (int y = 0; y < 512; y++)
3677 {
3678 for (int x = 0; x < 512; x++)
3679 {
3680 if (resultarr2[y, x] <= 0)
3681 returnarr[i] = 0.0000001f;
3682 else
3683 returnarr[i] = resultarr2[y, x];
3684
3685 i++;
3686 }
3687 }
3688
3689 return returnarr;
3690 }
3691
3692 private float[] ResizeTerrain512Interpolation(float[] heightMap)
3693 {
3694 float[] returnarr = new float[262144];
3695 float[,] resultarr = new float[512,512];
3696
3697 // Filling out the array into its multi-dimensional components
3698 for (int y = 0; y < 256; y++)
3699 {
3700 for (int x = 0; x < 256; x++)
3701 {
3702 resultarr[y, x] = heightMap[y * 256 + x];
3703 }
3704 }
3705
3706 // Resize using interpolation
3707
3708 // This particular way is quick but it only works on a multiple of the original
3709
3710 // The idea behind this method can be described with the following diagrams
3711 // second pass and third pass happen in the same loop really.. just separated
3712 // them to show what this does.
3713
3714 // First Pass
3715 // ResultArr:
3716 // 1,1,1,1,1,1
3717 // 1,1,1,1,1,1
3718 // 1,1,1,1,1,1
3719 // 1,1,1,1,1,1
3720 // 1,1,1,1,1,1
3721 // 1,1,1,1,1,1
3722
3723 // Second Pass
3724 // ResultArr2:
3725 // 1,,1,,1,,1,,1,,1,
3726 // ,,,,,,,,,,
3727 // 1,,1,,1,,1,,1,,1,
3728 // ,,,,,,,,,,
3729 // 1,,1,,1,,1,,1,,1,
3730 // ,,,,,,,,,,
3731 // 1,,1,,1,,1,,1,,1,
3732 // ,,,,,,,,,,
3733 // 1,,1,,1,,1,,1,,1,
3734 // ,,,,,,,,,,
3735 // 1,,1,,1,,1,,1,,1,
3736
3737 // Third pass fills in the blanks
3738 // ResultArr2:
3739 // 1,1,1,1,1,1,1,1,1,1,1,1
3740 // 1,1,1,1,1,1,1,1,1,1,1,1
3741 // 1,1,1,1,1,1,1,1,1,1,1,1
3742 // 1,1,1,1,1,1,1,1,1,1,1,1
3743 // 1,1,1,1,1,1,1,1,1,1,1,1
3744 // 1,1,1,1,1,1,1,1,1,1,1,1
3745 // 1,1,1,1,1,1,1,1,1,1,1,1
3746 // 1,1,1,1,1,1,1,1,1,1,1,1
3747 // 1,1,1,1,1,1,1,1,1,1,1,1
3748 // 1,1,1,1,1,1,1,1,1,1,1,1
3749 // 1,1,1,1,1,1,1,1,1,1,1,1
3750
3751 // X,Y = .
3752 // X+1,y = ^
3753 // X,Y+1 = *
3754 // X+1,Y+1 = #
3755
3756 // Filling in like this;
3757 // .*
3758 // ^#
3759 // 1st .
3760 // 2nd *
3761 // 3rd ^
3762 // 4th #
3763 // on single loop.
3764
3765 float[,] resultarr2 = new float[512,512];
3766 for (int y = 0; y < (int)Constants.RegionSize; y++)
3767 {
3768 for (int x = 0; x < (int)Constants.RegionSize; x++)
3769 {
3770 resultarr2[y*2, x*2] = resultarr[y, x];
3771
3772 if (y < (int)Constants.RegionSize)
3773 {
3774 if (y + 1 < (int)Constants.RegionSize)
3775 {
3776 if (x + 1 < (int)Constants.RegionSize)
3777 {
3778 resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] +
3779 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
3780 }
3781 else
3782 {
3783 resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x])/2);
3784 }
3785 }
3786 else
3787 {
3788 resultarr2[(y*2) + 1, x*2] = resultarr[y, x];
3789 }
3790 }
3791 if (x < (int)Constants.RegionSize)
3792 {
3793 if (x + 1 < (int)Constants.RegionSize)
3794 {
3795 if (y + 1 < (int)Constants.RegionSize)
3796 {
3797 resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
3798 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
3799 }
3800 else
3801 {
3802 resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y, x + 1])/2);
3803 }
3804 }
3805 else
3806 {
3807 resultarr2[y*2, (x*2) + 1] = resultarr[y, x];
3808 }
3809 }
3810 if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize)
3811 {
3812 if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize))
3813 {
3814 resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
3815 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
3816 }
3817 else
3818 {
3819 resultarr2[(y*2) + 1, (x*2) + 1] = resultarr[y, x];
3820 }
3821 }
3822 }
3823 }
3824 //Flatten out the array
3825 int i = 0;
3826 for (int y = 0; y < 512; y++)
3827 {
3828 for (int x = 0; x < 512; x++)
3829 {
3830 if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x]))
3831 {
3832 m_log.Warn("[ODE SCENE]: Non finite heightfield element detected. Setting it to 0");
3833 resultarr2[y, x] = 0;
3834 }
3835 returnarr[i] = resultarr2[y, x];
3836 i++;
3837 }
3838 }
3839
3840 return returnarr;
3841 }
3842
3843 #endregion
3844*/
3845 public override void SetTerrain(float[] heightMap) 3529 public override void SetTerrain(float[] heightMap)
3846 { 3530 {
3847 if (m_worldOffset != Vector3.Zero && m_parentScene != null) 3531 if (m_worldOffset != Vector3.Zero && m_parentScene != null)
@@ -3940,9 +3624,11 @@ namespace OpenSim.Region.PhysicsModule.ODE
3940 3624
3941 } 3625 }
3942 IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); 3626 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
3943 d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapHeight, heightmapWidth, 3627 d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0,
3944 (int)heightmapHeightSamples, (int)heightmapWidthSamples, scale, 3628 heightmapWidth, heightmapHeight,
3945 offset, thickness, wrap); 3629 (int)heightmapWidthSamples,
3630 (int)heightmapHeightSamples,
3631 scale, offset, thickness, wrap);
3946 3632
3947 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); 3633 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
3948 GroundGeom = d.CreateHeightfield(space, HeightmapData, 1); 3634 GroundGeom = d.CreateHeightfield(space, HeightmapData, 1);
@@ -3997,78 +3683,24 @@ namespace OpenSim.Region.PhysicsModule.ODE
3997 public override void SetWaterLevel(float baseheight) 3683 public override void SetWaterLevel(float baseheight)
3998 { 3684 {
3999 waterlevel = baseheight; 3685 waterlevel = baseheight;
4000// randomizeWater(waterlevel);
4001 } 3686 }
4002 3687
4003/* 3688 [HandleProcessCorruptedStateExceptions]
4004 private void randomizeWater(float baseheight) 3689 public override void Dispose()
4005 { 3690 {
4006 uint heightmapWidth = m_regionWidth + 2;
4007 uint heightmapHeight = m_regionHeight + 2;
4008 uint heightmapWidthSamples = m_regionWidth + 2;
4009 uint heightmapHeightSamples = m_regionHeight + 2;
4010 float scale = 1.0f;
4011 float offset = 0.0f;
4012 float thickness = 2.9f;
4013 int wrap = 0;
4014
4015 for (int i = 0; i < (258 * 258); i++)
4016 {
4017 _watermap[i] = (baseheight-0.1f) + ((float)fluidRandomizer.Next(1,9) / 10f);
4018 // m_log.Info((baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f));
4019 }
4020
4021 lock (OdeLock) 3691 lock (OdeLock)
4022 { 3692 {
4023 if (WaterGeom != IntPtr.Zero) 3693 if(world == IntPtr.Zero)
4024 { 3694 return;
4025 d.SpaceRemove(space, WaterGeom);
4026 }
4027 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
4028 d.GeomHeightfieldDataBuildSingle(HeightmapData, _watermap, 0, heightmapWidth, heightmapHeight,
4029 (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale,
4030 offset, thickness, wrap);
4031 d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight);
4032 WaterGeom = d.CreateHeightfield(space, HeightmapData, 1);
4033 if (WaterGeom != IntPtr.Zero)
4034 {
4035 d.GeomSetCategoryBits(WaterGeom, (int)(CollisionCategories.Water));
4036 d.GeomSetCollideBits(WaterGeom, (int)(CollisionCategories.Space));
4037 }
4038
4039 geom_name_map[WaterGeom] = "Water";
4040
4041 d.Matrix3 R = new d.Matrix3();
4042
4043 Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f);
4044 Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f);
4045 //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1));
4046
4047 q1 = q1 * q2;
4048 //q1 = q1 * q3;
4049 Vector3 v3;
4050 float angle;
4051 q1.GetAxisAngle(out v3, out angle);
4052 3695
4053 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); 3696 _worldInitialized = false;
4054 d.GeomSetRotation(WaterGeom, ref R);
4055 d.GeomSetPosition(WaterGeom, 128, 128, 0);
4056 }
4057 }
4058*/
4059 [HandleProcessCorruptedStateExceptions]
4060 public override void Dispose()
4061 {
4062 _worldInitialized = false;
4063 3697
4064 if (m_rayCastManager != null) 3698 if (m_rayCastManager != null)
4065 { 3699 {
4066 m_rayCastManager.Dispose(); 3700 m_rayCastManager.Dispose();
4067 m_rayCastManager = null; 3701 m_rayCastManager = null;
4068 } 3702 }
4069 3703
4070 lock (OdeLock)
4071 {
4072 lock (_prims) 3704 lock (_prims)
4073 { 3705 {
4074 foreach (OdePrim prm in _prims) 3706 foreach (OdePrim prm in _prims)
@@ -4081,9 +3713,22 @@ namespace OpenSim.Region.PhysicsModule.ODE
4081 //{ 3713 //{
4082 //RemoveAvatar(act); 3714 //RemoveAvatar(act);
4083 //} 3715 //}
3716 IntPtr GroundGeom = IntPtr.Zero;
3717 if (RegionTerrain.TryGetValue(m_worldOffset, out GroundGeom))
3718 {
3719 RegionTerrain.Remove(m_worldOffset);
3720 if (GroundGeom != IntPtr.Zero)
3721 {
3722 if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
3723 TerrainHeightFieldHeights.Remove(GroundGeom);
3724 d.GeomDestroy(GroundGeom);
3725 }
3726 }
3727
4084 try 3728 try
4085 { 3729 {
4086 d.WorldDestroy(world); 3730 d.WorldDestroy(world);
3731 world = IntPtr.Zero;
4087 } 3732 }
4088 catch (AccessViolationException e) 3733 catch (AccessViolationException e)
4089 { 3734 {
@@ -4091,7 +3736,6 @@ namespace OpenSim.Region.PhysicsModule.ODE
4091 } 3736 }
4092 //d.CloseODE(); 3737 //d.CloseODE();
4093 } 3738 }
4094
4095 } 3739 }
4096 3740
4097 public override Dictionary<uint, float> GetTopColliders() 3741 public override Dictionary<uint, float> GetTopColliders()