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;
}
}