Java Sector holding N-Size Tree – Quid =)

Quid tree like Octree that Holds Sectors like chunks in minecraft.
Quid Grow Down, if minimum sector is 3 x 3 it can grow on 9 x 9 sector.

Main usage chunk holder =)

int size_Aray - Array Len By Axis
2 x 2 Base 2D Octree size.


//Top Class
public class Quid_2D <E extends Quid_2D_Object>{
	private Quid_2D_Hold<E> Upper;
	
	public Quid_2D(int size_Aray){
		Upper = new Quid_2D_Hold<E>(size_Aray);
	}
	public void add_Object(Quid_2D_Object obj){
		Upper.add_Object(obj);
		Upper = Upper.get_Upper();
	}
	public E get_Object(GL_Vector_YX_int vec){
		return get_Object(vec.y, vec.x);
	}
	public E get_Object(int z, int x){
		E obj = Upper.get_Object(z, x);	
		return obj;
	}
}


public interface Quid_2D_Object{
	public GL_Vector_YX_int get_Pos_Id();
}


	public GL_Vector_YX_int(int ypos, int xpos){
		y = ypos;
		x = xpos;
	}

public class Quid_2D_Hold <E extends Quid_2D_Object> implements Quid_2D_Object{
	int Side_Aray;
	int Size_Sector;
	
	Quid_2D_Hold<E> Up;
	GL_Vector_YX_int Quid_Pos;
	Object Quids_Grid[];
	boolean last;
	
	/** 
	 *  Data holding in array
	 *  X X X -1 -1 -1 size 3
	 *  X 0 X
	 *  X X X
	 *  
	 *  X X X X -2 -2 -2 size 4
	 *  X X X X
	 *  X X 0 X
	 *  X X X X
	 */
	// z = y in code
	public Quid_2D_Hold(int size_Aray){
		int Dif = 0 - size_Aray / 2;//3 = 1// 4 = 2
		GL_Vector_YX_int quid_Pos = new GL_Vector_YX_int(Dif, Dif);//B
		Init(size_Aray, 1, quid_Pos);
		last = true;	
	}
	private Quid_2D_Hold(int size_Aray, int size_Sector, GL_Vector_YX_int Quid_Pos){
		Init(size_Aray, size_Sector, Quid_Pos);
	}
	private void Init(int size_Aray, int size_Sector, GL_Vector_YX_int quid_Pos){
		Size_Sector = size_Sector;
		Side_Aray = size_Aray;
		Quid_Pos = quid_Pos;
		Quids_Grid = new Object[Side_Aray * Side_Aray];//z x
	}
	public void add_Object(Quid_2D_Object obj){
		if(Check_Object_in(obj)) 
			add_Object_in(obj);
		else
			add_Object_Out(obj);	
	}
	public E get_Object(GL_Vector_YX_int vec){
		return get_Object(vec.y, vec.x);
	}
	public E get_Object(int z, int x){
		Quid_2D_Hold<E> quid = get_Upper();
		E obj = quid.get_Object_in(z, x);	
		return obj;
	}
	public Quid_2D_Hold<E> get_Upper(){
		Quid_2D_Hold<E> quid = this;
		while(quid.Up != null){
			quid = quid.Up;
		}
		return quid;
	}
////////////////////////////////////////////////////////////////////////
	private boolean Check_Object_in(Quid_2D_Object obj){
		GL_Vector_YX_int pos_Obj = obj.get_Pos_Id();
		return Check_Object_in(pos_Obj.y, pos_Obj.x);
	}
	private boolean Check_Object_in(int z, int x){
		int size = Side_Aray * Size_Sector;			
		int from_z = Quid_Pos.y;
		int to_z = from_z + size;		
		if(from_z <= z && z <= to_z){
			
			int from_x = Quid_Pos.x;
			int to_x = from_x + size;
			if(from_x <= x && x <= to_x){
				return true;
			}
		}
		return false;
	}
	
