ubOde: remove support for old native ODE lib; make inplace terrain changes, if possible

0.9.1.0-post-fixes
UbitUmarov 2018-11-12 11:12:52 +00:00
parent 9185d397df
commit c05598fe62
3 changed files with 126 additions and 310 deletions

View File

@ -743,10 +743,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
return CreateiOSTerrain(space, data, bPlaceable);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity]
internal static extern IntPtr CreateiGeom(int classnum);
internal static IntPtr CreateGeom(int classnum)
@ -794,8 +790,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
NTotalGeoms++;
return CreateiTriMesh(space, data, callback, arrayCallback, rayCallback);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity]
internal static extern dReal Dot(ref dReal X0, ref dReal X1, int n);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDQfromW"), SuppressUnmanagedCodeSecurity]
internal static extern void DQfromW(dReal[] dq, ref Vector3 w, ref Quaternion q);
@ -884,9 +878,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity]
internal static extern void GeomGetAABB(IntPtr geom, out AABB aabb);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity]
internal static extern void GeomGetAABB(IntPtr geom, out dReal minX);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetBody"), SuppressUnmanagedCodeSecurity]
internal static extern IntPtr GeomGetBody(IntPtr geom);

View File

@ -55,15 +55,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde
SafeNativeMethods.InitODE();
string ode_config = SafeNativeMethods.GetConfiguration();
if (ode_config != null && ode_config != "")
if (ode_config == null || ode_config == "" || !ode_config.Contains("ODE_OPENSIM"))
{
m_log.Error("[ubODE] Native ode library version not supported");
m_Enabled = false;
return;
}
m_log.InfoFormat("[ubODE] ode library configuration: {0}", ode_config);
if (ode_config.Contains("ODE_OPENSIM"))
{
OSOdeLib = true;
}
}
}
}
}

View File

