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
@@ -32,7 +32,7 @@ public class LoadRenderer implements Disposable{
private float testprogress = 0f; private float testprogress = 0f;
private StringBuilder assetText = new StringBuilder(); private StringBuilder assetText = new StringBuilder();
private Bar[] bars; 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 Camera3D cam = new Camera3D();
private int lastLength = -1; private int lastLength = -1;
private FxProcessor fx; private FxProcessor fx;
+1 -1
View File
@@ -21,7 +21,7 @@ public class HexMesh extends PlanetMesh{
@Override @Override
public void preRender(PlanetParams params){ public void preRender(PlanetParams params){
Shaders.planet.planet = planet; 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.lightDir.set(planet.solarSystem.position).sub(planet.position).rotate(Vec3.Y, planet.getRotation()).nor();
Shaders.planet.ambientColor.set(planet.solarSystem.lightColor); Shaders.planet.ambientColor.set(planet.solarSystem.lightColor);
} }
@@ -6,15 +6,16 @@ import arc.math.geom.*;
/** Defines color and height for a planet mesh. */ /** Defines color and height for a planet mesh. */
public interface HexMesher{ public interface HexMesher{
float getHeight(Vec3 position); default float getHeight(Vec3 position){
Color getColor(Vec3 position); return 0f;
default Color getEmissiveColor(Vec3 position){
return Color.clear;
} }
default boolean hasEmissive(){ default void getColor(Vec3 position, Color out){
return false;
}
default void getEmissiveColor(Vec3 position, Color out){
} }
default boolean skip(Vec3 position){ default boolean skip(Vec3 position){
@@ -21,8 +21,8 @@ public class HexSkyMesh extends PlanetMesh{
} }
@Override @Override
public Color getColor(Vec3 position){ public void getColor(Vec3 position, Color out){
return color; out.set(color);
} }
@Override @Override
+142 -127
View File
@@ -8,65 +8,39 @@ import mindustry.graphics.g3d.PlanetGrid.*;
import mindustry.maps.generators.*; import mindustry.maps.generators.*;
public class MeshBuilder{ 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 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 volatile float[] tmpHeights = new float[14580]; //highest amount of corners in vanilla
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();
/** 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); 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){ short[] indices = new short[result.indices.size];
return buildIcosphere(divisions, radius, Color.white); 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){ public static Mesh buildPlanetGrid(PlanetGrid grid, Color color, float scale){
int total = 0; Mesh mesh = begin(grid.tiles.length * 12, 0, false, false);
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);
float col = color.toFloatBits(); float col = color.toFloatBits();
float[] floats = new float[8];
for(Ptile tile : grid.tiles){ for(Ptile tile : grid.tiles){
Corner[] c = tile.corners; Corner[] c = tile.corners;
@@ -75,12 +49,21 @@ public class MeshBuilder{
Vec3 v1 = c[i].v; Vec3 v1 = c[i].v;
Vec3 v2 = c[(i + 1) % c.length].v; Vec3 v2 = c[(i + 1) % c.length].v;
vert(v1, nor, col, 0f); floats[0] = v1.x * scale;
vert(v2, nor, col, 0f); 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){ public static Mesh buildHex(Color color, int divisions, float radius){
@@ -91,29 +74,24 @@ public class MeshBuilder{
} }
@Override @Override
public Color getColor(Vec3 position){ public void getColor(Vec3 position, Color out){
return color; out.set(color);
} }
}, divisions, radius, 0); }, divisions, radius, 0);
} }
//TODO: make this thread safe //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 Mesh buildHex(HexMesher mesher, int divisions, float radius, float intensity){ public static synchronized Mesh buildHex(HexMesher mesher, int divisions, float radius, float intensity){
PlanetGrid grid = PlanetGrid.create(divisions); 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){ if(mesher instanceof PlanetGenerator generator){
generator.seed = generator.baseSeed; 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; Mesh mesh = begin(grid.tiles.length * 6, grid.tiles.length * 4 * 3, true, true);
if(indexed){
begin(grid.tiles.length * 6, grid.tiles.length * 4 * 3, emit);
}else{
begin(grid.tiles.length * 12, 0, emit);
}
float[] heights; float[] heights;
@@ -130,6 +108,12 @@ public class MeshBuilder{
int position = 0; 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){ for(Ptile tile : grid.tiles){
if(mesher.skip(tile.v)){ if(mesher.skip(tile.v)){
continue; continue;
@@ -137,60 +121,77 @@ public class MeshBuilder{
Corner[] c = tile.corners; Corner[] c = tile.corners;
for(Corner corner : c){ float
corner.v.scl((1f + heights[corner.id] * intensity) * radius); 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); shorts[0] = (short)(position);
float color = mesher.getColor(tile.v).toFloatBits(); shorts[1] = (short)(position + 1);
float emissive = emit ? mesher.getEmissiveColor(tile.v).toFloatBits() : 0f; shorts[2] = (short)(position + 2);
if(indexed){ shorts[3] = (short)(position);
for(var corner : c){ shorts[4] = (short)(position + 2);
vert(corner.v, nor, color, emissive); shorts[5] = (short)(position + 3);
}
indices(position, position + 1, position + 2); shorts[6] = (short)(position);
indices(position, position + 2, position + 3); shorts[7] = (short)(position + 3);
indices(position, position + 3, position + 4); shorts[8] = (short)(position + 4);
if(c.length > 5){
indices(position, position + 4, position + 5);
}
position += c.length; if(c.length > 5){
shorts[9] = (short)(position);
}else{ shorts[10] = (short)(position + 4);
verts(c[0].v, c[1].v, c[2].v, nor, color, emissive); shorts[11] = (short)(position + 5);
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);
}
} }
//restore mutated corners mesh.getIndicesBuffer().put(shorts, 0, c.length > 5 ? 12 : 9);
for(Corner corner : c){ position += c.length;
corner.v.nor();
}
} }
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( Seq<VertexAttribute> attributes = Seq.with(
VertexAttribute.position3, VertexAttribute.position3
//only GL30 supports GL_INT_2_10_10_10_REV
gl30 ? VertexAttribute.packedNormal : VertexAttribute.normal,
VertexAttribute.color
); );
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){ if(emissive){
attributes.add(new VertexAttribute(4, GL20.GL_UNSIGNED_BYTE, true, "a_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().limit(mesh.getVerticesBuffer().capacity());
mesh.getVerticesBuffer().position(0); mesh.getVerticesBuffer().position(0);
@@ -199,56 +200,70 @@ public class MeshBuilder{
mesh.getIndicesBuffer().limit(mesh.getIndicesBuffer().capacity()); mesh.getIndicesBuffer().limit(mesh.getIndicesBuffer().capacity());
mesh.getIndicesBuffer().position(0); mesh.getIndicesBuffer().position(0);
} }
return mesh;
} }
private static Mesh end(){ private static Mesh end(Mesh mesh){
Mesh last = mesh; mesh.getVerticesBuffer().limit(mesh.getVerticesBuffer().position());
last.getVerticesBuffer().limit(last.getVerticesBuffer().position()); if(mesh.getNumIndices() > 0){
if(last.getNumIndices() > 0){ mesh.getIndicesBuffer().limit(mesh.getIndicesBuffer().position());
last.getIndicesBuffer().limit(last.getIndicesBuffer().position());
} }
mesh = null;
return last; return mesh;
} }
private static Vec3 normal(Vec3 v1, Vec3 v2, Vec3 v3){ private static void normal(Vec3 v1, Vec3 v2, Vec3 v3, Vec3 out){
return v4.set(v2).sub(v1).crs(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z).nor(); 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){ private static void normal(float v1x, float v1y, float v1z, float v2x, float v2y, float v2z, float v3x, float v3y, float v3z, Vec3 out){
shorts[0] = (short)a; float
shorts[1] = (short)b; x = v2x - v1x,
shorts[2] = (short)c; y = v2y - v1y,
mesh.getIndicesBuffer().put(shorts); 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){ private static void vert(Mesh mesh, float[] floats, float x, float y, float z, Vec3 normal, float color, float emissive){
vert(a, normal, color, emissive); floats[0] = x;
vert(b, normal, color, emissive); floats[1] = y;
vert(c, normal, color, emissive); floats[2] = z;
}
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;
if(gl30){ if(gl30){
floats[3] = packNormals(normal.x, normal.y, normal.z); floats[3] = packNormals(normal.x, normal.y, normal.z);
floats[4] = color; floats[4] = color;
if(emit) floats[5] = emissive; floats[5] = emissive;
}else{ }else{
floats[3] = normal.x; floats[3] = normal.x;
floats[4] = normal.x; floats[4] = normal.x;
floats[5] = normal.x; floats[5] = normal.x;
floats[6] = color; floats[6] = color;
if(emit) floats[7] = emissive; floats[7] = emissive;
} }
mesh.getVerticesBuffer().put(floats); mesh.getVerticesBuffer().put(floats);
@@ -18,8 +18,8 @@ public class NoiseMesh extends HexMesh{
} }
@Override @Override
public Color getColor(Vec3 position){ public void getColor(Vec3 position, Color out){
return color; out.set(color);
} }
}, divisions, radius, 0.2f); }, divisions, radius, 0.2f);
} }
@@ -35,8 +35,8 @@ public class NoiseMesh extends HexMesh{
} }
@Override @Override
public Color getColor(Vec3 position){ public void getColor(Vec3 position, Color out){
return Simplex.noise3d(8 + seed, coct, cper, cscl, 5f + position.x, 5f + position.y, 5f + position.z) > cthresh ? color2 : color1; 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); }, divisions, radius, 0.2f);
} }
@@ -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 //cache grids between calls, since only ~5 different grids total are needed
if(size < cache.length && cache[size] != null){ if(size < cache.length && cache[size] != null){
return cache[size]; return cache[size];
+2 -3
View File
@@ -3,7 +3,6 @@ package mindustry.graphics.g3d;
import arc.graphics.*; import arc.graphics.*;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.util.*;
import arc.util.noise.*; import arc.util.noise.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.type.*; import mindustry.type.*;
@@ -19,9 +18,9 @@ public class SunMesh extends HexMesh{
} }
@Override @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; 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); }, divisions, Shaders.unlit);
} }
@@ -1,7 +1,5 @@
package mindustry.maps.generators; package mindustry.maps.generators;
import arc.graphics.*;
import arc.math.geom.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*; import mindustry.world.*;
@@ -9,16 +7,6 @@ import mindustry.world.*;
/** A planet generator that provides no weather, height, color or bases. Override generate().*/ /** A planet generator that provides no weather, height, color or bases. Override generate().*/
public class BlankPlanetGenerator extends PlanetGenerator{ public class BlankPlanetGenerator extends PlanetGenerator{
@Override
public float getHeight(Vec3 position){
return 0;
}
@Override
public Color getColor(Vec3 position){
return Color.white;
}
@Override @Override
public void addWeather(Sector sector, Rules rules){ public void addWeather(Sector sector, Rules rules){
@@ -39,15 +39,13 @@ public class ErekirPlanetGenerator extends PlanetGenerator{
} }
@Override @Override
public Color getColor(Vec3 position){ public void getColor(Vec3 position, Color out){
Block block = getBlock(position); Block block = getBlock(position);
//more obvious color //more obvious color
if(block == Blocks.crystallineStone) block = Blocks.crystalFloor; 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 @Override
@@ -66,12 +66,12 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
@Override @Override
public void onSectorCaptured(Sector sector){ public void onSectorCaptured(Sector sector){
sector.planet.requiresMeshReload = true; sector.planet.reloadMeshAsync();
} }
@Override @Override
public void onSectorLost(Sector sector){ public void onSectorLost(Sector sector){
sector.planet.requiresMeshReload = true; sector.planet.reloadMeshAsync();
} }
@Override @Override
@@ -96,26 +96,27 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
} }
@Override @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){ //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)); // 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); Block block = getBlock(position);
//replace salt with sand color //replace salt with sand color
if(block == Blocks.salt) return Blocks.sand.mapColor; if(block == Blocks.salt) block = Blocks.sand;
return Tmp.c1.set(block.mapColor).a(1f - block.albedo); out.set(block.mapColor).a(1f - block.albedo);
} }
@Override @Override
public boolean hasEmissive(){ public void getEmissiveColor(Vec3 position, Color out){
return true;
}
@Override
public Color getEmissiveColor(Vec3 position){
float dst = 999f, captureDst = 999f, lightScl = 0f; 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()){ 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)); 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()){ }else if(sector.hasBase()){
@@ -133,22 +134,23 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
float freq = 0.05f; float freq = 0.05f;
if(position.dst(basePos) < 0.55f ? 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){ 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) out.set(Team.crux.color)
.lerp(Team.sharded.color, 0.2f*Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 999f, position.z)); .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){ }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) 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)); .lerp(Team.crux.color, 0.3f*Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 999f, position.z)).toFloatBits();
}
return Color.clear; }
} }
@Override @Override
public void genTile(Vec3 position, TileGen tile){ public void genTile(Vec3 position, TileGen tile){
tile.floor = getBlock(position); tile.floor = getBlock(position);
if(tile.floor == Blocks.darkPanel6) tile.floor = Blocks.darkPanel3;
tile.block = tile.floor.asFloor().wall; tile.block = tile.floor.asFloor().wall;
if(Ridged.noise3d(seed + 1, position.x, position.y, position.z, 2, 22) > 0.31){ 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){ Block getBlock(Vec3 position){
float height = rawHeight(position); float height = rawHeight(position);
@@ -169,7 +171,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
height *= 1.2f; height *= 1.2f;
height = Mathf.clamp(height); 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)]; 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){ if(tar > 0.5f){
@@ -178,16 +180,22 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
if(position.within(basePos, 0.65f)){ if(position.within(basePos, 0.65f)){
float dst = 999f; 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()){ if(sector.hasEnemyBase()){
dst = Math.min(dst, position.dst(sector.tile.v)); 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){ 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; return res;
@@ -14,7 +14,7 @@ import mindustry.world.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class TantrosPlanetGenerator extends PlanetGenerator{ 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 = { Block[][] arr = {
{Blocks.redmat, Blocks.redmat, Blocks.darksand, Blocks.bluemat, Blocks.bluemat} {Blocks.redmat, Blocks.redmat, Blocks.darksand, Blocks.bluemat, Blocks.bluemat}
@@ -30,9 +30,9 @@ public class TantrosPlanetGenerator extends PlanetGenerator{
} }
@Override @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; 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 @Override
+15 -2
View File
@@ -43,8 +43,6 @@ public class Planet extends UnlockableContent{
public @Nullable GenericMesh cloudMesh; public @Nullable GenericMesh cloudMesh;
/** Mesh used for rendering planet grid outlines. Null on server or if {@link #grid} is null. */ /** Mesh used for rendering planet grid outlines. Null on server or if {@link #grid} is null. */
public @Nullable Mesh gridMesh; 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. */ /** Position in global coordinates. Will be 0,0,0 until the Universe updates it. */
public Vec3 position = new Vec3(); public Vec3 position = new Vec3();
/** Grid used for the sectors on the planet. Null if this planet can't be landed on. */ /** 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(); 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 @Override
public void load(){ public void load(){
super.load(); super.load();
@@ -33,6 +33,7 @@ import mindustry.graphics.g3d.*;
import mindustry.input.*; import mindustry.input.*;
import mindustry.io.*; import mindustry.io.*;
import mindustry.maps.*; import mindustry.maps.*;
import mindustry.maps.planet.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.type.Planet.*; import mindustry.type.Planet.*;
import mindustry.ui.*; import mindustry.ui.*;
@@ -285,11 +286,6 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
lookAt(state.planet.getLastSector()); lookAt(state.planet.getLastSector());
} }
if(state.planet.requiresMeshReload){
state.planet.requiresMeshReload = false;
state.planet.reloadMesh();
}
return super.show(); return super.show();
} }
@@ -662,6 +658,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
if(timeShift != 0){ if(timeShift != 0){
universe.setSeconds(universe.secondsf() + timeShift * Time.delta * 2.5f); 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)){ if(debugSectorAttackEdit && input.ctrl() && input.keyTap(KeyCode.s)){