Added support for changing cached floor/terrain
This commit is contained in:
@@ -1,12 +1,16 @@
|
|||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
precision lowp int;
|
||||||
|
#define INTEGER lowp int
|
||||||
|
#else
|
||||||
|
#define INTEGER int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define gradients false
|
#define gradients false
|
||||||
|
|
||||||
const int MAX_COLORS = 10;
|
const int MAX_COLORS = 10;
|
||||||
|
|
||||||
uniform int u_colornum;
|
uniform INTEGER u_colornum;
|
||||||
uniform vec4 u_colors[MAX_COLORS];
|
uniform vec4 u_colors[MAX_COLORS];
|
||||||
|
|
||||||
varying float v_height;
|
varying float v_height;
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
precision lowp int;
|
||||||
|
#define INTEGER lowp int
|
||||||
|
#else
|
||||||
|
#define INTEGER int
|
||||||
|
#endif
|
||||||
|
|
||||||
attribute vec4 a_position;
|
attribute vec4 a_position;
|
||||||
attribute vec3 a_normal;
|
attribute vec3 a_normal;
|
||||||
|
|
||||||
@@ -14,7 +22,7 @@ uniform float u_spread;
|
|||||||
uniform float u_magnitude;
|
uniform float u_magnitude;
|
||||||
uniform float u_seed;
|
uniform float u_seed;
|
||||||
|
|
||||||
uniform int u_colornum;
|
uniform INTEGER u_colornum;
|
||||||
|
|
||||||
varying float v_height;
|
varying float v_height;
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ public class Renderer implements ApplicationListener{
|
|||||||
|
|
||||||
drawBackground();
|
drawBackground();
|
||||||
|
|
||||||
|
blocks.floor.checkChanges();
|
||||||
blocks.floor.drawFloor();
|
blocks.floor.drawFloor();
|
||||||
|
|
||||||
Groups.drawFloor();
|
Groups.drawFloor();
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ public class World{
|
|||||||
return tile.block().linked(tile);
|
return tile.block().linked(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public Tile rawTile(int x, int y){
|
public Tile rawTile(int x, int y){
|
||||||
return tiles.getn(x, y);
|
return tiles.getn(x, y);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.editor;
|
package mindustry.editor;
|
||||||
|
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.Blocks;
|
||||||
import mindustry.core.GameState.State;
|
import mindustry.core.GameState.State;
|
||||||
import mindustry.editor.DrawOperation.OpType;
|
import mindustry.editor.DrawOperation.OpType;
|
||||||
@@ -20,7 +21,7 @@ public class EditorTile extends Tile{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFloor(Floor type){
|
public void setFloor(@NonNull Floor type){
|
||||||
if(state.is(State.playing)){
|
if(state.is(State.playing)){
|
||||||
super.setFloor(type);
|
super.setFloor(type);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -42,9 +42,21 @@ public enum CacheLayer{
|
|||||||
endShader(Shaders.slag);
|
endShader(Shaders.slag);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
normal,
|
normal(5),
|
||||||
walls;
|
walls;
|
||||||
|
|
||||||
|
public static final CacheLayer[] all = values();
|
||||||
|
/** Capacity multiplier. */
|
||||||
|
public final int capacity;
|
||||||
|
|
||||||
|
CacheLayer(){
|
||||||
|
this(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheLayer(int capacity){
|
||||||
|
this.capacity = capacity;
|
||||||
|
}
|
||||||
|
|
||||||
public void begin(){
|
public void begin(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,13 @@ import java.util.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class FloorRenderer implements Disposable{
|
public class FloorRenderer implements Disposable{
|
||||||
private final static int chunksize = 64;
|
//TODO find out number with best performance
|
||||||
|
private final static int chunksize = mobile ? 16 : 32;
|
||||||
|
|
||||||
private Chunk[][] cache;
|
private Chunk[][] cache;
|
||||||
private MultiCacheBatch cbatch;
|
private MultiCacheBatch cbatch;
|
||||||
private IntSet drawnLayerSet = new IntSet();
|
private IntSet drawnLayerSet = new IntSet();
|
||||||
|
private IntSet recacheSet = new IntSet();
|
||||||
private IntArray drawnLayers = new IntArray();
|
private IntArray drawnLayers = new IntArray();
|
||||||
private ObjectSet<CacheLayer> used = new ObjectSet<>();
|
private ObjectSet<CacheLayer> used = new ObjectSet<>();
|
||||||
|
|
||||||
@@ -28,6 +30,11 @@ public class FloorRenderer implements Disposable{
|
|||||||
Events.on(WorldLoadEvent.class, event -> clearTiles());
|
Events.on(WorldLoadEvent.class, event -> clearTiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Queues up a cache change for a tile. Only runs in render loop. */
|
||||||
|
public void recacheTile(Tile tile){
|
||||||
|
recacheSet.add(Pos.get(tile.x / chunksize, tile.y / chunksize));
|
||||||
|
}
|
||||||
|
|
||||||
public void drawFloor(){
|
public void drawFloor(){
|
||||||
if(cache == null){
|
if(cache == null){
|
||||||
return;
|
return;
|
||||||
@@ -41,7 +48,7 @@ public class FloorRenderer implements Disposable{
|
|||||||
int camx = (int)(camera.position.x / (chunksize * tilesize));
|
int camx = (int)(camera.position.x / (chunksize * tilesize));
|
||||||
int camy = (int)(camera.position.y / (chunksize * tilesize));
|
int camy = (int)(camera.position.y / (chunksize * tilesize));
|
||||||
|
|
||||||
int layers = CacheLayer.values().length;
|
int layers = CacheLayer.all.length;
|
||||||
|
|
||||||
drawnLayers.clear();
|
drawnLayers.clear();
|
||||||
drawnLayerSet.clear();
|
drawnLayerSet.clear();
|
||||||
@@ -77,7 +84,7 @@ public class FloorRenderer implements Disposable{
|
|||||||
beginDraw();
|
beginDraw();
|
||||||
|
|
||||||
for(int i = 0; i < drawnLayers.size; i++){
|
for(int i = 0; i < drawnLayers.size; i++){
|
||||||
CacheLayer layer = CacheLayer.values()[drawnLayers.get(i)];
|
CacheLayer layer = CacheLayer.all[drawnLayers.get(i)];
|
||||||
|
|
||||||
drawLayer(layer);
|
drawLayer(layer);
|
||||||
}
|
}
|
||||||
@@ -93,6 +100,19 @@ public class FloorRenderer implements Disposable{
|
|||||||
cbatch.endDraw();
|
cbatch.endDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void checkChanges(){
|
||||||
|
if(recacheSet.size > 0){
|
||||||
|
//recache one chunk at a time
|
||||||
|
IntSetIterator iterator = recacheSet.iterator();
|
||||||
|
while(iterator.hasNext){
|
||||||
|
int chunk = iterator.next();
|
||||||
|
cacheChunk(Pos.x(chunk), Pos.y(chunk));
|
||||||
|
}
|
||||||
|
|
||||||
|
recacheSet.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void beginDraw(){
|
public void beginDraw(){
|
||||||
if(cache == null){
|
if(cache == null){
|
||||||
return;
|
return;
|
||||||
@@ -146,16 +166,14 @@ public class FloorRenderer implements Disposable{
|
|||||||
used.clear();
|
used.clear();
|
||||||
Chunk chunk = cache[cx][cy];
|
Chunk chunk = cache[cx][cy];
|
||||||
|
|
||||||
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){
|
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize && tilex < world.width(); tilex++){
|
||||||
for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){
|
for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize && tiley < world.height(); tiley++){
|
||||||
Tile tile = world.tile(tilex, tiley);
|
Tile tile = world.rawTile(tilex, tiley);
|
||||||
|
|
||||||
if(tile != null){
|
if(tile.block().cacheLayer != CacheLayer.normal){
|
||||||
if(tile.block().cacheLayer != CacheLayer.normal){
|
used.add(tile.block().cacheLayer);
|
||||||
used.add(tile.block().cacheLayer);
|
}else{
|
||||||
}else{
|
used.add(tile.floor().cacheLayer);
|
||||||
used.add(tile.floor().cacheLayer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +187,12 @@ public class FloorRenderer implements Disposable{
|
|||||||
SpriteBatch current = Core.batch;
|
SpriteBatch current = Core.batch;
|
||||||
Core.batch = cbatch;
|
Core.batch = cbatch;
|
||||||
|
|
||||||
cbatch.beginCache();
|
//begin a new cache
|
||||||
|
if(chunk.caches[layer.ordinal()] == -1){
|
||||||
|
cbatch.beginCache();
|
||||||
|
}else{
|
||||||
|
cbatch.beginCache(chunk.caches[layer.ordinal()]);
|
||||||
|
}
|
||||||
|
|
||||||
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){
|
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){
|
||||||
for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){
|
for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){
|
||||||
@@ -191,13 +214,16 @@ public class FloorRenderer implements Disposable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.batch = current;
|
Core.batch = current;
|
||||||
|
cbatch.reserve(layer.capacity * chunksize * chunksize);
|
||||||
chunk.caches[layer.ordinal()] = cbatch.endCache();
|
chunk.caches[layer.ordinal()] = cbatch.endCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearTiles(){
|
public void clearTiles(){
|
||||||
if(cbatch != null) cbatch.dispose();
|
if(cbatch != null) cbatch.dispose();
|
||||||
|
|
||||||
|
recacheSet.clear();
|
||||||
int chunksx = Mathf.ceil((float)(world.width()) / chunksize),
|
int chunksx = Mathf.ceil((float)(world.width()) / chunksize),
|
||||||
chunksy = Mathf.ceil((float)(world.height()) / chunksize);
|
chunksy = Mathf.ceil((float)(world.height()) / chunksize);
|
||||||
cache = new Chunk[chunksx][chunksy];
|
cache = new Chunk[chunksx][chunksy];
|
||||||
@@ -226,6 +252,8 @@ public class FloorRenderer implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class Chunk{
|
private class Chunk{
|
||||||
int[] caches = new int[CacheLayer.values().length];
|
/** Maps cache layer ID to cache ID in the batch.
|
||||||
|
* -1 means that this cache is unoccupied. */
|
||||||
|
int[] caches = new int[CacheLayer.all.length];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public class MenuRenderer implements Disposable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generate(){
|
private void generate(){
|
||||||
|
world.beginMapLoad();
|
||||||
Tiles tiles = world.resize(width, height);
|
Tiles tiles = world.resize(width, height);
|
||||||
Array<Block> ores = content.blocks().select(b -> b instanceof OreBlock);
|
Array<Block> ores = content.blocks().select(b -> b instanceof OreBlock);
|
||||||
shadows = new FrameBuffer(width, height);
|
shadows = new FrameBuffer(width, height);
|
||||||
@@ -159,6 +160,8 @@ public class MenuRenderer implements Disposable{
|
|||||||
tile.setOverlay(ore);
|
tile.setOverlay(ore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
world.endMapLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cache(){
|
private void cache(){
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ public class Tile implements Position{
|
|||||||
/** Tile entity, usually null. */
|
/** Tile entity, usually null. */
|
||||||
public Tilec entity;
|
public Tilec entity;
|
||||||
public short x, y;
|
public short x, y;
|
||||||
protected Block block;
|
protected @NonNull Block block;
|
||||||
protected Floor floor;
|
protected @NonNull Floor floor;
|
||||||
protected Floor overlay;
|
protected @NonNull Floor overlay;
|
||||||
/** Rotation, 0-3. Also used to store offload location, in which case it can be any number.*/
|
/** Rotation, 0-3. Also used to store offload location, in which case it can be any number.*/
|
||||||
protected byte rotation;
|
protected byte rotation;
|
||||||
/** Team ordinal. */
|
/** Team ordinal. */
|
||||||
@@ -175,10 +175,13 @@ public class Tile implements Position{
|
|||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**This resets the overlay!*/
|
/** This resets the overlay! */
|
||||||
public void setFloor(@NonNull Floor type){
|
public void setFloor(@NonNull Floor type){
|
||||||
this.floor = type;
|
this.floor = type;
|
||||||
this.overlay = (Floor)Blocks.air;
|
this.overlay = (Floor)Blocks.air;
|
||||||
|
|
||||||
|
recache();
|
||||||
|
block.onProximityUpdate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the floor, preserving overlay.*/
|
/** Sets the floor, preserving overlay.*/
|
||||||
@@ -188,6 +191,19 @@ public class Tile implements Position{
|
|||||||
setOverlay(overlay);
|
setOverlay(overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void recache(){
|
||||||
|
if(!headless && !world.isGenerating()){
|
||||||
|
renderer.blocks.floor.recacheTile(this);
|
||||||
|
renderer.minimap.update(this);
|
||||||
|
for(int i = 0; i < 8; i++){
|
||||||
|
Tile other = world.tile(x + Geometry.d8[i].x, y + Geometry.d8[i].y);
|
||||||
|
if(other != null){
|
||||||
|
renderer.blocks.floor.recacheTile(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void remove(){
|
public void remove(){
|
||||||
link().getLinkedTiles(other -> other.setBlock(Blocks.air));
|
link().getLinkedTiles(other -> other.setBlock(Blocks.air));
|
||||||
}
|
}
|
||||||
@@ -441,10 +457,14 @@ public class Tile implements Position{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void preChanged(){
|
protected void preChanged(){
|
||||||
block().removed(this);
|
block.removed(this);
|
||||||
if(entity != null){
|
if(entity != null){
|
||||||
entity.removeFromProximity();
|
entity.removeFromProximity();
|
||||||
}
|
}
|
||||||
|
//recache when static blocks get changed
|
||||||
|
if(block.isStatic()){
|
||||||
|
recache();
|
||||||
|
}
|
||||||
team = 0;
|
team = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,6 +502,11 @@ public class Tile implements Position{
|
|||||||
updateOcclusion();
|
updateOcclusion();
|
||||||
|
|
||||||
world.notifyChanged(this);
|
world.notifyChanged(this);
|
||||||
|
|
||||||
|
//recache when static block is added
|
||||||
|
if(block.isStatic()){
|
||||||
|
recache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -234,15 +234,21 @@ public class Drill extends Block{
|
|||||||
returnCount = oreCount.get(itemArray.peek(), 0);
|
returnCount = oreCount.get(itemArray.peek(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProximityUpdate(Tile tile){
|
||||||
|
DrillEntity entity = tile.ent();
|
||||||
|
|
||||||
|
countOre(tile);
|
||||||
|
entity.dominantItem = returnItem;
|
||||||
|
entity.dominantItems = returnCount;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Tile tile){
|
public void update(Tile tile){
|
||||||
DrillEntity entity = tile.ent();
|
DrillEntity entity = tile.ent();
|
||||||
|
|
||||||
if(entity.dominantItem == null){
|
if(entity.dominantItem == null){
|
||||||
countOre(tile);
|
return;
|
||||||
if(returnItem == null) return;
|
|
||||||
entity.dominantItem = returnItem;
|
|
||||||
entity.dominantItems = returnCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity.timer(timerDump, dumpTime)){
|
if(entity.timer(timerDump, dumpTime)){
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=23a7b4c41d1723835af9b79aab1093384cfcc621
|
archash=80007985ae0f1cb24531272e910844d0b4b5bb18
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ public class ZoneTests{
|
|||||||
|
|
||||||
for(Zone zone : content.zones()){
|
for(Zone zone : content.zones()){
|
||||||
out.add(dynamicTest(zone.name, () -> {
|
out.add(dynamicTest(zone.name, () -> {
|
||||||
zone.generator.init(zone.loadout);
|
|
||||||
logic.reset();
|
logic.reset();
|
||||||
try{
|
try{
|
||||||
//world.loadGenerator(zone.generator);
|
//world.loadGenerator(zone.generator);
|
||||||
|
|||||||
Reference in New Issue
Block a user