@ -190,8 +190,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
// this netx dimensions are only relevant for terrain partition (mega regions)
// WorldExtents below has the simulation dimensions
// they should be identical except on mega regions
private uint m_regionWidth = Constants.RegionSize;
private uint m_regionHeight = Constants.RegionSize;
private int m_regionWidth = (int)Constants.RegionSize;
private int m_regionHeight = (int)Constants.RegionSize;
public float ODE_STEPSIZE = 0.020f;
public float HalfOdeStep = 0.01f;
@ -255,9 +255,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde
public ContactData[] m_materialContactsData = new ContactData[8];
private IntPtr TerrainGeom;
private float[] TerrainHeightFieldHeight;
private GCHandle TerrainHeightFieldHeightsHandler = new GCHandle();
private IntPtr m_terrainGeom;
private float[] m_terrainHeights;
private GCHandle m_terrainHeightsHandler = new GCHandle();
private IntPtr HeightmapData;
private int m_lastRegionWidth;
private int m_lastRegionHeight;
private int m_physicsiterations = 15;
private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag
@ -326,10 +329,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
m_frameWorkScene.RegisterModuleInterface<PhysicsScene>(this);
Initialization();
base.Initialise(m_frameWorkScene.PhysicsRequestAsset,
(m_frameWorkScene.Heightmap != null ? m_frameWorkScene.Heightmap.GetFloatsSerialised() : new float[m_frameWorkScene.RegionInfo.RegionSizeX * m_frameWorkScene.RegionInfo.RegionSizeY]),
(float)m_frameWorkScene.RegionInfo.RegionSettings.WaterHeight);
}
public void RegionLoaded()
@ -360,9 +359,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde
m_rayCastManager = new ODERayCastRequestManager(this);
WorldExtents.X = m_frameWorkScene.RegionInfo.RegionSizeX;
m_regionWidth = (uint)WorldExtents.X;
m_regionWidth = (int)WorldExtents.X;
WorldExtents.Y = m_frameWorkScene.RegionInfo.RegionSizeY;
m_regionHeight = (uint)WorldExtents.Y;
m_regionHeight = (int)WorldExtents.Y;
lock (OdeLock)
{
@ -549,6 +548,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde
m_lastframe = Util.GetTimeStamp();
m_lastMeshExpire = m_lastframe;
step_time = -1;
base.Initialise(m_frameWorkScene.PhysicsRequestAsset,
(m_frameWorkScene.Heightmap != null ? m_frameWorkScene.Heightmap.GetFloatsSerialised() : new float[m_frameWorkScene.RegionInfo.RegionSizeX * m_frameWorkScene.RegionInfo.RegionSizeY]),
(float)m_frameWorkScene.RegionInfo.RegionSettings.WaterHeight);
}
internal void waitForSpaceUnlock(IntPtr space)
@ -1867,10 +1871,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde
public float GetTerrainHeightAtXY(float x, float y)
{
if (TerrainGeom == IntPtr.Zero)
if (m_terrainGeom == IntPtr.Zero)
return 0f;
if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0)
if (m_terrainHeights == null || m_terrainHeights.Length == 0)
return 0f;
// TerrainHeightField for ODE as offset 1m
@ -1894,8 +1898,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
int regsizeY = (int)m_regionHeight + 3; // map size see setterrain number of samples
int regsize = regsizeX;
if (m_OSOdeLib)
{
if (x < regsizeX - 1)
{
ix = (int)x;
@ -1916,36 +1918,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
iy = regsizeY - 2;
dy = 0;
}
}
else
{
// 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
regsize = regsizeY;
if (x < regsizeX - 1)
{
iy = (int)x;
dy = x - (float)iy;
}
else // out world use external height
{
iy = regsizeX - 2;
dy = 0;
}
if (y < regsizeY - 1)
{
ix = (int)y;
dx = y - (float)ix;
}
else
{
ix = regsizeY - 2;
dx = 0;
}
}
float h0;
float h1;
@ -1954,7 +1926,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
iy *= regsize;
iy += ix; // all indexes have iy + ix
float[] heights = TerrainHeightFieldHeight;
float[] heights = m_terrainHeights;
/*
if ((dx + dy) <= 1.0f)
{
@ -1993,10 +1965,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde
{
Vector3 norm = new Vector3(0, 0, 1);
if (TerrainGeom == IntPtr.Zero)
if (m_terrainGeom == IntPtr.Zero)
return norm;
if (TerrainHeightFieldHeight == null || TerrainHeightFieldHeight.Length == 0)
if (m_terrainHeights == null || m_terrainHeights.Length == 0)
return norm;
// TerrainHeightField for ODE as offset 1m
@ -2024,8 +1996,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
int ystep = regsizeX;
bool firstTri = false;
if (m_OSOdeLib)
{
if (x < regsizeX - 1)
{
ix = (int)x;
@ -2047,39 +2017,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
dy = 0;
}
firstTri = dy > dx;
}
else
{
xstep = regsizeY;
ystep = 1;
regsize = regsizeY;
// 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 < regsizeX - 1)
{
iy = (int)x;
dy = x - (float)iy;
}
else // out world use external height
{
iy = regsizeX - 2;
dy = 0;
}
if (y < regsizeY - 1)
{
ix = (int)y;
dx = y - (float)ix;
}
else
{
ix = regsizeY - 2;
dx = 0;
}
firstTri = dx > dy;
}
float h0;
float h1;
@ -2088,7 +2025,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
iy *= regsize;
iy += ix; // all indexes have iy + ix
float[] heights = TerrainHeightFieldHeight;
float[] heights = m_terrainHeights;
if (firstTri)
{
@ -2113,167 +2050,96 @@ namespace OpenSim.Region.PhysicsModule.ubOde
return norm;
}
public override void SetTerrain(float[] heightMap)
private void InitTerrain()
{
if (m_OSOdeLib)
OSSetTerrain(heightMap);
else
OriSetTerrain(heightMap);
}
public void OriSetTerrain(float[] heightMap)
{
// assumes 1m size grid and constante size square regions
// needs to know about sims around in future
float[] _heightmap;
uint regionsizeX = m_regionWidth;
uint regionsizeY = m_regionHeight;
// map is rotated
uint heightmapWidth = regionsizeY + 2;
uint heightmapHeight = regionsizeX + 2;
uint heightmapWidthSamples = heightmapWidth + 1;
uint heightmapHeightSamples = heightmapHeight + 1;
_heightmap = new float[heightmapWidthSamples * heightmapHeightSamples];
const float scale = 1.0f;
const float offset = 0.0f;
const float thickness = 10f;
const int wrap = 0;
float hfmin = float.MaxValue;
float hfmax = float.MinValue;
float val;
uint xx;
uint yy;
uint maxXX = regionsizeX - 1;
uint maxYY = regionsizeY - 1;
// flipping map adding one margin all around so things don't fall in edges
uint xt = 0;
xx = 0;
for (uint x = 0; x < heightmapWidthSamples; x++)
{
if (x > 1 && xx < maxXX)
xx++;
yy = 0;
for (uint y = 0; y < heightmapHeightSamples; y++)
{
if (y > 1 && y < maxYY)
yy += regionsizeX;
val = heightMap[yy + xx];
if (val < -100.0f)
val = -100.0f;
_heightmap[xt + y] = val;
if (hfmin > val)
hfmin = val;
if (hfmax < val)
hfmax = val;
}
xt += heightmapHeightSamples;
}
lock (OdeLock)
{
SafeNativeMethods.AllocateODEDataForThread(~0U);
if (TerrainGeom != IntPtr.Zero)
if (m_terrainGeom != IntPtr.Zero)
{
actor_name_map.Remove(TerrainGeom);
SafeNativeMethods.GeomDestroy(TerrainGeom);
actor_name_map.Remove(m_terrainGeom);
SafeNativeMethods.GeomDestroy(m_terrainGeom);
}
if (TerrainHeightFieldHeightsHandler.IsAllocated)
TerrainHeightFieldHeightsHandler.Free();
if (m_terrainHeightsHandler.IsAllocated)
m_terrainHeightsHandler.Free();
m_terrainHeights = null;
IntPtr HeightmapData = SafeNativeMethods.GeomHeightfieldDataCreate();
int heightmapWidthSamples = m_regionWidth + 3;
int heightmapHeightSamples = m_regionHeight + 3;
TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned);
m_terrainHeights = new float[heightmapWidthSamples * heightmapHeightSamples];
m_terrainHeightsHandler = GCHandle.Alloc(m_terrainHeights, GCHandleType.Pinned);
SafeNativeMethods.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0,
heightmapHeight, heightmapWidth ,
(int)heightmapHeightSamples, (int)heightmapWidthSamples, scale,
offset, thickness, wrap);
m_lastRegionWidth = m_regionWidth;
SafeNativeMethods.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
HeightmapData = SafeNativeMethods.GeomOSTerrainDataCreate();
SafeNativeMethods.GeomOSTerrainDataBuild(HeightmapData, m_terrainHeightsHandler.AddrOfPinnedObject(), 0, 1.0f,
heightmapWidthSamples, heightmapHeightSamples,
1, 0);
TerrainGeom = SafeNativeMethods.CreateHeightfield(GroundSpace, HeightmapData, 1);
if (TerrainGeom != IntPtr.Zero)
m_terrainGeom = SafeNativeMethods.CreateOSTerrain(GroundSpace, HeightmapData, 1);
if (m_terrainGeom != IntPtr.Zero)
{
SafeNativeMethods.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land));
SafeNativeMethods.GeomSetCollideBits(TerrainGeom, 0);
SafeNativeMethods.GeomSetCategoryBits(m_terrainGeom, (uint)(CollisionCategories.Land));
SafeNativeMethods.GeomSetCollideBits(m_terrainGeom, 0);
PhysicsActor pa = new NullPhysicsActor();
pa.Name = "Terrain";
pa.PhysicsActorType = (int)ActorTypes.Ground;
actor_name_map[TerrainGeom] = pa;
actor_name_map[m_terrainGeom] = pa;
// geom_name_map[GroundGeom] = "Terrain";
//geom_name_map[GroundGeom] = "Terrain";
SafeNativeMethods.Quaternion q = new SafeNativeMethods.Quaternion();
q.X = 0.5f;
q.Y = 0.5f;
q.Z = 0.5f;
q.W = 0.5f;
SafeNativeMethods.GeomSetQuaternion(TerrainGeom, ref q);
SafeNativeMethods.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f);
TerrainHeightFieldHeight = _heightmap;
SafeNativeMethods.GeomSetPosition(m_terrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f);
}
else
TerrainHeightFieldHeightsHandler.Free();
m_terrainHeightsHandler.Free();
}
}
public void OSSetTerrain(float[] heightMap)
public override void SetTerrain(float[] heightMap)
{
// assumes 1m size grid and constante size square regions
// needs to know about sims around in future
float[] _heightmap;
if(m_regionWidth != m_lastRegionWidth ||
m_regionHeight != m_lastRegionHeight ||
!m_terrainHeightsHandler.IsAllocated ||
m_terrainGeom == IntPtr.Zero)
InitTerrain();
uint regionsizeX = m_regionWidth;
uint regionsizeY = m_regionHeight;
int regionsizeX = m_regionWidth;
int regionsizeY = m_regionHeight;
uint heightmapWidth = regionsizeX + 2;
uint heightmapHeight = regionsizeY + 2;
int heightmapWidth = regionsizeX + 2;
int heightmapHeight = regionsizeY + 2;
uint heightmapWidthSamples = heightmapWidth + 1;
uint heightmapHeightSamples = heightmapHeight + 1;
int heightmapWidthSamples = heightmapWidth + 1;
int heightmapHeightSamples = heightmapHeight + 1;
_heightmap = new float[heightmapWidthSamples * heightmapHeightSamples];
float hfmin = float.MaxValue;
// float hfmax = float.MinValue;
float val;
uint maxXX = regionsizeX + 1;
uint maxYY = regionsizeY + 1;
int maxXX = regionsizeX + 1;
int maxYY = regionsizeY + 1;
// adding one margin all around so things don't fall in edges
uint xx;
uint yy = 0;
uint yt = 0;
int xx;
int yy = 0;
int yt = 0;
float minH = float.MaxValue;
float maxH = float.MinValue;
for (uint y = 0; y < heightmapHeightSamples; y++)
for (int y = 0; y < heightmapHeightSamples; y++)
{
if (y > 1 && y < maxYY)
yy += regionsizeX;
xx = 0;
for (uint x = 0; x < heightmapWidthSamples; x++)
lock(OdeLock)
{
for (int x = 0; x < heightmapWidthSamples; x++)
{
if (x > 1 && x < maxXX)
xx++;
@ -2281,61 +2147,20 @@ namespace OpenSim.Region.PhysicsModule.ubOde
val = heightMap[yy + xx];
if (val < -100.0f)
val = -100.0f;
_heightmap[yt + x] = val;
if (hfmin > val)
hfmin = val;
// if (hfmax < val)
// hfmax = val;
if(val > maxH)
maxH = val;
if(val < minH)
minH = val;
m_terrainHeights[yt + x] = val;
}
}
yt += heightmapWidthSamples;
}
lock (OdeLock)
{
if (TerrainGeom != IntPtr.Zero)
{
actor_name_map.Remove(TerrainGeom);
SafeNativeMethods.GeomDestroy(TerrainGeom);
}
if (TerrainHeightFieldHeightsHandler.IsAllocated)
TerrainHeightFieldHeightsHandler.Free();
TerrainHeightFieldHeight = null;
IntPtr HeightmapData = SafeNativeMethods.GeomOSTerrainDataCreate();
const int wrap = 0;
float thickness = hfmin;
if (thickness < 0)
thickness = 1;
TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned);
SafeNativeMethods.GeomOSTerrainDataBuild(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, 1.0f,
(int)heightmapWidthSamples, (int)heightmapHeightSamples,
thickness, wrap);
// d.GeomOSTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
TerrainGeom = SafeNativeMethods.CreateOSTerrain(GroundSpace, HeightmapData, 1);
if (TerrainGeom != IntPtr.Zero)
{
SafeNativeMethods.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land));
SafeNativeMethods.GeomSetCollideBits(TerrainGeom, 0);
PhysicsActor pa = new NullPhysicsActor();
pa.Name = "Terrain";
pa.PhysicsActorType = (int)ActorTypes.Ground;
actor_name_map[TerrainGeom] = pa;
// geom_name_map[GroundGeom] = "Terrain";
SafeNativeMethods.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f);
TerrainHeightFieldHeight = _heightmap;
}
else
TerrainHeightFieldHeightsHandler.Free();
SafeNativeMethods.GeomOSTerrainDataSetBounds(HeightmapData, minH, maxH);
SafeNativeMethods.GeomSetPosition(m_terrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f);
}
}
@ -2394,14 +2219,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde
foreach (OdeCharacter ch in chtorem)
ch.DoAChange(changes.Remove, null);
if (TerrainGeom != IntPtr.Zero)
SafeNativeMethods.GeomDestroy(TerrainGeom);
TerrainGeom = IntPtr.Zero;
if (m_terrainGeom != IntPtr.Zero)
SafeNativeMethods.GeomDestroy(m_terrainGeom);
m_terrainGeom = IntPtr.Zero;
if (TerrainHeightFieldHeightsHandler.IsAllocated)
TerrainHeightFieldHeightsHandler.Free();
if (m_terrainHeightsHandler.IsAllocated)
m_terrainHeightsHandler.Free();
TerrainHeightFieldHeight = null;
m_terrainHeights = null;
m_lastRegionWidth = 0;
m_lastRegionHeight = 0;
if (ContactgeomsArray != IntPtr.Zero)
{