diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 143648e560..b462713b3f 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -74,8 +74,6 @@ namespace OpenSim.Region.Physics.Meshing
#endif
private bool cacheSculptMaps = true;
- private bool cacheSculptAlphaMaps = true;
-
private string decodedSculptMapPath = null;
private bool useMeshiesPhysicsMesh = false;
@@ -89,16 +87,7 @@ namespace OpenSim.Region.Physics.Meshing
IConfig mesh_config = config.Configs["Mesh"];
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
-
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
-
- if (Environment.OSVersion.Platform == PlatformID.Unix)
- {
- cacheSculptAlphaMaps = false;
- }
- else
- cacheSculptAlphaMaps = cacheSculptMaps;
-
if(mesh_config != null)
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
@@ -279,18 +268,15 @@ namespace OpenSim.Region.Physics.Meshing
{
if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
return null;
- // Remove the reference to any JPEG2000 sculpt data so it can be GCed
- // don't loose it
- // primShape.SculptData = Utils.EmptyBytes;
}
-// primShape.SculptDataLoaded = true;
}
else
{
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
return null;
}
- // keep compatible
+
+ // Remove the reference to any JPEG2000 sculpt data so it can be GCed
primShape.SculptData = Utils.EmptyBytes;
int numCoords = coords.Count;
@@ -335,7 +321,7 @@ namespace OpenSim.Region.Physics.Meshing
if (primShape.SculptData.Length <= 0)
{
- m_log.InfoFormat("[MESH]: asset data for {0} is zero length", primName);
+// m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName);
return false;
}
@@ -496,8 +482,7 @@ namespace OpenSim.Region.Physics.Meshing
//idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
- if (cacheSculptMaps && (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) ==0)))
- // don't cache images with alpha channel in linux since mono can't load them correctly)
+ if (cacheSculptMaps)
{
try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
@@ -721,7 +706,6 @@ namespace OpenSim.Region.Physics.Meshing
{
return CreateMesh(primName, primShape, size, lod, false);
}
-
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical)
{
#if SPAM
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index a41c8565b9..b2c2d8a600 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -63,6 +63,9 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_isphysical;
+ public int ExpectedCollisionContacts { get { return m_expectedCollisionContacts; } }
+ private int m_expectedCollisionContacts = 0;
+
///
/// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
///
@@ -97,6 +100,9 @@ namespace OpenSim.Region.Physics.OdePlugin
private Vector3 m_taintAngularLock = Vector3.One;
private IntPtr Amotor = IntPtr.Zero;
+ private object m_assetsLock = new object();
+ private bool m_assetFailed = false;
+
private Vector3 m_PIDTarget;
private float m_PIDTau;
private float PID_D = 35f;
@@ -279,6 +285,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
m_taintadd = true;
+ m_assetFailed = false;
_parent_scene.AddPhysicsActorTaint(this);
}
@@ -601,8 +608,8 @@ namespace OpenSim.Region.Physics.OdePlugin
break;
case HollowShape.Circle:
- // Hollow shape is a perfect cylinder in respect to the cube's scale
- // Cylinder hollow volume calculation
+ // Hollow shape is a perfect cyllinder in respect to the cube's scale
+ // Cyllinder hollow volume calculation
hollowVolume *= 0.1963495f * 3.07920140172638f;
break;
@@ -840,7 +847,7 @@ namespace OpenSim.Region.Physics.OdePlugin
int vertexStride, triStride;
mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
-
+ m_expectedCollisionContacts = indexCount;
mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
// We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at
@@ -1377,6 +1384,7 @@ Console.WriteLine("CreateGeom:");
{
//Console.WriteLine(" CreateGeom 1");
SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
+ m_expectedCollisionContacts = 3;
}
catch (AccessViolationException)
{
@@ -1391,6 +1399,7 @@ Console.WriteLine("CreateGeom:");
{
//Console.WriteLine(" CreateGeom 2");
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ m_expectedCollisionContacts = 4;
}
catch (AccessViolationException)
{
@@ -1406,6 +1415,7 @@ Console.WriteLine("CreateGeom:");
{
//Console.WriteLine(" CreateGeom 3");
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ m_expectedCollisionContacts = 4;
}
catch (AccessViolationException)
{
@@ -1421,6 +1431,7 @@ Console.WriteLine("CreateGeom:");
{
//Console.WriteLine(" CreateGeom 4");
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ m_expectedCollisionContacts = 4;
}
catch (AccessViolationException)
{
@@ -1446,11 +1457,13 @@ Console.WriteLine("CreateGeom:");
_parent_scene.geom_name_map.Remove(prim_geom);
_parent_scene.actor_name_map.Remove(prim_geom);
d.GeomDestroy(prim_geom);
+ m_expectedCollisionContacts = 0;
prim_geom = IntPtr.Zero;
}
catch (System.AccessViolationException)
{
prim_geom = IntPtr.Zero;
+ m_expectedCollisionContacts = 0;
m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
return false;
@@ -1489,6 +1502,8 @@ Console.WriteLine("CreateGeom:");
mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
// createmesh returns null when it's a shape that isn't a cube.
// m_log.Debug(m_localID);
+ if (mesh == null)
+ CheckMeshAsset();
}
#if SPAM
@@ -1988,7 +2003,12 @@ Console.WriteLine(" JointCreateFixed");
// Don't need to re-enable body.. it's done in SetMesh
if (_parent_scene.needsMeshing(_pbs))
+ {
mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
+ if (mesh == null)
+ CheckMeshAsset();
+ }
+
}
CreateGeom(m_targetSpace, mesh);
@@ -2048,6 +2068,8 @@ Console.WriteLine(" JointCreateFixed");
///
private void changeshape()
{
+ m_taintshape = false;
+
// Cleanup of old prim geometry and Bodies
if (IsPhysical && Body != IntPtr.Zero)
{
@@ -2075,6 +2097,7 @@ Console.WriteLine(" JointCreateFixed");
IMesh mesh = null;
+
if (_parent_scene.needsMeshing(_pbs))
{
// Don't need to re-enable body.. it's done in CreateMesh
@@ -2085,6 +2108,8 @@ Console.WriteLine(" JointCreateFixed");
// createmesh returns null when it doesn't mesh.
mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
+ if (mesh == null)
+ CheckMeshAsset();
}
CreateGeom(m_targetSpace, mesh);
@@ -2121,7 +2146,7 @@ Console.WriteLine(" JointCreateFixed");
}
resetCollisionAccounting();
- m_taintshape = false;
+// m_taintshape = false;
}
///
@@ -2387,6 +2412,7 @@ Console.WriteLine(" JointCreateFixed");
set
{
_pbs = value;
+ m_assetFailed = false;
m_taintshape = true;
}
}
@@ -2395,15 +2421,15 @@ Console.WriteLine(" JointCreateFixed");
{
get
{
- // Averate previous velocity with the new one so
+ // Average previous velocity with the new one so
// client object interpolation works a 'little' better
if (_zeroFlag)
return Vector3.Zero;
Vector3 returnVelocity = Vector3.Zero;
- returnVelocity.X = (m_lastVelocity.X + _velocity.X)/2;
- returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y)/2;
- returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z)/2;
+ returnVelocity.X = (m_lastVelocity.X + _velocity.X) * 0.5f; // 0.5f is mathematically equiv to '/ 2'
+ returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y) * 0.5f;
+ returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z) * 0.5f;
return returnVelocity;
}
set
@@ -2600,6 +2626,7 @@ Console.WriteLine(" JointCreateFixed");
{
Vector3 pv = Vector3.Zero;
bool lastZeroFlag = _zeroFlag;
+ float m_minvelocity = 0;
if (Body != (IntPtr)0) // FIXME -> or if it is a joint
{
d.Vector3 vec = d.BodyGetPosition(Body);
@@ -2752,8 +2779,21 @@ Console.WriteLine(" JointCreateFixed");
_acceleration = ((_velocity - m_lastVelocity) / 0.1f);
_acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f);
//m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString());
+
+ // Note here that linearvelocity is affecting angular velocity... so I'm guessing this is a vehicle specific thing...
+ // it does make sense to do this for tiny little instabilities with physical prim, however 0.5m/frame is fairly large.
+ // reducing this to 0.02m/frame seems to help the angular rubberbanding quite a bit, however, to make sure it doesn't affect elevators and vehicles
+ // adding these logical exclusion situations to maintain this where I think it was intended to be.
+ if (m_throttleUpdates || m_usePID || (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) || (Amotor != IntPtr.Zero))
+ {
+ m_minvelocity = 0.5f;
+ }
+ else
+ {
+ m_minvelocity = 0.02f;
+ }
- if (_velocity.ApproxEquals(pv, 0.5f))
+ if (_velocity.ApproxEquals(pv, m_minvelocity))
{
m_rotationalVelocity = pv;
}
@@ -3211,5 +3251,37 @@ Console.WriteLine(" JointCreateFixed");
{
m_material = pMaterial;
}
+
+
+ private void CheckMeshAsset()
+ {
+ if (_pbs.SculptEntry && !m_assetFailed && _pbs.SculptTexture != UUID.Zero)
+ {
+ m_assetFailed = true;
+ Util.FireAndForget(delegate
+ {
+ RequestAssetDelegate assetProvider = _parent_scene.RequestAssetMethod;
+ if (assetProvider != null)
+ assetProvider(_pbs.SculptTexture, MeshAssetReveived);
+ });
+ }
+ }
+
+ void MeshAssetReveived(AssetBase asset)
+ {
+ if (asset.Data != null && asset.Data.Length > 0)
+ {
+ if (!_pbs.SculptEntry)
+ return;
+ if (_pbs.SculptTexture.ToString() != asset.ID)
+ return;
+
+ _pbs.SculptData = new byte[asset.Data.Length];
+ asset.Data.CopyTo(_pbs.SculptData, 0);
+ m_assetFailed = false;
+ m_taintshape = true;
+ _parent_scene.AddPhysicsActorTaint(this);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
index 7e3ec63d23..8d7d3b3ae9 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
@@ -137,15 +137,8 @@ namespace OpenSim.Region.Physics.OdePlugin
ODERayCastRequest[] reqs = m_PendingRequests.ToArray();
for (int i = 0; i < reqs.Length; i++)
{
- try
- {
- if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
- RayCast(reqs[i]); // if there isn't anyone to send results
- }
- catch
- {
- //Fail silently
- }
+ if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
+ RayCast(reqs[i]); // if there isn't anyone to send results
}
m_PendingRequests.Clear();
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 929b019ecf..7a50c4c66a 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -336,6 +336,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public int geomContactPointsStartthrottle = 3;
public int geomUpdatesPerThrottledUpdate = 15;
+ private const int avatarExpectedContacts = 3;
public float bodyPIDD = 35f;
public float bodyPIDG = 25;
@@ -474,6 +475,8 @@ namespace OpenSim.Region.Physics.OdePlugin
private OdePrim cp1;
private OdeCharacter cc2;
private OdePrim cp2;
+ private int p1ExpectedPoints = 0;
+ private int p2ExpectedPoints = 0;
//private int cStartStop = 0;
//private string cDictKey = "";
@@ -498,6 +501,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public int physics_logging_interval = 0;
public bool physics_logging_append_existing_logfile = false;
+
public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f);
public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f);
@@ -644,7 +648,7 @@ namespace OpenSim.Region.Physics.OdePlugin
contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);
- geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3);
+ geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 5);
geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15);
geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
@@ -1064,7 +1068,10 @@ namespace OpenSim.Region.Physics.OdePlugin
PhysicsActor p1;
PhysicsActor p2;
-
+
+ p1ExpectedPoints = 0;
+ p2ExpectedPoints = 0;
+
if (!actor_name_map.TryGetValue(g1, out p1))
{
p1 = PANull;
@@ -1121,9 +1128,13 @@ namespace OpenSim.Region.Physics.OdePlugin
switch (p1.PhysicsActorType)
{
case (int)ActorTypes.Agent:
+ p1ExpectedPoints = avatarExpectedContacts;
p2.CollidingObj = true;
break;
case (int)ActorTypes.Prim:
+ if (p1 != null && p1 is OdePrim)
+ p1ExpectedPoints = ((OdePrim) p1).ExpectedCollisionContacts;
+
if (p2.Velocity.LengthSquared() > 0.0f)
p2.CollidingObj = true;
break;
@@ -1319,6 +1330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
(Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
{
+ p2ExpectedPoints = avatarExpectedContacts;
// Avatar is moving on terrain, use the movement terrain contact
AvatarMovementTerrainContact.geom = curContact;
@@ -1332,6 +1344,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (p2.PhysicsActorType == (int)ActorTypes.Agent)
{
+ p2ExpectedPoints = avatarExpectedContacts;
// Avatar is standing on terrain, use the non moving terrain contact
TerrainContact.geom = curContact;
@@ -1356,9 +1369,18 @@ namespace OpenSim.Region.Physics.OdePlugin
}
if (p2 is OdePrim)
- material = ((OdePrim)p2).m_material;
-
+ {
+ material = ((OdePrim) p2).m_material;
+ p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
+ }
+
+ // Unnessesary because p1 is defined above
+ //if (p1 is OdePrim)
+ // {
+ // p1ExpectedPoints = ((OdePrim)p1).ExpectedCollisionContacts;
+ // }
//m_log.DebugFormat("Material: {0}", material);
+
m_materialContacts[material, movintYN].geom = curContact;
if (m_global_contactcount < maxContactsbeforedeath)
@@ -1379,7 +1401,10 @@ namespace OpenSim.Region.Physics.OdePlugin
int material = (int)Material.Wood;
if (p2 is OdePrim)
+ {
material = ((OdePrim)p2).m_material;
+ p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
+ }
//m_log.DebugFormat("Material: {0}", material);
m_materialContacts[material, movintYN].geom = curContact;
@@ -1429,6 +1454,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if ((p2.PhysicsActorType == (int)ActorTypes.Agent))
{
+ p2ExpectedPoints = avatarExpectedContacts;
if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
{
// Avatar is moving on a prim, use the Movement prim contact
@@ -1458,7 +1484,10 @@ namespace OpenSim.Region.Physics.OdePlugin
int material = (int)Material.Wood;
if (p2 is OdePrim)
+ {
material = ((OdePrim)p2).m_material;
+ p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
+ }
//m_log.DebugFormat("Material: {0}", material);
m_materialContacts[material, 0].geom = curContact;
@@ -1479,8 +1508,8 @@ namespace OpenSim.Region.Physics.OdePlugin
}
collision_accounting_events(p1, p2, maxDepthContact);
-
- if (count > geomContactPointsStartthrottle)
+
+ if (count > ((p1ExpectedPoints + p2ExpectedPoints) * 0.25) + (geomContactPointsStartthrottle))
{
// If there are more then 3 contact points, it's likely
// that we've got a pile of objects, so ...