fix llEdgeOfWorld() for var regions (someone needs to test this better

LSLKeyTest
UbitUmarov 2016-07-29 00:55:40 +01:00
parent c692664f3d
commit 3d58198c55
1 changed files with 42 additions and 46 deletions

View File

@ -6394,65 +6394,61 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
// edge will be used to pass the Region Coordinates offset
// we want to check for a neighboring sim
LSL_Vector edge = new LSL_Vector(0, 0, 0);
if(dir.x == 0.0 && dir.y == 0.0)
return 1; // SL wiki
float rsx = World.RegionInfo.RegionSizeX;
float rsy = World.RegionInfo.RegionSizeY;
// can understand what sl does if position is not in region, so do something :)
float px = (float)Util.Clamp(pos.x, 0.5, rsx - 0.5);
float py = (float)Util.Clamp(pos.y, 0.5, rsy - 0.5);
float ex, ey;
if (dir.x == 0)
{
if (dir.y == 0)
ex = px;
ey = dir.y > 0.0 ? rsy + 1.0f : -1.0f;
}
else if(dir.y == 0.0f)
{
// Direction vector is 0,0 so return
// false since we're staying in the sim
// no SL says true
return 1;
ex = dir.x > 0 ? rsx + 1.0f : -1.0f;
ey = py;
}
else
{
// Y is the only valid direction
edge.y = dir.y / Math.Abs(dir.y) * (World.RegionInfo.RegionSizeY / Constants.RegionSize);
}
}
float dx = (float) dir.x;
float dy = (float) dir.y;
float t1 = dx * dx + dy * dy;
dx /= t1;
dy /= t1;
if(dx > 0)
t1 = (rsx + 1f - px)/dx;
else
{
LSL_Float mag;
if (dir.x > 0)
{
mag = (World.RegionInfo.RegionSizeX - pos.x) / dir.x;
}
t1 = -(px + 1f)/dx;
float t2;
if(dy > 0)
t2 = (rsy + 1f - py)/dy;
else
{
mag = (pos.x/dir.x);
t2 = -(py + 1f)/dy;
if(t1 > t2)
t1 = t2;
ex = px + t1 * dx;
ey = py + t1 * dy;
}
mag = Math.Abs(mag);
ex += World.RegionInfo.WorldLocX;
ey += World.RegionInfo.WorldLocY;
edge.y = pos.y + (dir.y * mag);
if (edge.y > World.RegionInfo.RegionSizeY || edge.y < 0)
{
// Y goes out of bounds first
edge.y = dir.y / Math.Abs(dir.y) * (World.RegionInfo.RegionSizeY / Constants.RegionSize);
}
else
{
// X goes out of bounds first or its a corner exit
edge.y = 0;
edge.x = dir.x / Math.Abs(dir.x) * (World.RegionInfo.RegionSizeY / Constants.RegionSize);
}
}
List<GridRegion> neighbors = World.GridService.GetNeighbours(World.RegionInfo.ScopeID, World.RegionInfo.RegionID);
uint neighborX = World.RegionInfo.RegionLocX + (uint)edge.x;
uint neighborY = World.RegionInfo.RegionLocY + (uint)edge.y;
foreach (GridRegion sri in neighbors)
{
if (sri.RegionCoordX == neighborX && sri.RegionCoordY == neighborY)
if(World.GridService.GetRegionByPosition(World.RegionInfo.ScopeID, (int)ex, (int)ey) != null)
return 0;
}
return 1;
}