* Fixes Terrain issues with combined regions.
parent
c9b52cd0b6
commit
64dcb71c14
|
@ -232,16 +232,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Exclude heightfield geom
|
// Exclude heightfield geom
|
||||||
if (g1 == m_scene.LandGeom)
|
|
||||||
return;
|
|
||||||
if (g2 == m_scene.LandGeom)
|
|
||||||
return;
|
|
||||||
if (g1 == m_scene.WaterGeom)
|
|
||||||
return;
|
|
||||||
if (g2 == m_scene.WaterGeom)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
|
if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
|
||||||
|
return;
|
||||||
|
|
||||||
// Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
|
// Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
|
||||||
if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
|
if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
|
||||||
|
|
|
@ -232,8 +232,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private float[] _watermap;
|
private float[] _watermap;
|
||||||
private bool m_filterCollisions = true;
|
private bool m_filterCollisions = true;
|
||||||
|
|
||||||
private float[] _origheightmap; // Used for Fly height. Kitto Flora
|
|
||||||
|
|
||||||
private d.NearCallback nearCallback;
|
private d.NearCallback nearCallback;
|
||||||
public d.TriCallback triCallback;
|
public d.TriCallback triCallback;
|
||||||
public d.TriArrayCallback triArrayCallback;
|
public d.TriArrayCallback triArrayCallback;
|
||||||
|
@ -257,6 +255,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private Object externalJointRequestsLock = new Object();
|
private Object externalJointRequestsLock = new Object();
|
||||||
private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = new Dictionary<String, PhysicsJoint>();
|
private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = new Dictionary<String, PhysicsJoint>();
|
||||||
private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = new Dictionary<String, PhysicsJoint>();
|
private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = new Dictionary<String, PhysicsJoint>();
|
||||||
|
private readonly DoubleDictionary<Vector3, IntPtr, IntPtr> RegionTerrain = new DoubleDictionary<Vector3, IntPtr, IntPtr>();
|
||||||
|
private readonly Dictionary<IntPtr,float[]> TerrainHeightFieldHeights = new Dictionary<IntPtr, float[]>();
|
||||||
|
|
||||||
private d.Contact contact;
|
private d.Contact contact;
|
||||||
private d.Contact TerrainContact;
|
private d.Contact TerrainContact;
|
||||||
|
@ -313,6 +313,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
private Vector3 m_worldOffset = Vector3.Zero;
|
private Vector3 m_worldOffset = Vector3.Zero;
|
||||||
public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize);
|
public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize);
|
||||||
|
private PhysicsScene m_parentScene = null;
|
||||||
|
|
||||||
private ODERayCastRequestManager m_rayCastManager;
|
private ODERayCastRequestManager m_rayCastManager;
|
||||||
|
|
||||||
|
@ -351,7 +352,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// zero out a heightmap array float array (single dimension [flattened]))
|
// zero out a heightmap array float array (single dimension [flattened]))
|
||||||
if ((int)WorldExtents.X == 256 && (int)m_worldOffset.Y == 256)
|
if ((int)Constants.RegionSize == 256)
|
||||||
_heightmap = new float[514*514];
|
_heightmap = new float[514*514];
|
||||||
else
|
else
|
||||||
_heightmap = new float[(((int)WorldExtents.Y + 2) * ((int)WorldExtents.X + 2))];
|
_heightmap = new float[(((int)WorldExtents.Y + 2) * ((int)WorldExtents.X + 2))];
|
||||||
|
@ -1564,28 +1565,60 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
m_worldOffset = offset;
|
m_worldOffset = offset;
|
||||||
WorldExtents = new Vector2(extents.X, extents.Y);
|
WorldExtents = new Vector2(extents.X, extents.Y);
|
||||||
|
m_parentScene = pScene;
|
||||||
|
|
||||||
}
|
}
|
||||||
// Recovered for use by fly height. Kitto Flora
|
// Recovered for use by fly height. Kitto Flora
|
||||||
public float GetTerrainHeightAtXY(float x, float y)
|
public float GetTerrainHeightAtXY(float x, float y)
|
||||||
|
{
|
||||||
|
|
||||||
|
int offsetX = ((int) (x/256)) * 256;
|
||||||
|
int offsetY = ((int) (y/256)) * 256;
|
||||||
|
|
||||||
|
IntPtr heightFieldGeom = IntPtr.Zero;
|
||||||
|
|
||||||
|
if (RegionTerrain.TryGetValue(new Vector3(offsetX,offsetY,0), out heightFieldGeom))
|
||||||
|
{
|
||||||
|
if (heightFieldGeom != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
if (TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
|
||||||
{
|
{
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
// Teravus: Kitto, this code causes recurring errors that stall physics permenantly unless
|
|
||||||
// the values are checked, so checking below.
|
|
||||||
// Is there any reason that we don't do this in ScenePresence?
|
|
||||||
// The only physics engine that benefits from it in the physics plugin is this one
|
|
||||||
|
|
||||||
if ((int)x > WorldExtents.X || (int)y > WorldExtents.Y ||
|
if ((int)x > WorldExtents.X || (int)y > WorldExtents.Y ||
|
||||||
(int)x < 0.001f || (int)y < 0.001f)
|
(int)x < 0.001f || (int)y < 0.001f)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
index = (int)((int)y * WorldExtents.Y + (int)x);
|
x = x - offsetX;
|
||||||
|
y = y - offsetY;
|
||||||
|
|
||||||
if (index < _origheightmap.Length)
|
index = (int)((int)y * (int)Constants.RegionSize + (int)x);
|
||||||
return (float)_origheightmap[(int)y * (int)WorldExtents.Y + (int)x];
|
|
||||||
|
if (index < TerrainHeightFieldHeights[heightFieldGeom].Length)
|
||||||
|
return (float)TerrainHeightFieldHeights[heightFieldGeom][(int)y * (int)Constants.RegionSize + (int)x];
|
||||||
else
|
else
|
||||||
return 0;
|
return 0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// End recovered. Kitto Flora
|
// End recovered. Kitto Flora
|
||||||
|
|
||||||
|
@ -2557,8 +2590,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (framecount >= int.MaxValue)
|
if (framecount >= int.MaxValue)
|
||||||
framecount = 0;
|
framecount = 0;
|
||||||
|
|
||||||
if (m_worldOffset != Vector3.Zero)
|
//if (m_worldOffset != Vector3.Zero)
|
||||||
return 0;
|
// return 0;
|
||||||
|
|
||||||
framecount++;
|
framecount++;
|
||||||
|
|
||||||
|
@ -3131,14 +3164,14 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public float[] ResizeTerrain512Interpolation(float[] heightMap)
|
public float[] ResizeTerrain512Interpolation(float[] heightMap)
|
||||||
{
|
{
|
||||||
float[] returnarr = new float[262144];
|
float[] returnarr = new float[262144];
|
||||||
float[,] resultarr = new float[(int)WorldExtents.X,(int)WorldExtents.Y];
|
float[,] resultarr = new float[512,512];
|
||||||
|
|
||||||
// Filling out the array into its multi-dimensional components
|
// Filling out the array into its multi-dimensional components
|
||||||
for (int y = 0; y < WorldExtents.Y; y++)
|
for (int y = 0; y < 256; y++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < WorldExtents.X; x++)
|
for (int x = 0; x < 256; x++)
|
||||||
{
|
{
|
||||||
resultarr[y, x] = heightMap[y*(int)WorldExtents.Y + x];
|
resultarr[y, x] = heightMap[y * 256 + x];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3202,17 +3235,17 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// on single loop.
|
// on single loop.
|
||||||
|
|
||||||
float[,] resultarr2 = new float[512,512];
|
float[,] resultarr2 = new float[512,512];
|
||||||
for (int y = 0; y < WorldExtents.Y; y++)
|
for (int y = 0; y < (int)Constants.RegionSize; y++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < WorldExtents.X; x++)
|
for (int x = 0; x < (int)Constants.RegionSize; x++)
|
||||||
{
|
{
|
||||||
resultarr2[y*2, x*2] = resultarr[y, x];
|
resultarr2[y*2, x*2] = resultarr[y, x];
|
||||||
|
|
||||||
if (y < WorldExtents.Y)
|
if (y < (int)Constants.RegionSize)
|
||||||
{
|
{
|
||||||
if (y + 1 < WorldExtents.Y)
|
if (y + 1 < (int)Constants.RegionSize)
|
||||||
{
|
{
|
||||||
if (x + 1 < WorldExtents.X)
|
if (x + 1 < (int)Constants.RegionSize)
|
||||||
{
|
{
|
||||||
resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] +
|
resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] +
|
||||||
resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
|
resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
|
||||||
|
@ -3227,11 +3260,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
resultarr2[(y*2) + 1, x*2] = resultarr[y, x];
|
resultarr2[(y*2) + 1, x*2] = resultarr[y, x];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x < WorldExtents.X)
|
if (x < (int)Constants.RegionSize)
|
||||||
{
|
{
|
||||||
if (x + 1 < WorldExtents.X)
|
if (x + 1 < (int)Constants.RegionSize)
|
||||||
{
|
{
|
||||||
if (y + 1 < WorldExtents.Y)
|
if (y + 1 < (int)Constants.RegionSize)
|
||||||
{
|
{
|
||||||
resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
|
resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
|
||||||
resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
|
resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
|
||||||
|
@ -3246,9 +3279,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
resultarr2[y*2, (x*2) + 1] = resultarr[y, x];
|
resultarr2[y*2, (x*2) + 1] = resultarr[y, x];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x < WorldExtents.X && y < WorldExtents.Y)
|
if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize)
|
||||||
{
|
{
|
||||||
if ((x + 1 < WorldExtents.X) && (y + 1 < WorldExtents.Y))
|
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] +
|
resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
|
||||||
resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
|
resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
|
||||||
|
@ -3282,44 +3315,60 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public override void SetTerrain(float[] heightMap)
|
public override void SetTerrain(float[] heightMap)
|
||||||
|
{
|
||||||
|
if (m_worldOffset != Vector3.Zero && m_parentScene != null)
|
||||||
|
{
|
||||||
|
if (m_parentScene is OdeScene)
|
||||||
|
{
|
||||||
|
((OdeScene)m_parentScene).SetTerrain(heightMap, m_worldOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetTerrain(heightMap, m_worldOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTerrain(float[] heightMap, Vector3 pOffset)
|
||||||
{
|
{
|
||||||
// this._heightmap[i] = (double)heightMap[i];
|
// this._heightmap[i] = (double)heightMap[i];
|
||||||
// dbm (danx0r) -- creating a buffer zone of one extra sample all around
|
// dbm (danx0r) -- creating a buffer zone of one extra sample all around
|
||||||
_origheightmap = heightMap; // Used for Fly height. Kitto Flora
|
//_origheightmap = heightMap;
|
||||||
uint heightmapWidth = (uint)WorldExtents.X + 1;
|
|
||||||
uint heightmapHeight = (uint)WorldExtents.Y + 1;
|
uint heightmapWidth = Constants.RegionSize + 1;
|
||||||
|
uint heightmapHeight = Constants.RegionSize + 1;
|
||||||
|
|
||||||
uint heightmapWidthSamples;
|
uint heightmapWidthSamples;
|
||||||
|
|
||||||
uint heightmapHeightSamples;
|
uint heightmapHeightSamples;
|
||||||
/*
|
|
||||||
if (((int)m_worldExtents.X) == 256 && (int)m_worldExtents.Y == 256)
|
if (((int)Constants.RegionSize) == 256)
|
||||||
{
|
{
|
||||||
heightmapWidthSamples = 2 * (uint)m_worldExtents.X + 2;
|
heightmapWidthSamples = 2 * (uint)Constants.RegionSize + 2;
|
||||||
heightmapHeightSamples = 2*(uint)m_worldExtents.Y + 2;
|
heightmapHeightSamples = 2 * (uint)Constants.RegionSize + 2;
|
||||||
heightmapWidth++;
|
heightmapWidth++;
|
||||||
heightmapHeight++;
|
heightmapHeight++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*/
|
|
||||||
heightmapWidthSamples = (uint)WorldExtents.X + 1;
|
heightmapWidthSamples = (uint)Constants.RegionSize + 1;
|
||||||
heightmapHeightSamples = (uint)WorldExtents.Y + 1;
|
heightmapHeightSamples = (uint)Constants.RegionSize + 1;
|
||||||
//}
|
}
|
||||||
|
|
||||||
const float scale = 1.0f;
|
const float scale = 1.0f;
|
||||||
const float offset = 0.0f;
|
const float offset = 0.0f;
|
||||||
const float thickness = 0.2f;
|
const float thickness = 0.2f;
|
||||||
const int wrap = 0;
|
const int wrap = 0;
|
||||||
|
|
||||||
|
int regionsize = (int) Constants.RegionSize;
|
||||||
//Double resolution
|
//Double resolution
|
||||||
//if (((int)m_worldExtents.X) == 256 && (int)m_worldExtents.Y == 256)
|
if (((int)Constants.RegionSize) == 256)
|
||||||
// heightMap = ResizeTerrain512Interpolation(heightMap);
|
heightMap = ResizeTerrain512Interpolation(heightMap);
|
||||||
|
|
||||||
|
|
||||||
//if (((int)m_worldExtents.X) == 256 && (int)m_worldExtents.Y == 256)
|
if (((int)Constants.RegionSize) == 256 && (int)Constants.RegionSize == 256)
|
||||||
// regionsize = 512;
|
regionsize = 512;
|
||||||
|
|
||||||
float hfmin = 2000;
|
float hfmin = 2000;
|
||||||
float hfmax = -2000;
|
float hfmax = -2000;
|
||||||
|
@ -3327,10 +3376,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
for (int y = 0; y < heightmapHeightSamples; y++)
|
for (int y = 0; y < heightmapHeightSamples; y++)
|
||||||
{
|
{
|
||||||
int xx = Util.Clip(x - 1, 0, (int)WorldExtents.X - 1);
|
int xx = Util.Clip(x - 1, 0, regionsize - 1);
|
||||||
int yy = Util.Clip(y - 1, 0, (int)WorldExtents.Y - 1);
|
int yy = Util.Clip(y - 1, 0, regionsize - 1);
|
||||||
|
|
||||||
float val = heightMap[yy*(int)WorldExtents.Y + xx];
|
float val = heightMap[yy * regionsize + xx];
|
||||||
_heightmap[x * heightmapHeightSamples + y] = val;
|
_heightmap[x * heightmapHeightSamples + y] = val;
|
||||||
hfmin = (val < hfmin) ? val : hfmin;
|
hfmin = (val < hfmin) ? val : hfmin;
|
||||||
hfmax = (val > hfmax) ? val : hfmax;
|
hfmax = (val > hfmax) ? val : hfmax;
|
||||||
|
@ -3339,23 +3388,34 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
lock (OdeLock)
|
lock (OdeLock)
|
||||||
{
|
{
|
||||||
if (LandGeom != IntPtr.Zero)
|
IntPtr GroundGeom = IntPtr.Zero;
|
||||||
|
if (RegionTerrain.TryGetValue(pOffset, out GroundGeom))
|
||||||
{
|
{
|
||||||
d.SpaceRemove(space, LandGeom);
|
RegionTerrain.Remove(pOffset);
|
||||||
|
if (GroundGeom != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
|
||||||
|
{
|
||||||
|
TerrainHeightFieldHeights.Remove(GroundGeom);
|
||||||
|
}
|
||||||
|
d.SpaceRemove(space, GroundGeom);
|
||||||
|
d.GeomDestroy(GroundGeom);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
|
IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
|
||||||
d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth, heightmapHeight,
|
d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth, heightmapHeight,
|
||||||
(int)heightmapWidthSamples, (int)heightmapHeightSamples, scale,
|
(int)heightmapWidthSamples, (int)heightmapHeightSamples, scale,
|
||||||
offset, thickness, wrap);
|
offset, thickness, wrap);
|
||||||
d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
|
d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
|
||||||
LandGeom = d.CreateHeightfield(space, HeightmapData, 1);
|
GroundGeom = d.CreateHeightfield(space, HeightmapData, 1);
|
||||||
if (LandGeom != IntPtr.Zero)
|
if (GroundGeom != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
d.GeomSetCategoryBits(LandGeom, (int)(CollisionCategories.Land));
|
d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land));
|
||||||
d.GeomSetCollideBits(LandGeom, (int)(CollisionCategories.Space));
|
d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space));
|
||||||
|
|
||||||
}
|
}
|
||||||
geom_name_map[LandGeom] = "Terrain";
|
geom_name_map[GroundGeom] = "Terrain";
|
||||||
|
|
||||||
d.Matrix3 R = new d.Matrix3();
|
d.Matrix3 R = new d.Matrix3();
|
||||||
|
|
||||||
|
@ -3370,8 +3430,16 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
q1.GetAxisAngle(out v3, out angle);
|
q1.GetAxisAngle(out v3, out angle);
|
||||||
|
|
||||||
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
|
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
|
||||||
d.GeomSetRotation(LandGeom, ref R);
|
d.GeomSetRotation(GroundGeom, ref R);
|
||||||
d.GeomSetPosition(LandGeom, (int)WorldExtents.X * 0.5f, (int)WorldExtents.Y * 0.5f, 0);
|
d.GeomSetPosition(GroundGeom, pOffset.X + ((int)Constants.RegionSize * 0.5f), (pOffset.Y + (int)Constants.RegionSize * 0.5f), 0);
|
||||||
|
IntPtr testGround = IntPtr.Zero;
|
||||||
|
if (RegionTerrain.TryGetValue(pOffset, out testGround))
|
||||||
|
{
|
||||||
|
RegionTerrain.Remove(pOffset);
|
||||||
|
}
|
||||||
|
RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
|
||||||
|
TerrainHeightFieldHeights.Add(GroundGeom,heightMap);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue