From e333eaf4b604453da9a8952356086d4a5a1fc4a8 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Fri, 29 Feb 2008 05:46:24 +0000 Subject: [PATCH] * ODEPlugin ** Added more realistic calculations of mass for the rest of the supported prim shapes+holes+cuts+tapers. Previously they were the generic height * width * length. Spheres roll (Angular velocity) more realistically, etc. --- .../Environment/Modules/FriendsModule.cs | 15 +- .../Modules/InstantMessageModule.cs | 20 +- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 208 +++++++++++++++++- 3 files changed, 227 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/Environment/Modules/FriendsModule.cs b/OpenSim/Region/Environment/Modules/FriendsModule.cs index e1d3e2ae4c..4d06750a9d 100644 --- a/OpenSim/Region/Environment/Modules/FriendsModule.cs +++ b/OpenSim/Region/Environment/Modules/FriendsModule.cs @@ -45,8 +45,8 @@ namespace OpenSim.Region.Environment.Modules private List m_scene = new List(); - Dictionary m_rootAgents = new Dictionary(); + Dictionary m_pendingFriendRequests = new Dictionary(); public void Initialise(Scene scene, IConfigSource config) @@ -66,9 +66,6 @@ namespace OpenSim.Region.Environment.Modules scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; scene.EventManager.OnMakeChildAgent += MakeChildAgent; scene.EventManager.OnClientClosed += ClientLoggedOut; - - - } public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req) { @@ -90,10 +87,6 @@ namespace OpenSim.Region.Environment.Modules client.OnDenyFriendRequest += OnDenyFriendRequest; client.OnTerminateFriendship += OnTerminateFriendship; - - - - } private void ClientLoggedOut(LLUUID AgentId) @@ -144,9 +137,9 @@ namespace OpenSim.Region.Environment.Modules } } - - } + } + #region FriendRequestHandling private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID, LLUUID fromAgentSession, LLUUID toAgentID, LLUUID imSessionID, uint timestamp, string fromAgentName, @@ -293,7 +286,7 @@ namespace OpenSim.Region.Environment.Modules new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), msg.binaryBucket); } - + #endregion private ScenePresence GetPresenceFromAgentID(LLUUID AgentID) { ScenePresence returnAgent = null; diff --git a/OpenSim/Region/Environment/Modules/InstantMessageModule.cs b/OpenSim/Region/Environment/Modules/InstantMessageModule.cs index 8df2acb95a..70f3d99484 100644 --- a/OpenSim/Region/Environment/Modules/InstantMessageModule.cs +++ b/OpenSim/Region/Environment/Modules/InstantMessageModule.cs @@ -26,27 +26,39 @@ * */ +using System.Collections; using System.Collections.Generic; using libsecondlife; using Nini.Config; +using Nwc.XmlRpc; using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Scenes; + namespace OpenSim.Region.Environment.Modules { public class InstantMessageModule : IRegionModule { private List m_scenes = new List(); + private Hashtable m_RegionInfoCache = new Hashtable(); public void Initialise(Scene scene, IConfigSource config) { - if (!m_scenes.Contains(scene)) + lock (m_scenes) { - m_scenes.Add(scene); - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage; + if (m_scenes.Count == 0) + { + //scene.AddXmlRPCHandler("avatar_location_update", processPresenceUpdate); + } + + if (!m_scenes.Contains(scene)) + { + m_scenes.Add(scene); + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage; + } } } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 05dcd7a312..62b6a7fac4 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -353,6 +353,176 @@ namespace OpenSim.Region.Physics.OdePlugin } break; + case ProfileShape.Circle: + if (_pbs.PathCurve == (byte)Extrusion.Straight) + { + // Cylinder + float volume1 = (float)(Math.PI * Math.Pow(_size.X, 2) * _size.Z); + float volume2 = (float)(Math.PI * Math.Pow(_size.Y, 2) * _size.Z); + + // Approximating the cylinder's irregularity. + if (volume1 > volume2) + { + volume = (float)volume1 - (volume1 - volume2); + } + else if (volume2 > volume1) + { + volume = (float)volume2 - (volume2 - volume1); + } + else + { + // Regular cylinder + volume = volume1; + } + } + else + { + // We don't know what the shape is yet, so use default + volume = _size.X * _size.Y * _size.Z; + } + // If the user has 'hollowed out' + // ProfileHollow is one of those 0 to 50000 values :P + // we like percentages better.. so turning into a percentage + + if (((float)_pbs.ProfileHollow / 50000f) > 0.0) + { + float hollowAmount = (float)_pbs.ProfileHollow / 50000f; + + // calculate the hollow volume by it's shape compared to the prim shape + float hollowVolume = 0; + switch (_pbs.HollowShape) + { + + case HollowShape.Same: + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation + float hRadius = _size.X / 2; + float hLength = _size.Z; + + // pi * r2 * h + hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount); + break; + + case HollowShape.Square: + // Cube Hollow volume calculation + float hollowsizex = _size.X * hollowAmount; + float hollowsizey = _size.Y * hollowAmount; + float hollowsizez = _size.Z * hollowAmount; + hollowVolume = hollowsizex * hollowsizey * hollowsizez; + break; + + + + case HollowShape.Triangle: + // Equilateral Triangular Prism volume hollow calculation + // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + + float aLength = _size.Y; + // 1/2 abh + hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); + break; + + default: + hollowVolume = 0; + break; + } + volume = volume - hollowVolume; + } + break; + + case ProfileShape.HalfCircle: + if (_pbs.PathCurve == (byte)Extrusion.Curve1) + { + if (_size.X == _size.Z && _size.Z == _size.X) + { + // regular sphere + // v = 4/3 * pi * r^3 + float sradius3 = (float)Math.Pow((_size.X / 2), 3); + volume = (float)((4 / 3) * Math.PI * sradius3); + } + else + { + // we treat this as a box currently + volume = _size.X * _size.Y * _size.Z; + } + + } + else + { + // We don't know what the shape is yet, so use default + volume = _size.X * _size.Y * _size.Z; + } + break; + case ProfileShape.EquilateralTriangle: + /* + v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h + + // seed mesh + Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f); + Vertex PM = new Vertex(+0.5f, 0f, 0.0f); + Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f); + */ + float xA = -0.25f * _size.X; + float yA = -0.45f * _size.Y; + + float xB = 0.5f * _size.X; + float yB = 0; + + float xC = -0.25f * _size.X; + float yC = 0.45f * _size.Y; + + volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z); + + // If the user has 'hollowed out' + // ProfileHollow is one of those 0 to 50000 values :P + // we like percentages better.. so turning into a percentage + float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f); + if (((float)fhollowFactor / 50000f) > 0.0) + { + float hollowAmount = (float)fhollowFactor / 50000f; + + // calculate the hollow volume by it's shape compared to the prim shape + float hollowVolume = 0; + switch (_pbs.HollowShape) + { + + case HollowShape.Same: + case HollowShape.Triangle: + // Equilateral Triangular Prism volume hollow calculation + // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + + float aLength = _size.Y; + // 1/2 abh + hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); + break; + + case HollowShape.Square: + // Cube Hollow volume calculation + float hollowsizex = _size.X * hollowAmount; + float hollowsizey = _size.Y * hollowAmount; + float hollowsizez = _size.Z * hollowAmount; + hollowVolume = hollowsizex * hollowsizey * hollowsizez; + break; + + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation + float hRadius = _size.X / 2; + float hLength = _size.Z; + + // pi * r2 * h + hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount); + break; + + + default: + hollowVolume = 0; + break; + } + volume = volume - hollowVolume; + } + break; default: // we don't have all of the volume formulas yet so @@ -383,9 +553,41 @@ namespace OpenSim.Region.Physics.OdePlugin volume = volume - (volume*pathCutAmount); } + UInt16 taperX = _pbs.PathScaleX; + UInt16 taperY = _pbs.PathScaleY; + float taperFactorX = 0; + float taperFactorY = 0; // Mass = density * volume + if (taperX != 100) + { + if (taperX > 100) + { + taperFactorX = 1.0f - ((float)taperX / 200); + //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString()); + } + else + { + taperFactorX = 1.0f - ((100 - (float)taperX) / 100); + //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString()); + } + volume = (float)volume * ((taperFactorX / 3f) + 0.001f); + } + if (taperY != 100) + { + if (taperY > 100) + { + taperFactorY = 1.0f - ((float)taperY / 200); + //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString()); + } + else + { + taperFactorY = 1.0f - ((100 - (float)taperY) / 100); + //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString()); + } + volume = (float)volume * ((taperFactorY / 3f) + 0.001f); + } returnMass = m_density*volume; return returnMass; @@ -395,7 +597,11 @@ namespace OpenSim.Region.Physics.OdePlugin { if (Body != (IntPtr) 0) { - d.MassSetBoxTotal(out pMass, CalculateMass(), _size.X, _size.Y, _size.Z); + float newmass = CalculateMass(); + m_log.Info("[PHYSICS]: New Mass: " + newmass.ToString()); + + if (newmass <= 0) newmass = 0.0001f; + d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z); d.BodySetMass(Body, ref pMass); } }