Package Hexel.chunk

Source Code of Hexel.chunk.ChunkVisibilityManager

package Hexel.chunk;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import Hexel.Engine;
import Hexel.blocks.types.BlockTransparent;
import Hexel.math.HexGeometry;
import Hexel.math.Vector2d;
import Hexel.math.Vector3i;
import Hexel.rendering.Camera;
import Hexel.rendering.GLChunk;
import Hexel.rendering.Renderer;
import Hexel.things.types.Thing;

public class ChunkVisibilityManager {

  private Chunks chunks;
  private Renderer renderer;

  public Set<Vector3i> renderedChunks = Collections.newSetFromMap(new ConcurrentHashMap<Vector3i, Boolean>());
  public Set<Vector3i> simulatedChunks = Collections.newSetFromMap(new ConcurrentHashMap<Vector3i, Boolean>());
  public Set<Vector3i> distanceChunks = Collections.newSetFromMap(new ConcurrentHashMap<Vector3i, Boolean>());

  public int renderDistance = 2*30;

  private Engine engine;
  private int lastLightLevel = 0;

  public ChunkVisibilityManager(Engine engine, Chunks chunks, Renderer renderer) {
    this.engine = engine;
    this.chunks = chunks;
    this.renderer = renderer;
  }

  public void updateVisibility(Camera camera) {
    Vector2d pos = new Vector2d();
    HexGeometry.cartesianToHex(camera.getCameraX(), camera.getCameraY(), pos);

    int cx = (int) Math.floor(pos.x / 16.0);
    int cy = (int) Math.floor(pos.y / 16.0);
    int cz = (int) Math.floor(camera.getCameraZ() / 16.0);

    ArrayList<Vector3i> points = new ArrayList<Vector3i>();
    ArrayList<Vector3i> inRenderRange = new ArrayList<Vector3i>();
    ArrayList<Vector3i> inSimRange = new ArrayList<Vector3i>();
    ArrayList<Vector3i> inDistRange = new ArrayList<Vector3i>();

    int lightLevel = (int) (BlockTransparent.MAX_LIGHT_LEVEL*engine.getAmbientLight());
    boolean resetLights = lastLightLevel != lightLevel;

    int distanceChunksRange = 8;
    int renderedChunksRange = 4;
    int simulatedChunksRange = 1;
    for (int x = -distanceChunksRange; x <= distanceChunksRange; x++) {
      for (int y = -distanceChunksRange; y <= distanceChunksRange; y++) {
        for (int z = -distanceChunksRange; z <= distanceChunksRange; z++) {
          int ncx = cx + x;
          int ncy = cy + y;
          int ncz = cz + z;
          Vector3i cpos = new Vector3i(ncx, ncy, ncz);
         
          boolean pInRenderRange = false;

          if (x >= -renderedChunksRange && x <= renderedChunksRange){
            if (y >= -renderedChunksRange && y <= renderedChunksRange){
              if (z >= -renderedChunksRange && z <= renderedChunksRange){
                pInRenderRange = true;
                inRenderRange.add(cpos);
                Chunk chunk = this.chunks.getChunk(cpos);
                if (!chunk.needFirstSim && !chunk.fastMode){
                  if (!this.renderedChunks.contains(cpos)) {
                    points.add(cpos);
                    chunk.setDirty(false);
                  } else {
                    if (resetLights || chunk.isDirty()) {
                      chunk.setDirty(false);
                      points.add(cpos);
                    }

                  }
                }
                if (points.size() > 10) {
                  this.renderer.loadChunks(points);
                  this.renderedChunks.addAll(points);
                  points = new ArrayList<Vector3i>();
                }
                if (x >= -simulatedChunksRange && x <= simulatedChunksRange){
                  if (y >= -simulatedChunksRange && y <= simulatedChunksRange){
                    if (z >= -simulatedChunksRange && z <= simulatedChunksRange){
                      inSimRange.add(cpos);
                      this.simulatedChunks.add(cpos);
                    }
                  }
                }
              }
            }
            if (!pInRenderRange){
              inDistRange.add(cpos);
            }
          }
        }
      }
    }
    this.renderer.loadChunks(points);
    this.renderedChunks.addAll(points);

    lastLightLevel = lightLevel;

    HashMap<Vector3i, GLChunk> glChunkTable = this.renderer.getGLChunkTable();
    for (Vector3i p : new HashSet<Vector3i>(glChunkTable.keySet())) {
      if (!inRenderRange.contains(p)) {
        this.renderer.unloadGLChunk(p);
      }
    }

    Iterator<Vector3i> iter = this.renderedChunks.iterator();
    ArrayList<Vector3i> toRemove = new ArrayList<Vector3i>();
    while (iter.hasNext()) {
      Vector3i position = iter.next();
      if (!inRenderRange.contains(position) && !points.contains(position)) {
        toRemove.add(position);
      }
    }
    this.renderedChunks.removeAll(toRemove);

    iter = this.simulatedChunks.iterator();
    toRemove = new ArrayList<Vector3i>();
    while (iter.hasNext()) {
      Vector3i position = iter.next();
      if (!inSimRange.contains(position)) {
        toRemove.add(position);
      }
    }
    this.simulatedChunks.removeAll(toRemove);

    iter = this.distanceChunks.iterator();
    toRemove = new ArrayList<Vector3i>();
    while (iter.hasNext()) {
      Vector3i position = iter.next();
      if (!inDistRange.contains(position)) {
        toRemove.add(position);
      }
    }
    this.distanceChunks.removeAll(toRemove);
  }
}
TOP

Related Classes of Hexel.chunk.ChunkVisibilityManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.