This commit is contained in:
Anuken
2020-01-20 16:14:29 -05:00
parent be0b13e27d
commit df1a102021
12 changed files with 208 additions and 150 deletions

View File

@@ -4,7 +4,10 @@ import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
//TODO clean this up somehow
public class PlanetGrid{
private static final PlanetGrid[] cache = new PlanetGrid[10];
private static final float x = -0.525731112119133606f;
private static final float z = -0.850650808352039932f;
@@ -20,12 +23,10 @@ public class PlanetGrid{
{5, 3, 10, 1, 4}, {2, 5, 4, 0, 11}, {3, 7, 6, 1, 8}, {7, 2, 9, 0, 6}
};
private static PlanetGrid[] cache = new PlanetGrid[10];
int size;
Ptile[] tiles;
Corner[] corners;
Edge[] edges;
public final int size;
public final Ptile[] tiles;
public final Corner[] corners;
public final Edge[] edges;
PlanetGrid(int size){
this.size = size;
@@ -46,7 +47,7 @@ public class PlanetGrid{
}
}
static PlanetGrid newGrid(int size){
public static PlanetGrid newGrid(int size){
//cache grids between calls, since only ~5 different grids total are needed
if(size < cache.length && cache[size] != null){
return cache[size];
@@ -104,8 +105,7 @@ public class PlanetGrid{
for(Ptile t : grid.tiles){
for(int k = 0; k < 5; k++){
if(t.edges[k] == null){
addEdge(nextEdge, grid, t.id, iTilesP[t.id][k]);
nextEdge++;
addEdge(nextEdge++, grid, t.id, iTilesP[t.id][k]);
}
}
}
@@ -220,13 +220,15 @@ public class PlanetGrid{
return 30 * Mathf.pow(3, size);
}
static class Ptile{
int id;
int edgeCount;
Vec3 v = new Vec3();
Ptile[] tiles;
Corner[] corners;
Edge[] edges;
public static class Ptile{
public final int id;
public final int edgeCount;
public final Ptile[] tiles;
public final Corner[] corners;
public final Edge[] edges;
public Vec3 v = new Vec3();
public Ptile(int id, int edgeCount){
this.id = id;
@@ -238,23 +240,24 @@ public class PlanetGrid{
}
}
static class Corner{
int id;
Ptile[] tiles = new Ptile[3];
Corner[] corners = new Corner[3];
Edge[] edges = new Edge[3];
Vec3 v = new Vec3();
Vec3 bv = new Vec3();
public static class Corner{
public final int id;
public final Ptile[] tiles = new Ptile[3];
public final Corner[] corners = new Corner[3];
public final Edge[] edges = new Edge[3];
public Vec3 v = new Vec3();
public Vec3 bv = new Vec3();
public Corner(int id){
this.id = id;
}
}
static class Edge{
int id;
Ptile[] tiles = new Ptile[2];
Corner[] corners = new Corner[2];
public static class Edge{
public final int id;
public final Ptile[] tiles = new Ptile[2];
public final Corner[] corners = new Corner[2];
public Edge(int id){
this.id = id;

View File

@@ -3,7 +3,6 @@ package mindustry.graphics;
import arc.graphics.*;
import arc.graphics.VertexAttributes.*;
import arc.graphics.gl.*;
import arc.graphics.g3d.*;
import arc.math.geom.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
@@ -12,11 +11,10 @@ import mindustry.maps.planet.*;
public class PlanetMesh{
private float[] floats = new float[3 + 3 + 1];
private Vec3 center = new Vec3(0, 0, 0);
private Vec3 vec = new Vec3();
private Plane plane = new Plane();
private Mesh mesh;
private PlanetGrid grid;
private Vec3 center = new Vec3();
private boolean lines;
private float radius, intensity = 0.2f;
@@ -46,6 +44,13 @@ public class PlanetMesh{
generateMesh();
}
/** @return the sector that is hit by this ray, or null if nothing intersects it. */
public @Nullable Ptile getTile(Ray ray){
boolean found = Intersector3D.intersectRaySphere(ray, center, radius, Tmp.v33);
if(!found) return null;
return Structs.findMin(grid.tiles, t -> t.v.dst(Tmp.v33));
}
public void render(Mat3D mat){
Shaders.planet.begin();
Shaders.planet.setUniformMatrix4("u_projModelView", mat.val);
@@ -53,46 +58,6 @@ public class PlanetMesh{
Shaders.planet.end();
}
/** Projects a tile onto a 4-corner square for use in map gen.
* Allocates a new object. Do not call in the main loop. */
public SectorRect projectTile(Ptile base){
Vec3[] corners = new Vec3[base.corners.length];
for(int i = 0; i < corners.length; i++){
corners[i] = base.corners[i].v.cpy().setLength(radius);
}
Tmp.v33.setZero();
for(Vec3 c : corners){
Tmp.v33.add(c);
}
//v33 is now the center of this shape
Vec3 center = Tmp.v33.scl(1f / corners.length).cpy(vec);
//radius of circle
float radius = Tmp.v33.dst(corners[0]) * 0.9f;
//get plane that these points are on
plane.set(corners[0], corners[2], corners[4]);
Vec3 planeTop = plane.project(center.cpy().add(0f, 1f, 0f)).sub(center).setLength(radius).add(center);
Vec3 planeRight = plane.project(center.cpy().rotate(Vec3.Y, -4f)).sub(center).setLength(radius).add(center);
return new SectorRect(center, planeTop.sub(center), planeRight.sub(center));
}
public @Nullable Ptile getTile(Ray ray){
Vec3 vec = intersect(ray);
if(vec == null) return null;
//TODO fix O(N) search
return Structs.findMin(grid.tiles, t -> t.v.dst(vec));
}
public @Nullable Vec3 intersect(Ray ray){
if(Intersector3D.intersectRaySphere(ray, center, radius, Tmp.v33)){
return Tmp.v33;
}
return null;
}
private void generateMesh(){
for(Ptile tile : grid.tiles){
@@ -172,22 +137,4 @@ public class PlanetMesh{
floats[6] = color.toFloatBits();
mesh.getVerticesBuffer().put(floats);
}
public static class SectorRect{
public final Vec3 center, top, right;
public final Vec3 result = new Vec3();
public SectorRect(Vec3 center, Vec3 top, Vec3 right){
this.center = center;
this.top = top;
this.right = right;
}
/** Project a coordinate into 3D space.
* Both coordinates should be normalized to floats of the value 0..1 */
public Vec3 project(float x, float y){
float nx = (x - 0.5f) * 2f, ny = (y - 0.5f) * 2f;
return result.set(center).add(right, nx).add(top, ny);
}
}
}

View File

@@ -7,15 +7,10 @@ import arc.graphics.g3d.*;
import arc.input.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.game.*;
import mindustry.graphics.PlanetGrid.*;
import mindustry.graphics.PlanetMesh.*;
import mindustry.maps.generators.*;
import mindustry.maps.planet.*;
import mindustry.type.*;
import mindustry.type.Sector.*;
import mindustry.world.*;
import static mindustry.Vars.*;
@@ -55,14 +50,17 @@ public class PlanetRenderer implements PlanetGenerator{
Ptile tile = outline.getTile(cam.getPickRay(Core.input.mouseX(), Core.input.mouseY()));
if(tile != null){
for(int i = 0; i < tile.corners.length; i++){
Sector sector = planet.getSector(tile);
for(int i = 0; i < sector.tile.corners.length; i++){
batch.color(outlineColor);
batch.vertex(tile.corners[i].v);
batch.vertex(sector.tile.corners[i].v);
}
batch.flush(cam.combined(), Gl.triangleFan);
if(drawnRect){
SectorRect rect = planet.mesh.projectTile(tile);
//TODO hack.
SectorRect rect = sector.rect;
rect.center.scl(outlineRad);
rect.right.scl(outlineRad);
rect.top.scl(outlineRad);
@@ -77,27 +75,12 @@ public class PlanetRenderer implements PlanetGenerator{
batch.vertex(rect.project(0, 1));
batch.flush(cam.combined(), Gl.lineLoop);
SectorRect coords = planet.mesh.projectTile(tile);
rect.center.scl(1f / outlineRad);
rect.right.scl(1f / outlineRad);
rect.top.scl(1f / outlineRad);
if(Core.input.keyTap(KeyCode.SPACE)){
logic.reset();
Vars.world.loadGenerator(new Generator(250, 250){
@Override
public void generate(Tiles tiles){
TileGen gen = new TileGen();
tiles.each((x, y) -> {
gen.reset();
Vec3 position = coords.project(x / (float)width, y / (float)height);
planet.generator.generate(position, gen);
tiles.set(x, y, new Tile(x, y, gen.floor, gen.overlay, gen.block));
});
tiles.get(width/2, height/2).setBlock(Blocks.coreShard, Team.sharded);
}
});
state.set(State.playing);
logic.play();
control.playSector(sector);
ui.planet.hide();
}
}