public override void SetTerrain(ITerrainChannel channel, short[] heightMap)
{
m_channel = channel;
float[] _heightmap = ODETerrainHeightFieldHeights;
if (ODETerrainHeightFieldHeights == null)
_heightmap = new float[m_region.RegionSizeX*m_region.RegionSizeY];
for (int x = 0; x < m_region.RegionSizeX; x++)
{
for (int y = 0; y < m_region.RegionSizeY; y++)
{
_heightmap[(x*m_region.RegionSizeY) + y] = heightMap[y*m_region.RegionSizeX + x]/
Constants.TerrainCompression;
}
}
float hfmin = _heightmap.Min();
float hfmax = _heightmap.Max();
SimulationChangesQueue.Enqueue(() =>
{
if (RegionTerrain != IntPtr.Zero)
{
IntPtr sGeomIsIn = d.GeomGetSpace(RegionTerrain); // 20140729 -greythane- this seems to correct the spaceremove crash
if (sGeomIsIn != IntPtr.Zero) // maybe 'space' has not yet been initialized??
{
if (d.GeomIsSpace(sGeomIsIn))
d.SpaceRemove(sGeomIsIn, RegionTerrain);
}
d.GeomHeightfieldDataDestroy(RegionTerrain);
// d.SpaceRemove(space, RegionTerrain); // <<==
//d.GeomDestroy(RegionTerrain);
GC.RemoveMemoryPressure(_heightmap.Length);
}
const float scale = 1f;
const float offset = 0.0f;
float thickness = 0.2f;
const int wrap = 0;
IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
GC.AddMemoryPressure(_heightmap.Length);
//Add the memory pressure properly (note: should we be doing this since we have it in managed memory?)
//Do NOT copy it! Otherwise, it'll copy the terrain into unmanaged memory where we can't release it each time
d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0,
m_region.RegionSizeY,
m_region.RegionSizeX,
m_region.RegionSizeY,
m_region.RegionSizeX, scale,
offset, thickness, wrap);
d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1.0f,
hfmax + 1.0f);
RegionTerrain = d.CreateHeightfield(space, HeightmapData, 1);
d.GeomSetCategoryBits(RegionTerrain, (int) (CollisionCategories.Land));
d.GeomSetCollideBits(RegionTerrain, (int) (CollisionCategories.Space));
actor_name_map[RegionTerrain] = new NullObjectPhysicsActor();
d.Matrix3 R = new d.Matrix3();
Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f);
Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f);
q1 = q1*q2;
Vector3 v3;
float angle;
q1.GetAxisAngle(out v3, out angle);
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
d.GeomSetRotation(RegionTerrain, ref R);
d.GeomSetPosition(RegionTerrain, (m_region.RegionSizeX*0.5f),
(m_region.RegionSizeY*0.5f), 0);
TerrainHeightFieldHeights = heightMap;
ODETerrainHeightFieldHeights = _heightmap;
});
}