Complete planet panning

This commit is contained in:
Anuken 2020-02-21 13:48:50 -05:00
parent 99d3e9ae7c
commit a5e469e96c
7 changed files with 128 additions and 212 deletions

View File

@ -6,12 +6,12 @@ varying vec4 v_col;
const vec3 ambientColor = vec3(1.0);
const vec3 ambientDir = normalize(vec3(1.0, 1.0, 1.0));
const vec3 diffuse = vec3(0.5);
const vec3 diffuse = vec3(0);
const vec3 v1 = vec3(1.0, 0.0, 1.0);
const vec3 v2 = vec3(1.0, 0.5, 0.0);
void main(){
vec3 norc = ambientColor * clamp((dot(a_normal, ambientDir) + 1.0) / 2.0, 0.0, 1.0);
vec3 norc = ambientColor * lerp(vec3(1.0), diffuse, 1.0 - clamp((dot(a_normal, ambientDir) + 1.0) / 2.0, 0.0, 1.0));
v_col = a_color * vec4(norc, 1.0);
gl_Position = u_projModelView * a_position;

View File

@ -4,7 +4,6 @@ import mindustry.ctype.*;
import mindustry.game.Objectives.*;
import mindustry.game.*;
import mindustry.maps.generators.*;
import mindustry.maps.zonegen.*;
import mindustry.type.*;
import static arc.struct.Array.with;
@ -31,7 +30,8 @@ public class Zones implements ContentList{
resources = with(copper, scrap, lead);
}};
desertWastes = new Zone("desertWastes", starter, new DesertWastesGenerator()){{
//TODO remove
desertWastes = new Zone("desertWastes", starter, new FileMapGenerator("groundZero")){{
startingItems = list(copper, 120);
conditionWave = 20;
launchPeriod = 10;

View File

@ -5,6 +5,7 @@ import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.graphics.g3d.*;
import arc.input.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.graphics.PlanetGrid.*;
@ -16,9 +17,9 @@ import mindustry.world.*;
import static mindustry.Vars.*;
public class PlanetRenderer implements PlanetGenerator{
private final Color outlineColor = Pal.accent.cpy().a(0.7f);
private final float camLength = 4f, outlineRad = 1.15f;
private final boolean drawRect = true;
private static final Color outlineColor = Pal.accent.cpy().a(0.7f);
private static final float camLength = 4f, outlineRad = 1.15f;
private static final boolean drawRect = false;
private final PlanetMesh[] outlines = new PlanetMesh[10];
private final Camera3D cam = new Camera3D();
@ -103,8 +104,24 @@ public class PlanetRenderer implements PlanetGenerator{
Vec3 v = Tmp.v33.set(Core.input.mouseX(), Core.input.mouseY(), 0);
if(Core.input.keyDown(KeyCode.MOUSE_LEFT)){
cam.position.rotate(Vec3.Y, (v.x - lastX) / 10);
float upV = cam.position.angle(Vec3.Y);
float margin = 1;
//scale X speed depending on polar coordinate
float speed = 1f - Math.abs(upV - 90) / 90f;
cam.position.rotate(cam.up, (v.x - lastX) / 10 * speed);
//prevent user from scrolling all the way up and glitching it out
float amount = (v.y - lastY) / 10;
amount = Mathf.clamp(upV + amount, margin, 180f - margin) - upV;
cam.position.rotate(Tmp.v31.set(cam.up).rotate(cam.direction, 90), amount);
}
//lock to Y coordinate so planet rotation doesn't get confusing
cam.up.set(Vec3.Y);
lastX = v.x;
lastY = v.y;
}

View File

@ -124,7 +124,7 @@ public abstract class BasicGenerator implements WorldGenerator{
tiles.each((x, y) -> {
int idx = y*tiles.width + x;
float cx = x + noise(x, y, scl, mag) - mag / 2f, cy = y + noise(x, y + 152f, scl, mag) - mag / 2f;
float cx = x + noise(x, y, scl, mag) - mag / 2f, cy = y + noise(x + 155f, y + 155f, scl, mag) - mag / 2f;
Tile other = tiles.getn(Mathf.clamp((int)cx, 0, tiles.width-1), Mathf.clamp((int)cy, 0, tiles.height-1));
blocks[idx] = other.block().id;
floors[idx] = other.floor().id;

View File

@ -6,12 +6,13 @@ import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import arc.util.noise.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.maps.zonegen.*;
import mindustry.maps.generators.*;
import mindustry.type.*;
import mindustry.world.*;
import static mindustry.Vars.schematics;
//TODO refactor into generic planet class
public class TestPlanetGenerator implements PlanetGenerator{
Simplex noise = new Simplex();
@ -24,9 +25,9 @@ public class TestPlanetGenerator implements PlanetGenerator{
Block[][] arr = {
{Blocks.water, Blocks.darksandWater, Blocks.darksand, Blocks.darksand, Blocks.darksand, Blocks.darksand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.darksandTaintedWater, Blocks.snow, Blocks.ice},
{Blocks.water, Blocks.darksandWater, Blocks.darksand, Blocks.darksand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.darksandTaintedWater, Blocks.snow, Blocks.snow, Blocks.ice},
{Blocks.water, Blocks.darksandWater, Blocks.darksand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.darksandTaintedWater, Blocks.snow, Blocks.ice, Blocks.ice},
{Blocks.water, Blocks.sandWater, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.iceSnow, Blocks.snow, Blocks.snow, Blocks.ice, Blocks.ice},
{Blocks.deepwater, Blocks.water, Blocks.sandWater, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.moss, Blocks.snow, Blocks.snow, Blocks.snow, Blocks.snow, Blocks.ice},
{Blocks.water, Blocks.darksandWater, Blocks.darksand, Blocks.sand, Blocks.salt, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.darksandTaintedWater, Blocks.snow, Blocks.ice, Blocks.ice},
{Blocks.water, Blocks.sandWater, Blocks.sand, Blocks.salt, Blocks.salt, Blocks.salt, Blocks.sand, Blocks.sand, Blocks.iceSnow, Blocks.snow, Blocks.snow, Blocks.ice, Blocks.ice},
{Blocks.deepwater, Blocks.water, Blocks.sandWater, Blocks.sand, Blocks.salt, Blocks.sand, Blocks.sand, Blocks.moss, Blocks.snow, Blocks.snow, Blocks.snow, Blocks.snow, Blocks.ice},
{Blocks.deepwater, Blocks.water, Blocks.sandWater, Blocks.sand, Blocks.sand, Blocks.sand, Blocks.moss, Blocks.iceSnow, Blocks.snow, Blocks.snow, Blocks.ice, Blocks.snow, Blocks.ice},
{Blocks.deepwater, Blocks.sandWater, Blocks.sand, Blocks.sand, Blocks.moss, Blocks.moss, Blocks.moss, Blocks.snow, Blocks.snow, Blocks.ice, Blocks.ice, Blocks.snow, Blocks.ice},
{Blocks.taintedWater, Blocks.darksandTaintedWater, Blocks.darksand, Blocks.darksand, Blocks.darksandTaintedWater, Blocks.moss, Blocks.snow, Blocks.snow, Blocks.snow, Blocks.ice, Blocks.snow, Blocks.ice, Blocks.ice},
@ -55,7 +56,9 @@ public class TestPlanetGenerator implements PlanetGenerator{
@Override
public Color getColor(Vec3 position){
return getBlock(position).color;
Block block = getBlock(position);
//replace salt with sand color
return block == Blocks.salt ? Blocks.sand.color : block.color;
}
@Override
@ -77,77 +80,7 @@ public class TestPlanetGenerator implements PlanetGenerator{
this.tiles = tiles;
this.sector = sec;
//OvergrowthGenerator generator = new OvergrowthGenerator(tiles.width, tiles.height);
//generator.init(Loadouts.basicNucleus);
//generator.generate(tiles);
GridBits write = new GridBits(tiles.width, tiles.height);
GridBits read = new GridBits(tiles.width, tiles.height);
//double removalChance = 0.2;
//remove random tiles
//tiles.each((x, y) -> {
//});
tiles.each((x, y) -> read.set(x, y, !tiles.get(x, y).block().isAir()));
int iterations = 4, birthLimit = 16, deathLimit = 16, radius = 3;
for(int i = 0; i < iterations; i++){
tiles.each((x, y) -> {
int alive = 0;
for(int cx = -radius; cx <= radius; cx++){
for(int cy = -radius; cy <= radius; cy++){
if((cx == 0 && cy == 0) || !Mathf.within(cx, cy, radius)) continue;
if(!Structs.inBounds(x + cx, y + cy, tiles.width, tiles.height) || read.get(x + cx, y + cy)){
alive++;
}
}
}
if(read.get(x, y)){
write.set(x, y, alive >= deathLimit);
}else{
write.set(x, y, alive > birthLimit);
}
});
//flush results
read.set(write);
}
tiles.each((x, y) -> tiles.get(x, y).setBlock(!read.get(x, y) ? Blocks.air : tiles.get(x, y).floor().wall));
distort(0.009f, 12f);
OvergrowthGenerator gen = new OvergrowthGenerator();
gen.generate(tiles);
//tiles.get(tiles.width /2, tiles.height /2).setBlock(Blocks.coreShard, Team.sharded);
}
void distort(float scl, float mag){
short[] blocks = new short[tiles.width * tiles.height];
short[] floors = new short[blocks.length];
tiles.each((x, y) -> {
int idx = y*tiles.width + x;
float cx = x + noise(x, y, scl, mag) - mag / 2f, cy = y + noise(x, y + 152f, scl, mag) - mag / 2f;
Tile other = tiles.getn(Mathf.clamp((int)cx, 0, tiles.width-1), Mathf.clamp((int)cy, 0, tiles.height-1));
blocks[idx] = other.block().id;
floors[idx] = other.floor().id;
});
for(int i = 0; i < blocks.length; i++){
Tile tile = tiles.geti(i);
tile.setFloor(Vars.content.block(floors[i]).asFloor());
tile.setBlock(Vars.content.block(blocks[i]));
}
}
protected float noise(float x, float y, float scl, float mag){
Vec3 v = sector.rect.project(x / tiles.width, y / tiles.height);
return (float)noise.octaveNoise3D(1f, 0f, 1f / scl, v.x, v.y, v.z) * mag;
new Terrain().generate(tiles);
}
Block getBlock(Vec3 position){
@ -162,4 +95,96 @@ public class TestPlanetGenerator implements PlanetGenerator{
return arr[Mathf.clamp((int)(temp * arr.length), 0, arr.length - 1)][Mathf.clamp((int)(height * arr[0].length), 0, arr[0].length - 1)];
}
class Terrain extends BasicGenerator{
Array<Block> ores = Array.with(Blocks.oreCopper, Blocks.oreLead, Blocks.oreCoal, Blocks.oreCopper);
@Override
protected void generate(){
cells(4);
distort(20f, 12f);
float constraint = 1.3f;
float radius = width / 2f / Mathf.sqrt3;
int rooms = Mathf.random(2, 5);
Array<Point3> array = new Array<>();
//TODO replace random calls with seed
for(int i = 0; i < rooms; i++){
Tmp.v1.trns(Mathf.random(360f), Mathf.random(radius / constraint));
float rx = (width/2f + Tmp.v1.x);
float ry = (height/2f + Tmp.v1.y);
float maxrad = radius - Tmp.v1.len();
float rrad = Math.min(Mathf.random(9f, maxrad / 2f), 30f);
array.add(new Point3((int)rx, (int)ry, (int)rrad));
}
for(Point3 room : array){
erase(room.x, room.y, room.z);
}
int connections = Mathf.random(Math.max(rooms - 1, 1), rooms + 3);
for(int i = 0; i < connections; i++){
Point3 from = array.random();
Point3 to = array.random();
float nscl = Mathf.random(20f, 60f);
int stroke = Mathf.random(4, 12);
brush(pathfind(from.x, from.y, to.x, to.y, tile -> (tile.solid() ? 5f : 0f) + (float)sim.octaveNoise2D(1, 1, 1f / nscl, tile.x, tile.y) * 50, manhattan), stroke);
}
cells(1);
distort(20f, 6f);
Point3 spawn = array.random();
inverseFloodFill(tiles.getn(spawn.x, spawn.y));
ores(ores);
for(Point3 other : array){
if(other != spawn){
// tiles.getn(other.x, other.y).setOverlay(Blocks.spawn);
}
}
schematics.placeLoadout(Loadouts.advancedShard, spawn.x, spawn.y);
}
void cells(int iterations){
GridBits write = new GridBits(tiles.width, tiles.height);
GridBits read = new GridBits(tiles.width, tiles.height);
tiles.each((x, y) -> read.set(x, y, !tiles.get(x, y).block().isAir()));
int birthLimit = 16, deathLimit = 16, cradius = 3;
for(int i = 0; i < iterations; i++){
tiles.each((x, y) -> {
int alive = 0;
for(int cx = -cradius; cx <= cradius; cx++){
for(int cy = -cradius; cy <= cradius; cy++){
if((cx == 0 && cy == 0) || !Mathf.within(cx, cy, cradius)) continue;
if(!Structs.inBounds(x + cx, y + cy, tiles.width, tiles.height) || read.get(x + cx, y + cy)){
alive++;
}
}
}
if(read.get(x, y)){
write.set(x, y, alive >= deathLimit);
}else{
write.set(x, y, alive > birthLimit);
}
});
//flush results
read.set(write);
}
tiles.each((x, y) -> tiles.get(x, y).setBlock(!read.get(x, y) ? Blocks.air : tiles.get(x, y).floor().wall));
}
}
}

View File

@ -1,46 +0,0 @@
package mindustry.maps.zonegen;
import mindustry.maps.generators.*;
//TODO remove
public class DesertWastesGenerator extends BasicGenerator{
/*
public DesertWastesGenerator(int width, int height){
super(width, height, Blocks.oreCopper, Blocks.oreLead, Blocks.oreCoal, Blocks.oreCopper);
}
@Override
public void generate(int x, int y){
floor = Blocks.sand;
}
@Override
public void decorate(Tiles tiles){
ores(tiles);
terrain(tiles, Blocks.sandRocks, 60f, 1.5f, 0.9f);
int rand = 40;
int border = 25;
int spawnX = Mathf.clamp(30 + Mathf.range(rand), border, width - border), spawnY = Mathf.clamp(30 + Mathf.range(rand), border, height - border);
int endX = Mathf.clamp(width - 30 + Mathf.range(rand), border, width - border), endY = Mathf.clamp(height - 30 + Mathf.range(rand), border, height - border);
brush(tiles, pathfind(tiles, spawnX, spawnY, endX, endY, tile -> tile.solid() ? 5f : 0f, manhattan), 6);
brush(tiles, pathfind(tiles, spawnX, spawnY, endX, endY, tile -> tile.solid() ? 4f : 0f + (float)sim.octaveNoise2D(1, 1, 1f / 40f, tile.x, tile.y) * 20, manhattan), 5);
erase(tiles, endX, endY, 10);
erase(tiles, spawnX, spawnY, 20);
distort(tiles, 20f, 4f);
inverseFloodFill(tiles, tiles.getn(spawnX, spawnY));
noise(tiles, Blocks.salt, Blocks.saltRocks, 5, 0.6f, 200f, 0.55f);
noise(tiles, Blocks.darksand, Blocks.duneRocks, 5, 0.7f, 120f, 0.5f);
tech(tiles);
overlay(tiles, Blocks.sand, Blocks.pebbles, 0.15f, 5, 0.8f, 30f, 0.62f);
//scatter(tiles, Blocks.sandRocks, Blocks.creeptree, 1f);
tiles.getn(endX, endY).setOverlay(Blocks.spawn);
schematics.placeLoadout(loadout, spawnX, spawnY);
}*/
}

View File

@ -1,80 +0,0 @@
package mindustry.maps.zonegen;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.maps.generators.*;
import mindustry.world.*;
import static mindustry.Vars.schematics;
//TODO remove
public class OvergrowthGenerator extends BasicGenerator{
Array<Block> ores = Array.with(Blocks.oreCopper, Blocks.oreLead, Blocks.oreCoal, Blocks.oreCopper);
@Override
protected void generate(){
//terrain(tiles, Blocks.sporePine, 70f, 1.4f, 1f);
//int rand = 40;
//int border = 25;
//int spawnX = Mathf.clamp(30 + Mathf.range(rand), border, width - border), spawnY = Mathf.clamp(30 + Mathf.range(rand), border, height - border);
//int endX = Mathf.clamp(width - 30 + Mathf.range(rand), border, width - border), endY = Mathf.clamp(height - 30 + Mathf.range(rand), border, height - border);
float constraint = 1.3f;
float radius = width / 2f / Mathf.sqrt3;
int rooms = Mathf.random(2, 5);
Array<Point3> array = new Array<>();
//TODO replace random calls with seed
for(int i = 0; i < rooms; i++){
Tmp.v1.trns(Mathf.random(360f), Mathf.random(radius / constraint));
float rx = (width/2f + Tmp.v1.x);
float ry = (height/2f + Tmp.v1.y);
float maxrad = radius - Tmp.v1.len();
float rrad = Math.min(Mathf.random(9f, maxrad), 40f);
array.add(new Point3((int)rx, (int)ry, (int)rrad));
}
for(Point3 room : array){
erase(room.x, room.y, room.z);
}
int connections = Mathf.random(Math.max(rooms - 1, 1), rooms + 3);
for(int i = 0; i < connections; i++){
Point3 from = array.random();
Point3 to = array.random();
float nscl = Mathf.random(20f, 60f);
int stroke = Mathf.random(4, 12);
brush(pathfind(from.x, from.y, to.x, to.y, tile -> (tile.solid() ? 5f : 0f) + (float)sim.octaveNoise2D(1, 1, 1f / nscl, tile.x, tile.y) * 50, manhattan), stroke);
}
//
//brush(tiles, pathfind(tiles, spawnX, spawnY, endX, endY, tile -> (tile.solid() ? 4f : 0f) + (float)sim.octaveNoise2D(1, 1, 1f / 90f, tile.x+999, tile.y) * 70, manhattan), 5);
//
//erase(tiles, spawnX, spawnY, 20);
distort(20f, 6f);
Point3 spawn = array.random();
inverseFloodFill(tiles.getn(spawn.x, spawn.y));
ores(ores);
for(Point3 other : array){
if(other != spawn){
// tiles.getn(other.x, other.y).setOverlay(Blocks.spawn);
}
}
//noise(tiles, Blocks.darksandTaintedWater, Blocks.duneRocks, 4, 0.7f, 120f, 0.64f);
//scatter(tiles, Blocks.sporePine, Blocks.whiteTreeDead, 1f);
//tiles.getn(endX, endY).setOverlay(Blocks.spawn);
schematics.placeLoadout(Loadouts.advancedShard, spawn.x, spawn.y);
}
}