From 0d51c42f59c1d539a47f9c057469e852a5ff3868 Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Mon, 27 Feb 2012 02:10:03 +0000
Subject: update ubitODE to my current working state
---
OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 514 ++++++-----------------
1 file changed, 123 insertions(+), 391 deletions(-)
(limited to 'OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs')
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
VehicleVectorParam,
VehicleRotationParam,
VehicleFlags,
+ SetVehicle,
Null //keep this last used do dim the methods array. does nothing but pulsing the prim
}
@@ -166,8 +167,8 @@ namespace OpenSim.Region.Physics.OdePlugin
float frictionMovementMult = 0.3f;
- float TerrainBounce = 0.3f;
- float TerrainFriction = 0.3f;
+ float TerrainBounce = 0.1f;
+ float TerrainFriction = 0.1f;
public float AvatarBounce = 0.3f;
public float AvatarFriction = 0;// 0.9f * 0.5f;
@@ -989,145 +990,62 @@ namespace OpenSim.Region.Physics.OdePlugin
///
private void collision_optimized()
{
-// _perloopContact.Clear();
-// clear characts IsColliding until we do it some other way
-
lock (_characters)
{
- foreach (OdeCharacter chr in _characters)
+ try
+ {
+ foreach (OdeCharacter chr in _characters)
{
- // this are odd checks if they are needed something is wrong elsewhere
- // keep for now
- if (chr == null)
- continue;
-
- if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
- continue;
-
- chr.IsColliding = false;
- // chr.CollidingGround = false; not done here
- chr.CollidingObj = false;
+ if (chr == null || chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
+ continue;
+
+ chr.IsColliding = false;
+ // chr.CollidingGround = false; not done here
+ chr.CollidingObj = false;
+ // do colisions with static space
+ d.SpaceCollide2(StaticSpace, chr.Shell, IntPtr.Zero, nearCallback);
}
}
-
- // now let ode do its job
- // colide active things amoung them
-
- int st = Util.EnvironmentTickCount();
- int ta;
- int ts;
- try
- {
- d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback);
- }
- catch (AccessViolationException)
+ catch (AccessViolationException)
{
- m_log.Warn("[PHYSICS]: Unable to Active space collide");
+ m_log.Warn("[PHYSICS]: Unable to collide Character to static space");
}
- ta = Util.EnvironmentTickCountSubtract(st);
- // then active things with static enviroment
- try
+
+ }
+
+ // collide active prims with static enviroment
+ lock (_activeprims)
+ {
+ try
{
- d.SpaceCollide2(ActiveSpace,StaticSpace, IntPtr.Zero, nearCallback);
+ foreach (OdePrim prm in _activeprims)
+ {
+ if (d.BodyIsEnabled(prm.Body))
+ d.SpaceCollide2(StaticSpace, prm.prim_geom, IntPtr.Zero, nearCallback);
+ }
}
- catch (AccessViolationException)
+ catch (AccessViolationException)
{
- m_log.Warn("[PHYSICS]: Unable to Active to static space collide");
+ m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space");
}
- ts = Util.EnvironmentTickCountSubtract(st);
-// _perloopContact.Clear();
- }
-
- #endregion
-
-
- public float GetTerrainHeightAtXY(float x, float y)
- {
- // assumes 1m size grid and constante size square regions
- // region offset in mega position
-
- int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
- int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
-
- IntPtr heightFieldGeom = IntPtr.Zero;
-
- // get region map
- if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom))
- return 0f;
-
- if (heightFieldGeom == IntPtr.Zero)
- return 0f;
-
- if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
- return 0f;
-
- // TerrainHeightField for ODE as offset 1m
- x += 1f - offsetX;
- y += 1f - offsetY;
-
- // make position fit into array
- if (x < 0)
- x = 0;
- if (y < 0)
- y = 0;
-
- // integer indexs
- int ix;
- int iy;
- // interpolators offset
- float dx;
- float dy;
-
- int regsize = (int)Constants.RegionSize + 2; // map size see setterrain
-
- // we still have square fixed size regions
- // also flip x and y because of how map is done for ODE fliped axis
- // so ix,iy,dx and dy are inter exchanged
- if (x < regsize - 1)
- {
- iy = (int)x;
- dy = x - (float)iy;
- }
- else // out world use external height
- {
- iy = regsize - 1;
- dy = 0;
}
- if (y < regsize - 1)
+
+ // finally colide active things amoung them
+ try
{
- ix = (int)y;
- dx = y - (float)ix;
+ d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback);
}
- else
+ catch (AccessViolationException)
{
- ix = regsize - 1;
- dx = 0;
+ m_log.Warn("[PHYSICS]: Unable to collide in Active space");
}
- float h0;
- float h1;
- float h2;
-
- iy *= regsize;
- iy += ix; // all indexes have iy + ix
+// _perloopContact.Clear();
+ }
- float[] heights = TerrainHeightFieldHeights[heightFieldGeom];
+ #endregion
- if ((dx + dy) <= 1.0f)
- {
- h0 = ((float)heights[iy]); // 0,0 vertice
- h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0
- h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0
- }
- else
- {
- h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice
- h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0
- h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1
- }
- return h0 + h1 + h2;
- }
///
/// Add actor to the list that should receive collision events in the simulate loop.
@@ -1835,273 +1753,94 @@ namespace OpenSim.Region.Physics.OdePlugin
get { return (false); }
}
- #region ODE Specific Terrain Fixes
- public float[] ResizeTerrain512NearestNeighbour(float[] heightMap)
+ public float GetTerrainHeightAtXY(float x, float y)
{
- float[] returnarr = new float[262144];
- float[,] resultarr = new float[(int)WorldExtents.X, (int)WorldExtents.Y];
+ // assumes 1m size grid and constante size square regions
+ // needs to know about sims around in future
+ // region offset in mega position
- // Filling out the array into its multi-dimensional components
- for (int y = 0; y < WorldExtents.Y; y++)
- {
- for (int x = 0; x < WorldExtents.X; x++)
- {
- resultarr[y, x] = heightMap[y * (int)WorldExtents.Y + x];
- }
- }
+ int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
+ int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
- // Resize using Nearest Neighbour
-
- // This particular way is quick but it only works on a multiple of the original
-
- // The idea behind this method can be described with the following diagrams
- // second pass and third pass happen in the same loop really.. just separated
- // them to show what this does.
-
- // First Pass
- // ResultArr:
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
-
- // Second Pass
- // ResultArr2:
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
-
- // Third pass fills in the blanks
- // ResultArr2:
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
-
- // X,Y = .
- // X+1,y = ^
- // X,Y+1 = *
- // X+1,Y+1 = #
-
- // Filling in like this;
- // .*
- // ^#
- // 1st .
- // 2nd *
- // 3rd ^
- // 4th #
- // on single loop.
-
- float[,] resultarr2 = new float[512, 512];
- for (int y = 0; y < WorldExtents.Y; y++)
- {
- for (int x = 0; x < WorldExtents.X; x++)
- {
- resultarr2[y * 2, x * 2] = resultarr[y, x];
+ IntPtr heightFieldGeom = IntPtr.Zero;
- if (y < WorldExtents.Y)
- {
- resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x];
- }
- if (x < WorldExtents.X)
- {
- resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x];
- }
- if (x < WorldExtents.X && y < WorldExtents.Y)
- {
- resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x];
- }
- }
- }
+ // get region map
+ if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom))
+ return 0f;
- //Flatten out the array
- int i = 0;
- for (int y = 0; y < 512; y++)
- {
- for (int x = 0; x < 512; x++)
- {
- if (resultarr2[y, x] <= 0)
- returnarr[i] = 0.0000001f;
- else
- returnarr[i] = resultarr2[y, x];
+ if (heightFieldGeom == IntPtr.Zero)
+ return 0f;
- i++;
- }
- }
+ if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
+ return 0f;
- return returnarr;
- }
+ // TerrainHeightField for ODE as offset 1m
+ x += 1f - offsetX;
+ y += 1f - offsetY;
- public float[] ResizeTerrain512Interpolation(float[] heightMap)
- {
- float[] returnarr = new float[262144];
- float[,] resultarr = new float[512,512];
+ // make position fit into array
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ y = 0;
+
+ // integer indexs
+ int ix;
+ int iy;
+ // interpolators offset
+ float dx;
+ float dy;
+
+ int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples
- // Filling out the array into its multi-dimensional components
- for (int y = 0; y < 256; y++)
+ // we still have square fixed size regions
+ // also flip x and y because of how map is done for ODE fliped axis
+ // so ix,iy,dx and dy are inter exchanged
+ if (x < regsize - 1)
{
- for (int x = 0; x < 256; x++)
- {
- resultarr[y, x] = heightMap[y * 256 + x];
- }
+ iy = (int)x;
+ dy = x - (float)iy;
}
-
- // Resize using interpolation
-
- // This particular way is quick but it only works on a multiple of the original
-
- // The idea behind this method can be described with the following diagrams
- // second pass and third pass happen in the same loop really.. just separated
- // them to show what this does.
-
- // First Pass
- // ResultArr:
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
-
- // Second Pass
- // ResultArr2:
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
-
- // Third pass fills in the blanks
- // ResultArr2:
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
-
- // X,Y = .
- // X+1,y = ^
- // X,Y+1 = *
- // X+1,Y+1 = #
-
- // Filling in like this;
- // .*
- // ^#
- // 1st .
- // 2nd *
- // 3rd ^
- // 4th #
- // on single loop.
-
- float[,] resultarr2 = new float[512,512];
- for (int y = 0; y < (int)Constants.RegionSize; y++)
+ else // out world use external height
{
- for (int x = 0; x < (int)Constants.RegionSize; x++)
- {
- resultarr2[y*2, x*2] = resultarr[y, x];
-
- if (y < (int)Constants.RegionSize)
- {
- if (y + 1 < (int)Constants.RegionSize)
- {
- if (x + 1 < (int)Constants.RegionSize)
- {
- resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] +
- resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
- }
- else
- {
- resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x])/2);
- }
- }
- else
- {
- resultarr2[(y*2) + 1, x*2] = resultarr[y, x];
- }
- }
- if (x < (int)Constants.RegionSize)
- {
- if (x + 1 < (int)Constants.RegionSize)
- {
- if (y + 1 < (int)Constants.RegionSize)
- {
- resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
- resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
- }
- else
- {
- resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y, x + 1])/2);
- }
- }
- else
- {
- resultarr2[y*2, (x*2) + 1] = resultarr[y, x];
- }
- }
- if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize)
- {
- if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize))
- {
- resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
- resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
- }
- else
- {
- resultarr2[(y*2) + 1, (x*2) + 1] = resultarr[y, x];
- }
- }
- }
+ iy = regsize - 1;
+ dy = 0;
}
- //Flatten out the array
- int i = 0;
- for (int y = 0; y < 512; y++)
+ if (y < regsize - 1)
{
- for (int x = 0; x < 512; x++)
- {
- if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x]))
- {
- m_log.Warn("[PHYSICS]: Non finite heightfield element detected. Setting it to 0");
- resultarr2[y, x] = 0;
- }
- returnarr[i] = resultarr2[y, x];
- i++;
- }
+ ix = (int)y;
+ dx = y - (float)ix;
+ }
+ else
+ {
+ ix = regsize - 1;
+ dx = 0;
}
- return returnarr;
- }
+ float h0;
+ float h1;
+ float h2;
- #endregion
+ iy *= regsize;
+ iy += ix; // all indexes have iy + ix
+ float[] heights = TerrainHeightFieldHeights[heightFieldGeom];
+
+ if ((dx + dy) <= 1.0f)
+ {
+ h0 = ((float)heights[iy]); // 0,0 vertice
+ h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0
+ h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0
+ }
+ else
+ {
+ h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice
+ h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0
+ h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1
+ }
+
+ return h0 + h1 + h2;
+ }
public override void SetTerrain(float[] heightMap)
{
if (m_worldOffset != Vector3.Zero && m_parentScene != null)
@@ -2124,48 +1863,47 @@ namespace OpenSim.Region.Physics.OdePlugin
public void SetTerrain(float[] heightMap, Vector3 pOffset)
{
+ // assumes 1m size grid and constante size square regions
+ // needs to know about sims around in future
float[] _heightmap;
- _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))];
uint heightmapWidth = Constants.RegionSize + 2;
uint heightmapHeight = Constants.RegionSize + 2;
- uint heightmapWidthSamples;
+ uint heightmapWidthSamples = heightmapWidth + 1;
+ uint heightmapHeightSamples = heightmapHeight + 1;
- uint heightmapHeightSamples;
-
- heightmapWidthSamples = (uint)Constants.RegionSize + 2;
- heightmapHeightSamples = (uint)Constants.RegionSize + 2;
+ _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples];
const float scale = 1.0f;
const float offset = 0.0f;
const float thickness = 10f;
const int wrap = 0;
- int regionsize = (int) Constants.RegionSize + 2;
+ uint regionsize = Constants.RegionSize;
float hfmin = float.MaxValue;
float hfmax = float.MinValue;
float val;
- int xx;
- int yy;
+ uint xx;
+ uint yy;
- int maxXXYY = regionsize - 3;
+ uint maxXXYY = regionsize - 1;
// flipping map adding one margin all around so things don't fall in edges
- int xt = 0;
+ uint xt = 0;
xx = 0;
- for (int x = 0; x < heightmapWidthSamples; x++)
+ for (uint x = 0; x < heightmapWidthSamples; x++)
{
if (x > 1 && xx < maxXXYY)
xx++;
yy = 0;
- for (int y = 0; y < heightmapHeightSamples; y++)
+ for (uint y = 0; y < heightmapHeightSamples; y++)
{
if (y > 1 && y < maxXXYY)
- yy += (int)Constants.RegionSize;
+ yy += regionsize;
val = heightMap[yy + xx];
_heightmap[xt + y] = val;
@@ -2176,8 +1914,7 @@ namespace OpenSim.Region.Physics.OdePlugin
hfmax = val;
}
-
- xt += regionsize;
+ xt += heightmapHeightSamples;
}
lock (OdeLock)
{
@@ -2230,11 +1967,6 @@ namespace OpenSim.Region.Physics.OdePlugin
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
d.GeomSetRotation(GroundGeom, ref R);
d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0);
- IntPtr testGround = IntPtr.Zero;
- if (RegionTerrain.TryGetValue(pOffset, out testGround))
- {
- RegionTerrain.Remove(pOffset);
- }
RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);
--
cgit v1.1