diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs index 6db9515729..5eb525b265 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs @@ -27,6 +27,7 @@ using System; using System.Reflection; using System.Threading; +using System.Runtime.InteropServices; using System.Collections.Generic; using OpenSim.Framework; using OpenSim.Services.Interfaces; @@ -159,15 +160,147 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid } } + // dont care about endianess + [StructLayout(LayoutKind.Explicit, Size = 8, Pack = 8)] + public class fastRegionHandle + { + [FieldOffset(0)] public ulong handle; + [FieldOffset(0)] public uint y; + [FieldOffset(4)] public uint x; + + public fastRegionHandle(ulong h) + { + handle = h; + } + + public fastRegionHandle(uint px, uint py) + { + y = py & 0xffffff00; + x = px & 0xffffff00; + } + // actually do care + public ulong toHandle() + { + if(BitConverter.IsLittleEndian) + return handle; + return (ulong) x << 32 | (ulong)y ; + } + + public static bool operator ==(fastRegionHandle value1, fastRegionHandle value2) + { + return value1.handle == value2.handle; + } + public static bool operator !=(fastRegionHandle value1, fastRegionHandle value2) + { + return value1.handle != value2.handle; + } + public override int GetHashCode() + { + return handle.GetHashCode(); + } + public override bool Equals(Object obj) + { + if(obj == null) + return false; + fastRegionHandle p = obj as fastRegionHandle; + return p.handle == handle; + } + } + +/* + [StructLayout(LayoutKind.Explicit, Size = 8, Pack = 8)] + public class regionHandle + { + [FieldOffset(0)] private ulong handle; + [FieldOffset(0)] public uint a; + [FieldOffset(4)] public uint b; + + public regionHandle(ulong h) + { + handle = h; + } + + public regionHandle(uint px, uint py) + { + if(BitConverter.IsLittleEndian) + { + a = py & 0xffffff00; + b = px & 0xffffff00; + } + else + { + a = px & 0xffffff00; + b = py & 0xffffff00; + } + } + + public uint x + { + get + { + if(BitConverter.IsLittleEndian) + return b; + return a; + } + set + { + if(BitConverter.IsLittleEndian) + b = value & 0xffffff00; + else + a = value & 0xffffff00; + } + } + + public uint y + { + get + { + if(BitConverter.IsLittleEndian) + return a; + return b; + } + set + { + if(BitConverter.IsLittleEndian) + a = value; + else + b = value; + } + } + + public static bool operator ==(regionHandle value1, regionHandle value2) + { + return value1.handle == value2.handle; + } + public static bool operator !=(regionHandle value1, regionHandle value2) + { + return value1.handle != value2.handle; + } + public override int GetHashCode() + { + return handle.GetHashCode(); + } + public override bool Equals(Object obj) + { + if(obj == null) + return false; + regionHandle p = obj as regionHandle; + return p.handle == handle; + } + } +*/ + public class RegionInfoForScope { - public const ulong HANDLEMASH = 0xffffff00ffffff00ul; - public const ulong HANDLECOORDMASH = 0xffffff00ul; + public const ulong HANDLEMASK = 0xffffff00ffffff00ul; + public const ulong HANDLECOORDMASK = 0xffffff00ul; private Dictionary storage; private Dictionary expires; private Dictionary byname; private Dictionary byuuid; + // includes handles to the inside of large regions + private Dictionary innerHandles = new Dictionary(); public RegionInfoForScope() { @@ -184,16 +317,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid byname = new Dictionary(); byuuid = new Dictionary(); - ulong handle = region.RegionHandle & HANDLEMASH; + ulong handle = region.RegionHandle & HANDLEMASK; storage[handle] = region; expires[handle] = expire; byname[region.RegionName] = handle; byuuid[region.RegionID] = handle; + addToInner(region); } public void Add(GridRegion region, DateTime expire) { - ulong handle = region.RegionHandle & HANDLEMASH; + ulong handle = region.RegionHandle & HANDLEMASK; if(storage != null && storage.ContainsKey(handle)) return; @@ -211,6 +345,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid expires[handle] = expire; byname[region.RegionName] = handle; byuuid[region.RegionID] = handle; + + addToInner(region); } public void AddUpdate(GridRegion region, DateTime expire) @@ -224,18 +360,32 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if(byuuid == null) byuuid = new Dictionary(); - ulong handle = region.RegionHandle & HANDLEMASH; + ulong handle = region.RegionHandle & HANDLEMASK; - storage[handle] = region; if(expires.ContainsKey(handle)) { if(expires[handle] < expire) expires[handle] = expire; + if(storage.ContainsKey(handle)) + { + GridRegion oldr = storage[handle]; + if (oldr.RegionSizeX != region.RegionSizeX + || oldr.RegionSizeY != region.RegionSizeY) + { + removeFromInner(oldr); + addToInner(region); + } + } } else - expires[handle] = expire; + { + expires[handle] = expire; + addToInner(region); + } + storage[handle] = region; byname[region.RegionName] = handle; byuuid[region.RegionID] = handle; + } public void Remove(GridRegion region) @@ -248,9 +398,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if(byuuid != null) byuuid.Remove(region.RegionID); - ulong handle = region.RegionHandle & HANDLEMASH; + ulong handle = region.RegionHandle & HANDLEMASK; if(storage != null) storage.Remove(handle); + removeFromInner(region); if(expires != null) { expires.Remove(handle); @@ -261,7 +412,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public void Remove(ulong handle) { - handle &= HANDLEMASH; + handle &= HANDLEMASK; if(storage != null) { @@ -272,6 +423,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid byname.Remove(r.RegionName); if(byuuid != null) byuuid.Remove(r.RegionID); + removeFromInner(r); } storage.Remove(handle); } @@ -297,6 +449,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid byuuid = null; storage = null; expires = null; + innerHandles.Clear(); } public bool Contains(GridRegion region) @@ -306,7 +459,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if(region == null) return false; - ulong handle = region.RegionHandle & HANDLEMASH; + ulong handle = region.RegionHandle & HANDLEMASK; return storage.ContainsKey(handle); } @@ -315,7 +468,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if(storage == null) return false; - handle &= HANDLEMASH; + handle &= HANDLEMASK; return storage.ContainsKey(handle); } @@ -324,10 +477,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if(storage == null) return null; - handle &= HANDLEMASH; + handle &= HANDLEMASK; if(storage.ContainsKey(handle)) return storage[handle]; + + if(!innerHandles.ContainsKey(handle)) + return null; + ulong rhandle = innerHandles[handle]; + if(storage.ContainsKey(rhandle)) + return storage[rhandle]; + return null; } @@ -359,13 +519,40 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid return null; // look for a handle first this should find normal size regions - ulong handle = (ulong)x & HANDLECOORDMASH; + ulong handle = (ulong)x & HANDLECOORDMASK; handle <<= 32; - handle |= ((ulong)y & HANDLECOORDMASH); + handle |= ((ulong)y & HANDLECOORDMASK); if(storage.ContainsKey(handle)) return storage[handle]; - + + if(!innerHandles.ContainsKey(handle)) + return null; + + ulong rhandle = innerHandles[handle]; + if(!storage.ContainsKey(rhandle)) + return null; + + GridRegion r = storage[rhandle]; + if(r == null) + return null; + + // extra check, possible redundant + + int test = r.RegionLocX; + if(x < test) + return null; + test += r.RegionSizeX; + if(x >= test) + return null; + test = r.RegionLocY; + if (y < test) + return null; + test += r.RegionSizeY; + if (y < test) + return r; + +/* // next do the harder work foreach(KeyValuePair kvp in storage) { @@ -386,6 +573,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (y < test) return r; } +*/ return null; } @@ -421,6 +609,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid byname.Remove(r.RegionName); if(byuuid != null) byuuid.Remove(r.RegionID); + removeFromInner(r); } storage.Remove(h); } @@ -447,6 +636,59 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid else return byname.Count; } + + private void addToInner(GridRegion region) + { + int rsx = region.RegionSizeX; + int rsy = region.RegionSizeY; + + if(rsx < 512 && rsy < 512) + return; + + rsx >>= 8; + rsy >>= 8; + + ulong handle = region.RegionHandle & HANDLEMASK; + fastRegionHandle fh = new fastRegionHandle(handle); + uint startY = fh.y; + for(int i = 0; i < rsx; i++) + { + for(int j = 0; j < rsy ; j++) + { + innerHandles[fh.toHandle()] = handle; + fh.y += 256; + } + + fh.y = startY; + fh.x += 256; + } + } + + private void removeFromInner(GridRegion region) + { + int rsx = region.RegionSizeX; + int rsy = region.RegionSizeY; + + if(rsx < 512 && rsy < 512) + return; + + rsx >>= 8; + rsy >>= 8; + ulong handle = region.RegionHandle & HANDLEMASK; + fastRegionHandle fh = new fastRegionHandle(handle); + uint startY = fh.y; + for(int i = 0; i < rsx; i++) + { + for(int j = 0; j < rsy ; j++) + { + innerHandles.Remove(fh.toHandle()); + fh.y += 256; + } + + fh.y = startY; + fh.x += 256; + } + } } public class RegionsExpiringCache diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs index 7d855f1ce2..49020e92e4 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs @@ -1108,7 +1108,24 @@ namespace OpenSim.Region.PhysicsModule.ubOde vec.Z = depth * PID_P * 50; if (!flying) + { vec.Z += -vel.Z * PID_D; + if(n.Z < 0.4f) + { + vec.X = depth * PID_P * 50 - vel.X * PID_D; + vec.X *= n.X; + vec.Y = depth * PID_P * 50 - vel.Y * PID_D; + vec.Y *= n.Y; + vec.Z *= n.Z; + if(n.Z < 0.1f) + { + // cancel the slope pose + n.X = 0f; + n.Y = 0f; + n.Z = 1.0f; + } + } + } if (depth < 0.2f) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e074af2985..cf61943287 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -16426,11 +16426,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private OSD ListToJson(object o) { - if (o is LSL_Float) - return OSD.FromReal(((LSL_Float)o).value); - if (o is LSL_Integer) + if (o is LSL_Float || o is double) { - int i = ((LSL_Integer)o).value; + double float_val; + if (o is double) + float_val = ((double)o); + else + float_val = ((LSL_Float)o).value; + + return OSD.FromReal(float_val); + } + if (o is LSL_Integer || o is int) + { + int i; + if (o is int) + i = ((int)o); + else + i = ((LSL_Integer)o).value; + if (i == 0) return OSD.FromBoolean(false); else if (i == 1) @@ -16441,9 +16454,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return OSD.FromString(((LSL_Rotation)o).ToString()); if (o is LSL_Vector) return OSD.FromString(((LSL_Vector)o).ToString()); - if (o is LSL_String) + if (o is LSL_String || o is string) { - string str = ((LSL_String)o).m_string; + string str; + if (o is string) + str = ((string)o); + else + str = ((LSL_String)o).m_string; + if (str == ScriptBaseClass.JSON_NULL) return new OSD(); return OSD.FromString(str);