Async mesh reloading for planets

This commit is contained in:
Anuken
2025-05-29 20:46:17 -04:00
parent 1e621259d5
commit 82a801b1c0
14 changed files with 218 additions and 196 deletions

View File

@@ -32,7 +32,7 @@ public class LoadRenderer implements Disposable{
private float testprogress = 0f;
private StringBuilder assetText = new StringBuilder();
private Bar[] bars;
private Mesh mesh = MeshBuilder.buildLineHex(colorRed, 2);
private Mesh mesh = MeshBuilder.buildPlanetGrid(PlanetGrid.create(2), colorRed, 1f);
private Camera3D cam = new Camera3D();
private int lastLength = -1;
private FxProcessor fx;

View File

@@ -21,7 +21,7 @@ public class HexMesh extends PlanetMesh{
@Override
public void preRender(PlanetParams params){
Shaders.planet.planet = planet;
Shaders.planet.emissive = planet.generator != null && planet.generator.hasEmissive();
Shaders.planet.emissive = planet.generator != null;
Shaders.planet.lightDir.set(planet.solarSystem.position).sub(planet.position).rotate(Vec3.Y, planet.getRotation()).nor();
Shaders.planet.ambientColor.set(planet.solarSystem.lightColor);
}

View File

@@ -6,15 +6,16 @@ import arc.math.geom.*;
/** Defines color and height for a planet mesh. */
public interface HexMesher{
float getHeight(Vec3 position);
Color getColor(Vec3 position);
default Color getEmissiveColor(Vec3 position){
return Color.clear;
default float getHeight(Vec3 position){
return 0f;
}
default boolean hasEmissive(){
return false;
default void getColor(Vec3 position, Color out){
}
default void getEmissiveColor(Vec3 position, Color out){
}
default boolean skip(Vec3 position){

View File

@@ -21,8 +21,8 @@ public class HexSkyMesh extends PlanetMesh{
}
@Override
public Color getColor(Vec3 position){
return color;
public void getColor(Vec3 position, Color out){
out.set(color);
}
@Override

View File

@@ -8,65 +8,39 @@ import mindustry.graphics.g3d.PlanetGrid.*;
import mindustry.maps.generators.*;
public class MeshBuilder{
private static final Vec3 v1 = new Vec3(), v2 = new Vec3(), v3 = new Vec3(), v4 = new Vec3();
private static final boolean gl30 = Core.gl30 != null;
private static final float[] floats = new float[3 + (gl30 ? 1 : 3) + 1], emissiveFloats = new float[floats.length + 1];
private static final short[] shorts = new short[3];
private static float[] tmpHeights = new float[14580]; //highest amount of corners in vanilla
private static Mesh mesh;
public static Mesh buildIcosphere(int divisions, float radius, Color color){
begin(20 * (2 << (2 * divisions - 1)) * 3, 0, false);
float col = color.toFloatBits();
private static volatile float[] tmpHeights = new float[14580]; //highest amount of corners in vanilla
/** Note that the resulting icosphere does not have normals or a color. */
public static Mesh buildIcosphere(int divisions, float radius){
MeshResult result = Icosphere.create(divisions);
for(int i = 0; i < result.indices.size; i+= 3){
v1.set(result.vertices.items, result.indices.items[i] * 3).setLength(radius);
v2.set(result.vertices.items, result.indices.items[i + 1] * 3).setLength(radius);
v3.set(result.vertices.items, result.indices.items[i + 2] * 3).setLength(radius);
verts(v1, v3, v2, normal(v1, v2, v3).scl(-1f), col, 0f);
Mesh mesh = begin(result.vertices.size / 3, result.indices.size, false, false);
if(result.vertices.size >= 65535) throw new RuntimeException("Due to index size limits, only meshes with a maximum of 65535 vertices are supported. If you want more than that, make your own non-indexed mesh builder.");
float[] items = result.vertices.items;
for(int i = 0; i < result.vertices.size; i ++){
items[i] *= radius;
}
return end();
}
mesh.getVerticesBuffer().put(items, 0, result.vertices.size);
public static Mesh buildIcosphere(int divisions, float radius){
return buildIcosphere(divisions, radius, Color.white);
short[] indices = new short[result.indices.size];
for(int i = 0; i < result.indices.size; i++){
indices[i] = (short)result.indices.items[i];
}
mesh.getIndicesBuffer().put(indices);
return end(mesh);
}
public static Mesh buildPlanetGrid(PlanetGrid grid, Color color, float scale){
int total = 0;
for(Ptile tile : grid.tiles){
total += tile.corners.length * 2;
}
float col = color.toFloatBits();
begin(total, 0, false);
for(Ptile tile : grid.tiles){
Corner[] c = tile.corners;
for(int i = 0; i < c.length; i++){
Vec3 a = v1.set(c[i].v).scl(scale);
Vec3 b = v2.set(c[(i + 1) % c.length].v).scl(scale);
vert(a, Vec3.Z, col, 0f);
vert(b, Vec3.Z, col, 0f);
}
}
return end();
}
public static Mesh buildLineHex(Color color, int divisions){
PlanetGrid grid = PlanetGrid.create(divisions);
begin(grid.tiles.length * 12, 0, false);
Vec3 nor = v4.set(1f, 1f, 1f);
Mesh mesh = begin(grid.tiles.length * 12, 0, false, false);
float col = color.toFloatBits();
float[] floats = new float[8];
for(Ptile tile : grid.tiles){
Corner[] c = tile.corners;
@@ -75,12 +49,21 @@ public class MeshBuilder{
Vec3 v1 = c[i].v;
Vec3 v2 = c[(i + 1) % c.length].v;
vert(v1, nor, col, 0f);
vert(v2, nor, col, 0f);
floats[0] = v1.x * scale;
floats[1] = v1.y * scale;
floats[2] = v1.z * scale;
floats[3] = col;
floats[4] = v2.x * scale;
floats[5] = v2.y * scale;
floats[6] = v2.z * scale;
floats[7] = col;
mesh.getVerticesBuffer().put(floats);
}
}
return end();
return end(mesh);
}
public static Mesh buildHex(Color color, int divisions, float radius){
@@ -91,29 +74,24 @@ public class MeshBuilder{
}
@Override
public Color getColor(Vec3 position){
return color;
public void getColor(Vec3 position, Color out){
out.set(color);
}
}, divisions, radius, 0);
}
//TODO: make this thread safe
public static Mesh buildHex(HexMesher mesher, int divisions, float radius, float intensity){
//TODO: in principle this should not be synchronized, but I would rather not realloc tmpHeights every time, and it is unlikely that two planets will be reloading at the same time
public static synchronized Mesh buildHex(HexMesher mesher, int divisions, float radius, float intensity){
PlanetGrid grid = PlanetGrid.create(divisions);
//TODO: this is NOT thread safe, but in practice, it should never cause a problem
if(mesher instanceof PlanetGenerator generator){
generator.seed = generator.baseSeed;
}
boolean emit = mesher.hasEmissive();
if(grid.tiles.length * 6 >= 65535) throw new RuntimeException("Due to index size limits, only meshes with a maximum of 65535 vertices are supported. If you want more than that, make your own non-indexed mesh builder.");
boolean indexed = grid.tiles.length * 6 < 65535;
if(indexed){
begin(grid.tiles.length * 6, grid.tiles.length * 4 * 3, emit);
}else{
begin(grid.tiles.length * 12, 0, emit);
}
Mesh mesh = begin(grid.tiles.length * 6, grid.tiles.length * 4 * 3, true, true);
float[] heights;
@@ -130,6 +108,12 @@ public class MeshBuilder{
int position = 0;
short[] shorts = new short[12];
float[] floats = new float[3 + (gl30 ? 1 : 3) + 1 + 1];
Vec3 nor = new Vec3();
Color tmpCol = new Color();
for(Ptile tile : grid.tiles){
if(mesher.skip(tile.v)){
continue;
@@ -137,60 +121,77 @@ public class MeshBuilder{
Corner[] c = tile.corners;
for(Corner corner : c){
corner.v.scl((1f + heights[corner.id] * intensity) * radius);
float
h1 = (1f + heights[c[0].id] * intensity) * radius,
h2 = (1f + heights[c[2].id] * intensity) * radius,
h3 = (1f + heights[c[4].id] * intensity) * radius;
Vec3
v1 = c[0].v,
v2 = c[2].v,
v3 = c[4].v;
normal(
v1.x * h1, v1.y * h1, v1.z * h1,
v2.x * h2, v2.y * h2, v2.z * h2,
v3.x * h3, v3.y * h3, v3.z * h3,
nor);
tmpCol.set(1f, 1f, 1f, 1f);
mesher.getColor(tile.v, tmpCol);
float color = tmpCol.toFloatBits();
tmpCol.set(0f, 0f, 0f, 0f);
mesher.getEmissiveColor(tile.v, tmpCol);
float emissive = tmpCol.toFloatBits();
for(var corner : c){
float height = (1f + heights[corner.id] * intensity) * radius;
vert(mesh, floats, corner.v.x * height, corner.v.y * height, corner.v.z * height, nor, color, emissive);
}
Vec3 nor = normal(c[0].v, c[2].v, c[4].v);
float color = mesher.getColor(tile.v).toFloatBits();
float emissive = emit ? mesher.getEmissiveColor(tile.v).toFloatBits() : 0f;
shorts[0] = (short)(position);
shorts[1] = (short)(position + 1);
shorts[2] = (short)(position + 2);
if(indexed){
for(var corner : c){
vert(corner.v, nor, color, emissive);
}
shorts[3] = (short)(position);
shorts[4] = (short)(position + 2);
shorts[5] = (short)(position + 3);
indices(position, position + 1, position + 2);
indices(position, position + 2, position + 3);
indices(position, position + 3, position + 4);
if(c.length > 5){
indices(position, position + 4, position + 5);
}
shorts[6] = (short)(position);
shorts[7] = (short)(position + 3);
shorts[8] = (short)(position + 4);
position += c.length;
}else{
verts(c[0].v, c[1].v, c[2].v, nor, color, emissive);
verts(c[0].v, c[2].v, c[3].v, nor, color, emissive);
verts(c[0].v, c[3].v, c[4].v, nor, color, emissive);
if(c.length > 5){
verts(c[0].v, c[4].v, c[5].v, nor, color, emissive);
}
if(c.length > 5){
shorts[9] = (short)(position);
shorts[10] = (short)(position + 4);
shorts[11] = (short)(position + 5);
}
//restore mutated corners
for(Corner corner : c){
corner.v.nor();
}
mesh.getIndicesBuffer().put(shorts, 0, c.length > 5 ? 12 : 9);
position += c.length;
}
return end();
return end(mesh);
}
private static void begin(int vertices, int indices, boolean emissive){
private static Mesh begin(int vertices, int indices, boolean normal, boolean emissive){
Seq<VertexAttribute> attributes = Seq.with(
VertexAttribute.position3,
//only GL30 supports GL_INT_2_10_10_10_REV
gl30 ? VertexAttribute.packedNormal : VertexAttribute.normal,
VertexAttribute.color
VertexAttribute.position3
);
if(normal){
//only GL30 supports GL_INT_2_10_10_10_REV
attributes.add(gl30 ? VertexAttribute.packedNormal : VertexAttribute.normal);
}
attributes.add(VertexAttribute.color);
if(emissive){
attributes.add(new VertexAttribute(4, GL20.GL_UNSIGNED_BYTE, true, "a_emissive"));
}
mesh = new Mesh(true, vertices, indices, attributes.toArray(VertexAttribute.class));
Mesh mesh = new Mesh(true, vertices, indices, attributes.toArray(VertexAttribute.class));
mesh.getVerticesBuffer().limit(mesh.getVerticesBuffer().capacity());
mesh.getVerticesBuffer().position(0);
@@ -199,56 +200,70 @@ public class MeshBuilder{
mesh.getIndicesBuffer().limit(mesh.getIndicesBuffer().capacity());
mesh.getIndicesBuffer().position(0);
}
return mesh;
}
private static Mesh end(){
Mesh last = mesh;
last.getVerticesBuffer().limit(last.getVerticesBuffer().position());
if(last.getNumIndices() > 0){
last.getIndicesBuffer().limit(last.getIndicesBuffer().position());
private static Mesh end(Mesh mesh){
mesh.getVerticesBuffer().limit(mesh.getVerticesBuffer().position());
if(mesh.getNumIndices() > 0){
mesh.getIndicesBuffer().limit(mesh.getIndicesBuffer().position());
}
mesh = null;
return last;
return mesh;
}
private static Vec3 normal(Vec3 v1, Vec3 v2, Vec3 v3){
return v4.set(v2).sub(v1).crs(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z).nor();
private static void normal(Vec3 v1, Vec3 v2, Vec3 v3, Vec3 out){
float
x = v2.x - v1.x,
y = v2.y - v1.y,
z = v2.z - v1.z,
vx = v3.x - v1.x,
vy = v3.y - v1.y,
vz = v3.z - v1.z;
float
cx = y * vz - z * vy,
cy = z * vx - x * vz,
cz = x * vy - y * vx;
out.set(cx, cy, cz).nor();
}
private static void indices(int a, int b, int c){
shorts[0] = (short)a;
shorts[1] = (short)b;
shorts[2] = (short)c;
mesh.getIndicesBuffer().put(shorts);
private static void normal(float v1x, float v1y, float v1z, float v2x, float v2y, float v2z, float v3x, float v3y, float v3z, Vec3 out){
float
x = v2x - v1x,
y = v2y - v1y,
z = v2z - v1z,
vx = v3x - v1x,
vy = v3y - v1y,
vz = v3z - v1z;
float
cx = y * vz - z * vy,
cy = z * vx - x * vz,
cz = x * vy - y * vx;
out.set(cx, cy, cz).nor();
}
private static void verts(Vec3 a, Vec3 b, Vec3 c, Vec3 normal, float color, float emissive){
vert(a, normal, color, emissive);
vert(b, normal, color, emissive);
vert(c, normal, color, emissive);
}
private static void vert(Vec3 a, Vec3 normal, float color, float emissive){
boolean emit = mesh.getVertexSize() == emissiveFloats.length*4;
float[] floats = emit ? emissiveFloats : MeshBuilder.floats;
floats[0] = a.x;
floats[1] = a.y;
floats[2] = a.z;
private static void vert(Mesh mesh, float[] floats, float x, float y, float z, Vec3 normal, float color, float emissive){
floats[0] = x;
floats[1] = y;
floats[2] = z;
if(gl30){
floats[3] = packNormals(normal.x, normal.y, normal.z);
floats[4] = color;
if(emit) floats[5] = emissive;
floats[5] = emissive;
}else{
floats[3] = normal.x;
floats[4] = normal.x;
floats[5] = normal.x;
floats[6] = color;
if(emit) floats[7] = emissive;
floats[7] = emissive;
}
mesh.getVerticesBuffer().put(floats);

View File

@@ -18,8 +18,8 @@ public class NoiseMesh extends HexMesh{
}
@Override
public Color getColor(Vec3 position){
return color;
public void getColor(Vec3 position, Color out){
out.set(color);
}
}, divisions, radius, 0.2f);
}
@@ -35,8 +35,8 @@ public class NoiseMesh extends HexMesh{
}
@Override
public Color getColor(Vec3 position){
return Simplex.noise3d(8 + seed, coct, cper, cscl, 5f + position.x, 5f + position.y, 5f + position.z) > cthresh ? color2 : color1;
public void getColor(Vec3 position, Color out){
out.set(Simplex.noise3d(8 + seed, coct, cper, cscl, 5f + position.x, 5f + position.y, 5f + position.z) > cthresh ? color2 : color1);
}
}, divisions, radius, 0.2f);
}

View File

@@ -47,7 +47,7 @@ public class PlanetGrid{
}
}
public static PlanetGrid create(int size){
public static synchronized PlanetGrid create(int size){
//cache grids between calls, since only ~5 different grids total are needed
if(size < cache.length && cache[size] != null){
return cache[size];

View File

@@ -3,7 +3,6 @@ package mindustry.graphics.g3d;
import arc.graphics.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import arc.util.noise.*;
import mindustry.graphics.*;
import mindustry.type.*;
@@ -19,9 +18,9 @@ public class SunMesh extends HexMesh{
}
@Override
public Color getColor(Vec3 position){
public void getColor(Vec3 position, Color out){
double height = Math.pow(Simplex.noise3d(0, octaves, persistence, scl, position.x, position.y, position.z), pow) * mag;
return Tmp.c1.set(colors[Mathf.clamp((int)(height * colors.length), 0, colors.length - 1)]).mul(colorScale);
out.set(colors[Mathf.clamp((int)(height * colors.length), 0, colors.length - 1)]).mul(colorScale);
}
}, divisions, Shaders.unlit);
}

View File

@@ -1,7 +1,5 @@
package mindustry.maps.generators;
import arc.graphics.*;
import arc.math.geom.*;
import mindustry.game.*;
import mindustry.type.*;
import mindustry.world.*;
@@ -9,16 +7,6 @@ import mindustry.world.*;
/** A planet generator that provides no weather, height, color or bases. Override generate().*/
public class BlankPlanetGenerator extends PlanetGenerator{
@Override
public float getHeight(Vec3 position){
return 0;
}
@Override
public Color getColor(Vec3 position){
return Color.white;
}
@Override
public void addWeather(Sector sector, Rules rules){

View File

@@ -39,15 +39,13 @@ public class ErekirPlanetGenerator extends PlanetGenerator{
}
@Override
public Color getColor(Vec3 position){
public void getColor(Vec3 position, Color out){
Block block = getBlock(position);
//more obvious color
if(block == Blocks.crystallineStone) block = Blocks.crystalFloor;
//TODO this might be too green
//if(block == Blocks.beryllicStone) block = Blocks.arkyicStone;
return Tmp.c1.set(block.mapColor).a(1f - block.albedo);
out.set(block.mapColor).a(1f - block.albedo);
}
@Override

View File

@@ -66,12 +66,12 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
@Override
public void onSectorCaptured(Sector sector){
sector.planet.requiresMeshReload = true;
sector.planet.reloadMeshAsync();
}
@Override
public void onSectorLost(Sector sector){
sector.planet.requiresMeshReload = true;
sector.planet.reloadMeshAsync();
}
@Override
@@ -96,26 +96,27 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
}
@Override
public Color getColor(Vec3 position){
public void getColor(Vec3 position, Color out){
//if(dst*metalDstScl + Simplex.noise3d(seed, 3, 0.4, 4f, position.x, position.y + 200f, position.z)*0.14f < 0.09f){
// return Tmp.c1.set(Team.crux.color).lerp(Team.sharded.color, 0.4f*Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 999f, position.z)).a(packAlpha(0f, 1f));
//}
Block block = getBlock(position);
//replace salt with sand color
if(block == Blocks.salt) return Blocks.sand.mapColor;
return Tmp.c1.set(block.mapColor).a(1f - block.albedo);
if(block == Blocks.salt) block = Blocks.sand;
out.set(block.mapColor).a(1f - block.albedo);
}
@Override
public boolean hasEmissive(){
return true;
}
@Override
public Color getEmissiveColor(Vec3 position){
public void getEmissiveColor(Vec3 position, Color out){
float dst = 999f, captureDst = 999f, lightScl = 0f;
for(Sector sector : Planets.serpulo.sectors){
Object[] sectors = Planets.serpulo.sectors.items;
int size = Planets.serpulo.sectors.size;
for(int i = 0; i < size; i ++){
var sector = (Sector)sectors[i];
if(sector.hasEnemyBase() && !sector.isCaptured()){
dst = Math.min(dst, position.dst(sector.tile.v) - (sector.preset != null ? sector.preset.difficulty/10f * 0.03f - 0.03f : 0f));
}else if(sector.hasBase()){
@@ -133,22 +134,23 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
float freq = 0.05f;
if(position.dst(basePos) < 0.55f ?
dst*metalDstScl + Simplex.noise3d(seed, 3, 0.4, 5.5f, position.x, position.y + 200f, position.z)*0.08f + ((basePos.dst(position) + 0.00f) % freq < freq/2f ? 1f : 0f) * 0.07f < 0.08f :
dst*metalDstScl + Simplex.noise3d(seed, 3, 0.4, 5.5f, position.x, position.y + 200f, position.z)*0.08f + ((basePos.dst(position) + 0.00f) % freq < freq/2f ? 1f : 0f) * 0.07f < 0.08f/* || dst <= 0.0001f*/ :
dst*metalDstScl + Simplex.noise3d(seed, 3, 0.4, 9f, position.x, position.y + 370f, position.z)*0.06f < 0.045){
return Tmp.c1.set(Team.crux.color).mul(0.8f + Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 99f, position.z) * 0.4f)
.lerp(Team.sharded.color, 0.2f*Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 999f, position.z));
out.set(Team.crux.color)
.mul(0.8f + Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 99f, position.z) * 0.4f)
.lerp(Team.sharded.color, 0.2f*Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 999f, position.z)).toFloatBits();
}else if(captureDst*metalDstScl + Simplex.noise3d(seed, 3, 0.4, 9f, position.x, position.y + 600f, position.z)*0.07f < 0.05 * lightScl){
return Tmp.c1.set(Team.sharded.color).mul(0.7f + Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 99f, position.z) * 0.4f)
.lerp(Team.crux.color, 0.3f*Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 999f, position.z));
}
out.set(Team.sharded.color).mul(0.7f + Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 99f, position.z) * 0.4f)
.lerp(Team.crux.color, 0.3f*Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 999f, position.z)).toFloatBits();
return Color.clear;
}
}
@Override
public void genTile(Vec3 position, TileGen tile){
tile.floor = getBlock(position);
if(tile.floor == Blocks.darkPanel6) tile.floor = Blocks.darkPanel3;
tile.block = tile.floor.asFloor().wall;
if(Ridged.noise3d(seed + 1, position.x, position.y, position.z, 2, 22) > 0.31){
@@ -156,7 +158,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
}
}
public static double metalMag = 0.11, metalScl = 1, metalDstScl = 0.25, metalThresh = 0.1;
static double metalDstScl = 0.25;
Block getBlock(Vec3 position){
float height = rawHeight(position);
@@ -169,7 +171,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
height *= 1.2f;
height = Mathf.clamp(height);
float tar = Simplex.noise3d(seed, 4, 0.55f, 1f/2f, px, py + 999f, pz) * 0.3f + Tmp.v31.dst(0, 0, 1f) * 0.2f;
float tar = Simplex.noise3d(seed, 4, 0.55f, 1f/2f, px, py + 999f, pz) * 0.3f + position.dst(0, 0, 1f) * 0.2f;
Block res = arr[Mathf.clamp((int)(temp * arr.length), 0, arr[0].length - 1)][Mathf.clamp((int)(height * arr[0].length), 0, arr[0].length - 1)];
if(tar > 0.5f){
@@ -178,16 +180,22 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
if(position.within(basePos, 0.65f)){
float dst = 999f;
for(Sector sector : Planets.serpulo.sectors){
Object[] sectors = Planets.serpulo.sectors.items;
int size = Planets.serpulo.sectors.size;
for(int i = 0; i < size; i ++){
var sector = (Sector)sectors[i];
if(sector.hasEnemyBase()){
dst = Math.min(dst, position.dst(sector.tile.v));
}
}
float freq = 0.05f;
float freq = 0.05f, freq2 = 0.07f;
if(dst*0.85f + Simplex.noise3d(seed, 3, 0.4, 5.5f, position.x, position.y + 200f, position.z)*0.015f + ((basePos.dst(position) + 0.00f) % freq < freq/2f ? 1f : 0f) * 0.07f < 0.15f){
return Blocks.metalFloor;
return ((basePos.dst(position) + 0.01f) % freq2 < freq2*0.65f) ? Blocks.metalFloor : Blocks.darkPanel6;
}
}
return res;

View File

@@ -14,7 +14,7 @@ import mindustry.world.*;
import static mindustry.Vars.*;
public class TantrosPlanetGenerator extends PlanetGenerator{
Color c1 = Color.valueOf("5057a6"), c2 = Color.valueOf("272766"), out = new Color();
Color c1 = Color.valueOf("5057a6"), c2 = Color.valueOf("272766");
Block[][] arr = {
{Blocks.redmat, Blocks.redmat, Blocks.darksand, Blocks.bluemat, Blocks.bluemat}
@@ -30,9 +30,9 @@ public class TantrosPlanetGenerator extends PlanetGenerator{
}
@Override
public Color getColor(Vec3 position){
public void getColor(Vec3 position, Color out){
float depth = Simplex.noise3d(seed, 2, 0.56, 1.7f, position.x, position.y, position.z) / 2f;
return c1.write(out).lerp(c2, Mathf.clamp(Mathf.round(depth, 0.15f))).a(1f - 0.2f);
out.set(c1).lerp(c2, Mathf.clamp(Mathf.round(depth, 0.15f))).a(1f - 0.2f).toFloatBits();
}
@Override

View File

@@ -43,8 +43,6 @@ public class Planet extends UnlockableContent{
public @Nullable GenericMesh cloudMesh;
/** Mesh used for rendering planet grid outlines. Null on server or if {@link #grid} is null. */
public @Nullable Mesh gridMesh;
/** If true, this planet's mesh should be reloaded when it is next shown. */
public boolean requiresMeshReload;
/** Position in global coordinates. Will be 0,0,0 until the Universe updates it. */
public Vec3 position = new Vec3();
/** Grid used for the sectors on the planet. Null if this planet can't be landed on. */
@@ -360,6 +358,21 @@ public class Planet extends UnlockableContent{
mesh = meshLoader.get();
}
public void reloadMeshAsync(){
if(headless) return;
mainExecutor.submit(() -> {
var newMesh = meshLoader.get();
Core.app.post(() -> {
if(mesh != null){
mesh.dispose();
}
mesh = newMesh;
});
});
}
@Override
public void load(){
super.load();

View File

@@ -33,6 +33,7 @@ import mindustry.graphics.g3d.*;
import mindustry.input.*;
import mindustry.io.*;
import mindustry.maps.*;
import mindustry.maps.planet.*;
import mindustry.type.*;
import mindustry.type.Planet.*;
import mindustry.ui.*;
@@ -285,11 +286,6 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
lookAt(state.planet.getLastSector());
}
if(state.planet.requiresMeshReload){
state.planet.requiresMeshReload = false;
state.planet.reloadMesh();
}
return super.show();
}
@@ -662,6 +658,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
if(timeShift != 0){
universe.setSeconds(universe.secondsf() + timeShift * Time.delta * 2.5f);
}
if(input.keyTap(KeyCode.r)){
state.planet.reloadMeshAsync();
}
}
if(debugSectorAttackEdit && input.ctrl() && input.keyTap(KeyCode.s)){