chODE and ubitODE always return prim mass (they where returning object mass on physical prims) so SOG can do the total add. (ubitODE as more code to use a simpler terrain geom on a modified ode lib but should do autodetect and work with normal lib).

avinationmerge
UbitUmarov 2012-04-09 20:58:40 +01:00
parent 87fdb2ed7e
commit 39079a62c0
4 changed files with 320 additions and 74 deletions

View File

@ -179,6 +179,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public bool m_outofBounds; public bool m_outofBounds;
private float m_density = 10.000006836f; // Aluminum g/cm3; private float m_density = 10.000006836f; // Aluminum g/cm3;
private float m_primMass = 10.000006836f; // Aluminum g/cm3;
private byte m_shapetype; private byte m_shapetype;
private byte m_taintshapetype; private byte m_taintshapetype;
@ -538,7 +540,11 @@ namespace OpenSim.Region.Physics.OdePlugin
public override float Mass public override float Mass
{ {
get { return CalculateMass(); } get
{
CalculateMass();
return m_primMass;
}
} }
public override Vector3 Force public override Vector3 Force
@ -1316,6 +1322,9 @@ namespace OpenSim.Region.Physics.OdePlugin
m_primMass = returnMass;
if (m_primMass > _parent_scene.maximumMassObject)
m_primMass = _parent_scene.maximumMassObject;
// Recursively calculate mass // Recursively calculate mass
bool HasChildPrim = false; bool HasChildPrim = false;

View File

@ -395,7 +395,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public override float Mass public override float Mass
{ {
get { return _mass; } get { return primMass; }
} }
public override Vector3 Force public override Vector3 Force

View File

@ -113,10 +113,11 @@ namespace OdeAPI
HashSpaceClass, HashSpaceClass,
QuadTreeSpaceClass, QuadTreeSpaceClass,
LastSpaceClass = QuadTreeSpaceClass, LastSpaceClass = QuadTreeSpaceClass,
UbitTerrainClass,
FirstUserClass, FirstUserClass,
LastUserClass = FirstUserClass + MaxUserClasses - 1, LastUserClass = FirstUserClass + MaxUserClasses - 1,
NumClasses, NumClasses,
MaxUserClasses = 4 MaxUserClasses = 5
} }
public enum JointType : int public enum JointType : int
@ -204,6 +205,9 @@ namespace OdeAPI
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z); public delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate dReal UbitTerrainGetHeight(IntPtr p_user_data, int x, int z);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2); public delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2);
@ -729,6 +733,18 @@ namespace OdeAPI
return CreateiHeightfield(space, data, bPlaceable); return CreateiHeightfield(space, data, bPlaceable);
} }
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateUbitTerrain"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateiUbitTerrain(IntPtr space, IntPtr data, int bPlaceable);
public static IntPtr CreateUbitTerrain(IntPtr space, IntPtr data, int bPlaceable)
{
NTotalGeoms++;
return CreateiUbitTerrain(space, data, bPlaceable);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity] [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateiGeom(int classnum); public static extern IntPtr CreateiGeom(int classnum);
public static IntPtr CreateGeom(int classnum) public static IntPtr CreateGeom(int classnum)
@ -964,6 +980,8 @@ namespace OdeAPI
dReal width, dReal depth, int widthSamples, int depthSamples, dReal width, dReal depth, int widthSamples, int depthSamples,
dReal scale, dReal offset, dReal thickness, int bWrap); dReal scale, dReal offset, dReal thickness, int bWrap);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity] [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity]
public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData, public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData,
dReal width, dReal depth, int widthSamples, int depthSamples, dReal width, dReal depth, int widthSamples, int depthSamples,
@ -989,6 +1007,33 @@ namespace OdeAPI
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldSetHeightfieldData"), SuppressUnmanagedCodeSecurity] [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldSetHeightfieldData"), SuppressUnmanagedCodeSecurity]
public static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d); public static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataBuild"), SuppressUnmanagedCodeSecurity]
public static extern void GeomUbitTerrainDataBuild(IntPtr d, float[] pHeightData, int bCopyHeightData,
dReal sampleSize, int widthSamples, int depthSamples,
dReal offset, dReal thickness, int bWrap);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataBuild"), SuppressUnmanagedCodeSecurity]
public static extern void GeomUbitTerrainDataBuild(IntPtr d, IntPtr pHeightData, int bCopyHeightData,
dReal sampleSize, int widthSamples, int depthSamples,
dReal thickness, int bWrap);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataCreate"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GeomUbitTerrainDataCreate();
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataDestroy"), SuppressUnmanagedCodeSecurity]
public static extern void GeomUbitTerrainDataDestroy(IntPtr d);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataSetBounds"), SuppressUnmanagedCodeSecurity]
public static extern void GeomUbitTerrainDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainGetHeightfieldData"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GeomUbitTerrainGetHeightfieldData(IntPtr g);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainSetHeightfieldData"), SuppressUnmanagedCodeSecurity]
public static extern void GeomUbitTerrainSetHeightfieldData(IntPtr g, IntPtr d);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsEnabled"), SuppressUnmanagedCodeSecurity] [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsEnabled"), SuppressUnmanagedCodeSecurity]
public static extern bool GeomIsEnabled(IntPtr geom); public static extern bool GeomIsEnabled(IntPtr geom);

