From 9d184c103ab264511411c667f83970a83c03822b Mon Sep 17 00:00:00 2001 From: ubit Date: Thu, 10 May 2012 18:01:35 +0200 Subject: direct upload of odedynamics.cs for testing ( ubitode ) --- .../Region/Physics/UbitOdePlugin/ODEDynamics.cs | 254 +++++++++++++-------- 1 file changed, 154 insertions(+), 100 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index 8f2feba..e88e559 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs @@ -117,14 +117,23 @@ namespace OpenSim.Region.Physics.OdePlugin // auxiliar - private float m_lmEfect = 0; // current linear motor eficiency - private float m_lmDecay = 1.0f; + private float m_lmEfect = 0f; // current linear motor eficiency + private float m_lmDecay = 0f; // current linear decay + private float m_amEfect = 0; // current angular motor eficiency + private float m_amDecay = 0f; // current linear decay + private float m_ffactor = 1.0f; private float m_timestep = 0.02f; private float m_invtimestep = 50; + + float m_ampwr; + float m_amdampX; + float m_amdampY; + float m_amdampZ; + public float FrictionFactor { get @@ -146,6 +155,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_type = vd.m_type; m_flags = vd.m_flags; + // Linear properties m_linearMotorDirection = vd.m_linearMotorDirection; @@ -309,7 +319,10 @@ namespace OpenSim.Region.Physics.OdePlugin len = m_angularMotorDirection.Length(); if (len > 12.566f) m_angularMotorDirection *= (12.566f / len); - m_amEfect = 1.0f; // turn it on + + m_amEfect = 1.0f / m_angularMotorTimescale; // turn it on + m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale; + if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) d.BodyEnable(rootPrim.Body); @@ -323,8 +336,10 @@ namespace OpenSim.Region.Physics.OdePlugin len = m_linearMotorDirection.Length(); if (len > 100.0f) m_linearMotorDirection *= (100.0f / len); + m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale; m_lmEfect = 1.0f / m_linearMotorTimescale; // turn it on + m_ffactor = 0.01f; if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) @@ -358,7 +373,10 @@ namespace OpenSim.Region.Physics.OdePlugin len = m_angularMotorDirection.Length(); if (len > 12.566f) m_angularMotorDirection *= (12.566f / len); - m_amEfect = 1.0f; // turn it on + + m_amEfect = 1.0f / m_angularMotorTimescale; // turn it on + m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale; + if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) d.BodyEnable(rootPrim.Body); @@ -374,8 +392,12 @@ namespace OpenSim.Region.Physics.OdePlugin len = m_linearMotorDirection.Length(); if (len > 100.0f) m_linearMotorDirection *= (100.0f / len); - m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale; + m_lmEfect = 1.0f / m_linearMotorTimescale; // turn it on + m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale; + + + m_ffactor = 0.01f; if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) @@ -421,6 +443,7 @@ namespace OpenSim.Region.Physics.OdePlugin internal void ProcessTypeChange(Vehicle pType) { m_lmEfect = 0; + m_amEfect = 0; m_ffactor = 1f; @@ -607,15 +630,20 @@ namespace OpenSim.Region.Physics.OdePlugin // m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | // VehicleFlag.HOVER_GLOBAL_HEIGHT); break; + } + m_lmDecay = (1.0f - 1.0f / m_linearMotorDecayTimescale); + m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale; + }//end SetDefaultsForType internal void Stop() { m_lmEfect = 0; - m_lmDecay = 1.0f; + m_lmDecay = 0f; m_amEfect = 0; + m_amDecay = 0; m_ffactor = 1f; } @@ -642,6 +670,7 @@ namespace OpenSim.Region.Physics.OdePlugin private const float pi = (float)Math.PI; private const float halfpi = 0.5f * (float)Math.PI; + private const float twopi = 2.0f * pi; public static Vector3 ubitRot2Euler(Quaternion rot) { @@ -744,6 +773,8 @@ namespace OpenSim.Region.Physics.OdePlugin curAngVel.Z = dvtmp.Z; Vector3 curLocalAngVel = curAngVel * irotq; // current angular velocity in local + float ldampZ = 0; + // linear motor if (m_lmEfect > 0.001 && m_linearMotorTimescale < 1000) { @@ -766,9 +797,11 @@ namespace OpenSim.Region.Physics.OdePlugin force.Y += tmpV.Y; force.Z += tmpV.Z; } + m_lmEfect *= m_lmDecay; - m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared(); + // m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared(); + m_ffactor = 0; } else { @@ -776,18 +809,6 @@ namespace OpenSim.Region.Physics.OdePlugin m_ffactor = 1f; } - // friction - if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0) - { - tmpV.X = -curLocalVel.X / m_linearFrictionTimescale.X; - tmpV.Y = -curLocalVel.Y / m_linearFrictionTimescale.Y; - tmpV.Z = -curLocalVel.Z / m_linearFrictionTimescale.Z; - tmpV *= rotq; // to world - force.X += tmpV.X; - force.Y += tmpV.Y; - force.Z += tmpV.Z; - } - // hover if (m_VhoverTimescale < 300 && rootPrim.prim_geom != IntPtr.Zero) { @@ -823,10 +844,16 @@ namespace OpenSim.Region.Physics.OdePlugin else if (t > m_VhoverHeight) perr = t - pos.Z; ; - if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == 0 || perr > 0) + if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == 0 || perr > -0.1) { - // force.Z += (perr / m_VhoverTimescale / m_VhoverTimescale - curVel.Z * m_VhoverEfficiency) / m_timestep; - force.Z += (perr / m_VhoverTimescale - curVel.Z * m_VhoverEfficiency);// * m_invtimestep); + ldampZ = m_VhoverEfficiency * m_invtimestep; + + perr *= (1.0f + ldampZ) / m_VhoverTimescale; + + // force.Z += perr - curVel.Z * tmp; + force.Z += perr; + ldampZ *= -curVel.Z; + force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy); } else // no buoyancy @@ -844,7 +871,6 @@ namespace OpenSim.Region.Physics.OdePlugin float len = curVel.Length(); if (len > 0.01) // if moving { - Vector3 atAxis; atAxis = Xrot(rotq); // where are we pointing to atAxis *= len; // make it same size as world velocity vector @@ -870,56 +896,19 @@ namespace OpenSim.Region.Physics.OdePlugin } } - // angular motor - if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000) - { - tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error - tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep - torque.X += tmpV.X; - torque.Y += tmpV.Y; - torque.Z += tmpV.Z; - m_amEfect *= (1 - 1.0f / m_angularMotorDecayTimescale); - } - else - m_amEfect = 0; - - // angular friction - if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0) - { - torque.X -= curLocalAngVel.X / m_angularFrictionTimescale.X; - torque.Y -= curLocalAngVel.Y / m_angularFrictionTimescale.Y; - torque.Z -= curLocalAngVel.Z / m_angularFrictionTimescale.Z; - } - - // angular deflection - if (m_angularDeflectionEfficiency > 0) + // linear friction/damping + if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0) { - Vector3 dirv; - - if (curLocalVel.X > 0.01f) - dirv = curLocalVel; - else if (curLocalVel.X < -0.01f) - // use oposite - dirv = -curLocalVel; - else - { - // make it fall into small positive x case - dirv.X = 0.01f; - dirv.Y = curLocalVel.Y; - dirv.Z = curLocalVel.Z; - } - - float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale; - - if (Math.Abs(dirv.Z) > 0.01) - { - torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp; - } + tmpV.X = -curLocalVel.X / m_linearFrictionTimescale.X; + tmpV.Y = -curLocalVel.Y / m_linearFrictionTimescale.Y; + tmpV.Z = -curLocalVel.Z / m_linearFrictionTimescale.Z; + tmpV *= rotq; // to world - if (Math.Abs(dirv.Y) > 0.01) - { - torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp; - } + if(ldampZ != 0 && Math.Abs(ldampZ) > Math.Abs(tmpV.Z)) + tmpV.Z = ldampZ; + force.X += tmpV.X; + force.Y += tmpV.Y; + force.Z += tmpV.Z; } // vertical atractor @@ -928,29 +917,30 @@ namespace OpenSim.Region.Physics.OdePlugin float roll; float pitch; - GetRollPitch(irotq, out roll, out pitch); - float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale * m_invtimestep; + + float ftmp = m_invtimestep / m_verticalAttractionTimescale / m_verticalAttractionTimescale; + float ftmp2; - if (m_bankingEfficiency == 0) - ftmp2 = m_verticalAttractionEfficiency * m_invtimestep; - else - ftmp2 = 0; + ftmp2 = 0.5f * m_verticalAttractionEfficiency * m_invtimestep; + m_amdampX = ftmp2; + + m_ampwr = 1.0f - 0.8f * m_verticalAttractionEfficiency; + + GetRollPitch(irotq, out roll, out pitch); if (roll > halfpi) roll = pi - roll; else if (roll < -halfpi) - roll = -pi - roll; + roll = -pi - roll; float effroll = pitch / halfpi; effroll *= effroll; effroll = 1 - effroll; effroll *= roll; - if (Math.Abs(effroll) > 0.01) // roll - { - torque.X -= -effroll * ftmp + curLocalAngVel.X * ftmp2; - } + + torque.X += effroll * ftmp; if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0) { @@ -958,24 +948,21 @@ namespace OpenSim.Region.Physics.OdePlugin effpitch *= effpitch; effpitch = 1 - effpitch; effpitch *= pitch; - - if (Math.Abs(effpitch) > 0.01) // pitch - { - torque.Y -= -effpitch * ftmp + curLocalAngVel.Y * ftmp2; - } + + torque.Y += effpitch * ftmp; } if (m_bankingEfficiency != 0 && Math.Abs(effroll) > 0.01) { float broll = effroll; -/* - if (broll > halfpi) - broll = pi - broll; - else if (broll < -halfpi) - broll = -pi - broll; -*/ - broll *= m_bankingEfficiency; + /* + if (broll > halfpi) + broll = pi - broll; + else if (broll < -halfpi) + broll = -pi - broll; + */ + broll *= m_bankingEfficiency; if (m_bankingMix != 0) { float vfact = Math.Abs(curLocalVel.X) / 10.0f; @@ -984,24 +971,91 @@ namespace OpenSim.Region.Physics.OdePlugin if (curLocalVel.X >= 0) broll *= (1 + (vfact - 1) * m_bankingMix); else - broll *= -(1 + (vfact - 1) * m_bankingMix); + broll *= -(1 + (vfact - 1) * m_bankingMix); } // make z rot be in world Z not local as seems to be in sl broll = broll / m_bankingTimescale; - ftmp = -Math.Abs(m_bankingEfficiency) / m_bankingTimescale; - tmpV.X = ftmp * curAngVel.X; - tmpV.Y = ftmp * curAngVel.Y; - tmpV.Z = broll + ftmp * curAngVel.Z; - tmpV *= irotq; + tmpV = Zrot(irotq); + tmpV *= broll; torque.X += tmpV.X; torque.Y += tmpV.Y; torque.Z += tmpV.Z; + + m_amdampZ = Math.Abs(m_bankingEfficiency) / m_bankingTimescale; + m_amdampY = m_amdampZ; + + } + else + { + m_amdampZ = 1 / m_angularFrictionTimescale.Z; + m_amdampY = m_amdampX; + } + } + else + { + m_ampwr = 1.0f; + m_amdampX = 1 / m_angularFrictionTimescale.X; + m_amdampY = 1 / m_angularFrictionTimescale.Y; + m_amdampZ = 1 / m_angularFrictionTimescale.Z; + } + + // angular motor + if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000) + { + tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error + tmpV *= m_amEfect; // error to correct in this timestep + torque.X += tmpV.X * m_ampwr; + torque.Y += tmpV.Y * m_ampwr; + torque.Z += tmpV.Z; + + m_amEfect *= m_amDecay; + } + else + m_amEfect = 0; + + // angular deflection + if (m_angularDeflectionEfficiency > 0) + { + Vector3 dirv; + + if (curLocalVel.X > 0.01f) + dirv = curLocalVel; + else if (curLocalVel.X < -0.01f) + // use oposite + dirv = -curLocalVel; + else + { + // make it fall into small positive x case + dirv.X = 0.01f; + dirv.Y = curLocalVel.Y; + dirv.Z = curLocalVel.Z; + } + + float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale; + + if (Math.Abs(dirv.Z) > 0.01) + { + torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp; + } + + if (Math.Abs(dirv.Y) > 0.01) + { + torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp; } } + + // angular friction + if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0) + { + torque.X -= curLocalAngVel.X * m_amdampX; + torque.Y -= curLocalAngVel.Y * m_amdampY; + torque.Z -= curLocalAngVel.Z * m_amdampZ; + } + d.Mass dmass; d.BodyGetMass(Body,out dmass); -- cgit v1.1 From 6535f23e4b8fec9578dae5275db69b237a99e498 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 7 Jul 2012 02:05:01 +0200 Subject: Add saving vehicle physics data to the database --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 19 ++++++++-- OpenSim/Region/Framework/Scenes/SOPVehicle.cs | 33 +++++++++++++++++- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 40 +++++++++++----------- .../Scenes/Serialization/SceneObjectSerializer.cs | 8 ++--- 4 files changed, 73 insertions(+), 27 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 5e4df3a..fecc329 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -175,7 +175,8 @@ namespace OpenSim.Data.MySQL "PassCollisions, " + "LinkNumber, MediaURL, KeyframeMotion, " + "PhysicsShapeType, Density, GravityModifier, " + - "Friction, Restitution) values (" + "?UUID, " + + "Friction, Restitution, Vehicle " + + ") values (" + "?UUID, " + "?CreationDate, ?Name, ?Text, " + "?Description, ?SitName, ?TouchName, " + "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + @@ -209,7 +210,7 @@ namespace OpenSim.Data.MySQL "?CollisionSoundVolume, ?PassTouches, ?PassCollisions, " + "?LinkNumber, ?MediaURL, ?KeyframeMotion, " + "?PhysicsShapeType, ?Density, ?GravityModifier, " + - "?Friction, ?Restitution)"; + "?Friction, ?Restitution, ?Vehicle)"; FillPrimCommand(cmd, prim, obj.UUID, regionUUID); @@ -1258,6 +1259,15 @@ namespace OpenSim.Data.MySQL prim.GravityModifier = (float)(double)row["GravityModifier"]; prim.Friction = (float)(double)row["Friction"]; prim.Bounciness = (float)(double)row["Restitution"]; + + SOPVehicle vehicle = null; + + if (row["Vehicle"].ToString() != String.Empty) + { + vehicle = SOPVehicle.FromXml2(row["Vehicle"].ToString()); + if (vehicle != null) + prim.VehicleParams = vehicle; + } return prim; } @@ -1635,6 +1645,11 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier); cmd.Parameters.AddWithValue("Friction", (double)prim.Friction); cmd.Parameters.AddWithValue("Restitution", (double)prim.Bounciness); + + if (prim.VehicleParams != null) + { + cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2()); + } } /// diff --git a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs index d3c2d27..45ca00c 100644 --- a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs +++ b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs @@ -30,6 +30,8 @@ using System.Collections.Generic; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Physics.Manager; +using System.Text; +using System.IO; using System.Xml; using OpenSim.Framework.Serialization; using OpenSim.Framework.Serialization.External; @@ -561,6 +563,35 @@ namespace OpenSim.Region.Framework.Scenes } + public string ToXml2() + { + MemoryStream ms = new MemoryStream(); + UTF8Encoding enc = new UTF8Encoding(); + XmlTextWriter writer = new XmlTextWriter(ms, null); + ToXml2(writer); + return enc.GetString(ms.ToArray()); + } + + public static SOPVehicle FromXml2(string text) + { + if (text == String.Empty) + return null; + UTF8Encoding enc = new UTF8Encoding(); + MemoryStream ms = new MemoryStream(enc.GetBytes(text)); + XmlTextReader reader = new XmlTextReader(ms); + + SOPVehicle v = new SOPVehicle(); + bool error; + + v.FromXml2(reader, out error); + if (error) + { + v = null; + return null; + } + + return v; + } public void FromXml2(XmlTextReader _reader, out bool errors) { @@ -739,4 +770,4 @@ namespace OpenSim.Region.Framework.Scenes vd.m_referenceFrame = XRquat(); } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ed32adc..dd30a59 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -338,7 +338,7 @@ namespace OpenSim.Region.Framework.Scenes private int LastColSoundSentTime; - private SOPVehicle m_vehicle = null; + private SOPVehicle m_vehicleParams = null; private KeyframeMotion m_keyframeMotion = null; @@ -3379,15 +3379,15 @@ namespace OpenSim.Region.Framework.Scenes Force = force; } - public SOPVehicle sopVehicle + public SOPVehicle VehicleParams { get { - return m_vehicle; + return m_vehicleParams; } set { - m_vehicle = value; + m_vehicleParams = value; } } @@ -3396,10 +3396,10 @@ namespace OpenSim.Region.Framework.Scenes { get { - if (m_vehicle == null) + if (m_vehicleParams == null) return (int)Vehicle.TYPE_NONE; else - return (int)m_vehicle.Type; + return (int)m_vehicleParams.Type; } set { @@ -3409,7 +3409,7 @@ namespace OpenSim.Region.Framework.Scenes public void SetVehicleType(int type) { - m_vehicle = null; + m_vehicleParams = null; if (type == (int)Vehicle.TYPE_NONE) { @@ -3417,8 +3417,8 @@ namespace OpenSim.Region.Framework.Scenes PhysActor.VehicleType = (int)Vehicle.TYPE_NONE; return; } - m_vehicle = new SOPVehicle(); - m_vehicle.ProcessTypeChange((Vehicle)type); + m_vehicleParams = new SOPVehicle(); + m_vehicleParams.ProcessTypeChange((Vehicle)type); { if (_parentID ==0 && PhysActor != null) PhysActor.VehicleType = type; @@ -3428,10 +3428,10 @@ namespace OpenSim.Region.Framework.Scenes public void SetVehicleFlags(int param, bool remove) { - if (m_vehicle == null) + if (m_vehicleParams == null) return; - m_vehicle.ProcessVehicleFlags(param, remove); + m_vehicleParams.ProcessVehicleFlags(param, remove); if (_parentID ==0 && PhysActor != null) { @@ -3441,10 +3441,10 @@ namespace OpenSim.Region.Framework.Scenes public void SetVehicleFloatParam(int param, float value) { - if (m_vehicle == null) + if (m_vehicleParams == null) return; - m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value); + m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value); if (_parentID == 0 && PhysActor != null) { @@ -3454,10 +3454,10 @@ namespace OpenSim.Region.Framework.Scenes public void SetVehicleVectorParam(int param, Vector3 value) { - if (m_vehicle == null) + if (m_vehicleParams == null) return; - m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value); + m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value); if (_parentID == 0 && PhysActor != null) { @@ -3467,10 +3467,10 @@ namespace OpenSim.Region.Framework.Scenes public void SetVehicleRotationParam(int param, Quaternion rotation) { - if (m_vehicle == null) + if (m_vehicleParams == null) return; - m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); + m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation); if (_parentID == 0 && PhysActor != null) { @@ -4637,8 +4637,8 @@ namespace OpenSim.Region.Framework.Scenes if (VolumeDetectActive) // change if not the default only pa.SetVolumeDetect(1); - if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId) - m_vehicle.SetVehicle(pa); + if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId) + m_vehicleParams.SetVehicle(pa); // we are going to tell rest of code about physics so better have this here PhysActor = pa; @@ -4676,7 +4676,7 @@ namespace OpenSim.Region.Framework.Scenes pa.RotationalVelocity = rotationalVelocity; // if not vehicle and root part apply force and torque - if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE) + if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE) && LocalId == ParentGroup.RootPart.LocalId) { pa.Force = Force; diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 151eba2..c7e4c3e 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -630,13 +630,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization if (errors) { - obj.sopVehicle = null; + obj.VehicleParams = null; m_log.DebugFormat( "[SceneObjectSerializer]: Parsing Vehicle for object part {0} {1} encountered errors. Please see earlier log entries.", obj.Name, obj.UUID); } else - obj.sopVehicle = _vehicle; + obj.VehicleParams = _vehicle; } private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) @@ -1325,8 +1325,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("VolumeDetectActive", sop.VolumeDetectActive.ToString().ToLower()); - if (sop.sopVehicle != null) - sop.sopVehicle.ToXml2(writer); + if (sop.VehicleParams != null) + sop.VehicleParams.ToXml2(writer); if(sop.PhysicsShapeType != sop.DefaultPhysicsShapeType()) writer.WriteElementString("PhysicsShapeType", sop.PhysicsShapeType.ToString().ToLower()); -- cgit v1.1 From 3024bdd097ab3d4378501da1d00fa6e12da3dfe6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 7 Jul 2012 02:29:21 +0200 Subject: Fix storing vehicle data --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index fecc329..7df5a81 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -1647,9 +1647,9 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("Restitution", (double)prim.Bounciness); if (prim.VehicleParams != null) - { cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2()); - } + else + cmd.Parameters.AddWithValue("Vehicle", String.Empty); } /// -- cgit v1.1 From d50b852d530bd17f2bb5a7964e9ddf81acff9146 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 7 Jul 2012 03:16:41 +0100 Subject: ODE turn off material dependent friction while vehicle linear motor is Effective. Increase a bit world damping of velocities --- OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | 9 ++++++--- OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 1 + OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index e27be1e..e900c02 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs @@ -137,6 +137,7 @@ namespace OpenSim.Region.Physics.OdePlugin float m_amdampY; float m_amdampZ; + public float FrictionFactor { get @@ -145,6 +146,7 @@ namespace OpenSim.Region.Physics.OdePlugin } } + public ODEDynamics(OdePrim rootp) { rootPrim = rootp; @@ -345,7 +347,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale; m_lmEfect = 1.0f; // turn it on - m_ffactor = 0.01f; + m_ffactor = 0.0f; if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) d.BodyEnable(rootPrim.Body); @@ -401,7 +403,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_lmEfect = 1.0f; // turn it on m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale; - m_ffactor = 0.01f; + m_ffactor = 0.0f; if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) d.BodyEnable(rootPrim.Body); @@ -805,7 +807,8 @@ namespace OpenSim.Region.Physics.OdePlugin } m_lmEfect *= m_lmDecay; - m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared(); +// m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared(); + m_ffactor = 0.0f; } else { diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 9b3b51b..3d8e680 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -275,6 +275,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (veh != null && veh.Type != Vehicle.TYPE_NONE) cdata.mu *= veh.FrictionFactor; +// cdata.mu *= 0; } } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 6c72324..4552f3f 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -526,8 +526,8 @@ namespace OpenSim.Region.Physics.OdePlugin d.WorldSetGravity(world, gravityx, gravityy, gravityz); d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); - d.WorldSetLinearDamping(world, 0.001f); - d.WorldSetAngularDamping(world, 0.001f); + d.WorldSetLinearDamping(world, 0.002f); + d.WorldSetAngularDamping(world, 0.002f); d.WorldSetAngularDampingThreshold(world, 0f); d.WorldSetLinearDampingThreshold(world, 0f); d.WorldSetMaxAngularSpeed(world, 100f); -- cgit v1.1 From afa02aa104e0cfbedd0e1b6c1d7b60522a79a4e8 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 7 Jul 2012 07:41:11 +0100 Subject: fix vehicle to XML string --- OpenSim/Region/Framework/Scenes/SOPVehicle.cs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs index 45ca00c..e2ef77b 100644 --- a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs +++ b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs @@ -565,31 +565,37 @@ namespace OpenSim.Region.Framework.Scenes public string ToXml2() { - MemoryStream ms = new MemoryStream(); + MemoryStream ms = new MemoryStream(512); UTF8Encoding enc = new UTF8Encoding(); - XmlTextWriter writer = new XmlTextWriter(ms, null); - ToXml2(writer); - return enc.GetString(ms.ToArray()); + XmlTextWriter xwriter = new XmlTextWriter(ms, enc); + ToXml2(xwriter); + xwriter.Flush(); + string s = ms.GetStreamString(); + xwriter.Close(); + return s; } public static SOPVehicle FromXml2(string text) { if (text == String.Empty) return null; + UTF8Encoding enc = new UTF8Encoding(); MemoryStream ms = new MemoryStream(enc.GetBytes(text)); - XmlTextReader reader = new XmlTextReader(ms); + XmlTextReader xreader = new XmlTextReader(ms); SOPVehicle v = new SOPVehicle(); bool error; - v.FromXml2(reader, out error); + v.FromXml2(xreader, out error); + + xreader.Close(); + if (error) { v = null; return null; } - return v; } -- cgit v1.1 From 470019b52a72de1a8777933ce3254cde87e184f9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 7 Jul 2012 19:59:55 +0200 Subject: Change semantics of FromXML on vehicle data to make the serializer a bit cleaner --- OpenSim/Region/Framework/Scenes/SOPVehicle.cs | 15 ++++++++++++++- .../Scenes/Serialization/SceneObjectSerializer.cs | 11 +++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs index e2ef77b..41e8944 100644 --- a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs +++ b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs @@ -599,7 +599,20 @@ namespace OpenSim.Region.Framework.Scenes return v; } - public void FromXml2(XmlTextReader _reader, out bool errors) + public static SOPVehicle FromXml2(XmlTextReader reader) + { + SOPVehicle vehicle = new SOPVehicle(); + + bool errors = false; + + vehicle.FromXml2(reader, out errors); + if (errors) + return null; + + return vehicle; + } + + private void FromXml2(XmlTextReader _reader, out bool errors) { errors = false; reader = _reader; diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index c7e4c3e..abca14f 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -623,12 +623,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessVehicle(SceneObjectPart obj, XmlTextReader reader) { - bool errors = false; - SOPVehicle _vehicle = new SOPVehicle(); + SOPVehicle vehicle = SOPVehicle.FromXml2(reader); - _vehicle.FromXml2(reader, out errors); - - if (errors) + if (vehicle == null) { obj.VehicleParams = null; m_log.DebugFormat( @@ -636,7 +633,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization obj.Name, obj.UUID); } else - obj.VehicleParams = _vehicle; + { + obj.VehicleParams = vehicle; + } } private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) -- cgit v1.1 From d3b778ebbe617a37a32c866101c75284dad8f15a Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 8 Jul 2012 06:06:33 +0200 Subject: Address map lag issue seen with non-avination viewers --- .../CoreModules/World/WorldMap/MapSearchModule.cs | 161 +++++----- .../CoreModules/World/WorldMap/WorldMapModule.cs | 357 ++++++++++----------- .../Server/Handlers/Map/MapGetServerConnector.cs | 15 +- 3 files changed, 271 insertions(+), 262 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 4e6bfb8..2417b1a 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -86,90 +86,93 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { - if (mapName.Length < 2) + Util.FireAndForget(x => { - remoteClient.SendAlertMessage("Use a search string with at least 2 characters"); - return; - } + if (mapName.Length < 2) + { + remoteClient.SendAlertMessage("Use a search string with at least 2 characters"); + return; + } - //m_log.DebugFormat("MAP NAME=({0})", mapName); - - // Hack to get around the fact that ll V3 now drops the port from the - // map name. See https://jira.secondlife.com/browse/VWR-28570 - // - // Caller, use this magic form instead: - // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 - // or url encode if possible. - // the hacks we do with this viewer... - // - string mapNameOrig = mapName; - if (mapName.Contains("|")) - mapName = mapName.Replace('|', ':'); - if (mapName.Contains("+")) - mapName = mapName.Replace('+', ' '); - if (mapName.Contains("!")) - mapName = mapName.Replace('!', '/'); - - // try to fetch from GridServer - List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); -// if (regionInfos.Count == 0) -// remoteClient.SendAlertMessage("Hyperlink could not be established."); - - //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); - List blocks = new List(); - - MapBlockData data; - if (regionInfos.Count > 0) - { - foreach (GridRegion info in regionInfos) + //m_log.DebugFormat("MAP NAME=({0})", mapName); + + // Hack to get around the fact that ll V3 now drops the port from the + // map name. See https://jira.secondlife.com/browse/VWR-28570 + // + // Caller, use this magic form instead: + // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 + // or url encode if possible. + // the hacks we do with this viewer... + // + string mapNameOrig = mapName; + if (mapName.Contains("|")) + mapName = mapName.Replace('|', ':'); + if (mapName.Contains("+")) + mapName = mapName.Replace('+', ' '); + if (mapName.Contains("!")) + mapName = mapName.Replace('!', '/'); + + // try to fetch from GridServer + List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); + // if (regionInfos.Count == 0) + // remoteClient.SendAlertMessage("Hyperlink could not be established."); + + //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); + List blocks = new List(); + + MapBlockData data; + if (regionInfos.Count > 0) { - data = new MapBlockData(); - data.Agents = 0; - data.Access = info.Access; - if (flags == 2) // V2 sends this - data.MapImageId = UUID.Zero; - else - data.MapImageId = info.TerrainImage; - // ugh! V2-3 is very sensitive about the result being - // exactly the same as the requested name - if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+")) - data.Name = mapNameOrig; - else - data.Name = info.RegionName; - data.RegionFlags = 0; // TODO not used? - data.WaterHeight = 0; // not used - data.X = (ushort)(info.RegionLocX / Constants.RegionSize); - data.Y = (ushort)(info.RegionLocY / Constants.RegionSize); - blocks.Add(data); + foreach (GridRegion info in regionInfos) + { + data = new MapBlockData(); + data.Agents = 0; + data.Access = info.Access; + if (flags == 2) // V2 sends this + data.MapImageId = UUID.Zero; + else + data.MapImageId = info.TerrainImage; + // ugh! V2-3 is very sensitive about the result being + // exactly the same as the requested name + if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+")) + data.Name = mapNameOrig; + else + data.Name = info.RegionName; + data.RegionFlags = 0; // TODO not used? + data.WaterHeight = 0; // not used + data.X = (ushort)(info.RegionLocX / Constants.RegionSize); + data.Y = (ushort)(info.RegionLocY / Constants.RegionSize); + blocks.Add(data); + } } - } - // final block, closing the search result - data = new MapBlockData(); - data.Agents = 0; - data.Access = 255; - data.MapImageId = UUID.Zero; - data.Name = mapName; - data.RegionFlags = 0; - data.WaterHeight = 0; // not used - data.X = 0; - data.Y = 0; - blocks.Add(data); - - // flags are agent flags sent from the viewer. - // they have different values depending on different viewers, apparently - remoteClient.SendMapBlock(blocks, flags); - - // send extra user messages for V3 - // because the UI is very confusing - // while we don't fix the hard-coded urls - if (flags == 2) - { - if (regionInfos.Count == 0) - remoteClient.SendAgentAlertMessage("No regions found with that name.", true); - else if (regionInfos.Count == 1) - remoteClient.SendAgentAlertMessage("Region found!", false); - } + // final block, closing the search result + data = new MapBlockData(); + data.Agents = 0; + data.Access = 255; + data.MapImageId = UUID.Zero; + data.Name = mapName; + data.RegionFlags = 0; + data.WaterHeight = 0; // not used + data.X = 0; + data.Y = 0; + blocks.Add(data); + + // flags are agent flags sent from the viewer. + // they have different values depending on different viewers, apparently + remoteClient.SendMapBlock(blocks, flags); + + // send extra user messages for V3 + // because the UI is very confusing + // while we don't fix the hard-coded urls + if (flags == 2) + { + if (regionInfos.Count == 0) + remoteClient.SendAgentAlertMessage("No regions found with that name.", true); + else if (regionInfos.Count == 1) + remoteClient.SendAgentAlertMessage("Region found!", false); + } + }); } // private Scene GetClientScene(IClientAPI client) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 899e5ea..721ac5c 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -63,7 +63,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private static readonly UUID STOP_UUID = UUID.Random(); private static readonly string m_mapLayerPath = "0001/"; - private OpenSim.Framework.BlockingQueue requests = new OpenSim.Framework.BlockingQueue(); + private ManualResetEvent queueEvent = new ManualResetEvent(false); + private Queue requests = new Queue(); protected Scene m_scene; private List cachedMapBlocks = new List(); @@ -71,7 +72,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private int blacklistTimeout = 10*60*1000; // 10 minutes private byte[] myMapImageJPEG; protected volatile bool m_Enabled = false; - private Dictionary m_openRequests = new Dictionary(); private Dictionary m_blacklistedurls = new Dictionary(); private Dictionary m_blacklistedregions = new Dictionary(); private Dictionary m_cachedRegionMapItemsAddress = new Dictionary(); @@ -368,7 +368,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap st.itemtype=0; st.regionhandle=0; - requests.Enqueue(st); + lock (requests) + { + queueEvent.Set(); + requests.Enqueue(st); + } } public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, @@ -519,12 +523,26 @@ namespace OpenSim.Region.CoreModules.World.WorldMap /// public void process() { - const int MAX_ASYNC_REQUESTS = 20; + const int MAX_ASYNC_REQUESTS = 5; try { while (true) { - MapRequestState st = requests.Dequeue(1000); + MapRequestState st = new MapRequestState(); + bool valid = false; + queueEvent.WaitOne(); + lock (requests) + { + if (requests.Count > 0) + { + st = requests.Dequeue(); + valid = true; + } + if (requests.Count == 0) + queueEvent.Reset(); + } + if (!valid) + continue; // end gracefully if (st.agentID == STOP_UUID) @@ -541,14 +559,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) { - while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break - Thread.Sleep(80); +// while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break +// Thread.Sleep(500); - RequestMapItemsDelegate d = RequestMapItemsAsync; - d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null); - //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); - //RequestMapItemsCompleted(response); Interlocked.Increment(ref nAsyncRequests); + RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); } } @@ -570,110 +585,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap /// public void EnqueueMapItemRequest(MapRequestState state) { - requests.Enqueue(state); - } - - /// - /// Sends the mapitem response to the IClientAPI - /// - /// The OSDMap Response for the mapitem - private void RequestMapItemsCompleted(IAsyncResult iar) - { - AsyncResult result = (AsyncResult)iar; - RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate; - - OSDMap response = (OSDMap)icon.EndInvoke(iar); - - Interlocked.Decrement(ref nAsyncRequests); - - if (!response.ContainsKey("requestID")) - return; - - UUID requestID = response["requestID"].AsUUID(); - - if (requestID != UUID.Zero) + lock (requests) { - MapRequestState mrs = new MapRequestState(); - mrs.agentID = UUID.Zero; - lock (m_openRequests) - { - if (m_openRequests.ContainsKey(requestID)) - { - mrs = m_openRequests[requestID]; - m_openRequests.Remove(requestID); - } - } - - if (mrs.agentID != UUID.Zero) - { - ScenePresence av = null; - m_scene.TryGetScenePresence(mrs.agentID, out av); - if (av != null) - { - if (response.ContainsKey(mrs.itemtype.ToString())) - { - List returnitems = new List(); - OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()]; - for (int i = 0; i < itemarray.Count; i++) - { - OSDMap mapitem = (OSDMap)itemarray[i]; - mapItemReply mi = new mapItemReply(); - mi.x = (uint)mapitem["X"].AsInteger(); - mi.y = (uint)mapitem["Y"].AsInteger(); - mi.id = mapitem["ID"].AsUUID(); - mi.Extra = mapitem["Extra"].AsInteger(); - mi.Extra2 = mapitem["Extra2"].AsInteger(); - mi.name = mapitem["Name"].AsString(); - returnitems.Add(mi); - } - av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); - } - - // Service 7 (MAP_ITEM_LAND_FOR_SALE) - uint itemtype = 7; - - if (response.ContainsKey(itemtype.ToString())) - { - List returnitems = new List(); - OSDArray itemarray = (OSDArray)response[itemtype.ToString()]; - for (int i = 0; i < itemarray.Count; i++) - { - OSDMap mapitem = (OSDMap)itemarray[i]; - mapItemReply mi = new mapItemReply(); - mi.x = (uint)mapitem["X"].AsInteger(); - mi.y = (uint)mapitem["Y"].AsInteger(); - mi.id = mapitem["ID"].AsUUID(); - mi.Extra = mapitem["Extra"].AsInteger(); - mi.Extra2 = mapitem["Extra2"].AsInteger(); - mi.name = mapitem["Name"].AsString(); - returnitems.Add(mi); - } - av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); - } - - // Service 1 (MAP_ITEM_TELEHUB) - itemtype = 1; - - if (response.ContainsKey(itemtype.ToString())) - { - List returnitems = new List(); - OSDArray itemarray = (OSDArray)response[itemtype.ToString()]; - for (int i = 0; i < itemarray.Count; i++) - { - OSDMap mapitem = (OSDMap)itemarray[i]; - mapItemReply mi = new mapItemReply(); - mi.x = (uint)mapitem["X"].AsInteger(); - mi.y = (uint)mapitem["Y"].AsInteger(); - mi.id = mapitem["ID"].AsUUID(); - mi.Extra = mapitem["Extra"].AsInteger(); - mi.Extra2 = mapitem["Extra2"].AsInteger(); - mi.name = mapitem["Name"].AsString(); - returnitems.Add(mi); - } - av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); - } - } - } + queueEvent.Set(); + requests.Enqueue(state); } } @@ -700,8 +615,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap EnqueueMapItemRequest(st); } - private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags, - uint EstateID, bool godlike, uint itemtype, ulong regionhandle); /// /// Does the actual remote mapitem request /// This should be called from an asynchronous thread @@ -716,7 +629,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap /// passed in from packet /// Region we're looking up /// - private OSDMap RequestMapItemsAsync(UUID id, uint flags, + private void RequestMapItemsAsync(UUID id, uint flags, uint EstateID, bool godlike, uint itemtype, ulong regionhandle) { // m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); @@ -739,7 +652,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } if (blacklisted) - return new OSDMap(); + { + Interlocked.Decrement(ref nAsyncRequests); + return; + } UUID requestID = UUID.Random(); lock (m_cachedRegionMapItemsAddress) @@ -747,6 +663,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) httpserver = m_cachedRegionMapItemsAddress[regionhandle]; } + if (httpserver.Length == 0) { uint x = 0, y = 0; @@ -791,18 +708,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // Can't find the http server if (httpserver.Length == 0 || blacklisted) - return new OSDMap(); - - MapRequestState mrs = new MapRequestState(); - mrs.agentID = id; - mrs.EstateID = EstateID; - mrs.flags = flags; - mrs.godlike = godlike; - mrs.itemtype=itemtype; - mrs.regionhandle = regionhandle; - - lock (m_openRequests) - m_openRequests.Add(requestID, mrs); + { + Interlocked.Decrement(ref nAsyncRequests); + return; + } WebRequest mapitemsrequest = null; try @@ -812,7 +721,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap catch (Exception e) { m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); - return new OSDMap(); + Interlocked.Decrement(ref nAsyncRequests); + return; } mapitemsrequest.Method = "POST"; @@ -826,6 +736,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap OSDMap responseMap = new OSDMap(); responseMap["requestID"] = OSD.FromUUID(requestID); +return; Stream os = null; try { // send the Post @@ -837,7 +748,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap catch (WebException ex) { m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); - responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedurls) { if (!m_blacklistedurls.ContainsKey(httpserver)) @@ -846,13 +756,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); - return responseMap; + Interlocked.Decrement(ref nAsyncRequests); + return; } catch { m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); - responseMap["connect"] = OSD.FromBoolean(false); - return responseMap; + Interlocked.Decrement(ref nAsyncRequests); + return; } finally { @@ -873,12 +784,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } else { - return new OSDMap(); + Interlocked.Decrement(ref nAsyncRequests); + return; } } catch (WebException) { - responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedurls) { if (!m_blacklistedurls.ContainsKey(httpserver)) @@ -887,19 +798,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); - return responseMap; + Interlocked.Decrement(ref nAsyncRequests); + return; } catch { m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); - responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedregions) { if (!m_blacklistedregions.ContainsKey(regionhandle)) m_blacklistedregions.Add(regionhandle, Environment.TickCount); } - return responseMap; + Interlocked.Decrement(ref nAsyncRequests); + return; } finally { @@ -918,14 +830,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap catch (Exception ex) { m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); - responseMap["connect"] = OSD.FromBoolean(false); lock (m_blacklistedregions) { if (!m_blacklistedregions.ContainsKey(regionhandle)) m_blacklistedregions.Add(regionhandle, Environment.TickCount); } - return responseMap; + Interlocked.Decrement(ref nAsyncRequests); + return; } } @@ -939,7 +851,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } } - return responseMap; + Interlocked.Decrement(ref nAsyncRequests); + + if (id != UUID.Zero) + { + ScenePresence av = null; + m_scene.TryGetScenePresence(id, out av); + if (av != null) + { + if (responseMap.ContainsKey(itemtype.ToString())) + { + List returnitems = new List(); + OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()]; + for (int i = 0; i < itemarray.Count; i++) + { + OSDMap mapitem = (OSDMap)itemarray[i]; + mapItemReply mi = new mapItemReply(); + mi.x = (uint)mapitem["X"].AsInteger(); + mi.y = (uint)mapitem["Y"].AsInteger(); + mi.id = mapitem["ID"].AsUUID(); + mi.Extra = mapitem["Extra"].AsInteger(); + mi.Extra2 = mapitem["Extra2"].AsInteger(); + mi.name = mapitem["Name"].AsString(); + returnitems.Add(mi); + } + av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags); + } + + // Service 7 (MAP_ITEM_LAND_FOR_SALE) + itemtype = 7; + + if (responseMap.ContainsKey(itemtype.ToString())) + { + List returnitems = new List(); + OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()]; + for (int i = 0; i < itemarray.Count; i++) + { + OSDMap mapitem = (OSDMap)itemarray[i]; + mapItemReply mi = new mapItemReply(); + mi.x = (uint)mapitem["X"].AsInteger(); + mi.y = (uint)mapitem["Y"].AsInteger(); + mi.id = mapitem["ID"].AsUUID(); + mi.Extra = mapitem["Extra"].AsInteger(); + mi.Extra2 = mapitem["Extra2"].AsInteger(); + mi.name = mapitem["Name"].AsString(); + returnitems.Add(mi); + } + av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags); + } + + // Service 1 (MAP_ITEM_TELEHUB) + itemtype = 1; + + if (responseMap.ContainsKey(itemtype.ToString())) + { + List returnitems = new List(); + OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()]; + for (int i = 0; i < itemarray.Count; i++) + { + OSDMap mapitem = (OSDMap)itemarray[i]; + mapItemReply mi = new mapItemReply(); + mi.x = (uint)mapitem["X"].AsInteger(); + mi.y = (uint)mapitem["Y"].AsInteger(); + mi.id = mapitem["ID"].AsUUID(); + mi.Extra = mapitem["Extra"].AsInteger(); + mi.Extra2 = mapitem["Extra2"].AsInteger(); + mi.name = mapitem["Name"].AsString(); + returnitems.Add(mi); + } + av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags); + } + } + } } /// @@ -951,53 +934,56 @@ namespace OpenSim.Region.CoreModules.World.WorldMap /// public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { - //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); - if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible + Util.FireAndForget(x => { - List response = new List(); - - // this should return one mapblock at most. It is triggered by a click - // on an unloaded square. - // But make sure: Look whether the one we requested is in there - List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - minX * (int)Constants.RegionSize, - maxX * (int)Constants.RegionSize, - minY * (int)Constants.RegionSize, - maxY * (int)Constants.RegionSize); - - if (regions != null) + //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); + if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible { - foreach (GridRegion r in regions) + List response = new List(); + + // this should return one mapblock at most. It is triggered by a click + // on an unloaded square. + // But make sure: Look whether the one we requested is in there + List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, + minX * (int)Constants.RegionSize, + maxX * (int)Constants.RegionSize, + minY * (int)Constants.RegionSize, + maxY * (int)Constants.RegionSize); + + if (regions != null) { - if ((r.RegionLocX == minX * (int)Constants.RegionSize) && - (r.RegionLocY == minY * (int)Constants.RegionSize)) + foreach (GridRegion r in regions) { - // found it => add it to response - MapBlockData block = new MapBlockData(); - MapBlockFromGridRegion(block, r, flag); - response.Add(block); - break; + if ((r.RegionLocX == minX * (int)Constants.RegionSize) && + (r.RegionLocY == minY * (int)Constants.RegionSize)) + { + // found it => add it to response + MapBlockData block = new MapBlockData(); + MapBlockFromGridRegion(block, r, flag); + response.Add(block); + break; + } } } - } - if (response.Count == 0) + if (response.Count == 0) + { + // response still empty => couldn't find the map-tile the user clicked on => tell the client + MapBlockData block = new MapBlockData(); + block.X = (ushort)minX; + block.Y = (ushort)minY; + block.Access = 254; // means 'simulator is offline' + response.Add(block); + } + // The lower 16 bits are an unsigned int16 + remoteClient.SendMapBlock(response, flag & 0xffff); + } + else { - // response still empty => couldn't find the map-tile the user clicked on => tell the client - MapBlockData block = new MapBlockData(); - block.X = (ushort)minX; - block.Y = (ushort)minY; - block.Access = 254; // means 'simulator is offline' - response.Add(block); + // normal mapblock request. Use the provided values + GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); } - // The lower 16 bits are an unsigned int16 - remoteClient.SendMapBlock(response, flag & 0xffff); - } - else - { - // normal mapblock request. Use the provided values - GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); - } + }); } protected virtual List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) @@ -1013,8 +999,15 @@ namespace OpenSim.Region.CoreModules.World.WorldMap MapBlockData block = new MapBlockData(); MapBlockFromGridRegion(block, r, flag); mapBlocks.Add(block); + if (mapBlocks.Count >= 20) + { + remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); + mapBlocks.Clear(); + Thread.Sleep(1000); + } } - remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); + if (mapBlocks.Count > 0) + remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); return mapBlocks; } diff --git a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs index fb85d1c..4502b7d 100644 --- a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs @@ -29,6 +29,7 @@ using System; using System.IO; using System.Net; using System.Reflection; +using System.Threading; using Nini.Config; using log4net; @@ -70,6 +71,8 @@ namespace OpenSim.Server.Handlers.MapImage class MapServerGetHandler : BaseStreamHandler { + public static ManualResetEvent ev = new ManualResetEvent(true); + // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IMapImageService m_MapService; @@ -82,8 +85,13 @@ namespace OpenSim.Server.Handlers.MapImage public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - byte[] result = new byte[0]; + ev.WaitOne(); + lock (ev) + { + ev.Reset(); + } + byte[] result = new byte[0]; string format = string.Empty; result = m_MapService.GetMapTile(path.Trim('/'), out format); if (result.Length > 0) @@ -100,6 +108,11 @@ namespace OpenSim.Server.Handlers.MapImage httpResponse.ContentType = "text/plain"; } + lock (ev) + { + ev.Set(); + } + return result; } -- cgit v1.1 From 73c5a6e66637b9f5f0d7dc3f4bf4c9818223b3e9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 8 Jul 2012 07:42:40 +0200 Subject: Instead of sending 20 records in 2 packets, send just one as we intended in the first place. --- OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 721ac5c..88aacb9 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -999,7 +999,7 @@ return; MapBlockData block = new MapBlockData(); MapBlockFromGridRegion(block, r, flag); mapBlocks.Add(block); - if (mapBlocks.Count >= 20) + if (mapBlocks.Count >= 10) { remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); mapBlocks.Clear(); -- cgit v1.1 From 1e4c65649736db82d0221b6b2aa57f7f45c7163c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 8 Jul 2012 10:44:53 +0200 Subject: Revamp map block sending to eliminate overload of the grid server connection and the sim's http client --- .../CoreModules/Hypergrid/HGWorldMapModule.cs | 4 +- .../CoreModules/World/WorldMap/WorldMapModule.cs | 298 ++++++++++++++------- 2 files changed, 204 insertions(+), 98 deletions(-) diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index 0c60391..4f18b53 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -90,9 +90,9 @@ namespace OpenSim.Region.CoreModules.Hypergrid } } - protected override List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + protected override List GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { - List mapBlocks = base.GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); + List mapBlocks = base.GetAndSendBlocksInternal(remoteClient, minX, minY, maxX, maxY, flag); lock (m_SeenMapBlocks) { if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId)) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 88aacb9..a226b78 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -66,6 +66,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private ManualResetEvent queueEvent = new ManualResetEvent(false); private Queue requests = new Queue(); + private ManualResetEvent m_mapBlockRequestEvent = new ManualResetEvent(false); + private Dictionary> m_mapBlockRequests = new Dictionary>(); + protected Scene m_scene; private List cachedMapBlocks = new List(); private int cachedTime = 0; @@ -227,54 +230,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. - if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) - { - ScenePresence avatarPresence = null; - - m_scene.TryGetScenePresence(agentID, out avatarPresence); - - if (avatarPresence != null) - { - bool lookup = false; - - lock (cachedMapBlocks) - { - if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) - { - List mapBlocks; - - mapBlocks = cachedMapBlocks; - avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); - } - else - { - lookup = true; - } - } - if (lookup) - { - List mapBlocks = new List(); ; - - List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, - (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, - (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, - (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); - foreach (GridRegion r in regions) - { - MapBlockData block = new MapBlockData(); - MapBlockFromGridRegion(block, r, 0); - mapBlocks.Add(block); - } - avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); - - lock (cachedMapBlocks) - cachedMapBlocks = mapBlocks; - - cachedTime = Util.UnixTimeSinceEpoch(); - } - } - } + //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) + //{ + // ScenePresence avatarPresence = null; + + // m_scene.TryGetScenePresence(agentID, out avatarPresence); + + // if (avatarPresence != null) + // { + // bool lookup = false; + + // lock (cachedMapBlocks) + // { + // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) + // { + // List mapBlocks; + + // mapBlocks = cachedMapBlocks; + // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); + // } + // else + // { + // lookup = true; + // } + // } + // if (lookup) + // { + // List mapBlocks = new List(); ; + + // List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, + // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, + // (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, + // (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, + // (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); + // foreach (GridRegion r in regions) + // { + // MapBlockData block = new MapBlockData(); + // MapBlockFromGridRegion(block, r, 0); + // mapBlocks.Add(block); + // } + // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); + + // lock (cachedMapBlocks) + // cachedMapBlocks = mapBlocks; + + // cachedTime = Util.UnixTimeSinceEpoch(); + // } + // } + //} LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); @@ -301,8 +304,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap protected static OSDMapLayer GetOSDMapLayerResponse() { OSDMapLayer mapLayer = new OSDMapLayer(); - mapLayer.Right = 5000; - mapLayer.Top = 5000; + mapLayer.Right = 2048; + mapLayer.Top = 2048; mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); return mapLayer; @@ -331,6 +334,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { m_rootAgents.Remove(AgentId); } + lock (m_mapBlockRequestEvent) + { + if (m_mapBlockRequests.ContainsKey(AgentId)) + m_mapBlockRequests.Remove(AgentId); + } } #endregion @@ -353,6 +361,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap ThreadPriority.BelowNormal, true, true); + Watchdog.StartThread( + MapBlockSendThread, + string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName), + ThreadPriority.BelowNormal, + true, + true); } /// @@ -373,6 +387,22 @@ namespace OpenSim.Region.CoreModules.World.WorldMap queueEvent.Set(); requests.Enqueue(st); } + + MapBlockRequestData req = new MapBlockRequestData(); + + req.client = null; + req.minX = 0; + req.maxX = 0; + req.minY = 0; + req.maxY = 0; + req.flags = 0; + + lock (m_mapBlockRequestEvent) + { + m_mapBlockRequests[UUID.Zero] = new Queue(); + m_mapBlockRequests[UUID.Zero].Enqueue(req); + m_mapBlockRequestEvent.Set(); + } } public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, @@ -932,84 +962,144 @@ return; /// /// /// - public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { - Util.FireAndForget(x => + //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); + if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible { - //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); - if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible + List response = new List(); + + // this should return one mapblock at most. It is triggered by a click + // on an unloaded square. + // But make sure: Look whether the one we requested is in there + List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, + minX * (int)Constants.RegionSize, + maxX * (int)Constants.RegionSize, + minY * (int)Constants.RegionSize, + maxY * (int)Constants.RegionSize); + + if (regions != null) { - List response = new List(); - - // this should return one mapblock at most. It is triggered by a click - // on an unloaded square. - // But make sure: Look whether the one we requested is in there - List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - minX * (int)Constants.RegionSize, - maxX * (int)Constants.RegionSize, - minY * (int)Constants.RegionSize, - maxY * (int)Constants.RegionSize); - - if (regions != null) + foreach (GridRegion r in regions) { - foreach (GridRegion r in regions) + if ((r.RegionLocX == minX * (int)Constants.RegionSize) && + (r.RegionLocY == minY * (int)Constants.RegionSize)) { - if ((r.RegionLocX == minX * (int)Constants.RegionSize) && - (r.RegionLocY == minY * (int)Constants.RegionSize)) - { - // found it => add it to response - MapBlockData block = new MapBlockData(); - MapBlockFromGridRegion(block, r, flag); - response.Add(block); - break; - } + // found it => add it to response + MapBlockData block = new MapBlockData(); + MapBlockFromGridRegion(block, r, flag); + response.Add(block); + break; } } + } - if (response.Count == 0) + if (response.Count == 0) + { + // response still empty => couldn't find the map-tile the user clicked on => tell the client + MapBlockData block = new MapBlockData(); + block.X = (ushort)minX; + block.Y = (ushort)minY; + block.Access = 254; // means 'simulator is offline' + response.Add(block); + } + // The lower 16 bits are an unsigned int16 + remoteClient.SendMapBlock(response, flag & 0xffff); + } + else + { + // normal mapblock request. Use the provided values + GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); + } + } + + protected virtual List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + { + MapBlockRequestData req = new MapBlockRequestData(); + + req.client = remoteClient; + req.minX = minX; + req.maxX = maxX; + req.minY = minY; + req.maxY = maxY; + req.flags = flag; + + lock (m_mapBlockRequestEvent) + { + if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId)) + m_mapBlockRequests[remoteClient.AgentId] = new Queue(); + m_mapBlockRequests[remoteClient.AgentId].Enqueue(req); + m_mapBlockRequestEvent.Set(); + } + + return new List(); + } + + protected void MapBlockSendThread() + { + while (true) + { + List thisRunData = new List(); + + m_mapBlockRequestEvent.WaitOne(); + lock (m_mapBlockRequestEvent) + { + int total = 0; + foreach (Queue q in m_mapBlockRequests.Values) { - // response still empty => couldn't find the map-tile the user clicked on => tell the client - MapBlockData block = new MapBlockData(); - block.X = (ushort)minX; - block.Y = (ushort)minY; - block.Access = 254; // means 'simulator is offline' - response.Add(block); + if (q.Count > 0) + thisRunData.Add(q.Dequeue()); + + total += q.Count; } - // The lower 16 bits are an unsigned int16 - remoteClient.SendMapBlock(response, flag & 0xffff); + + if (total == 0) + m_mapBlockRequestEvent.Reset(); } - else + + foreach (MapBlockRequestData req in thisRunData) { - // normal mapblock request. Use the provided values - GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); + // Null client stops thread + if (req.client == null) + return; + + GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags); } - }); + + Thread.Sleep(50); + } } - protected virtual List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + protected virtual List GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { + List allBlocks = new List(); List mapBlocks = new List(); List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - (minX - 4) * (int)Constants.RegionSize, - (maxX + 4) * (int)Constants.RegionSize, - (minY - 4) * (int)Constants.RegionSize, - (maxY + 4) * (int)Constants.RegionSize); + minX * (int)Constants.RegionSize, + maxX * (int)Constants.RegionSize, + minY * (int)Constants.RegionSize, + maxY * (int)Constants.RegionSize); +// (minX - 4) * (int)Constants.RegionSize, +// (maxX + 4) * (int)Constants.RegionSize, +// (minY - 4) * (int)Constants.RegionSize, +// (maxY + 4) * (int)Constants.RegionSize); foreach (GridRegion r in regions) { MapBlockData block = new MapBlockData(); MapBlockFromGridRegion(block, r, flag); mapBlocks.Add(block); + allBlocks.Add(block); if (mapBlocks.Count >= 10) { remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); mapBlocks.Clear(); - Thread.Sleep(1000); + Thread.Sleep(50); } } if (mapBlocks.Count > 0) remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); - return mapBlocks; + return allBlocks; } protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) @@ -1408,6 +1498,12 @@ return; { m_rootAgents.Remove(avatar.UUID); } + + lock (m_mapBlockRequestEvent) + { + if (m_mapBlockRequests.ContainsKey(avatar.UUID)) + m_mapBlockRequests.Remove(avatar.UUID); + } } public void OnRegionUp(GridRegion otherRegion) @@ -1531,4 +1627,14 @@ return; public uint itemtype; public ulong regionhandle; } + + public struct MapBlockRequestData + { + public IClientAPI client; + public int minX; + public int minY; + public int maxX; + public int maxY; + public uint flags; + } } -- cgit v1.1 From 1077d7b6f5874a036752f1ca672ce6b8c41004a0 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 8 Jul 2012 21:53:23 +0200 Subject: Reinstate parallel fetching of residents and remove a left over return from debugging --- OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index a226b78..1dedcce 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -553,7 +553,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap /// public void process() { - const int MAX_ASYNC_REQUESTS = 5; + const int MAX_ASYNC_REQUESTS = 20; try { while (true) @@ -589,11 +589,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) { -// while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break -// Thread.Sleep(500); + while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break + Thread.Sleep(100); Interlocked.Increment(ref nAsyncRequests); - RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); + Util.FireAndForget(x => + { + RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); + }); } } @@ -766,7 +769,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap OSDMap responseMap = new OSDMap(); responseMap["requestID"] = OSD.FromUUID(requestID); -return; Stream os = null; try { // send the Post -- cgit v1.1 From fb8e8dcbce6b2ecbb8fbfe8278657260ac55e823 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 9 Jul 2012 13:25:17 +0100 Subject: fix ODE dispose plus minor clean. On regions restart ode.dispose seems to be called with scene still calling simulation, that should be changed, for now added a check for a valid world in ode simulation --- OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 58 ++++++++++++++++++------ 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 4552f3f..5920838 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -268,7 +268,7 @@ namespace OpenSim.Region.Physics.OdePlugin public ContactData[] m_materialContactsData = new ContactData[8]; - private readonly DoubleDictionary RegionTerrain = new DoubleDictionary(); + private readonly Dictionary RegionTerrain = new Dictionary(); private readonly Dictionary TerrainHeightFieldHeights = new Dictionary(); private readonly Dictionary TerrainHeightFieldHeightsHandlers = new Dictionary(); @@ -1892,18 +1892,22 @@ namespace OpenSim.Region.Physics.OdePlugin lock (SimulationLock) lock(OdeLock) { + if (world == IntPtr.Zero) + return 0; + // adjust number of iterations per step - try - { + +// try +// { d.WorldSetQuickStepNumIterations(world, curphysiteractions); - } +/* } catch (StackOverflowException) { m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim."); // ode.drelease(world); base.TriggerPhysicsBasedRestart(); } - +*/ while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever { try @@ -2383,11 +2387,9 @@ namespace OpenSim.Region.Physics.OdePlugin d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); d.GeomSetRotation(GroundGeom, ref R); 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); + RegionTerrain.Add(pOffset, GroundGeom); TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); - TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler); - + TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler); } } @@ -2486,8 +2488,7 @@ namespace OpenSim.Region.Physics.OdePlugin 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); + RegionTerrain.Add(pOffset, GroundGeom); TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler); } @@ -2649,19 +2650,42 @@ namespace OpenSim.Region.Physics.OdePlugin public override void Dispose() { - m_rayCastManager.Dispose(); - m_rayCastManager = null; - lock (OdeLock) { + m_rayCastManager.Dispose(); + m_rayCastManager = null; + lock (_prims) { + ChangesQueue.Clear(); foreach (OdePrim prm in _prims) { - RemovePrim(prm); + prm.DoAChange(changes.Remove, null); + _collisionEventPrim.Remove(prm); } + _prims.Clear(); } + OdeCharacter[] chtorem; + lock (_characters) + { + chtorem = new OdeCharacter[_characters.Count]; + _characters.CopyTo(chtorem); + } + + ChangesQueue.Clear(); + foreach (OdeCharacter ch in chtorem) + ch.DoAChange(changes.Remove, null); + + + foreach (IntPtr GroundGeom in RegionTerrain.Values) + { + if (GroundGeom != IntPtr.Zero) + d.GeomDestroy(GroundGeom); + } + + RegionTerrain.Clear(); + if (TerrainHeightFieldHeightsHandlers.Count > 0) { foreach (GCHandle gch in TerrainHeightFieldHeightsHandlers.Values) @@ -2671,6 +2695,9 @@ namespace OpenSim.Region.Physics.OdePlugin } } + TerrainHeightFieldHeightsHandlers.Clear(); + TerrainHeightFieldHeights.Clear(); + if (WaterGeom != IntPtr.Zero) { d.GeomDestroy(WaterGeom); @@ -2691,6 +2718,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.WorldDestroy(world); + world = IntPtr.Zero; //d.CloseODE(); } } -- cgit v1.1 From 0ac161c9a89075b414941d00b34b50e16c023a51 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 9 Jul 2012 16:51:56 +0100 Subject: log ODE lib configuration --- OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 5920838..46251de 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -175,7 +175,7 @@ namespace OpenSim.Region.Physics.OdePlugin const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; const float MaxERP = 0.8f; - const float minERP = 0.1f; + const float minERP = 0.2f; const float comumContactCFM = 0.0001f; float frictionMovementMult = 0.8f; @@ -408,7 +408,7 @@ namespace OpenSim.Region.Physics.OdePlugin // checkThread(); mesher = meshmerizer; m_config = config; -/* + string ode_config = d.GetConfiguration("ODE"); if (ode_config != null && ode_config != "") { @@ -419,7 +419,7 @@ namespace OpenSim.Region.Physics.OdePlugin OdeUbitLib = true; } } -*/ + /* if (region != null) { @@ -921,6 +921,8 @@ namespace OpenSim.Region.Physics.OdePlugin cfm = 0.0001f / cfm; if (cfm > 0.01f) cfm = 0.01f; + else if (cfm < 0.0001f) + cfm = 0.0001f; if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) mu *= frictionMovementMult; @@ -947,6 +949,8 @@ namespace OpenSim.Region.Physics.OdePlugin cfm = 0.0001f / cfm; if (cfm > 0.01f) cfm = 0.01f; + else if (cfm < 0.0001f) + cfm = 0.0001f; if (d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) { -- cgit v1.1 From a7097680851528f01477903d946095abce99e504 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 9 Jul 2012 17:01:52 +0100 Subject: fix ode getconfiguration --- OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | 2 +- OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs index 0e4961b..34865c1 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs @@ -1312,7 +1312,7 @@ namespace OdeAPI public static extern void GeomTriMeshSetRayCallback(IntPtr g, TriRayCallback callback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGetConfiguration"), SuppressUnmanagedCodeSecurity] - public static extern string GetConfiguration(string str); + public static extern string GetConfiguration(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceCreate"), SuppressUnmanagedCodeSecurity] public static extern IntPtr HashSpaceCreate(IntPtr space); diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 46251de..d5938f4 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -409,7 +409,7 @@ namespace OpenSim.Region.Physics.OdePlugin mesher = meshmerizer; m_config = config; - string ode_config = d.GetConfiguration("ODE"); + string ode_config = d.GetConfiguration(); if (ode_config != null && ode_config != "") { m_log.WarnFormat("ODE configuration: {0}", ode_config); -- cgit v1.1 From 3a1d46ad446cb4d5d0f193bd9d7cdcfc4f65a565 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 9 Jul 2012 17:21:54 +0100 Subject: retry fixing ode getconfiguration() --- OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs index 34865c1..2341186 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs @@ -1312,7 +1312,14 @@ namespace OdeAPI public static extern void GeomTriMeshSetRayCallback(IntPtr g, TriRayCallback callback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGetConfiguration"), SuppressUnmanagedCodeSecurity] - public static extern string GetConfiguration(); + public static extern IntPtr iGetConfiguration(); + + public static string GetConfiguration() + { + IntPtr ptr = iGetConfiguration(); + string s = Marshal.PtrToStringAnsi(ptr); + return s; + } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceCreate"), SuppressUnmanagedCodeSecurity] public static extern IntPtr HashSpaceCreate(IntPtr space); -- cgit v1.1 From 34f4dc29a1b2c6e3e26f5117a605670c488efe05 Mon Sep 17 00:00:00 2001 From: ubit Date: Tue, 10 Jul 2012 02:24:09 +0200 Subject: change linux 32bit libode.so to ode version 0.12 --- bin/lib32/libode.so | Bin 3051566 -> 3134141 bytes 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 bin/lib32/libode.so diff --git a/bin/lib32/libode.so b/bin/lib32/libode.so old mode 100644 new mode 100755 index 6bb85fb..5b110ae Binary files a/bin/lib32/libode.so and b/bin/lib32/libode.so differ -- cgit v1.1 From 0d605685644081f5853dc1e8ddb591d3a8c2f299 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 10 Jul 2012 01:29:44 +0100 Subject: changed ODE lib for win32 to version 0.12 --- bin/lib32/ode.dll | Bin 496640 -> 548864 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/lib32/ode.dll b/bin/lib32/ode.dll index f310358..90106ca 100755 Binary files a/bin/lib32/ode.dll and b/bin/lib32/ode.dll differ -- cgit v1.1 From ca41ec9eb4616c0cb96ed48d591e473d95af2701 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 10 Jul 2012 05:11:06 +0100 Subject: let rotationVelocity or AngularVelocity be setted on prims. Limited to 12rad/s --- OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 65 +++++++++++++++++-------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 3d8e680..14e4272 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -583,8 +583,6 @@ namespace OpenSim.Region.Physics.OdePlugin if (value.IsFinite()) { AddChange(changes.Velocity, value); -// _velocity = value; - } else { @@ -676,9 +674,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (value.IsFinite()) { - m_rotationalVelocity = value; - if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) - d.BodyEnable(Body); + AddChange(changes.AngVelocity, value); } else { @@ -687,7 +683,6 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public override float Buoyancy { get { return m_buoyancy; } @@ -1737,17 +1732,14 @@ namespace OpenSim.Region.Physics.OdePlugin d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); -// d.BodySetLinearDampingThreshold(Body, 0.01f); -// d.BodySetAngularDampingThreshold(Body, 0.001f); - d.BodySetDamping(Body, .002f, .002f); - - if (m_targetSpace != IntPtr.Zero) - { - _parent_scene.waitForSpaceUnlock(m_targetSpace); - if (d.SpaceQuery(m_targetSpace, prim_geom)) - d.SpaceRemove(m_targetSpace, prim_geom); - } + d.BodySetDamping(Body, .005f, .005f); + if (m_targetSpace != IntPtr.Zero) + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + if (d.SpaceQuery(m_targetSpace, prim_geom)) + d.SpaceRemove(m_targetSpace, prim_geom); + } if (childrenPrim.Count == 0) { @@ -3296,6 +3288,13 @@ namespace OpenSim.Region.Physics.OdePlugin private void changevelocity(Vector3 newVel) { + float len = newVel.LengthSquared(); + if (len > 100000.0f) // limit to 100m/s + { + len = 100.0f / (float)Math.Sqrt(len); + newVel *= len; + } + if (!m_isSelected) { if (Body != IntPtr.Zero) @@ -3312,6 +3311,33 @@ namespace OpenSim.Region.Physics.OdePlugin _velocity = newVel; } + + private void changeangvelocity(Vector3 newAngVel) + { + float len = newAngVel.LengthSquared(); + if (len > 144.0f) // limit to 12rad/s + { + len = 12.0f / (float)Math.Sqrt(len); + newAngVel *= len; + } + + if (!m_isSelected) + { + if (Body != IntPtr.Zero) + { + if (m_disabled) + enableBodySoft(); + else if (!d.BodyIsEnabled(Body)) + d.BodyEnable(Body); + + + d.BodySetAngularVel(Body, newAngVel.X, newAngVel.Y, newAngVel.Z); + } + //resetCollisionAccounting(); + } + m_rotationalVelocity = newAngVel; + } + private void changeVolumedetetion(bool newVolDtc) { m_isVolumeDetect = newVolDtc; @@ -3948,9 +3974,10 @@ namespace OpenSim.Region.Physics.OdePlugin // case changes.Acceleration: // changeacceleration((Vector3)arg); // break; -// case changes.AngVelocity: -// changeangvelocity((Vector3)arg); -// break; + + case changes.AngVelocity: + changeangvelocity((Vector3)arg); + break; case changes.Force: changeForce((Vector3)arg); -- cgit v1.1 From 652ac5f66bacb048628bc953497ffe4256676f05 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 10 Jul 2012 05:28:47 +0100 Subject: more work on llSetAngularVelocity() --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 29 +++++++++++++++++++++- .../Shared/Api/Implementation/LSL_Api.cs | 4 +-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index dd30a59..0f44823 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1845,7 +1845,7 @@ namespace OpenSim.Region.Framework.Scenes } } -// SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future + // SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future public void SetVelocity(Vector3 pVel, bool localGlobalTF) { if (ParentGroup == null || ParentGroup.IsDeleted) @@ -1871,6 +1871,33 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.Velocity = pVel; } + + // SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future + public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF) + { + if (ParentGroup == null || ParentGroup.IsDeleted) + return; + + if (ParentGroup.IsAttachment) + return; // don't work on attachments (for now ??) + + SceneObjectPart root = ParentGroup.RootPart; + + if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles + return; + + PhysicsActor pa = root.PhysActor; + + if (pa == null || !pa.IsPhysical) + return; + + if (localGlobalTF) + { + pAngVel = pAngVel * GetWorldRotation(); + } + + root.AngularVelocity = pAngVel; + } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0ee2748..cae7343 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2597,12 +2597,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); } - public void llSetAngularVelocity(LSL_Vector avel, int local) { m_host.AddScriptLPS(1); - // Still not done !!!! -// m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0); + m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0); } public LSL_Vector llGetOmega() -- cgit v1.1 From acec9da95c2faa861ee37cc5e820118fc4649c80 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 10 Jul 2012 05:37:41 +0100 Subject: let SOP AngularVelocity set physics actor angular velocity if it's physical root prim and not a vehicle. With this llSetAngularVelocity should work and also llTargetOmega will do the same in this case. but for now this llTargetOmega is being a normal physical rotation with damping, and stops with selection. Thats not like SL apparently --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 0f44823..16a8588 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -959,7 +959,15 @@ namespace OpenSim.Region.Framework.Scenes } return m_angularVelocity; } - set { m_angularVelocity = value; } + set + { + m_angularVelocity = value; + PhysicsActor actor = PhysActor; + if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE) + { + actor.RotationalVelocity = m_angularVelocity; + } + } } /// -- cgit v1.1 From df55de5b3d88e241f35217d5c08d02b921991513 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 10 Jul 2012 05:51:41 +0100 Subject: lltargetomega efective spinrate now multiplied by gain ( need check ) --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index cae7343..05bb161 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3804,6 +3804,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) { + spinrate *= gain; part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate))); } -- cgit v1.1 From 6b8b7007c4a8c5ed3386093fd0cfac0032587121 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 10 Jul 2012 18:23:38 +0100 Subject: console region restart: Let Xengine not cry all over the place with errors also. May not be that good, but is not in use in AVN (i hope). Still safer to do a full shutdown and refire the region from a OS tool like a script, monit, etc etc --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 1e0f01f..2a01fc4 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -596,7 +596,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (!m_Enabled) return; lockScriptsForRead(true); - foreach (IScriptInstance instance in m_Scripts.Values) + + List instancesToDel = new List(m_Scripts.Values); + +// foreach (IScriptInstance instance in m_Scripts.Values) + foreach (IScriptInstance instance in instancesToDel) { // Force a final state save // @@ -619,7 +623,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine // Must be done explicitly because they have infinite // lifetime // - if (!m_SimulatorShuttingDown) +// if (!m_SimulatorShuttingDown) { m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); if (m_DomainScripts[instance.AppDomain].Count == 0) @@ -629,10 +633,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } - m_Scripts.Clear(); - m_PrimObjects.Clear(); - m_Assemblies.Clear(); - m_DomainScripts.Clear(); +// m_Scripts.Clear(); +// m_PrimObjects.Clear(); +// m_Assemblies.Clear(); +// m_DomainScripts.Clear(); } lockScriptsForRead(false); lockScriptsForWrite(true); -- cgit v1.1 From b5b763f7e1a7c77239bf9fa9bfaabd0f8daa8a81 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 10 Jul 2012 19:13:24 +0100 Subject: add some more memory information to StatsCollector --- OpenSim/Framework/Statistics/BaseStatsCollector.cs | 24 ++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/OpenSim/Framework/Statistics/BaseStatsCollector.cs b/OpenSim/Framework/Statistics/BaseStatsCollector.cs index c9e57ce..3f918f3 100644 --- a/OpenSim/Framework/Statistics/BaseStatsCollector.cs +++ b/OpenSim/Framework/Statistics/BaseStatsCollector.cs @@ -48,10 +48,26 @@ namespace OpenSim.Framework.Statistics string.Format( "Allocated to OpenSim objects: {0} MB\n", Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0))); - sb.Append( - string.Format( - "Process memory : {0} MB\n", - Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0))); + + Process myprocess = Process.GetCurrentProcess(); + if (!myprocess.HasExited) + { + myprocess.Refresh(); + sb.Append( + string.Format( + "Process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n", + Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0), + Math.Round(Process.GetCurrentProcess().PagedMemorySize64 / 1024.0 / 1024.0), + Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0))); + sb.Append( + string.Format( + "Peak process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n", + Math.Round(Process.GetCurrentProcess().PeakWorkingSet64 / 1024.0 / 1024.0), + Math.Round(Process.GetCurrentProcess().PeakPagedMemorySize64 / 1024.0 / 1024.0), + Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0))); + } + else + sb.Append("Process reported as Exited \n"); return sb.ToString(); } -- cgit v1.1 From ac3a2296fa6de7ad07f862fbe073e9e3495677f1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 11 Jul 2012 04:01:20 +0200 Subject: Make sure handles stay intact when removing from the MinHeap --- OpenSim/Framework/MinHeap.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/OpenSim/Framework/MinHeap.cs b/OpenSim/Framework/MinHeap.cs index f2218c9..99ac25d 100644 --- a/OpenSim/Framework/MinHeap.cs +++ b/OpenSim/Framework/MinHeap.cs @@ -63,12 +63,15 @@ namespace OpenSim.Framework internal void Clear() { - this.value = default(T); if (this.handle != null) - { this.handle.Clear(); - this.handle = null; - } + ClearRef(); + } + + internal void ClearRef() + { + this.value = default(T); + this.handle = null; } } @@ -285,7 +288,7 @@ namespace OpenSim.Framework if (--this.size > 0 && index != this.size) { Set(this.items[this.size], index); - this.items[this.size].Clear(); + this.items[this.size].ClearRef(); if (!BubbleUp(index)) BubbleDown(index); } -- cgit v1.1 From 7676ae6f744379c69f169d372c8688f49684ea6c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 11 Jul 2012 03:56:39 +0100 Subject: clear released minheap items so they don't keep holding references to objects. --- OpenSim/Framework/MinHeap.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Framework/MinHeap.cs b/OpenSim/Framework/MinHeap.cs index 33d0364..f2218c9 100644 --- a/OpenSim/Framework/MinHeap.cs +++ b/OpenSim/Framework/MinHeap.cs @@ -285,6 +285,7 @@ namespace OpenSim.Framework if (--this.size > 0 && index != this.size) { Set(this.items[this.size], index); + this.items[this.size].Clear(); if (!BubbleUp(index)) BubbleDown(index); } -- cgit v1.1 From 7836933133a27bb57cd89663134f37b78fed5f7c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 11 Jul 2012 03:58:58 +0100 Subject: Melanie fix: detach SOGs from backup on linking --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index a600b86..0587846 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1820,6 +1820,8 @@ namespace OpenSim.Region.Framework.Scenes { parentGroup.LinkToGroup(child); + child.DetachFromBackup(); + // this is here so physics gets updated! // Don't remove! Bad juju! Stay away! or fix physics! child.AbsolutePosition = child.AbsolutePosition; -- cgit v1.1 From bb78b327c0c36b515f0e60e2783961e9325062da Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 11 Jul 2012 06:43:03 +0100 Subject: stop keeping references to objects on released items --- OpenSim/Framework/LocklessQueue.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OpenSim/Framework/LocklessQueue.cs b/OpenSim/Framework/LocklessQueue.cs index dd3d201..84f887c 100644 --- a/OpenSim/Framework/LocklessQueue.cs +++ b/OpenSim/Framework/LocklessQueue.cs @@ -99,8 +99,13 @@ namespace OpenSim.Framework } else { - item = oldHeadNext.Item; + item = oldHeadNext.Item; haveAdvancedHead = CAS(ref head, oldHead, oldHeadNext); + if (haveAdvancedHead) + { + oldHeadNext.Item = default(T); + oldHead.Next = null; + } } } } @@ -111,6 +116,10 @@ namespace OpenSim.Framework public void Clear() { + // ugly + T item; + while(count > 0) + Dequeue(out item); Init(); } -- cgit v1.1 From 84ab4c44628441b32ec7ef0c728d035b5cf40b39 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 11 Jul 2012 08:13:57 +0100 Subject: ubitODE leaks --- .../Region/Physics/UbitOdePlugin/ODECharacter.cs | 2 + OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 2 + OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 54 ++++++++++++---------- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 6e4e41f..865180f 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -740,6 +740,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (Shell != IntPtr.Zero) { _parent_scene.geom_name_map.Remove(Shell); + _parent_scene.actor_name_map.Remove(Shell); _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); d.GeomDestroy(Shell); Shell = IntPtr.Zero; @@ -1188,6 +1189,7 @@ namespace OpenSim.Region.Physics.OdePlugin } else { + _parent_scene.RemoveCollisionEventReporting(this); _parent_scene.RemoveCharacter(this); // destroy avatar capsule and related ODE data AvatarGeomAndBodyDestroy(); diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 14e4272..ff17a6e 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -943,6 +943,8 @@ namespace OpenSim.Region.Physics.OdePlugin CollisionEventsThisFrame = null; } m_eventsubscription = 0; + // for now still done on odescene +// _parent_scene.RemoveCollisionEventReporting(this); } public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index d5938f4..7848b35 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -175,7 +175,7 @@ namespace OpenSim.Region.Physics.OdePlugin const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; const float MaxERP = 0.8f; - const float minERP = 0.2f; + const float minERP = 0.1f; const float comumContactCFM = 0.0001f; float frictionMovementMult = 0.8f; @@ -237,20 +237,20 @@ namespace OpenSim.Region.Physics.OdePlugin private d.NearCallback nearCallback; - private readonly HashSet _characters = new HashSet(); - private readonly HashSet _prims = new HashSet(); - private readonly HashSet _activeprims = new HashSet(); - private readonly HashSet _activegroups = new HashSet(); + private HashSet _characters = new HashSet(); + private HashSet _prims = new HashSet(); + private HashSet _activeprims = new HashSet(); + private HashSet _activegroups = new HashSet(); public OpenSim.Framework.LocklessQueue ChangesQueue = new OpenSim.Framework.LocklessQueue(); /// /// A list of actors that should receive collision events. /// - private readonly List _collisionEventPrim = new List(); - private readonly List _collisionEventPrimRemove = new List(); + private List _collisionEventPrim = new List(); + private List _collisionEventPrimRemove = new List(); - private readonly HashSet _badCharacter = new HashSet(); + private HashSet _badCharacter = new HashSet(); public Dictionary geom_name_map = new Dictionary(); public Dictionary actor_name_map = new Dictionary(); @@ -264,26 +264,21 @@ namespace OpenSim.Region.Physics.OdePlugin private volatile int m_global_contactcount = 0; - private readonly IntPtr contactgroup; + private IntPtr contactgroup; public ContactData[] m_materialContactsData = new ContactData[8]; - private readonly Dictionary RegionTerrain = new Dictionary(); - private readonly Dictionary TerrainHeightFieldHeights = new Dictionary(); - private readonly Dictionary TerrainHeightFieldHeightsHandlers = new Dictionary(); + private Dictionary RegionTerrain = new Dictionary(); + private Dictionary TerrainHeightFieldHeights = new Dictionary(); + private Dictionary TerrainHeightFieldHeightsHandlers = new Dictionary(); private int m_physicsiterations = 10; private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag - private readonly PhysicsActor PANull = new NullPhysicsActor(); + private PhysicsActor PANull = new NullPhysicsActor(); private float step_time = 0.0f; public IntPtr world; - private uint obj2LocalID = 0; - private OdeCharacter cc1; - private OdePrim cp1; - private OdeCharacter cc2; - private OdePrim cp2; // split the spaces acording to contents type // ActiveSpace contains characters and active prims @@ -921,8 +916,8 @@ namespace OpenSim.Region.Physics.OdePlugin cfm = 0.0001f / cfm; if (cfm > 0.01f) cfm = 0.01f; - else if (cfm < 0.0001f) - cfm = 0.0001f; + else if (cfm < 0.00001f) + cfm = 0.00001f; if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) mu *= frictionMovementMult; @@ -949,8 +944,8 @@ namespace OpenSim.Region.Physics.OdePlugin cfm = 0.0001f / cfm; if (cfm > 0.01f) cfm = 0.01f; - else if (cfm < 0.0001f) - cfm = 0.0001f; + else if (cfm < 0.00001f) + cfm = 0.00001f; if (d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) { @@ -993,6 +988,8 @@ namespace OpenSim.Region.Physics.OdePlugin cfm = 0.0001f / cfm; if (cfm > 0.01f) cfm = 0.01f; + else if (cfm < 0.00001f) + cfm = 0.00001f; if (curContact.side1 > 0) // should be 2 ? IgnoreNegSides = true; @@ -1159,7 +1156,13 @@ namespace OpenSim.Region.Physics.OdePlugin private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { - obj2LocalID = 0; + + OdeCharacter cc1; + OdePrim cp1; + OdeCharacter cc2; + OdePrim cp2; + + uint obj2LocalID = 0; bool p1events = p1.SubscribedEvents(); bool p2events = p2.SubscribedEvents(); @@ -1963,6 +1966,7 @@ namespace OpenSim.Region.Physics.OdePlugin { RemoveCharacter(defect); } + defects.Clear(); } } @@ -2068,13 +2072,13 @@ namespace OpenSim.Region.Physics.OdePlugin _badCharacter.Clear(); } } - +/* int nactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); int ntopgeoms = d.SpaceGetNumGeoms(TopSpace); int nbodies = d.NTotalBodies; int ngeoms = d.NTotalGeoms; - +*/ // Finished with all sim stepping. If requested, dump world state to file for debugging. // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? -- cgit v1.1 From 6252114ea02c07bab2b61fa882f4a26264cbb347 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 11 Jul 2012 09:03:18 +0100 Subject: remove expensive and leaked ( in Xengine at least) SayShout timer and replace it by a simpler function that should do the same (?) (don't like much those 10 + 1 bursts) --- .../Shared/Api/Implementation/LSL_Api.cs | 28 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 05bb161..ca62bac 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -108,8 +108,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected Dictionary m_userInfoCache = new Dictionary(); - protected Timer m_ShoutSayTimer; +// protected Timer m_ShoutSayTimer; protected int m_SayShoutCount = 0; + DateTime m_lastSayShoutCheck; private Dictionary MovementAnimationsForLSL = new Dictionary { @@ -135,10 +136,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) { +/* m_ShoutSayTimer = new Timer(1000); m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed; m_ShoutSayTimer.AutoReset = true; m_ShoutSayTimer.Start(); +*/ + m_lastSayShoutCheck = DateTime.UtcNow; m_ScriptEngine = ScriptEngine; m_host = host; @@ -900,12 +904,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); } + private void CheckSayShoutTime() + { + DateTime now = DateTime.UtcNow; + if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec + { + m_lastSayShoutCheck = now; + m_SayShoutCount = 0; + } + else + m_SayShoutCount++; + } + public void llSay(int channelID, string text) { m_host.AddScriptLPS(1); if (channelID == 0) - m_SayShoutCount++; +// m_SayShoutCount++; + CheckSayShoutTime(); if (m_SayShoutCount >= 11) ScriptSleep(2000); @@ -933,7 +950,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (channelID == 0) - m_SayShoutCount++; +// m_SayShoutCount++; + CheckSayShoutTime(); if (m_SayShoutCount >= 11) ScriptSleep(2000); @@ -12373,12 +12391,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return rq.ToString(); } - +/* private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args) { m_SayShoutCount = 0; } - +*/ private struct Tri { public Vector3 p1; -- cgit v1.1