Emissive planet system upgrades / Indexed vertices for planets
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
attribute vec4 a_position;
|
attribute vec4 a_position;
|
||||||
attribute vec3 a_normal;
|
attribute vec3 a_normal;
|
||||||
attribute vec4 a_color;
|
attribute vec4 a_color;
|
||||||
|
attribute vec4 a_emissive;
|
||||||
|
|
||||||
uniform mat4 u_proj;
|
uniform mat4 u_proj;
|
||||||
uniform mat4 u_trans;
|
uniform mat4 u_trans;
|
||||||
@@ -8,6 +9,7 @@ uniform vec3 u_lightdir;
|
|||||||
uniform vec3 u_camdir;
|
uniform vec3 u_camdir;
|
||||||
uniform vec3 u_campos;
|
uniform vec3 u_campos;
|
||||||
uniform vec3 u_ambientColor;
|
uniform vec3 u_ambientColor;
|
||||||
|
uniform float u_emissive;
|
||||||
|
|
||||||
varying vec4 v_col;
|
varying vec4 v_col;
|
||||||
|
|
||||||
@@ -20,8 +22,8 @@ void main(){
|
|||||||
vec3 lightReflect = normalize(reflect(a_normal, u_lightdir));
|
vec3 lightReflect = normalize(reflect(a_normal, u_lightdir));
|
||||||
vec3 vertexEye = normalize(u_campos - (u_trans * a_position).xyz);
|
vec3 vertexEye = normalize(u_campos - (u_trans * a_position).xyz);
|
||||||
|
|
||||||
float albedo = a_color.a > 0.5 ? 0.0 : min(a_color.a * 2.0, 1.0);
|
float albedo = 1.0 - a_color.a;
|
||||||
float emissive = a_color.a < 0.5 ? 0.0 : 1.0 - (a_color.a - 0.5) * 2.0;
|
float emissive = a_emissive.a * u_emissive;
|
||||||
|
|
||||||
float specularFactor = dot(vertexEye, lightReflect);
|
float specularFactor = dot(vertexEye, lightReflect);
|
||||||
if(specularFactor > 0.0){
|
if(specularFactor > 0.0){
|
||||||
@@ -30,6 +32,6 @@ void main(){
|
|||||||
|
|
||||||
vec3 norc = (u_ambientColor + specular) * (diffuse + vec3(clamp((dot(a_normal, u_lightdir) + 1.0) / 2.0, 0.0, 1.0)));
|
vec3 norc = (u_ambientColor + specular) * (diffuse + vec3(clamp((dot(a_normal, u_lightdir) + 1.0) / 2.0, 0.0, 1.0)));
|
||||||
|
|
||||||
v_col = vec4(a_color.rgb, 1.0) * vec4(mix(norc, vec3(1.0), emissive), 1.0);
|
v_col = vec4(mix(a_color.rgb, a_emissive.rgb, vec3(1.0 - norc)), 1.0) * vec4(mix(norc, vec3(1.0), emissive), 1.0);
|
||||||
gl_Position = u_proj * u_trans * a_position;
|
gl_Position = u_proj * u_trans * a_position;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,12 +97,6 @@ public class Universe{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSimulationSeconds(int seconds){
|
|
||||||
this.seconds = seconds;
|
|
||||||
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearLoadoutInfo(){
|
public void clearLoadoutInfo(){
|
||||||
lastLoadout = null;
|
lastLoadout = null;
|
||||||
lastLaunchResources = new ItemSeq();
|
lastLaunchResources = new ItemSeq();
|
||||||
@@ -328,6 +322,13 @@ public class Universe{
|
|||||||
return net.client() ? netSeconds : seconds;
|
return net.client() ? netSeconds : seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSeconds(float seconds){
|
||||||
|
this.seconds = (int)seconds;
|
||||||
|
this.secondCounter = seconds - this.seconds;
|
||||||
|
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
public float secondsf(){
|
public float secondsf(){
|
||||||
return seconds() + secondCounter;
|
return seconds() + secondCounter;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.buildHex(colorRed, 2, true, 1f);
|
private Mesh mesh = MeshBuilder.buildLineHex(colorRed, 2);
|
||||||
private Camera3D cam = new Camera3D();
|
private Camera3D cam = new Camera3D();
|
||||||
private int lastLength = -1;
|
private int lastLength = -1;
|
||||||
private FxProcessor fx;
|
private FxProcessor fx;
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ public class Shaders{
|
|||||||
public Color ambientColor = Color.white.cpy();
|
public Color ambientColor = Color.white.cpy();
|
||||||
public Vec3 camDir = new Vec3();
|
public Vec3 camDir = new Vec3();
|
||||||
public Vec3 camPos = new Vec3();
|
public Vec3 camPos = new Vec3();
|
||||||
|
public boolean emissive;
|
||||||
public Planet planet;
|
public Planet planet;
|
||||||
|
|
||||||
public PlanetShader(){
|
public PlanetShader(){
|
||||||
@@ -123,6 +124,7 @@ public class Shaders{
|
|||||||
setUniformf("u_ambientColor", ambientColor.r, ambientColor.g, ambientColor.b);
|
setUniformf("u_ambientColor", ambientColor.r, ambientColor.g, ambientColor.b);
|
||||||
setUniformf("u_camdir", camDir);
|
setUniformf("u_camdir", camDir);
|
||||||
setUniformf("u_campos", renderer.planets.cam.position);
|
setUniformf("u_campos", renderer.planets.cam.position);
|
||||||
|
setUniformf("u_emissive", emissive ? 1f : 0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import mindustry.type.*;
|
|||||||
public class HexMesh extends PlanetMesh{
|
public class HexMesh extends PlanetMesh{
|
||||||
|
|
||||||
public HexMesh(Planet planet, int divisions){
|
public HexMesh(Planet planet, int divisions){
|
||||||
super(planet, MeshBuilder.buildHex(planet.generator, divisions, false, planet.radius, 0.2f), Shaders.planet);
|
super(planet, MeshBuilder.buildHex(planet.generator, divisions, planet.radius, 0.2f), Shaders.planet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HexMesh(Planet planet, HexMesher mesher, int divisions, Shader shader){
|
public HexMesh(Planet planet, HexMesher mesher, int divisions, Shader shader){
|
||||||
super(planet, MeshBuilder.buildHex(mesher, divisions, false, planet.radius, 0.2f), shader);
|
super(planet, MeshBuilder.buildHex(mesher, divisions, planet.radius, 0.2f), shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HexMesh(){
|
public HexMesh(){
|
||||||
@@ -21,6 +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.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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,18 @@ 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);
|
float getHeight(Vec3 position);
|
||||||
Color getColor(Vec3 position);
|
Color getColor(Vec3 position);
|
||||||
|
|
||||||
|
default Color getEmissiveColor(Vec3 position){
|
||||||
|
return Color.clear;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean hasEmissive(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
default boolean skip(Vec3 position){
|
default boolean skip(Vec3 position){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class HexSkyMesh extends PlanetMesh{
|
|||||||
public boolean skip(Vec3 position){
|
public boolean skip(Vec3 position){
|
||||||
return Simplex.noise3d(7 + seed, octaves, persistence, scl, position.x, position.y * 3f, position.z) >= thresh;
|
return Simplex.noise3d(7 + seed, octaves, persistence, scl, position.x, position.y * 3f, position.z) >= thresh;
|
||||||
}
|
}
|
||||||
}, divisions, false, planet.radius, radius), Shaders.clouds);
|
}, divisions, planet.radius, radius), Shaders.clouds);
|
||||||
|
|
||||||
this.speed = speed;
|
this.speed = speed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,18 +3,23 @@ package mindustry.graphics.g3d;
|
|||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.graphics.g3d.PlanetGrid.*;
|
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 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];
|
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 float[] tmpHeights = new float[14580]; //highest amount of corners in vanilla
|
||||||
private static Mesh mesh;
|
private static Mesh mesh;
|
||||||
|
|
||||||
public static Mesh buildIcosphere(int divisions, float radius, Color color){
|
public static Mesh buildIcosphere(int divisions, float radius, Color color){
|
||||||
begin(20 * (2 << (2 * divisions - 1)) * 3);
|
begin(20 * (2 << (2 * divisions - 1)) * 3, 0, false);
|
||||||
|
|
||||||
|
float col = color.toFloatBits();
|
||||||
|
|
||||||
MeshResult result = Icosphere.create(divisions);
|
MeshResult result = Icosphere.create(divisions);
|
||||||
for(int i = 0; i < result.indices.size; i+= 3){
|
for(int i = 0; i < result.indices.size; i+= 3){
|
||||||
@@ -22,7 +27,7 @@ public class MeshBuilder{
|
|||||||
v2.set(result.vertices.items, result.indices.items[i + 1] * 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);
|
v3.set(result.vertices.items, result.indices.items[i + 2] * 3).setLength(radius);
|
||||||
|
|
||||||
verts(v1, v3, v2, normal(v1, v2, v3).scl(-1f), color);
|
verts(v1, v3, v2, normal(v1, v2, v3).scl(-1f), col, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return end();
|
return end();
|
||||||
@@ -38,22 +43,48 @@ public class MeshBuilder{
|
|||||||
total += tile.corners.length * 2;
|
total += tile.corners.length * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
begin(total);
|
float col = color.toFloatBits();
|
||||||
|
|
||||||
|
begin(total, 0, false);
|
||||||
for(Ptile tile : grid.tiles){
|
for(Ptile tile : grid.tiles){
|
||||||
Corner[] c = tile.corners;
|
Corner[] c = tile.corners;
|
||||||
for(int i = 0; i < c.length; i++){
|
for(int i = 0; i < c.length; i++){
|
||||||
Vec3 a = v1.set(c[i].v).scl(scale);
|
Vec3 a = v1.set(c[i].v).scl(scale);
|
||||||
Vec3 b = v2.set(c[(i + 1) % c.length].v).scl(scale);
|
Vec3 b = v2.set(c[(i + 1) % c.length].v).scl(scale);
|
||||||
|
|
||||||
vert(a, Vec3.Z, color);
|
vert(a, Vec3.Z, col, 0f);
|
||||||
vert(b, Vec3.Z, color);
|
vert(b, Vec3.Z, col, 0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Mesh buildHex(Color color, int divisions, boolean lines, float radius){
|
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();
|
||||||
|
|
||||||
|
for(Ptile tile : grid.tiles){
|
||||||
|
Corner[] c = tile.corners;
|
||||||
|
|
||||||
|
for(int i = 0; i < c.length; i++){
|
||||||
|
Vec3 v1 = c[i].v;
|
||||||
|
Vec3 v2 = c[(i + 1) % c.length].v;
|
||||||
|
|
||||||
|
vert(v1, nor, col, 0f);
|
||||||
|
vert(v2, nor, col, 0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mesh buildHex(Color color, int divisions, float radius){
|
||||||
return buildHex(new HexMesher(){
|
return buildHex(new HexMesher(){
|
||||||
@Override
|
@Override
|
||||||
public float getHeight(Vec3 position){
|
public float getHeight(Vec3 position){
|
||||||
@@ -64,17 +95,25 @@ public class MeshBuilder{
|
|||||||
public Color getColor(Vec3 position){
|
public Color getColor(Vec3 position){
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
}, divisions, lines, radius, 0);
|
}, divisions, radius, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Mesh buildHex(HexMesher mesher, int divisions, boolean lines, float radius, float intensity){
|
public static Mesh buildHex(HexMesher mesher, int divisions, float radius, float intensity){
|
||||||
PlanetGrid grid = PlanetGrid.create(divisions);
|
PlanetGrid grid = PlanetGrid.create(divisions);
|
||||||
|
|
||||||
if(mesher instanceof PlanetGenerator generator){
|
if(mesher instanceof PlanetGenerator generator){
|
||||||
generator.seed = generator.baseSeed;
|
generator.seed = generator.baseSeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
begin(grid.tiles.length * 12);
|
boolean emit = mesher.hasEmissive();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
float[] heights;
|
float[] heights;
|
||||||
|
|
||||||
@@ -89,6 +128,8 @@ public class MeshBuilder{
|
|||||||
heights[i] = mesher.getHeight(grid.corners[i].v);
|
heights[i] = mesher.getHeight(grid.corners[i].v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int position = 0;
|
||||||
|
|
||||||
for(Ptile tile : grid.tiles){
|
for(Ptile tile : grid.tiles){
|
||||||
if(mesher.skip(tile.v)){
|
if(mesher.skip(tile.v)){
|
||||||
continue;
|
continue;
|
||||||
@@ -101,25 +142,30 @@ public class MeshBuilder{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vec3 nor = normal(c[0].v, c[2].v, c[4].v);
|
Vec3 nor = normal(c[0].v, c[2].v, c[4].v);
|
||||||
Color color = mesher.getColor(v2.set(tile.v));
|
float color = mesher.getColor(tile.v).toFloatBits();
|
||||||
|
float emissive = emit ? mesher.getEmissiveColor(tile.v).toFloatBits() : 0f;
|
||||||
|
|
||||||
if(lines){
|
if(indexed){
|
||||||
nor.set(1f, 1f, 1f);
|
for(var corner : c){
|
||||||
|
vert(corner.v, nor, color, emissive);
|
||||||
for(int i = 0; i < c.length; i++){
|
|
||||||
Vec3 v1 = c[i].v;
|
|
||||||
Vec3 v2 = c[(i + 1) % c.length].v;
|
|
||||||
|
|
||||||
vert(v1, nor, color);
|
|
||||||
vert(v2, nor, color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
position += c.length;
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
verts(c[0].v, c[1].v, c[2].v, nor, color);
|
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);
|
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);
|
verts(c[0].v, c[3].v, c[4].v, nor, color, emissive);
|
||||||
|
|
||||||
if(c.length > 5){
|
if(c.length > 5){
|
||||||
verts(c[0].v, c[4].v, c[5].v, nor, color);
|
verts(c[0].v, c[4].v, c[5].v, nor, color, emissive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,28 +173,49 @@ public class MeshBuilder{
|
|||||||
for(Corner corner : c){
|
for(Corner corner : c){
|
||||||
corner.v.nor();
|
corner.v.nor();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void begin(int count){
|
private static void begin(int vertices, int indices, boolean emissive){
|
||||||
mesh = new Mesh(true, count, 0,
|
Seq<VertexAttribute> attributes = Seq.with(
|
||||||
VertexAttribute.position3,
|
VertexAttribute.position3,
|
||||||
!gl30 ? VertexAttribute.normal : VertexAttribute.packedNormal,
|
//only GL30 supports GL_INT_2_10_10_10_REV
|
||||||
|
gl30 ? VertexAttribute.packedNormal : VertexAttribute.normal,
|
||||||
VertexAttribute.color
|
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.getVerticesBuffer().limit(mesh.getVerticesBuffer().capacity());
|
mesh.getVerticesBuffer().limit(mesh.getVerticesBuffer().capacity());
|
||||||
mesh.getVerticesBuffer().position(0);
|
mesh.getVerticesBuffer().position(0);
|
||||||
|
|
||||||
|
if(indices > 0){
|
||||||
|
mesh.getIndicesBuffer().limit(mesh.getIndicesBuffer().capacity());
|
||||||
|
mesh.getIndicesBuffer().position(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int totalBytes;
|
||||||
|
|
||||||
private static Mesh end(){
|
private static Mesh end(){
|
||||||
Mesh last = mesh;
|
Mesh last = mesh;
|
||||||
last.getVerticesBuffer().limit(last.getVerticesBuffer().position());
|
last.getVerticesBuffer().limit(last.getVerticesBuffer().position());
|
||||||
|
if(last.getNumIndices() > 0){
|
||||||
|
last.getIndicesBuffer().limit(last.getIndicesBuffer().position());
|
||||||
|
}
|
||||||
mesh = null;
|
mesh = null;
|
||||||
|
|
||||||
|
totalBytes += last.getVerticesBuffer().capacity() * 4;
|
||||||
|
totalBytes += last.getIndicesBuffer().capacity() * 2;
|
||||||
|
|
||||||
|
Log.info("total memory used: @ mb", totalBytes / 1000f / 1000f);
|
||||||
|
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,13 +223,23 @@ public class MeshBuilder{
|
|||||||
return v4.set(v2).sub(v1).crs(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z).nor();
|
return v4.set(v2).sub(v1).crs(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z).nor();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void verts(Vec3 a, Vec3 b, Vec3 c, Vec3 normal, Color color){
|
private static void indices(int a, int b, int c){
|
||||||
vert(a, normal, color);
|
shorts[0] = (short)a;
|
||||||
vert(b, normal, color);
|
shorts[1] = (short)b;
|
||||||
vert(c, normal, color);
|
shorts[2] = (short)c;
|
||||||
|
mesh.getIndicesBuffer().put(shorts);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void vert(Vec3 a, Vec3 normal, Color color){
|
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[0] = a.x;
|
||||||
floats[1] = a.y;
|
floats[1] = a.y;
|
||||||
floats[2] = a.z;
|
floats[2] = a.z;
|
||||||
@@ -170,13 +247,15 @@ public class MeshBuilder{
|
|||||||
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.toFloatBits();
|
floats[4] = color;
|
||||||
|
if(emit) 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.toFloatBits();
|
floats[6] = color;
|
||||||
|
if(emit) floats[7] = emissive;
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.getVerticesBuffer().put(floats);
|
mesh.getVerticesBuffer().put(floats);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class NoiseMesh extends HexMesh{
|
|||||||
public Color getColor(Vec3 position){
|
public Color getColor(Vec3 position){
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
}, divisions, false, radius, 0.2f);
|
}, divisions, radius, 0.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Two-color variant. */
|
/** Two-color variant. */
|
||||||
@@ -38,6 +38,6 @@ public class NoiseMesh extends HexMesh{
|
|||||||
public Color getColor(Vec3 position){
|
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;
|
return Simplex.noise3d(8 + seed, coct, cper, cscl, 5f + position.x, 5f + position.y, 5f + position.z) > cthresh ? color2 : color1;
|
||||||
}
|
}
|
||||||
}, divisions, false, radius, 0.2f);
|
}, divisions, radius, 0.2f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class PlanetRenderer implements Disposable{
|
|||||||
setThreshold(0.8f);
|
setThreshold(0.8f);
|
||||||
blurPasses = 6;
|
blurPasses = 6;
|
||||||
}};
|
}};
|
||||||
public final Mesh atmosphere = MeshBuilder.buildHex(Color.white, 2, false, 1.5f);
|
public final Mesh atmosphere = MeshBuilder.buildHex(Color.white, 2, 1.5f);
|
||||||
|
|
||||||
//seed: 8kmfuix03fw
|
//seed: 8kmfuix03fw
|
||||||
public final CubemapMesh skybox = new CubemapMesh(new Cubemap("cubemaps/stars/"));
|
public final CubemapMesh skybox = new CubemapMesh(new Cubemap("cubemaps/stars/"));
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package mindustry.maps.generators;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.struct.ObjectIntMap.*;
|
import arc.struct.ObjectIntMap.*;
|
||||||
@@ -26,10 +25,6 @@ public abstract class PlanetGenerator extends BasicGenerator implements HexMeshe
|
|||||||
|
|
||||||
protected @Nullable Sector sector;
|
protected @Nullable Sector sector;
|
||||||
|
|
||||||
public static float packAlpha(float albedo, float emissive){
|
|
||||||
return emissive > 0 ? 1f + 1f/255f - 0.5f * Mathf.clamp(emissive) : Mathf.clamp(albedo) * 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Should generate sector bases for a planet. */
|
/** Should generate sector bases for a planet. */
|
||||||
public void generateSector(Sector sector){
|
public void generateSector(Sector sector){
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class ErekirPlanetGenerator extends PlanetGenerator{
|
|||||||
//TODO this might be too green
|
//TODO this might be too green
|
||||||
//if(block == Blocks.beryllicStone) block = Blocks.arkyicStone;
|
//if(block == Blocks.beryllicStone) block = Blocks.arkyicStone;
|
||||||
|
|
||||||
return Tmp.c1.set(block.mapColor).a(packAlpha(block.albedo, 0f));
|
return Tmp.c1.set(block.mapColor).a(1f - block.albedo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -64,17 +64,17 @@ public class ErekirPlanetGenerator extends PlanetGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Block getBlock(Vec3 position){
|
Block getBlock(Vec3 position){
|
||||||
float ice = rawTemp(position);
|
float px = position.x, py = position.y, pz = position.z;
|
||||||
Tmp.v32.set(position);
|
|
||||||
|
|
||||||
|
float ice = rawTemp(position);
|
||||||
float height = rawHeight(position);
|
float height = rawHeight(position);
|
||||||
Tmp.v31.set(position);
|
|
||||||
height *= 1.2f;
|
height *= 1.2f;
|
||||||
height = Mathf.clamp(height);
|
height = Mathf.clamp(height);
|
||||||
|
|
||||||
Block result = terrain[Mathf.clamp((int)(height * terrain.length), 0, terrain.length - 1)];
|
Block result = terrain[Mathf.clamp((int)(height * terrain.length), 0, terrain.length - 1)];
|
||||||
|
|
||||||
if(ice < 0.3 + Math.abs(Ridged.noise3d(seed + crystalSeed, position.x + 4f, position.y + 8f, position.z + 1f, crystalOct, crystalScl)) * crystalMag){
|
if(ice < 0.3 + Math.abs(Ridged.noise3d(seed + crystalSeed, px + 4f, py + 8f, pz + 1f, crystalOct, crystalScl)) * crystalMag){
|
||||||
return Blocks.crystallineStone;
|
return Blocks.crystallineStone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,11 +85,9 @@ public class ErekirPlanetGenerator extends PlanetGenerator{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
position = Tmp.v32;
|
|
||||||
|
|
||||||
//TODO tweak this to make it more natural
|
//TODO tweak this to make it more natural
|
||||||
//TODO edge distortion?
|
//TODO edge distortion?
|
||||||
if(ice < redThresh - noArkThresh && Ridged.noise3d(seed + arkSeed, position.x + 2f, position.y + 8f, position.z + 1f, arkOct, arkScl) > arkThresh){
|
if(ice < redThresh - noArkThresh && Ridged.noise3d(seed + arkSeed, px + 2f, py + 8f, pz + 1f, arkOct, arkScl) > arkThresh){
|
||||||
//TODO arkyic in middle
|
//TODO arkyic in middle
|
||||||
result = Blocks.beryllicStone;
|
result = Blocks.beryllicStone;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,17 +87,6 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getColor(Vec3 position){
|
public Color getColor(Vec3 position){
|
||||||
float dst = 999f;
|
|
||||||
for(Sector sector : Planets.serpulo.sectors){
|
|
||||||
if(sector.hasEnemyBase() && !sector.isCaptured()){
|
|
||||||
dst = Math.min(dst, position.dst(sector.tile.v));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 < 0.06f){
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
//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));
|
||||||
//}
|
//}
|
||||||
@@ -105,7 +94,30 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
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) return Blocks.sand.mapColor;
|
||||||
return Tmp.c1.set(block.mapColor).a(packAlpha(block.albedo, 0f));
|
return Tmp.c1.set(block.mapColor).a(1f - block.albedo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasEmissive(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getEmissiveColor(Vec3 position){
|
||||||
|
float dst = 999f;
|
||||||
|
for(Sector sector : Planets.serpulo.sectors){
|
||||||
|
if(sector.hasEnemyBase() && !sector.isCaptured()){
|
||||||
|
dst = Math.min(dst, position.dst(sector.tile.v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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){
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Color.clear;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -123,17 +135,16 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
|||||||
Block getBlock(Vec3 position){
|
Block getBlock(Vec3 position){
|
||||||
//float metalDst = position.dst(basePos);
|
//float metalDst = position.dst(basePos);
|
||||||
float height = rawHeight(position);
|
float height = rawHeight(position);
|
||||||
Tmp.v31.set(position);
|
float px = position.x * scl, py = position.y * scl, pz = position.z * scl;
|
||||||
position = Tmp.v33.set(position).scl(scl);
|
|
||||||
|
|
||||||
float rad = scl;
|
float rad = scl;
|
||||||
float temp = Mathf.clamp(Math.abs(position.y * 2f) / (rad));
|
float temp = Mathf.clamp(Math.abs(py * 2f) / (rad));
|
||||||
float tnoise = Simplex.noise3d(seed, 7, 0.56, 1f/3f, position.x, position.y + 999f, position.z);
|
float tnoise = Simplex.noise3d(seed, 7, 0.56, 1f/3f, px, py + 999f, pz);
|
||||||
temp = Mathf.lerp(temp, tnoise, 0.5f);
|
temp = Mathf.lerp(temp, tnoise, 0.5f);
|
||||||
height *= 1.2f;
|
height *= 1.2f;
|
||||||
height = Mathf.clamp(height);
|
height = Mathf.clamp(height);
|
||||||
|
|
||||||
float tar = Simplex.noise3d(seed, 4, 0.55f, 1f/2f, position.x, position.y + 999f, position.z) * 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 + Tmp.v31.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){
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class TantrosPlanetGenerator extends PlanetGenerator{
|
|||||||
@Override
|
@Override
|
||||||
public Color getColor(Vec3 position){
|
public Color getColor(Vec3 position){
|
||||||
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(packAlpha(0.2f, 0f));
|
return c1.write(out).lerp(c2, Mathf.clamp(Mathf.round(depth, 0.15f))).a(1f - 0.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -285,6 +285,11 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -652,6 +657,13 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
if(scene.getDialog() == PlanetDialog.this && (scene.getHoverElement() == null || !scene.getHoverElement().isDescendantOf(e -> e instanceof ScrollPane))){
|
if(scene.getDialog() == PlanetDialog.this && (scene.getHoverElement() == null || !scene.getHoverElement().isDescendantOf(e -> e instanceof ScrollPane))){
|
||||||
scene.setScrollFocus(PlanetDialog.this);
|
scene.setScrollFocus(PlanetDialog.this);
|
||||||
|
|
||||||
|
if(debugSectorAttackEdit){
|
||||||
|
int timeShift = input.keyDown(KeyCode.rightBracket) ? 1 : input.keyDown(KeyCode.leftBracket) ? -1 : 0;
|
||||||
|
if(timeShift != -1){
|
||||||
|
universe.setSeconds(universe.secondsf() + timeShift * Time.delta * 2f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(debugSectorAttackEdit && input.ctrl() && input.keyTap(KeyCode.s)){
|
if(debugSectorAttackEdit && input.ctrl() && input.keyTap(KeyCode.s)){
|
||||||
try{
|
try{
|
||||||
PlanetData data = new PlanetData();
|
PlanetData data = new PlanetData();
|
||||||
|
|||||||
Reference in New Issue
Block a user