Planet rendering refactoring
This commit is contained in:
@@ -5,7 +5,6 @@ import arc.*;
|
|||||||
import arc.assets.*;
|
import arc.assets.*;
|
||||||
import arc.files.*;
|
import arc.files.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g3d.*;
|
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
@@ -165,7 +164,6 @@ public class Vars implements Loadable{
|
|||||||
/** list of all locales that can be switched to */
|
/** list of all locales that can be switched to */
|
||||||
public static Locale[] locales;
|
public static Locale[] locales;
|
||||||
|
|
||||||
public static Camera3D cam3;
|
|
||||||
public static FileTree tree = new FileTree();
|
public static FileTree tree = new FileTree();
|
||||||
public static Net net;
|
public static Net net;
|
||||||
public static ContentLoader content;
|
public static ContentLoader content;
|
||||||
@@ -264,10 +262,6 @@ public class Vars implements Loadable{
|
|||||||
|
|
||||||
mods.load();
|
mods.load();
|
||||||
maps.load();
|
maps.load();
|
||||||
|
|
||||||
if(!headless){
|
|
||||||
cam3 = new Camera3D();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadLogger(){
|
public static void loadLogger(){
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import mindustry.content.*;
|
|||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.graphics.g3d.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
|
|
||||||
import static arc.Core.*;
|
import static arc.Core.*;
|
||||||
@@ -24,6 +25,7 @@ public class Renderer implements ApplicationListener{
|
|||||||
public final OverlayRenderer overlays = new OverlayRenderer();
|
public final OverlayRenderer overlays = new OverlayRenderer();
|
||||||
public final LightRenderer lights = new LightRenderer();
|
public final LightRenderer lights = new LightRenderer();
|
||||||
public final Pixelator pixelator = new Pixelator();
|
public final Pixelator pixelator = new Pixelator();
|
||||||
|
public PlanetRenderer planets;
|
||||||
|
|
||||||
public FrameBuffer effectBuffer = new FrameBuffer();
|
public FrameBuffer effectBuffer = new FrameBuffer();
|
||||||
private Bloom bloom;
|
private Bloom bloom;
|
||||||
@@ -47,6 +49,8 @@ public class Renderer implements ApplicationListener{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(){
|
public void init(){
|
||||||
|
planets = new PlanetRenderer();
|
||||||
|
|
||||||
if(settings.getBool("bloom")){
|
if(settings.getBool("bloom")){
|
||||||
setupBloom();
|
setupBloom();
|
||||||
}
|
}
|
||||||
@@ -96,6 +100,7 @@ public class Renderer implements ApplicationListener{
|
|||||||
minimap.dispose();
|
minimap.dispose();
|
||||||
effectBuffer.dispose();
|
effectBuffer.dispose();
|
||||||
blocks.dispose();
|
blocks.dispose();
|
||||||
|
planets.dispose();
|
||||||
if(bloom != null){
|
if(bloom != null){
|
||||||
bloom.dispose();
|
bloom.dispose();
|
||||||
bloom = null;
|
bloom = null;
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ public class Shaders{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(){
|
public void apply(){
|
||||||
|
camDir.set(renderer.planets.cam.direction).rotate(Vec3.Y, renderer.planets.planet.getRotation());
|
||||||
|
|
||||||
setUniformf("u_lightdir", lightDir);
|
setUniformf("u_lightdir", lightDir);
|
||||||
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);
|
||||||
|
|||||||
351
core/src/mindustry/graphics/g3d/PlanetRenderer.java
Normal file
351
core/src/mindustry/graphics/g3d/PlanetRenderer.java
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
package mindustry.graphics.g3d;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.graphics.g3d.*;
|
||||||
|
import arc.graphics.gl.*;
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.game.Objectives.*;
|
||||||
|
import mindustry.game.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
|
import mindustry.graphics.g3d.PlanetGrid.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
import mindustry.type.Sector.*;
|
||||||
|
import mindustry.ui.*;
|
||||||
|
|
||||||
|
public class PlanetRenderer implements Disposable{
|
||||||
|
public static final float outlineRad = 1.17f, camLength = 4f;
|
||||||
|
public static final Color
|
||||||
|
outlineColor = Pal.accent.cpy().a(1f),
|
||||||
|
hoverColor = Pal.accent.cpy().a(0.5f),
|
||||||
|
borderColor = Pal.accent.cpy().a(0.3f),
|
||||||
|
shadowColor = new Color(0, 0, 0, 0.7f);
|
||||||
|
|
||||||
|
private static final Array<Vec3> points = new Array<>();
|
||||||
|
|
||||||
|
/** Camera direction relative to the planet. Length is determined by zoom. */
|
||||||
|
public final Vec3 camPos = new Vec3();
|
||||||
|
/** The sun/main planet of the solar system from which everything is rendered. */
|
||||||
|
public final Planet solarSystem = Planets.sun;
|
||||||
|
/** Planet being looked at. */
|
||||||
|
public Planet planet = Planets.starter;
|
||||||
|
/** Camera used for rendering. */
|
||||||
|
public Camera3D cam = new Camera3D();
|
||||||
|
|
||||||
|
public float zoom = 1f, selectAlpha = 1f;
|
||||||
|
public @Nullable Sector selected, hovered;
|
||||||
|
|
||||||
|
private final Mesh[] outlines = new Mesh[10];
|
||||||
|
private final VertexBatch3D batch = new VertexBatch3D(10000, false, true, 0);
|
||||||
|
private final PlaneBatch3D projector = new PlaneBatch3D();
|
||||||
|
private final Mat3D mat = new Mat3D();
|
||||||
|
private final FrameBuffer buffer = new FrameBuffer(2, 2, true);
|
||||||
|
|
||||||
|
private final Bloom bloom = new Bloom(Core.graphics.getWidth()/4, Core.graphics.getHeight()/4, true, false){{
|
||||||
|
setThreshold(0.8f);
|
||||||
|
blurPasses = 6;
|
||||||
|
}};
|
||||||
|
private final Mesh atmosphere = MeshBuilder.buildHex(Color.white, 2, false, 1.5f);
|
||||||
|
|
||||||
|
//seed: 8kmfuix03fw
|
||||||
|
private final CubemapMesh skybox = new CubemapMesh(new Cubemap("cubemaps/stars/"));
|
||||||
|
|
||||||
|
public PlanetRenderer(){
|
||||||
|
camPos.set(0, 0f, camLength);
|
||||||
|
projector.setScaling(1f / 150f);
|
||||||
|
cam.fov = 60f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Render the entire planet scene to the screen. */
|
||||||
|
public void render(){
|
||||||
|
Draw.flush();
|
||||||
|
Gl.clear(Gl.depthBufferBit);
|
||||||
|
Gl.enable(Gl.depthTest);
|
||||||
|
Gl.depthMask(true);
|
||||||
|
|
||||||
|
Gl.enable(Gl.cullFace);
|
||||||
|
Gl.cullFace(Gl.back);
|
||||||
|
|
||||||
|
//lock to up vector so it doesn't get confusing
|
||||||
|
cam.up.set(Vec3.Y);
|
||||||
|
|
||||||
|
cam.resize(Core.graphics.getWidth(), Core.graphics.getHeight());
|
||||||
|
camPos.setLength(planet.radius * camLength + (zoom-1f) * planet.radius * 2);
|
||||||
|
cam.position.set(planet.position).add(camPos);
|
||||||
|
cam.lookAt(planet.position);
|
||||||
|
cam.update();
|
||||||
|
|
||||||
|
projector.proj(cam.combined);
|
||||||
|
batch.proj(cam.combined);
|
||||||
|
|
||||||
|
beginBloom();
|
||||||
|
|
||||||
|
skybox.render(cam.combined);
|
||||||
|
|
||||||
|
renderPlanet(solarSystem);
|
||||||
|
|
||||||
|
endBloom();
|
||||||
|
|
||||||
|
Gl.enable(Gl.blend);
|
||||||
|
|
||||||
|
//TODO perhaps draw this somewhere else
|
||||||
|
if(hovered != null){
|
||||||
|
Draw.batch(projector, () -> {
|
||||||
|
setPlane(hovered);
|
||||||
|
Draw.color(Color.white, Pal.accent, Mathf.absin(5f, 1f));
|
||||||
|
|
||||||
|
TextureRegion icon = hovered.locked() ? Icon.lock.getRegion() : hovered.is(SectorAttribute.naval) ? Liquids.water.icon(Cicon.large) : null;
|
||||||
|
|
||||||
|
if(icon != null){
|
||||||
|
Draw.rect(icon, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw.reset();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Gl.disable(Gl.cullFace);
|
||||||
|
Gl.disable(Gl.depthTest);
|
||||||
|
|
||||||
|
cam.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void beginBloom(){
|
||||||
|
bloom.resize(Core.graphics.getWidth() / 4, Core.graphics.getHeight() / 4);
|
||||||
|
bloom.capture();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void endBloom(){
|
||||||
|
bloom.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderPlanet(Planet planet){
|
||||||
|
//render planet at offsetted position in the world
|
||||||
|
planet.mesh.render(cam.combined, planet.getTransform(mat));
|
||||||
|
|
||||||
|
renderOrbit(planet);
|
||||||
|
|
||||||
|
if(planet.isLandable() && planet == this.planet){
|
||||||
|
renderSectors(planet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(planet.parent != null && planet.hasAtmosphere && Core.settings.getBool("atmosphere")){
|
||||||
|
Blending.additive.apply();
|
||||||
|
|
||||||
|
Shaders.atmosphere.camera = cam;
|
||||||
|
Shaders.atmosphere.planet = planet;
|
||||||
|
Shaders.atmosphere.bind();
|
||||||
|
Shaders.atmosphere.apply();
|
||||||
|
|
||||||
|
atmosphere.render(Shaders.atmosphere, Gl.triangles);
|
||||||
|
|
||||||
|
Blending.normal.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Planet child : planet.children){
|
||||||
|
renderPlanet(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderOrbit(Planet planet){
|
||||||
|
if(planet.parent == null) return;
|
||||||
|
|
||||||
|
Vec3 center = planet.parent.position;
|
||||||
|
float radius = planet.orbitRadius;
|
||||||
|
int points = (int)(radius * 50);
|
||||||
|
Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray));
|
||||||
|
batch.flush(Gl.lineLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderSectors(Planet planet){
|
||||||
|
//apply transformed position
|
||||||
|
batch.proj().mul(planet.getTransform(mat));
|
||||||
|
|
||||||
|
for(Sector sec : planet.sectors){
|
||||||
|
|
||||||
|
if(selectAlpha > 0.01f){
|
||||||
|
if(sec.unlocked()){
|
||||||
|
Color color =
|
||||||
|
sec.hasBase() ? Team.sharded.color :
|
||||||
|
sec.preset != null ? Team.derelict.color :
|
||||||
|
sec.hasEnemyBase() ? Team.crux.color :
|
||||||
|
null;
|
||||||
|
|
||||||
|
if(color != null){
|
||||||
|
drawSelection(sec, Tmp.c1.set(color).mul(0.8f).a(selectAlpha), 0.026f, -0.001f);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
draw(sec, Tmp.c1.set(shadowColor).mul(1, 1, 1, selectAlpha), -0.001f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hovered != null){
|
||||||
|
draw(hovered, hoverColor, -0.001f);
|
||||||
|
drawBorders(hovered, borderColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(selected != null){
|
||||||
|
drawSelection(selected);
|
||||||
|
drawBorders(selected, borderColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
batch.flush(Gl.triangles);
|
||||||
|
|
||||||
|
//render arcs
|
||||||
|
if(selected != null && selected.preset != null){
|
||||||
|
for(Objective o : selected.preset.requirements){
|
||||||
|
if(o instanceof SectorObjective){
|
||||||
|
SectorPreset preset = ((SectorObjective)o).preset;
|
||||||
|
drawArc(planet, selected.tile.v, preset.sector.tile.v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//render sector grid
|
||||||
|
Mesh mesh = outline(planet.grid.size);
|
||||||
|
Shader shader = Shaders.planetGrid;
|
||||||
|
Vec3 tile = planet.intersect(cam.getMouseRay(), outlineRad);
|
||||||
|
Shaders.planetGrid.mouse.lerp(tile == null ? Vec3.Zero : tile.sub(planet.position).rotate(Vec3.Y, planet.getRotation()), 0.2f);
|
||||||
|
|
||||||
|
shader.bind();
|
||||||
|
shader.setUniformMatrix4("u_proj", cam.combined.val);
|
||||||
|
shader.setUniformMatrix4("u_trans", planet.getTransform(mat).val);
|
||||||
|
shader.apply();
|
||||||
|
mesh.render(shader, Gl.lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawArc(Planet planet, Vec3 a, Vec3 b){
|
||||||
|
Vec3 avg = Tmp.v31.set(a).add(b).scl(0.5f);
|
||||||
|
avg.setLength(planet.radius*2f);
|
||||||
|
|
||||||
|
points.clear();
|
||||||
|
points.addAll(Tmp.v33.set(a).setLength(outlineRad), Tmp.v31, Tmp.v34.set(b).setLength(outlineRad));
|
||||||
|
Tmp.bz3.set(points);
|
||||||
|
float points = 25;
|
||||||
|
|
||||||
|
for(int i = 0; i < points + 1; i++){
|
||||||
|
float f = i / points;
|
||||||
|
Tmp.c1.set(Pal.accent).lerp(Color.clear, (f+Time.globalTime()/80f)%1f);
|
||||||
|
batch.color(Tmp.c1);
|
||||||
|
batch.vertex(Tmp.bz3.valueAt(Tmp.v32, f));
|
||||||
|
|
||||||
|
}
|
||||||
|
batch.flush(Gl.lineStrip);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawBorders(Sector sector, Color base){
|
||||||
|
Color color = Tmp.c1.set(base).a(base.a + 0.3f + Mathf.absin(Time.globalTime(), 5f, 0.3f));
|
||||||
|
|
||||||
|
float r1 = 1f;
|
||||||
|
float r2 = outlineRad + 0.001f;
|
||||||
|
|
||||||
|
for(int i = 0; i < sector.tile.corners.length; i++){
|
||||||
|
Corner c = sector.tile.corners[i], next = sector.tile.corners[(i+1) % sector.tile.corners.length];
|
||||||
|
|
||||||
|
Tmp.v31.set(c.v).setLength(r2);
|
||||||
|
Tmp.v32.set(next.v).setLength(r2);
|
||||||
|
Tmp.v33.set(c.v).setLength(r1);
|
||||||
|
|
||||||
|
batch.tri2(Tmp.v31, Tmp.v32, Tmp.v33, color);
|
||||||
|
|
||||||
|
Tmp.v31.set(next.v).setLength(r2);
|
||||||
|
Tmp.v32.set(next.v).setLength(r1);
|
||||||
|
Tmp.v33.set(c.v).setLength(r1);
|
||||||
|
|
||||||
|
batch.tri2(Tmp.v31, Tmp.v32, Tmp.v33, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(batch.getNumVertices() >= batch.getMaxVertices() - 6 * 6){
|
||||||
|
batch.flush(Gl.triangles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPlane(Sector sector){
|
||||||
|
float rotation = -planet.getRotation();
|
||||||
|
float length = 0.01f;
|
||||||
|
|
||||||
|
projector.setPlane(
|
||||||
|
//origin on sector position
|
||||||
|
Tmp.v33.set(sector.tile.v).setLength(outlineRad + length).rotate(Vec3.Y, rotation).add(planet.position),
|
||||||
|
//face up
|
||||||
|
sector.plane.project(Tmp.v32.set(sector.tile.v).add(Vec3.Y)).sub(sector.tile.v).rotate(Vec3.Y, rotation).nor(),
|
||||||
|
//right vector
|
||||||
|
Tmp.v31.set(Tmp.v32).rotate(Vec3.Y, -rotation).add(sector.tile.v).rotate(sector.tile.v, 90).sub(sector.tile.v).rotate(Vec3.Y, rotation).nor()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void draw(Sector sector, Color color, float offset){
|
||||||
|
float rr = outlineRad + offset;
|
||||||
|
for(int i = 0; i < sector.tile.corners.length; i++){
|
||||||
|
Corner c = sector.tile.corners[i], next = sector.tile.corners[(i+1) % sector.tile.corners.length];
|
||||||
|
batch.tri(Tmp.v31.set(c.v).setLength(rr), Tmp.v32.set(next.v).setLength(rr), Tmp.v33.set(sector.tile.v).setLength(rr), color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawSelection(Sector sector){
|
||||||
|
drawSelection(sector, Pal.accent, 0.04f, 0.001f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawSelection(Sector sector, Color color, float stroke, float length){
|
||||||
|
float arad = outlineRad + length;
|
||||||
|
|
||||||
|
for(int i = 0; i < sector.tile.corners.length; i++){
|
||||||
|
Corner next = sector.tile.corners[(i + 1) % sector.tile.corners.length];
|
||||||
|
Corner curr = sector.tile.corners[i];
|
||||||
|
|
||||||
|
next.v.scl(arad);
|
||||||
|
curr.v.scl(arad);
|
||||||
|
sector.tile.v.scl(arad);
|
||||||
|
|
||||||
|
Tmp.v31.set(curr.v).sub(sector.tile.v).setLength(curr.v.dst(sector.tile.v) - stroke).add(sector.tile.v);
|
||||||
|
Tmp.v32.set(next.v).sub(sector.tile.v).setLength(next.v.dst(sector.tile.v) - stroke).add(sector.tile.v);
|
||||||
|
|
||||||
|
batch.tri(curr.v, next.v, Tmp.v31, color);
|
||||||
|
batch.tri(Tmp.v31, next.v, Tmp.v32, color);
|
||||||
|
|
||||||
|
sector.tile.v.scl(1f / arad);
|
||||||
|
next.v.scl(1f / arad);
|
||||||
|
curr.v.scl(1f /arad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mesh outline(int size){
|
||||||
|
if(outlines[size] == null){
|
||||||
|
outlines[size] = MeshBuilder.buildHex(new HexMesher(){
|
||||||
|
@Override
|
||||||
|
public float getHeight(Vec3 position){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getColor(Vec3 position){
|
||||||
|
return outlineColor;
|
||||||
|
}
|
||||||
|
}, size, true, outlineRad, 0.2f);
|
||||||
|
}
|
||||||
|
return outlines[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose(){
|
||||||
|
skybox.dispose();
|
||||||
|
batch.dispose();
|
||||||
|
projector.dispose();
|
||||||
|
atmosphere.dispose();
|
||||||
|
buffer.dispose();
|
||||||
|
bloom.dispose();
|
||||||
|
for(Mesh m : outlines){
|
||||||
|
if(m != null){
|
||||||
|
m.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,27 +3,18 @@ package mindustry.ui.dialogs;
|
|||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.graphics.g3d.*;
|
|
||||||
import arc.graphics.gl.*;
|
import arc.graphics.gl.*;
|
||||||
import arc.input.*;
|
import arc.input.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.scene.event.*;
|
import arc.scene.event.*;
|
||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.scene.ui.TextButton.*;
|
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
|
||||||
import mindustry.content.*;
|
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.game.EventType.*;
|
|
||||||
import mindustry.game.Objectives.*;
|
|
||||||
import mindustry.game.*;
|
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.graphics.g3d.*;
|
import mindustry.graphics.g3d.*;
|
||||||
import mindustry.graphics.g3d.PlanetGrid.*;
|
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.type.Sector.*;
|
import mindustry.type.Sector.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
@@ -31,61 +22,15 @@ import mindustry.ui.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class PlanetDialog extends BaseDialog{
|
public class PlanetDialog extends BaseDialog{
|
||||||
private static final Color
|
|
||||||
outlineColor = Pal.accent.cpy().a(1f),
|
|
||||||
hoverColor = Pal.accent.cpy().a(0.5f),
|
|
||||||
borderColor = Pal.accent.cpy().a(0.3f),
|
|
||||||
shadowColor = new Color(0, 0, 0, 0.7f);
|
|
||||||
private static final float camLength = 4f;
|
|
||||||
private static final float outlineRad = 1.16f;
|
|
||||||
private static final Array<Vec3> points = new Array<>();
|
|
||||||
|
|
||||||
//the base planet that's being rendered
|
|
||||||
private final Planet solarSystem = Planets.sun;
|
|
||||||
|
|
||||||
private final Mesh[] outlines = new Mesh[10];
|
|
||||||
private final VertexBatch3D batch = new VertexBatch3D(10000, false, true, 0);
|
|
||||||
private final PlaneBatch3D projector = new PlaneBatch3D();
|
|
||||||
private final Mat3D mat = new Mat3D();
|
|
||||||
private final Vec3 camRelative = new Vec3();
|
|
||||||
private final ResourcesDialog resources = new ResourcesDialog();
|
|
||||||
private final FrameBuffer buffer = new FrameBuffer(2, 2, true);
|
private final FrameBuffer buffer = new FrameBuffer(2, 2, true);
|
||||||
|
private final PlanetRenderer planets = renderer.planets;
|
||||||
|
|
||||||
private float zoom = 1f, smoothZoom = 1f, selectAlpha = 1f;
|
private float zoom = 1f;
|
||||||
private Bloom bloom = new Bloom(Core.graphics.getWidth()/4, Core.graphics.getHeight()/4, true, false){{
|
|
||||||
setThreshold(0.8f);
|
|
||||||
blurPasses = 6;
|
|
||||||
}};
|
|
||||||
private Planet planet = Planets.starter;
|
|
||||||
private @Nullable Sector selected, hovered;
|
|
||||||
private Table stable;
|
private Table stable;
|
||||||
private Mesh atmosphere = MeshBuilder.buildHex(Color.white, 2, false, 1.5f);
|
|
||||||
|
|
||||||
//seed: 8kmfuix03fw
|
|
||||||
private CubemapMesh skybox = new CubemapMesh(new Cubemap("cubemaps/stars/"));
|
|
||||||
|
|
||||||
public PlanetDialog(){
|
public PlanetDialog(){
|
||||||
super("", Styles.fullDialog);
|
super("", Styles.fullDialog);
|
||||||
|
|
||||||
Events.on(DisposeEvent.class, () -> {
|
|
||||||
skybox.dispose();
|
|
||||||
batch.dispose();
|
|
||||||
projector.dispose();
|
|
||||||
atmosphere.dispose();
|
|
||||||
for(Mesh m : outlines){
|
|
||||||
if(m != null){
|
|
||||||
m.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Events.on(ResizeEvent.class, e -> {
|
|
||||||
bloom.resize(Core.graphics.getWidth() / 4, Core.graphics.getHeight() / 4);
|
|
||||||
});
|
|
||||||
|
|
||||||
TextButtonStyle style = Styles.cleart;
|
|
||||||
float bmargin = 6f;
|
|
||||||
|
|
||||||
getCell(buttons).padBottom(-4);
|
getCell(buttons).padBottom(-4);
|
||||||
buttons.background(Styles.black).defaults().growX().height(64f).pad(0);
|
buttons.background(Styles.black).defaults().growX().height(64f).pad(0);
|
||||||
|
|
||||||
@@ -95,54 +40,34 @@ public class PlanetDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//TODO
|
|
||||||
//buttons.button("$back", Icon.left, style, this::hide).margin(bmargin);
|
|
||||||
//buttons.button("Research", Icon.tree, style, () -> ui.tech.show()).margin(bmargin);
|
|
||||||
//buttons.button("Database", Icon.book, style, () -> ui.database.show()).margin(bmargin);
|
|
||||||
//buttons.button("Resources", Icon.file, style, resources::show).margin(bmargin);
|
|
||||||
|
|
||||||
cam3.fov = 60f;
|
|
||||||
|
|
||||||
camRelative.set(0, 0f, camLength);
|
|
||||||
projector.setScaling(1f / 150f);
|
|
||||||
|
|
||||||
dragged((cx, cy) -> {
|
dragged((cx, cy) -> {
|
||||||
float upV = camRelative.angle(Vec3.Y);
|
Vec3 pos = planets.camPos;
|
||||||
|
|
||||||
|
float upV = pos.angle(Vec3.Y);
|
||||||
float xscale = 9f, yscale = 10f;
|
float xscale = 9f, yscale = 10f;
|
||||||
float margin = 1;
|
float margin = 1;
|
||||||
|
|
||||||
//scale X speed depending on polar coordinate
|
//scale X speed depending on polar coordinate
|
||||||
float speed = 1f - Math.abs(upV - 90) / 90f;
|
float speed = 1f - Math.abs(upV - 90) / 90f;
|
||||||
|
|
||||||
camRelative.rotate(cam3.up, cx / xscale * speed);
|
pos.rotate(planets.cam.up, cx / xscale * speed);
|
||||||
|
|
||||||
//prevent user from scrolling all the way up and glitching it out
|
//prevent user from scrolling all the way up and glitching it out
|
||||||
float amount = cy / yscale;
|
float amount = cy / yscale;
|
||||||
amount = Mathf.clamp(upV + amount, margin, 180f - margin) - upV;
|
amount = Mathf.clamp(upV + amount, margin, 180f - margin) - upV;
|
||||||
|
|
||||||
camRelative.rotate(Tmp.v31.set(cam3.up).rotate(cam3.direction, 90), amount);
|
pos.rotate(Tmp.v31.set(planets.cam.up).rotate(planets.cam.direction, 90), amount);
|
||||||
});
|
});
|
||||||
|
|
||||||
scrolled(value -> {
|
scrolled(value -> {
|
||||||
zoom = Mathf.clamp(zoom + value / 10f, 0.5f, 2f);
|
zoom = Mathf.clamp(zoom + value / 10f, 0.5f, 2f);
|
||||||
});
|
});
|
||||||
|
|
||||||
update(() -> {
|
|
||||||
if(planet.isLandable()){
|
|
||||||
hovered = planet.getSector(cam3.getMouseRay(), outlineRad);
|
|
||||||
}else{
|
|
||||||
hovered = selected = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
smoothZoom = Mathf.lerpDelta(smoothZoom, zoom, 0.4f);
|
|
||||||
selectAlpha = Mathf.lerpDelta(selectAlpha, Mathf.num(smoothZoom < 1.9f), 0.1f);
|
|
||||||
});
|
|
||||||
|
|
||||||
addListener(new ElementGestureListener(){
|
addListener(new ElementGestureListener(){
|
||||||
@Override
|
@Override
|
||||||
public void tap(InputEvent event, float x, float y, int count, KeyCode button){
|
public void tap(InputEvent event, float x, float y, int count, KeyCode button){
|
||||||
selected = hovered != null && hovered.locked() ? null : hovered;
|
planets.selected = planets.hovered != null && planets.hovered.locked() ? null : planets.hovered;
|
||||||
if(selected != null){
|
if(planets.selected != null){
|
||||||
updateSelected();
|
updateSelected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,12 +87,12 @@ public class PlanetDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void show(Sector selected, int range){
|
public void show(Sector selected, int range){
|
||||||
this.selected = null;
|
planets.selected = null;
|
||||||
this.hovered = null;
|
planets.hovered = null;
|
||||||
|
|
||||||
//update view to sector
|
//update view to sector
|
||||||
camRelative.set(Tmp.v33.set(selected.tile.v).rotate(Vec3.Y, -selected.planet.getRotation()));
|
planets.camPos.set(Tmp.v33.set(selected.tile.v).rotate(Vec3.Y, -selected.planet.getRotation()));
|
||||||
zoom = smoothZoom = 1f;
|
zoom = planets.zoom = 1f;
|
||||||
|
|
||||||
show();
|
show();
|
||||||
//TODO
|
//TODO
|
||||||
@@ -177,7 +102,7 @@ public class PlanetDialog extends BaseDialog{
|
|||||||
cont.clear();
|
cont.clear();
|
||||||
titleTable.remove();
|
titleTable.remove();
|
||||||
|
|
||||||
cont.rect((x, y, w, h) -> render()).grow();
|
cont.rect((x, y, w, h) -> planets.render()).grow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -199,249 +124,59 @@ public class PlanetDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void render(){
|
@Override
|
||||||
Draw.flush();
|
public void act(float delta){
|
||||||
Gl.clear(Gl.depthBufferBit);
|
super.act(delta);
|
||||||
Gl.enable(Gl.depthTest);
|
|
||||||
Gl.depthMask(true);
|
|
||||||
|
|
||||||
Gl.enable(Gl.cullFace);
|
if(planets.selected != null){
|
||||||
Gl.cullFace(Gl.back);
|
|
||||||
|
|
||||||
//lock to up vector so it doesn't get confusing
|
|
||||||
cam3.up.set(Vec3.Y);
|
|
||||||
|
|
||||||
cam3.resize(Core.graphics.getWidth(), Core.graphics.getHeight());
|
|
||||||
camRelative.setLength(planet.radius * camLength + (smoothZoom-1f) * planet.radius * 2);
|
|
||||||
cam3.position.set(planet.position).add(camRelative);
|
|
||||||
cam3.lookAt(planet.position);
|
|
||||||
cam3.update();
|
|
||||||
|
|
||||||
//TODO hacky
|
|
||||||
Shaders.planet.camDir.set(cam3.direction).rotate(Vec3.Y, planet.getRotation());
|
|
||||||
|
|
||||||
projector.proj(cam3.combined);
|
|
||||||
batch.proj(cam3.combined);
|
|
||||||
|
|
||||||
beginBloom();
|
|
||||||
|
|
||||||
skybox.render(cam3.combined);
|
|
||||||
|
|
||||||
renderPlanet(solarSystem);
|
|
||||||
|
|
||||||
endBloom();
|
|
||||||
|
|
||||||
Gl.enable(Gl.blend);
|
|
||||||
|
|
||||||
if(hovered != null){
|
|
||||||
Draw.batch(projector, () -> {
|
|
||||||
setPlane(hovered);
|
|
||||||
Draw.color(Color.white, Pal.accent, Mathf.absin(5f, 1f));
|
|
||||||
|
|
||||||
TextureRegion icon = hovered.locked() ? Icon.lock.getRegion() : hovered.is(SectorAttribute.naval) ? Liquids.water.icon(Cicon.large) : null;
|
|
||||||
|
|
||||||
if(icon != null){
|
|
||||||
Draw.rect(icon, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Draw.reset();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Gl.disable(Gl.cullFace);
|
|
||||||
Gl.disable(Gl.depthTest);
|
|
||||||
|
|
||||||
if(selected != null){
|
|
||||||
addChild(stable);
|
addChild(stable);
|
||||||
Vec3 pos = cam3.project(Tmp.v31.set(selected.tile.v).setLength(outlineRad).rotate(Vec3.Y, -planet.getRotation()).add(planet.position));
|
Vec3 pos = planets.cam.project(Tmp.v31.set(planets.selected.tile.v).setLength(PlanetRenderer.outlineRad).rotate(Vec3.Y, -planets.planet.getRotation()).add(planets.planet.position));
|
||||||
stable.setPosition(pos.x, pos.y, Align.center);
|
stable.setPosition(pos.x, pos.y, Align.center);
|
||||||
stable.toFront();
|
stable.toFront();
|
||||||
}else{
|
}else{
|
||||||
stable.remove();
|
stable.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
cam3.update();
|
if(planets.planet.isLandable()){
|
||||||
}
|
planets.hovered = planets.planet.getSector(planets.cam.getMouseRay(), PlanetRenderer.outlineRad);
|
||||||
|
|
||||||
private void beginBloom(){
|
|
||||||
bloom.capture();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void endBloom(){
|
|
||||||
bloom.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderPlanet(Planet planet){
|
|
||||||
//render planet at offsetted position in the world
|
|
||||||
planet.mesh.render(cam3.combined, planet.getTransform(mat));
|
|
||||||
|
|
||||||
renderOrbit(planet);
|
|
||||||
|
|
||||||
if(planet.isLandable() && planet == this.planet){
|
|
||||||
renderSectors(planet);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(planet.parent != null && planet.hasAtmosphere && Core.settings.getBool("atmosphere")){
|
|
||||||
Blending.additive.apply();
|
|
||||||
|
|
||||||
Shaders.atmosphere.camera = cam3;
|
|
||||||
Shaders.atmosphere.planet = planet;
|
|
||||||
Shaders.atmosphere.bind();
|
|
||||||
Shaders.atmosphere.apply();
|
|
||||||
|
|
||||||
atmosphere.render(Shaders.atmosphere, Gl.triangles);
|
|
||||||
|
|
||||||
Blending.normal.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Planet child : planet.children){
|
|
||||||
renderPlanet(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderOrbit(Planet planet){
|
|
||||||
if(planet.parent == null) return;
|
|
||||||
|
|
||||||
Vec3 center = planet.parent.position;
|
|
||||||
float radius = planet.orbitRadius;
|
|
||||||
int points = (int)(radius * 50);
|
|
||||||
Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray));
|
|
||||||
batch.flush(Gl.lineLoop);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderSectors(Planet planet){
|
|
||||||
//apply transformed position
|
|
||||||
batch.proj().mul(planet.getTransform(mat));
|
|
||||||
|
|
||||||
for(Sector sec : planet.sectors){
|
|
||||||
|
|
||||||
if(selectAlpha > 0.01f){
|
|
||||||
if(sec.unlocked()){
|
|
||||||
Color color =
|
|
||||||
sec.hasBase() ? Team.sharded.color :
|
|
||||||
sec.preset != null ? Team.derelict.color :
|
|
||||||
sec.hasEnemyBase() ? Team.crux.color :
|
|
||||||
null;
|
|
||||||
|
|
||||||
if(color != null){
|
|
||||||
drawSelection(sec, Tmp.c1.set(color).mul(0.8f).a(selectAlpha), 0.026f, -0.001f);
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
draw(sec, Tmp.c1.set(shadowColor).mul(1, 1, 1, selectAlpha), -0.001f);
|
planets.hovered = planets.selected = null;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hovered != null){
|
planets.zoom = Mathf.lerpDelta(planets.zoom, zoom, 0.4f);
|
||||||
draw(hovered, hoverColor, -0.001f);
|
planets.selectAlpha = Mathf.lerpDelta(planets.selectAlpha, Mathf.num(planets.zoom < 1.9f), 0.1f);
|
||||||
drawBorders(hovered, borderColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(selected != null){
|
|
||||||
drawSelection(selected);
|
|
||||||
drawBorders(selected, borderColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
batch.flush(Gl.triangles);
|
|
||||||
|
|
||||||
//render arcs
|
|
||||||
if(selected != null && selected.preset != null){
|
|
||||||
for(Objective o : selected.preset.requirements){
|
|
||||||
if(o instanceof SectorObjective){
|
|
||||||
SectorPreset preset = ((SectorObjective)o).preset;
|
|
||||||
drawArc(planet, selected.tile.v, preset.sector.tile.v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//render sector grid
|
|
||||||
Mesh mesh = outline(planet.grid.size);
|
|
||||||
Shader shader = Shaders.planetGrid;
|
|
||||||
Vec3 tile = planet.intersect(cam3.getMouseRay(), outlineRad);
|
|
||||||
Shaders.planetGrid.mouse.lerp(tile == null ? Vec3.Zero : tile.sub(planet.position).rotate(Vec3.Y, planet.getRotation()), 0.2f);
|
|
||||||
|
|
||||||
shader.bind();
|
|
||||||
shader.setUniformMatrix4("u_proj", cam3.combined.val);
|
|
||||||
shader.setUniformMatrix4("u_trans", planet.getTransform(mat).val);
|
|
||||||
shader.apply();
|
|
||||||
mesh.render(shader, Gl.lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawArc(Planet planet, Vec3 a, Vec3 b){
|
|
||||||
Vec3 avg = Tmp.v31.set(a).add(b).scl(0.5f);
|
|
||||||
avg.setLength(planet.radius*2f);
|
|
||||||
|
|
||||||
points.clear();
|
|
||||||
points.addAll(Tmp.v33.set(a).setLength(outlineRad), Tmp.v31, Tmp.v34.set(b).setLength(outlineRad));
|
|
||||||
Tmp.bz3.set(points);
|
|
||||||
float points = 25;
|
|
||||||
|
|
||||||
for(int i = 0; i < points + 1; i++){
|
|
||||||
float f = i / points;
|
|
||||||
Tmp.c1.set(Pal.accent).lerp(Color.clear, (f+Time.globalTime()/80f)%1f);
|
|
||||||
batch.color(Tmp.c1);
|
|
||||||
batch.vertex(Tmp.bz3.valueAt(Tmp.v32, f));
|
|
||||||
|
|
||||||
}
|
|
||||||
batch.flush(Gl.lineStrip);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawBorders(Sector sector, Color base){
|
|
||||||
Color color = Tmp.c1.set(base).a(base.a + 0.3f + Mathf.absin(Time.globalTime(), 5f, 0.3f));
|
|
||||||
|
|
||||||
float r1 = 1f;
|
|
||||||
float r2 = outlineRad + 0.001f;
|
|
||||||
|
|
||||||
for(int i = 0; i < sector.tile.corners.length; i++){
|
|
||||||
Corner c = sector.tile.corners[i], next = sector.tile.corners[(i+1) % sector.tile.corners.length];
|
|
||||||
|
|
||||||
Tmp.v31.set(c.v).setLength(r2);
|
|
||||||
Tmp.v32.set(next.v).setLength(r2);
|
|
||||||
Tmp.v33.set(c.v).setLength(r1);
|
|
||||||
|
|
||||||
batch.tri2(Tmp.v31, Tmp.v32, Tmp.v33, color);
|
|
||||||
|
|
||||||
Tmp.v31.set(next.v).setLength(r2);
|
|
||||||
Tmp.v32.set(next.v).setLength(r1);
|
|
||||||
Tmp.v33.set(c.v).setLength(r1);
|
|
||||||
|
|
||||||
batch.tri2(Tmp.v31, Tmp.v32, Tmp.v33, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(batch.getNumVertices() >= batch.getMaxVertices() - 6 * 6){
|
|
||||||
batch.flush(Gl.triangles);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO add strings to bundle after prototyping is done
|
||||||
private void updateSelected(){
|
private void updateSelected(){
|
||||||
|
Sector sector = planets.selected;
|
||||||
|
|
||||||
float x = stable.getX(Align.center), y = stable.getY(Align.center);
|
float x = stable.getX(Align.center), y = stable.getY(Align.center);
|
||||||
stable.clear();
|
stable.clear();
|
||||||
stable.background(Styles.black6);
|
stable.background(Styles.black6);
|
||||||
|
|
||||||
//TODO add strings to bundle after prototyping is done
|
stable.add("[accent]" + (sector.preset == null ? sector.id : sector.preset.localizedName)).row();
|
||||||
|
|
||||||
stable.add("[accent]" + (selected.preset == null ? selected.id : selected.preset.localizedName)).row();
|
|
||||||
stable.image().color(Pal.accent).fillX().height(3f).pad(3f).row();
|
stable.image().color(Pal.accent).fillX().height(3f).pad(3f).row();
|
||||||
stable.add(selected.save != null ? selected.save.getPlayTime() : "[lightgray]Unexplored").row();
|
stable.add(sector.save != null ? sector.save.getPlayTime() : "[lightgray]Unexplored").row();
|
||||||
|
|
||||||
stable.add("Resources:").row();
|
stable.add("Resources:").row();
|
||||||
stable.table(t -> {
|
stable.table(t -> {
|
||||||
t.left();
|
t.left();
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
int max = 5;
|
int max = 5;
|
||||||
for(UnlockableContent c : selected.data.resources){
|
for(UnlockableContent c : sector.data.resources){
|
||||||
t.image(c.icon(Cicon.small)).padRight(3);
|
t.image(c.icon(Cicon.small)).padRight(3);
|
||||||
if(++idx % max == 0) t.row();
|
if(++idx % max == 0) t.row();
|
||||||
}
|
}
|
||||||
}).fillX().row();
|
}).fillX().row();
|
||||||
|
|
||||||
//production
|
//production
|
||||||
if(selected.hasBase() && selected.save.meta.hasProduction){
|
if(sector.hasBase() && sector.save.meta.hasProduction){
|
||||||
stable.add("Production:").row();
|
stable.add("Production:").row();
|
||||||
stable.table(t -> {
|
stable.table(t -> {
|
||||||
t.left();
|
t.left();
|
||||||
|
|
||||||
selected.save.meta.secinfo.exportRates().each(entry -> {
|
sector.save.meta.secinfo.exportRates().each(entry -> {
|
||||||
int total = (int)(entry.value * turnDuration / 60f);
|
int total = (int)(entry.value * turnDuration / 60f);
|
||||||
if(total > 1){
|
if(total > 1){
|
||||||
t.image(entry.key.icon(Cicon.small)).padRight(3);
|
t.image(entry.key.icon(Cicon.small)).padRight(3);
|
||||||
@@ -453,7 +188,7 @@ public class PlanetDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//stored resources
|
//stored resources
|
||||||
if(selected.hasBase() && selected.save.meta.secinfo.coreItems.size > 0){
|
if(sector.hasBase() && sector.save.meta.secinfo.coreItems.size > 0){
|
||||||
stable.add("Stored:").row();
|
stable.add("Stored:").row();
|
||||||
stable.table(t -> {
|
stable.table(t -> {
|
||||||
t.left();
|
t.left();
|
||||||
@@ -461,7 +196,7 @@ public class PlanetDialog extends BaseDialog{
|
|||||||
t.table(res -> {
|
t.table(res -> {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
int amount = selected.save.meta.secinfo.coreItems.get(item);
|
int amount = sector.save.meta.secinfo.coreItems.get(item);
|
||||||
if(amount > 0){
|
if(amount > 0){
|
||||||
res.image(item.icon(Cicon.small)).padRight(3);
|
res.image(item.icon(Cicon.small)).padRight(3);
|
||||||
res.add(ui.formatAmount(amount)).color(Color.lightGray);
|
res.add(ui.formatAmount(amount)).color(Color.lightGray);
|
||||||
@@ -477,107 +212,39 @@ public class PlanetDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//display how many turns this sector has been attacked
|
//display how many turns this sector has been attacked
|
||||||
if(selected.getTurnsPassed() > 0 && selected.hasBase()){
|
if(sector.getTurnsPassed() > 0 && sector.hasBase()){
|
||||||
stable.row();
|
stable.row();
|
||||||
|
|
||||||
stable.add("[scarlet]" + Iconc.warning + " " + selected.getTurnsPassed() + "x attacks");
|
stable.add("[scarlet]" + Iconc.warning + " " + sector.getTurnsPassed() + "x attacks");
|
||||||
}
|
}
|
||||||
|
|
||||||
stable.row();
|
stable.row();
|
||||||
|
|
||||||
stable.button("Launch", Styles.transt, () -> {
|
stable.button("Launch", Styles.transt, () -> {
|
||||||
if(selected != null){
|
if(sector.is(SectorAttribute.naval)){
|
||||||
if(selected.is(SectorAttribute.naval)){
|
|
||||||
ui.showInfo("You need a naval loadout to launch here.");
|
ui.showInfo("You need a naval loadout to launch here.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
control.playSector(selected);
|
control.playSector(sector);
|
||||||
hide();
|
hide();
|
||||||
}
|
|
||||||
}).growX().padTop(2f).height(50f).minWidth(170f);
|
}).growX().padTop(2f).height(50f).minWidth(170f);
|
||||||
|
|
||||||
stable.pack();
|
stable.pack();
|
||||||
stable.setPosition(x, y, Align.center);
|
stable.setPosition(x, y, Align.center);
|
||||||
|
|
||||||
stable.update(() -> {
|
stable.update(() -> {
|
||||||
if(selected != null){
|
if(planets.selected != null){
|
||||||
//fade out UI when not facing selected sector
|
//fade out UI when not facing selected sector
|
||||||
Tmp.v31.set(selected.tile.v).rotate(Vec3.Y, -planet.getRotation()).scl(-1f).nor();
|
Tmp.v31.set(planets.selected.tile.v).rotate(Vec3.Y, -planets.planet.getRotation()).scl(-1f).nor();
|
||||||
float dot = cam3.direction.dot(Tmp.v31);
|
float dot = planets.cam.direction.dot(Tmp.v31);
|
||||||
stable.getColor().a = Math.max(dot, 0f)*2f;
|
stable.getColor().a = Math.max(dot, 0f)*2f;
|
||||||
if(dot*2f <= -0.1f){
|
if(dot*2f <= -0.1f){
|
||||||
stable.remove();
|
stable.remove();
|
||||||
selected = null;
|
planets.selected = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stable.act(0f);
|
stable.act(0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPlane(Sector sector){
|
|
||||||
float rotation = -planet.getRotation();
|
|
||||||
float length = 0.01f;
|
|
||||||
|
|
||||||
projector.setPlane(
|
|
||||||
//origin on sector position
|
|
||||||
Tmp.v33.set(sector.tile.v).setLength(outlineRad + length).rotate(Vec3.Y, rotation).add(planet.position),
|
|
||||||
//face up
|
|
||||||
sector.plane.project(Tmp.v32.set(sector.tile.v).add(Vec3.Y)).sub(sector.tile.v).rotate(Vec3.Y, rotation).nor(),
|
|
||||||
//right vector
|
|
||||||
Tmp.v31.set(Tmp.v32).rotate(Vec3.Y, -rotation).add(sector.tile.v).rotate(sector.tile.v, 90).sub(sector.tile.v).rotate(Vec3.Y, rotation).nor()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void draw(Sector sector, Color color, float offset){
|
|
||||||
float rr = outlineRad + offset;
|
|
||||||
for(int i = 0; i < sector.tile.corners.length; i++){
|
|
||||||
Corner c = sector.tile.corners[i], next = sector.tile.corners[(i+1) % sector.tile.corners.length];
|
|
||||||
batch.tri(Tmp.v31.set(c.v).setLength(rr), Tmp.v32.set(next.v).setLength(rr), Tmp.v33.set(sector.tile.v).setLength(rr), color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawSelection(Sector sector){
|
|
||||||
drawSelection(sector, Pal.accent, 0.04f, 0.001f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawSelection(Sector sector, Color color, float stroke, float length){
|
|
||||||
float arad = outlineRad + length;
|
|
||||||
|
|
||||||
for(int i = 0; i < sector.tile.corners.length; i++){
|
|
||||||
Corner next = sector.tile.corners[(i + 1) % sector.tile.corners.length];
|
|
||||||
Corner curr = sector.tile.corners[i];
|
|
||||||
|
|
||||||
next.v.scl(arad);
|
|
||||||
curr.v.scl(arad);
|
|
||||||
sector.tile.v.scl(arad);
|
|
||||||
|
|
||||||
Tmp.v31.set(curr.v).sub(sector.tile.v).setLength(curr.v.dst(sector.tile.v) - stroke).add(sector.tile.v);
|
|
||||||
Tmp.v32.set(next.v).sub(sector.tile.v).setLength(next.v.dst(sector.tile.v) - stroke).add(sector.tile.v);
|
|
||||||
|
|
||||||
batch.tri(curr.v, next.v, Tmp.v31, color);
|
|
||||||
batch.tri(Tmp.v31, next.v, Tmp.v32, color);
|
|
||||||
|
|
||||||
sector.tile.v.scl(1f / arad);
|
|
||||||
next.v.scl(1f / arad);
|
|
||||||
curr.v.scl(1f /arad);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Mesh outline(int size){
|
|
||||||
if(outlines[size] == null){
|
|
||||||
outlines[size] = MeshBuilder.buildHex(new HexMesher(){
|
|
||||||
@Override
|
|
||||||
public float getHeight(Vec3 position){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Color getColor(Vec3 position){
|
|
||||||
return outlineColor;
|
|
||||||
}
|
|
||||||
}, size, true, outlineRad, 0.2f);
|
|
||||||
}
|
|
||||||
return outlines[size];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user