Async mesh reloading for planets
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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){
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)){
|
||||
|
||||
Reference in New Issue
Block a user