	private void add_Object_in(Quid_2D_Object obj){
		GL_Vector_YX_int pos_Obj = obj.get_Pos_Id();
		int z = pos_Obj.y - Quid_Pos.y;
		int x = pos_Obj.x - Quid_Pos.x;
		z /= Size_Sector;
		x /= Size_Sector;
		
		int pos_Ar = z * Side_Aray + x;
		if(last){
			if(Quids_Grid[pos_Ar] != null)
				throw new IllegalArgumentException("Quid2D Try create Double " + obj.get_Pos_Id());
			Quids_Grid[pos_Ar] = obj;
		}
		else{
			Quid_2D_Hold<E> in_Quid = (Quid_2D_Hold<E>) Quids_Grid[pos_Ar];
			if(in_Quid == null){
				in_Quid = Create_Quid_Down(z, x);
				Quids_Grid[pos_Ar] = in_Quid;
			}
			in_Quid.add_Object(obj);
		}
	}
	private void add_Object_Out(Quid_2D_Object obj){
		if(Up == null){
			Create_Quid_Up();
		}
		Up.add_Object(obj);
	}
	private Quid_2D_Hold<E> Create_Quid_Down(int z, int x){
		z = z * Size_Sector + Quid_Pos.y;
		x = x * Size_Sector + Quid_Pos.x;
		GL_Vector_YX_int quid_Pos = new GL_Vector_YX_int(z, x);
		int size_Sector = Size_Sector / Side_Aray;
		Quid_2D_Hold<E> down = new Quid_2D_Hold<E>(Side_Aray, size_Sector, quid_Pos);
		if(size_Sector == 1)
			down.last = true;
		down.Up = this;
		D.S("Create Down " + down);
		return down;
	}
	private void Create_Quid_Up(){
		int size_Sector = Size_Sector * Side_Aray;
		//Midls pos
		int Dif = 0 - Side_Aray / 2;
		Dif *= size_Sector;
		int z = Dif + Quid_Pos.y;
		int x = Dif + Quid_Pos.x;
		GL_Vector_YX_int quid_Pos = new GL_Vector_YX_int(z, x);
		Quid_2D_Hold<E> up = new Quid_2D_Hold<E>(Side_Aray, size_Sector, quid_Pos);
		up.add_Quid_in(this);
		Up = up;
		D.S("Create Up " + Up);
	}
	private void add_Quid_in(Quid_2D_Object obj){
		GL_Vector_YX_int pos_Obj = obj.get_Pos_Id();
		int z = pos_Obj.y - Quid_Pos.y;
		int x = pos_Obj.x - Quid_Pos.x;
		z /= Size_Sector;
		x /= Size_Sector;
		
		int pos_Ar = z * Side_Aray + x;
		Quids_Grid[pos_Ar] = obj;
	}

	private E get_Object_in(int oz, int ox){
		int z = oz - Quid_Pos.y;
		int x = ox - Quid_Pos.x;
		z /= Size_Sector;
		x /= Size_Sector;
		
		int pos_Ar = z * Side_Aray + x;
		if(pos_Ar < 0 || pos_Ar >= Quids_Grid.length)
			return null;//out
		
		if(last){
			E obj = (E) Quids_Grid[pos_Ar];
			return obj;
		}
		else{
			Quid_2D_Hold<E> in_Quid = (Quid_2D_Hold<E>) Quids_Grid[pos_Ar];
			if(in_Quid == null)
				return null;
			return in_Quid.get_Object_in(oz, ox);
		}
	}
	
	@Override
	public GL_Vector_YX_int get_Pos_Id(){
		return Quid_Pos;
	}
	
	@Override
	public String toString(){
		String te = " z:" + (Quid_Pos.y)  + " * " + (Quid_Pos.y + Side_Aray * Size_Sector - 1);
		te += " x:" + (Quid_Pos.x)  + " * " + (Quid_Pos.x + Side_Aray * Size_Sector - 1);
		te += " s:" + Size_Sector;
		return te;
	}
}