Browse Source

Reworking zone models.
Tests shows reduction in loading times of up to 80%.

GodKratos 13 years ago
parent
commit
13b56e0a39

+ 25 - 69
L2J_Server_BETA/java/com/l2jserver/gameserver/model/zone/form/ZoneCuboid.java

@@ -14,6 +14,8 @@
  */
 package com.l2jserver.gameserver.model.zone.form;
 
+import java.awt.Rectangle;
+
 import com.l2jserver.gameserver.GeoEngine;
 import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
 import com.l2jserver.gameserver.model.zone.L2ZoneForm;
@@ -27,92 +29,41 @@ import com.l2jserver.util.Rnd;
  */
 public class ZoneCuboid extends L2ZoneForm
 {
-	private int _x1, _x2, _y1, _y2, _z1, _z2;
+	private int _z1, _z2;
+	Rectangle _r;
 	
 	public ZoneCuboid(int x1, int x2, int y1, int y2, int z1, int z2)
 	{
-		_x1 = x1;
-		_x2 = x2;
-		if (_x1 > _x2) // switch them if alignment is wrong
-		{
-			_x1 = x2;
-			_x2 = x1;
-		}
+		int _x1 = Math.min(x1, x2);
+		int _x2 = Math.max(x1, x2);
+		int _y1 = Math.min(y1, y2);
+		int _y2 = Math.max(y1, y2);
 		
-		_y1 = y1;
-		_y2 = y2;
-		if (_y1 > _y2) // switch them if alignment is wrong
-		{
-			_y1 = y2;
-			_y2 = y1;
-		}
+		_r = new Rectangle(_x1, _y2, _x2 - _x1, _y2 - _y1);
 		
-		_z1 = z1;
-		_z2 = z2;
-		if (_z1 > _z2) // switch them if alignment is wrong
-		{
-			_z1 = z2;
-			_z2 = z1;
-		}
+		_z1 = Math.min(z1, z2);
+		_z2 = Math.max(z1, z2);
 	}
 	
 	@Override
 	public boolean isInsideZone(int x, int y, int z)
 	{
-		if (x < _x1 || x > _x2 || y < _y1 || y > _y2 || z < _z1 || z > _z2)
-			return false;
-		return true;
+		return (_r.contains(x, y) && z >= _z1 && z <= _z2);
 	}
 	
 	@Override
 	public boolean intersectsRectangle(int ax1, int ax2, int ay1, int ay2)
 	{
-		// Check if any point inside this rectangle
-		if (isInsideZone(ax1, ay1, (_z2 - 1)))
-			return true;
-		if (isInsideZone(ax1, ay2, (_z2 - 1)))
-			return true;
-		if (isInsideZone(ax2, ay1, (_z2 - 1)))
-			return true;
-		if (isInsideZone(ax2, ay2, (_z2 - 1)))
-			return true;
-		
-		// Check if any point from this rectangle is inside the other one
-		if (_x1 > ax1 && _x1 < ax2 && _y1 > ay1 && _y1 < ay2)
-			return true;
-		if (_x1 > ax1 && _x1 < ax2 && _y2 > ay1 && _y2 < ay2)
-			return true;
-		if (_x2 > ax1 && _x2 < ax2 && _y1 > ay1 && _y1 < ay2)
-			return true;
-		if (_x2 > ax1 && _x2 < ax2 && _y2 > ay1 && _y2 < ay2)
-			return true;
-		
-		// Horizontal lines may intersect vertical lines
-		if (lineSegmentsIntersect(_x1, _y1, _x2, _y1, ax1, ay1, ax1, ay2))
-			return true;
-		if (lineSegmentsIntersect(_x1, _y1, _x2, _y1, ax2, ay1, ax2, ay2))
-			return true;
-		if (lineSegmentsIntersect(_x1, _y2, _x2, _y2, ax1, ay1, ax1, ay2))
-			return true;
-		if (lineSegmentsIntersect(_x1, _y2, _x2, _y2, ax2, ay1, ax2, ay2))
-			return true;
-		
-		// Vertical lines may intersect horizontal lines
-		if (lineSegmentsIntersect(_x1, _y1, _x1, _y2, ax1, ay1, ax2, ay1))
-			return true;
-		if (lineSegmentsIntersect(_x1, _y1, _x1, _y2, ax1, ay2, ax2, ay2))
-			return true;
-		if (lineSegmentsIntersect(_x2, _y1, _x2, _y2, ax1, ay1, ax2, ay1))
-			return true;
-		if (lineSegmentsIntersect(_x2, _y1, _x2, _y2, ax1, ay2, ax2, ay2))
-			return true;
-		
-		return false;
+		return (_r.intersects(Math.min(ax1, ax2), Math.min(ay1, ay2), Math.max(ax1, ax2) - Math.min(ax1, ax2), Math.max(ay1, ay2) - Math.min(ay1, ay2)));
 	}
 	
 	@Override
 	public double getDistanceToZone(int x, int y)
 	{
+		int _x1 = _r.x;
+		int _x2 = _r.x + _r.width;
+		int _y1 = _r.y;
+		int _y2 = _r.y + _r.height;
 		double test, shortestDist = Math.pow(_x1 - x, 2) + Math.pow(_y1 - y, 2);
 		
 		test = Math.pow(_x1 - x, 2) + Math.pow(_y2 - y, 2);
@@ -131,7 +82,7 @@ public class ZoneCuboid extends L2ZoneForm
 	}
 	
 	/* getLowZ() / getHighZ() - These two functions were added to cope with the demand of the new
-	 * fishing algorithms, wich are now able to correctly place the hook in the water, thanks to getHighZ().
+	 * fishing algorithms, which are now able to correctly place the hook in the water, thanks to getHighZ().
 	 * getLowZ() was added, considering potential future modifications.
 	 */
 	@Override
@@ -149,6 +100,11 @@ public class ZoneCuboid extends L2ZoneForm
 	@Override
 	public void visualizeZone(int z)
 	{
+		int _x1 = _r.x;
+		int _x2 = _r.x + _r.width;
+		int _y1 = _r.y;
+		int _y2 = _r.y + _r.height;
+		
 		//x1->x2
 		for (int x = _x1; x < _x2; x = x + STEP)
 		{
@@ -166,8 +122,8 @@ public class ZoneCuboid extends L2ZoneForm
 	@Override
 	public int[] getRandomPoint()
 	{
-		int x = Rnd.get(_x1, _x2);
-		int y = Rnd.get(_y1, _y2);
+		int x = Rnd.get(_r.x, _r.x + _r.width);
+		int y = Rnd.get(_r.y, _r.y + _r.height);
 		
 		return new int[] { x, y, GeoEngine.getInstance().getHeight(x, y, _z1) };
 	}

+ 21 - 73
L2J_Server_BETA/java/com/l2jserver/gameserver/model/zone/form/ZoneNPoly.java

@@ -14,8 +14,9 @@
  */
 package com.l2jserver.gameserver.model.zone.form;
 
+import java.awt.Polygon;
+
 import com.l2jserver.gameserver.GeoEngine;
-import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
 import com.l2jserver.gameserver.model.zone.L2ZoneForm;
 import com.l2jserver.util.Rnd;
@@ -28,14 +29,9 @@ import com.l2jserver.util.Rnd;
  */
 public class ZoneNPoly extends L2ZoneForm
 {
-	private int[] _x;
-	private int[] _y;
+	private Polygon _p;
 	private int _z1;
 	private int _z2;
-	private int _minX = L2World.MAP_MAX_X;
-	private int _maxX = L2World.MAP_MIN_X;
-	private int _minY = L2World.MAP_MAX_Y;
-	private int _maxY = L2World.MAP_MIN_Y;
 	
 	/**
 	 * @param x
@@ -45,88 +41,32 @@ public class ZoneNPoly extends L2ZoneForm
 	 */
 	public ZoneNPoly(int[] x, int[] y, int z1, int z2)
 	{
-		_x = x;
-		_y = y;
-		_z1 = z1;
-		_z2 = z2;
+		_p = new Polygon(x, y, x.length);
 		
-		for (int i = 0; i < x.length; i++)
-		{
-			if (x[i] < _minX)
-				_minX = x[i];
-			if (x[i] > _maxX)
-				_maxX = x[i];
-		}
-		for (int i = 0; i < y.length; i++)
-		{
-			if (y[i] < _minY)
-				_minY = y[i];
-			if (y[i] > _maxY)
-				_maxY = y[i];
-		}
+		_z1 = Math.min(z1, z2);
+		_z2 = Math.max(z1, z2);
 	}
 	
 	@Override
 	public boolean isInsideZone(int x, int y, int z)
 	{
-		if (z < _z1 || z > _z2)
-			return false;
-		
-		boolean inside = false;
-		for (int i = 0, j = _x.length - 1; i < _x.length; j = i++)
-		{
-			if ((((_y[i] <= y) && (y < _y[j])) || ((_y[j] <= y) && (y < _y[i]))) && (x < (_x[j] - _x[i]) * (y - _y[i]) / (_y[j] - _y[i]) + _x[i]))
-			{
-				inside = !inside;
-			}
-		}
-		return inside;
+		return (_p.contains(x, y) && z >= _z1 && z <= _z2);
 	}
 	
 	@Override
 	public boolean intersectsRectangle(int ax1, int ax2, int ay1, int ay2)
 	{
-		int tX, tY, uX, uY;
-		
-		// First check if a point of the polygon lies inside the rectangle
-		if (_x[0] > ax1 && _x[0] < ax2 && _y[0] > ay1 && _y[0] < ay2)
-			return true;
-		
-		// Or a point of the rectangle inside the polygon
-		if (isInsideZone(ax1, ay1, (_z2 - 1)))
-			return true;
-		
-		// If the first point wasn't inside the rectangle it might still have any line crossing any side
-		// of the rectangle
-		
-		// Check every possible line of the polygon for a collision with any of the rectangles side
-		for (int i = 0; i < _y.length; i++)
-		{
-			tX = _x[i];
-			tY = _y[i];
-			uX = _x[(i + 1) % _x.length];
-			uY = _y[(i + 1) % _x.length];
-			
-			// Check if this line intersects any of the four sites of the rectangle
-			if (lineSegmentsIntersect(tX, tY, uX, uY, ax1, ay1, ax1, ay2))
-				return true;
-			if (lineSegmentsIntersect(tX, tY, uX, uY, ax1, ay1, ax2, ay1))
-				return true;
-			if (lineSegmentsIntersect(tX, tY, uX, uY, ax2, ay2, ax1, ay2))
-				return true;
-			if (lineSegmentsIntersect(tX, tY, uX, uY, ax2, ay2, ax2, ay1))
-				return true;
-		}
-		
-		return false;
+		return (_p.intersects(Math.min(ax1, ax2), Math.min(ay1, ay2), Math.max(ax1, ax2) - Math.min(ax1, ax2), Math.max(ay1, ay2) - Math.min(ay1, ay2)));
 	}
 	
 	@Override
 	public double getDistanceToZone(int x, int y)
 	{
+		int[] _x = _p.xpoints;
+		int[] _y = _p.ypoints;
 		double test, shortestDist = Math.pow(_x[0] - x, 2) + Math.pow(_y[0] - y, 2);
 		
-		for (int i = 1; i < _y.length; i++)
+		for (int i = 1; i < _p.npoints; i++)
 		{
 			test = Math.pow(_x[i] - x, 2) + Math.pow(_y[i] - y, 2);
 			if (test < shortestDist)
@@ -155,7 +95,10 @@ public class ZoneNPoly extends L2ZoneForm
 	@Override
 	public void visualizeZone(int z)
 	{
-		for (int i = 0; i < _x.length; i++)
+		int[] _x = _p.xpoints;
+		int[] _y = _p.ypoints;
+		
+		for (int i = 0; i < _p.npoints; i++)
 		{
 			int nextIndex = i + 1;
 			// ending point to first one
@@ -178,11 +121,16 @@ public class ZoneNPoly extends L2ZoneForm
 	{
 		int x, y;
 		
+		int _minX = _p.getBounds().x;
+		int _maxX = _p.getBounds().x + _p.getBounds().width;
+		int _minY = _p.getBounds().y;
+		int _maxY = _p.getBounds().y + _p.getBounds().height;
+		
 		x = Rnd.get(_minX, _maxX);
 		y = Rnd.get(_minY, _maxY);
 		
 		int antiBlocker = 0;
-		while (!isInsideZone(x, y, getHighZ()) && antiBlocker < 1000)
+		while (!_p.contains(x, y) && antiBlocker < 1000)
 		{
 			x = Rnd.get(_minX, _maxX);
 			y = Rnd.get(_minY, _maxY);