View File

@ -156,6 +156,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private readonly ILog m_log; private readonly ILog m_log;
// private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>();
public bool OdeUbitLib = false;
// private int threadid = 0; // private int threadid = 0;
private Random fluidRandomizer = new Random(Environment.TickCount); private Random fluidRandomizer = new Random(Environment.TickCount);
@ -374,7 +375,14 @@ namespace OpenSim.Region.Physics.OdePlugin
mesher = meshmerizer; mesher = meshmerizer;
m_config = config; m_config = config;
// m_log.WarnFormat("ODE configuration: {0}", d.GetConfiguration("ODE")); string ode_config = d.GetConfiguration("ODE");
m_log.WarnFormat("ODE configuration: {0}", ode_config);
if (ode_config.Contains("ODE_Ubit"))
{
OdeUbitLib = true;
}
/* /*
if (region != null) if (region != null)
{ {
@ -527,13 +535,24 @@ namespace OpenSim.Region.Physics.OdePlugin
// sets a global contact for a joint for contactgeom , and base contact description) // sets a global contact for a joint for contactgeom , and base contact description)
private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom, float mu, float bounce,float cfm,float erp) private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom, float mu, float bounce, float cfm, float erpscale, float dscale)
{ {
if (GlobalContactsArray == IntPtr.Zero || m_global_contactcount >= maxContactsbeforedeath) if (GlobalContactsArray == IntPtr.Zero || m_global_contactcount >= maxContactsbeforedeath)
return IntPtr.Zero; return IntPtr.Zero;
float erp = contactGeom.depth;
erp *= erpscale;
if (erp < minERP)
erp = minERP;
else if (erp > MaxERP)
erp = MaxERP;
float depth = contactGeom.depth * dscale;
if (depth > 0.5f)
depth = 0.5f;
d.Contact newcontact = new d.Contact(); d.Contact newcontact = new d.Contact();
newcontact.geom.depth = contactGeom.depth; newcontact.geom.depth = depth;
newcontact.geom.g1 = contactGeom.g1; newcontact.geom.g1 = contactGeom.g1;
newcontact.geom.g2 = contactGeom.g2; newcontact.geom.g2 = contactGeom.g2;
newcontact.geom.pos = contactGeom.pos; newcontact.geom.pos = contactGeom.pos;
@ -692,6 +711,10 @@ namespace OpenSim.Region.Physics.OdePlugin
float bounce = 0; float bounce = 0;
float cfm = 0.0001f; float cfm = 0.0001f;
float erp = 0.1f; float erp = 0.1f;
float erpscale = 1.0f;
float dscale = 1.0f;
bool IgnoreNegSides = false;
ContactData contactdata1 = new ContactData(0, 0, false); ContactData contactdata1 = new ContactData(0, 0, false);
ContactData contactdata2 = new ContactData(0, 0, false); ContactData contactdata2 = new ContactData(0, 0, false);
@ -781,10 +804,14 @@ namespace OpenSim.Region.Physics.OdePlugin
cfm = p1.Mass; cfm = p1.Mass;
if (cfm > p2.Mass) if (cfm > p2.Mass)
cfm = p2.Mass; cfm = p2.Mass;
cfm = (float)Math.Sqrt(cfm); dscale = 10 / cfm;
cfm *= 0.0001f; dscale = (float)Math.Sqrt(dscale);
if (cfm > 0.8f) if (dscale > 1.0f)
cfm = 0.8f; dscale = 1.0f;
erpscale = cfm * 0.01f;
cfm = 0.0001f / cfm;
if (cfm > 0.01f)
cfm = 0.01f;
if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult; mu *= frictionMovementMult;
@ -801,11 +828,22 @@ namespace OpenSim.Region.Physics.OdePlugin
if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f)
mu *= frictionMovementMult; mu *= frictionMovementMult;
p1.CollidingGround = true; p1.CollidingGround = true;
cfm = p1.Mass; cfm = p1.Mass;
cfm = (float)Math.Sqrt(cfm); dscale = 10 / cfm;
cfm *= 0.0001f; dscale = (float)Math.Sqrt(dscale);
if (cfm > 0.8f) if (dscale > 1.0f)
cfm = 0.8f; dscale = 1.0f;
erpscale = cfm * 0.01f;
cfm = 0.0001f / cfm;
if (cfm > 0.01f)
cfm = 0.01f;
if (d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass)
{
if (curContact.side1 > 0)
IgnoreNegSides = true;
}
} }
else if (name == "Water") else if (name == "Water")
@ -830,11 +868,21 @@ namespace OpenSim.Region.Physics.OdePlugin
p2.getContactData(ref contactdata2); p2.getContactData(ref contactdata2);
bounce = contactdata2.bounce * TerrainBounce; bounce = contactdata2.bounce * TerrainBounce;
mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction);
cfm = p2.Mass; cfm = p2.Mass;
cfm = (float)Math.Sqrt(cfm); dscale = 10 / cfm;
cfm *= 0.0001f; dscale = (float)Math.Sqrt(dscale);
if (cfm > 0.8f)
cfm = 0.8f; if (dscale > 1.0f)
dscale = 1.0f;
erpscale = cfm * 0.01f;
cfm = 0.0001f / cfm;
if (cfm > 0.01f)
cfm = 0.01f;
if (curContact.side1 > 0) // should be 2 ?
IgnoreNegSides = true;
if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f)
mu *= frictionMovementMult; mu *= frictionMovementMult;
@ -861,26 +909,31 @@ namespace OpenSim.Region.Physics.OdePlugin
int i = 0; int i = 0;
while(true) while(true)
{
if (IgnoreNegSides && curContact.side1 < 0)
{
if (++i >= count)
break;
if (!GetCurContactGeom(i, ref curContact))
break;
}
else
{ {
if (dop1foot && (p1.Position.Z - curContact.pos.Z) > (p1.Size.Z - avCapRadius) * 0.5f) if (dop1foot && (p1.Position.Z - curContact.pos.Z) > (p1.Size.Z - avCapRadius) * 0.5f)
p1.IsColliding = true; p1.IsColliding = true;
if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f) if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f)
p2.IsColliding = true; p2.IsColliding = true;
Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale);
erp = curContact.depth;
if (erp < minERP)
erp = minERP;
else if (erp > MaxERP)
erp = MaxERP;
Joint = CreateContacJoint(ref curContact, mu, bounce,cfm,erp);
d.JointAttach(Joint, b1, b2); d.JointAttach(Joint, b1, b2);
if (++m_global_contactcount >= maxContactsbeforedeath) if (++m_global_contactcount >= maxContactsbeforedeath)
break; break;
if(++i >= count) if (++i >= count)
break; break;
if (!GetCurContactGeom(i, ref curContact)) if (!GetCurContactGeom(i, ref curContact))
@ -897,6 +950,7 @@ namespace OpenSim.Region.Physics.OdePlugin
maxDepthContact.PenetrationDepth = curContact.depth; maxDepthContact.PenetrationDepth = curContact.depth;
} }
} }
}
collision_accounting_events(p1, p2, maxDepthContact); collision_accounting_events(p1, p2, maxDepthContact);
@ -1865,13 +1919,12 @@ namespace OpenSim.Region.Physics.OdePlugin
public float GetTerrainHeightAtXY(float x, float y) public float GetTerrainHeightAtXY(float x, float y)
{ {
// assumes 1m size grid and constante size square regions
// needs to know about sims around in future
// region offset in mega position
int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize; int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize; int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
IntPtr heightFieldGeom = IntPtr.Zero; IntPtr heightFieldGeom = IntPtr.Zero;
// get region map // get region map
@ -1903,6 +1956,32 @@ namespace OpenSim.Region.Physics.OdePlugin
int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples
if (OdeUbitLib)
{
if (x < regsize - 1)
{
ix = (int)x;
dx = x - (float)ix;
}
else // out world use external height
{
ix = regsize - 1;
dx = 0;
}
if (y < regsize - 1)
{
iy = (int)y;
dy = y - (float)iy;
}
else
{
iy = regsize - 1;
dy = 0;
}
}
else
{
// we still have square fixed size regions // we still have square fixed size regions
// also flip x and y because of how map is done for ODE fliped axis // also flip x and y because of how map is done for ODE fliped axis
// so ix,iy,dx and dy are inter exchanged // so ix,iy,dx and dy are inter exchanged
@ -1926,6 +2005,7 @@ namespace OpenSim.Region.Physics.OdePlugin
ix = regsize - 1; ix = regsize - 1;
dx = 0; dx = 0;
} }
}
float h0; float h0;
float h1; float h1;
@ -1951,6 +2031,8 @@ namespace OpenSim.Region.Physics.OdePlugin
return h0 + h1 + h2; return h0 + h1 + h2;
} }
public override void SetTerrain(float[] heightMap) public override void SetTerrain(float[] heightMap)
{ {
if (m_worldOffset != Vector3.Zero && m_parentScene != null) if (m_worldOffset != Vector3.Zero && m_parentScene != null)
@ -1972,6 +2054,14 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
public void SetTerrain(float[] heightMap, Vector3 pOffset) public void SetTerrain(float[] heightMap, Vector3 pOffset)
{
if (OdeUbitLib)
UbitSetTerrain(heightMap, pOffset);
else
OriSetTerrain(heightMap, pOffset);
}
public void OriSetTerrain(float[] heightMap, Vector3 pOffset)
{ {
// assumes 1m size grid and constante size square regions // assumes 1m size grid and constante size square regions
// needs to know about sims around in future // needs to know about sims around in future
@ -2086,6 +2176,108 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
public void UbitSetTerrain(float[] heightMap, Vector3 pOffset)
{
// assumes 1m size grid and constante size square regions
// needs to know about sims around in future
float[] _heightmap;
uint heightmapWidth = Constants.RegionSize + 2;
uint heightmapHeight = Constants.RegionSize + 2;
uint heightmapWidthSamples = heightmapWidth + 1;
uint heightmapHeightSamples = heightmapHeight + 1;
_heightmap = new float[heightmapWidthSamples * heightmapHeightSamples];
uint regionsize = Constants.RegionSize;
float hfmin = float.MaxValue;
// float hfmax = float.MinValue;
float val;
uint maxXXYY = regionsize - 1;
// adding one margin all around so things don't fall in edges
uint xx;
uint yy = 0;
uint yt = 0;
for (uint y = 0; y < heightmapHeightSamples; y++)
{
if (y > 1 && y < maxXXYY)
yy += regionsize;
xx = 0;
for (uint x = 0; x < heightmapWidthSamples; x++)
{
if (x > 1 && x < maxXXYY)
xx++;
val = heightMap[yy + xx];
if (val < 0.0f)
val = 0.0f; // no neg terrain as in chode
_heightmap[yt + x] = val;
if (hfmin > val)
hfmin = val;
// if (hfmax < val)
// hfmax = val;
}
yt += heightmapWidthSamples;
}
lock (OdeLock)
{
IntPtr GroundGeom = IntPtr.Zero;
if (RegionTerrain.TryGetValue(pOffset, out GroundGeom))
{
RegionTerrain.Remove(pOffset);
if (GroundGeom != IntPtr.Zero)
{
if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
{
TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
TerrainHeightFieldHeightsHandlers.Remove(GroundGeom);
TerrainHeightFieldHeights.Remove(GroundGeom);
}
d.SpaceRemove(StaticSpace, GroundGeom);
d.GeomDestroy(GroundGeom);
}
}
IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
const int wrap = 0;
float thickness = hfmin;
if (thickness < 0)
thickness = 1;
GCHandle _heightmaphandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned);
d.GeomUbitTerrainDataBuild(HeightmapData, _heightmaphandler.AddrOfPinnedObject(), 0, 1.0f,
(int)heightmapWidthSamples, (int)heightmapHeightSamples,
thickness, wrap);
// d.GeomUbitTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1);
if (GroundGeom != IntPtr.Zero)
{
d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land));
d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space));
}
geom_name_map[GroundGeom] = "Terrain";
d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0);
RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);
TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler);
}
}
public override void DeleteTerrain() public override void DeleteTerrain()
{ {
} }