Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.klassekatze.mineassistant.hpathmgr;
- import java.util.ArrayList;
- import net.minecraft.block.Block;
- import net.minecraft.block.material.Material;
- import net.minecraft.client.Minecraft;
- import net.minecraft.util.math.BlockPos;
- import net.minecraft.world.IBlockAccess;
- import net.minecraft.world.ChunkCache;
- public class AABBChunk {
- IBlockAccess blockCache = null;
- public BlockPos pointOfOrigin = null;
- public ArrayList<I_AABB_base> AABBCache;
- public ArrayList<I_AABB_base> AABBCache_airlike = new ArrayList<I_AABB_base>();
- public ArrayList<I_AABB_base> AABBCache_airlike_with_ground = new ArrayList<I_AABB_base>();
- boolean isDirty = false;
- public void setDirty()
- {
- isDirty = true;
- }
- int MAX_STEPPABLE_Y = 1;
- void updateAirlikeNeighborLists()//todo logic to incorporate other chunks...
- {
- regenIfDirty();
- for(int i = 0; i < AABBCache.size(); i++)
- {
- I_AABB_base a = AABBCache.get(i);
- //if(a.neighbors_steppable != null)a.neighbors_steppable.clear();
- //e/lse a.neighbors_steppable = new ArrayList<I_AABB_base>();
- if(a.neighbors_all_airlike != null)a.neighbors_all_airlike.clear();
- else a.neighbors_all_airlike = new ArrayList<I_AABB_base>();
- if(a.airlike)
- {
- for(int n = 0; n < AABBCache.size(); n++)
- {
- I_AABB_base b = AABBCache.get(n);
- if(b != a && b.airlike && is_aabb_adjacent(a, b))
- {
- a.neighbors_all_airlike.add(b);
- /*if(
- a.Max.y() - b.Min.y() <= MAX_STEPPABLE_Y ||
- b.Max.y() - a.Min.y() <= MAX_STEPPABLE_Y
- )
- {
- a.neighbors_steppable.add(b);
- }*/
- }
- }
- }
- }
- }
- void updateHasGroundFlags()
- {
- for(int i = 0; i < AABBCache.size(); i++)
- {
- I_AABB_base a = AABBCache.get(i);
- a.has_any_nonairlike_bottom = false;
- for(int n = 0; n < AABBCache.size(); n++)
- {
- I_AABB_base b = AABBCache.get(n);
- if(this.is_aabb_groundfor(a, b))
- {
- a.has_any_nonairlike_bottom = true;
- break;
- }
- }
- }
- }
- public boolean regenIfDirty()
- {
- if(isDirty)
- {
- isDirty = false;
- //regenhere
- blockCache = new ChunkCache(Minecraft.getMinecraft().world, pointOfOrigin, pointOfOrigin.add(15, 15, 15), 0);
- //after some thought, this is probably a waste to keep in memory most of the time
- //it literally doubles chunks in memory in a way
- AccessRotator access = new AccessRotator(blockCache,pointOfOrigin);
- //.access.if(blockCache.getWorldType())
- ArrayList<I_AABB_base> aabbs = get_AABBs_from_volume(access);
- blockCache = null;//drop it now.
- AABBCache = aabbs;
- //updateHasGroundFlags();
- //updateAirlikeNeighborLists();
- /*AABBCache_airlike.clear();
- AABBCache_airlike_with_ground.clear();
- for(int i = 0; i < AABBCache.size(); i++)
- {
- I_AABB_base a = AABBCache.get(i);
- if(a.airlike)AABBCache_airlike.add(a);
- if(a.has_any_nonairlike_bottom)AABBCache_airlike_with_ground.add(a);
- }*/
- return true;
- }
- return false;
- }
- /*public VoxelChunk() {
- // TODO Auto-generated constructor stub
- }*/
- I_AABB_base IVox_AABBfor(Block voxel, int x, int y, int z, int l, int w, int h)
- {
- //IVox_AABB v = IVec_AABBfor(x, y, z, l, w, h);
- I_AABB_base v = new I_AABB_base();// = IVox_AABB();
- v.Min = new SimpleMutableBlockPos(x,y,z);//glm::ivec3(x, y, z);
- v.Max = new SimpleMutableBlockPos(x+l,y+w,z+h);//glm::ivec3(x + l, y + w, z + h);
- v.airlike = voxel.getDefaultState().getMaterial() == Material.AIR;//isAir(state, , pos)
- //v.mVoxel = voxel;
- return v;
- }
- boolean sweep_volume_solid_aabb(AccessRotator Volume, RawVoxelVolume<I_AABB_base> ownfield, I_AABB_base aabb, boolean material_limit)
- {
- int min_x = aabb.Min.getX();//x;
- int min_y = aabb.Min.getY();//y;
- int min_z = aabb.Min.getZ();//z;
- int max_x = aabb.Max.getX();//x;
- int max_y = aabb.Max.getY();//y;
- int max_z = aabb.Max.getZ();//z;
- //PolyVox::Region enclosure = ownfield->getEnclosingRegion();
- //if (min_x < enclosure.getLowerX() || min_y < enclosure.getLowerY() || min_z < enclosure.getLowerZ())return false;
- //if (max_x > enclosure.getUpperX() || max_y > enclosure.getUpperY() || max_z > enclosure.getUpperZ())return false;
- for (int x = min_x; x < max_x; x++)
- {
- for (int y = min_y; y < max_y; y++)
- {
- for (int z = min_z; z < max_z; z++)
- {
- //if (material_limit && Volume->getVoxel(x, y, z).getMaterial() == 0)return false;
- //if(Volume.getVoxel(x, y, z).getDefaultState().getMaterial() == Material.AIR)return false;
- if (ownfield.getVoxel(x, y, z) != null)return false;
- //if (material_limit && Volume->getVoxel(x, y, z) != aabb.mVoxel)return false;
- }
- }
- }
- return true;
- }
- boolean is_aabb_adjacent(I_AABB_base a, I_AABB_base b)
- {
- if(
- a.Max.x() == b.Min.x() ||
- a.Max.y() == b.Min.y() ||
- a.Max.z() == b.Min.z() ||
- b.Max.x() == a.Min.x() ||
- b.Max.y() == a.Min.y() ||
- b.Max.z() == a.Min.z()
- )
- {
- return true;
- }
- return false;
- }
- boolean is_aabb_groundfor(I_AABB_base a, I_AABB_base b)
- {
- if(b.Max.y() == a.Min.y() && b.airlike == false && a.airlike == true)
- {
- return true;
- }
- return false;
- }
- /*.boolean is_aabb_adjacency_within_offset(I_AABB_base a, I_AABB_base b, BlockPos offset)
- {
- if(
- a.Max.x() - b.Min.x() <= offset.getX() ||
- a.Max.y() - b.Min.y() <= offset.getY() ||
- a.Max.z() - b.Min.z() <= offset.getZ() ||
- b.Max.x() - a.Min.x() <= offset.getX() ||
- b.Max.y() - a.Min.y() <= offset.getY() ||
- b.Max.z() - a.Min.z() <= offset.getZ()
- )
- {
- return true;
- }
- return false;
- }*/
- boolean sweep_volume_solid_aabb_markowned(RawVoxelVolume<I_AABB_base> ownfield, I_AABB_base aabb)
- {
- int min_x = aabb.Min.x();
- int min_y = aabb.Min.y();
- int min_z = aabb.Min.z();
- int max_x = aabb.Max.x();
- int max_y = aabb.Max.y();
- int max_z = aabb.Max.z();
- for (int x = min_x; x < max_x; x++)
- {
- for (int y = min_y; y < max_y; y++)
- {
- for (int z = min_z; z < max_z; z++)
- {
- ownfield.setVoxel(x, y, z, aabb);
- }
- }
- }
- return true;
- }
- ArrayList<I_AABB_base> generate_aabbs_from_voxels(AccessRotator accessor, boolean only_solids)
- {
- RawVoxelVolume<I_AABB_base> aabb_voxel_claims = new RawVoxelVolume<I_AABB_base>(accessor.getHeight(), accessor.getWidth(), accessor.getDepth(), null);
- //.getClass().OwnField aabb_voxel_claims = OwnField(accessor->getHeight(), accessor->getWidth(), accessor->getDepth(), nullptr);
- //establish owner data - so as we iterate a AABB can claim voxels it includes and we can quickly find owners without reiterating...
- //its easy and it should be faster, albeit (irrelevantly) more memory
- ArrayList<I_AABB_base> aabbs = new ArrayList<I_AABB_base>();
- aabbs.clear();
- for (int z = 0; z < accessor.getDepth(); z++)
- {
- for (int y = 0; y < accessor.getWidth(); y++)
- {
- for (int x = 0; x < accessor.getHeight(); x++)
- {
- //alright so grab current block.
- Block voxel = accessor.getVoxel(new BlockPos(x, y, z));
- I_AABB_base cur_voxel_box = IVox_AABBfor(voxel, x, y, z,1,1,1);//create a 1,1,1 wide box at x,y,z
- boolean keep = sweep_volume_solid_aabb(accessor, aabb_voxel_claims, cur_voxel_box, only_solids);//check if it is solid and unowned
- if (keep)//we have a starting voxel
- {
- int stored_axis_min;
- stored_axis_min = cur_voxel_box.Min.x();
- do
- {
- //cur_voxel_box.Max.x += 1;
- //cur_voxel_box.Min.x += 1;
- cur_voxel_box.Max.addX(1);
- cur_voxel_box.Min.addX(1);
- //shift forward one
- keep = sweep_volume_solid_aabb(accessor, aabb_voxel_claims, cur_voxel_box, only_solids) && cur_voxel_box.Max.x() < accessor.getHeight();
- } while (keep);
- //shift failed, backstep one to legit
- cur_voxel_box.Max.subX(1);
- //restore min to encompass all legit slices
- cur_voxel_box.Min.setX(stored_axis_min);
- stored_axis_min = cur_voxel_box.Min.y();
- do
- {
- //cur_voxel_box.Max.y += 1;
- //cur_voxel_box.Min.y += 1;
- cur_voxel_box.Max.addY(1);
- cur_voxel_box.Min.addY(1);
- //shift forward one
- keep = sweep_volume_solid_aabb(accessor, aabb_voxel_claims, cur_voxel_box, only_solids) && cur_voxel_box.Max.y() < accessor.getWidth();
- } while (keep);
- //shift failed, backstep one to legit
- cur_voxel_box.Max.subY(1);
- //restore min to encompass all legit slices
- cur_voxel_box.Min.setY(stored_axis_min);
- stored_axis_min = cur_voxel_box.Min.z();
- do
- {
- cur_voxel_box.Max.addZ(1);
- cur_voxel_box.Min.addZ(1);
- //shift forward one
- keep = sweep_volume_solid_aabb(accessor, aabb_voxel_claims, cur_voxel_box, only_solids) && cur_voxel_box.Max.z() < accessor.getDepth();
- } while (keep);
- //shift failed, backstep one to legit
- cur_voxel_box.Max.subZ(1);
- //restore min to encompass all legit slices
- cur_voxel_box.Min.setZ(stored_axis_min);
- sweep_volume_solid_aabb_markowned(aabb_voxel_claims, cur_voxel_box);//mark all enciompassed voxels as owned (by this aabb)
- //mark as owned.
- //now add to list
- //set_void_exposure_aabb(accessor, cur_voxel_box);
- aabbs.add(cur_voxel_box);
- }
- }
- }
- }
- return aabbs;
- }
- ArrayList<I_AABB_base> derotate_aabbs(ArrayList<I_AABB_base> aabbs, int width, int rot)
- {
- ArrayList<I_AABB_base> ret = new ArrayList<I_AABB_base>();
- for (int i = 0; i < aabbs.size(); i++)
- {
- //le sigh
- I_AABB_base aabb = aabbs.get(i);//[i];
- //reverse dpesn't work. it seems that the accessor flipped things in this specific case???
- BlockPos a = AccessRotator.BlockPosRotator.rotate_ivec3(aabb.Min.subtract(pointOfOrigin), width, rot, false).add(pointOfOrigin);
- BlockPos b = AccessRotator.BlockPosRotator.rotate_ivec3(aabb.Max.subtract(pointOfOrigin), width, rot, false).add(pointOfOrigin);
- aabb.Min.setPos(Math.min(a.getX(), b.getX()),Math.min(a.getY(), b.getY()),Math.min(a.getZ(), b.getZ()));
- aabb.Max.setPos(Math.max(a.getX(), b.getX()),Math.max(a.getY(), b.getY()),Math.max(a.getZ(), b.getZ()));
- //aabb.Min = glm::ivec3(glm::min(a.x, b.x), glm::min(a.y, b.y), glm::min(a.z, b.z));
- //aabb.Max = glm::ivec3(glm::max(a.x, b.x), glm::max(a.y, b.y), glm::max(a.z, b.z));
- if (rot > 2)
- {
- aabb.Min.addX(1);
- aabb.Min.addY(1);
- aabb.Min.addZ(1);
- aabb.Max.addX(1);
- aabb.Max.addY(1);
- aabb.Max.addZ(1);
- //aabb.Min = aabb.Min.add(1,1,1);// += 1;
- //aabb.Max = aabb.Max.add(1,1,1);//aabb.Max// += 1;
- }
- ret.add(aabb);
- //thinkin this maybe? eh.
- }
- return ret;
- }
- ArrayList<I_AABB_base> get_AABBs_from_volume(AccessRotator Volume)
- {
- ArrayList<I_AABB_base> fin_aabbs = new ArrayList<I_AABB_base>();
- //for (int rot = 0; rot < 6; rot++)
- int rot = 0;
- {
- Volume.setRotation(rot);
- ArrayList<I_AABB_base> aabbs = generate_aabbs_from_voxels(Volume, true);
- if (rot > 0)aabbs = derotate_aabbs(aabbs, 16, rot);
- if (fin_aabbs.size() == 0 || (aabbs.size() < fin_aabbs.size() && aabbs.size() > 0))
- {
- fin_aabbs = aabbs;
- }
- }
- //mVolumeAABB = fin_aabbs;
- return fin_aabbs;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement