Universe time + Progress on solar system framework

This commit is contained in:
Anuken 2020-02-28 20:21:00 -05:00
commit f0857fa22d
10 changed files with 184 additions and 17 deletions

View File

@ -165,6 +165,7 @@ public class Vars implements Loadable{
public static Schematics schematics = new Schematics();
public static BeControl becontrol;
public static Universe universe;
public static World world;
public static Maps maps;
public static WaveSpawner spawner;
@ -217,6 +218,7 @@ public class Vars implements Loadable{
defaultWaves = new DefaultWaves();
collisions = new EntityCollisions();
world = new World();
universe = new Universe();
becontrol = new BeControl();
maps = new Maps();

View File

@ -5,12 +5,18 @@ import mindustry.maps.planet.*;
import mindustry.type.*;
public class Planets implements ContentList{
//TODO make all names
public static Planet starter;
public static Planet
sun,
starter;
@Override
public void load(){
starter = new Planet("TODO", 3){{
sun = new Planet("sun", null, 3, 1){{
detail = 6;
generator = new TestPlanetGenerator();
}};
starter = new Planet("TODO", sun, 3, 1){{
detail = 6;
generator = new TestPlanetGenerator();
}};

View File

@ -267,4 +267,8 @@ public class ContentLoader{
public Array<UnitType> units(){
return getBy(ContentType.unit);
}
public Array<Planet> planets(){
return getBy(ContentType.planet);
}
}

View File

@ -270,6 +270,8 @@ public class Control implements ApplicationListener, Loadable{
logic.reset();
world.loadSector(sector);
state.rules.sector = sector;
//TODO enable for lighting
//state.rules.lighting = true;
logic.play();
control.saves.saveSector(sector);
//TODO uncomment for efffect

View File

@ -211,6 +211,7 @@ public class Logic implements ApplicationListener{
}
if(!state.isPaused()){
universe.update();
Time.update();
if(state.rules.waves && state.rules.waveTimer && !state.gameOver){

View File

@ -0,0 +1,48 @@
package mindustry.game;
import arc.*;
import arc.util.*;
public class Universe{
private long seconds;
private float secondCounter;
public Universe(){
load();
}
public void update(){
secondCounter += Time.delta() / 60f;
if(secondCounter >= 1){
seconds += (int)secondCounter;
secondCounter %= 1f;
//save every few seconds
if(seconds % 10 == 1){
save();
}
}
}
public float secondsMod(float mod, float scale){
return (seconds / scale) % mod;
}
public long seconds(){
return seconds;
}
public float secondsf(){
return seconds + secondCounter;
}
private void save(){
Core.settings.put("utime", seconds);
Core.settings.save();
}
private void load(){
seconds = Core.settings.getLong("utime");
}
}

View File

@ -201,4 +201,4 @@ public class LightRenderer{
lights.clear();
}
}
}

View File

@ -1,6 +1,7 @@
package mindustry.type;
import arc.files.*;
import arc.math.*;
import arc.math.geom.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
@ -14,9 +15,13 @@ import mindustry.graphics.g3d.PlanetGrid.*;
import mindustry.maps.generators.*;
import mindustry.type.Sector.*;
import static mindustry.Vars.universe;
public class Planet extends UnlockableContent{
/** Default spacing between planet orbits in world units. */
private static final float orbitSpacing = 6f;
/** Mesh used for rendering. Created on load() - will be null on the server! */
public PlanetMesh mesh;
public GenericMesh mesh;
/** Grid used for the sectors on the planet. */
public @NonNull PlanetGrid grid;
/** Generator that will make the planet. */
@ -25,15 +30,28 @@ public class Planet extends UnlockableContent{
public @NonNull Array<Sector> sectors;
/** Detail in divisions. Must be between 1 and 10. 6 is a good number for this.*/
public int detail = 3;
/** Size in terms of divisions. This only controls the amount of sectors on the planet, not the visuals. */
public int size;
/** Radius of the mesh/sphere. */
public float radius = 1f;
/** Radius of this planet's sphere. Does not take into account sattelites. */
public float radius;
/** Orbital radius around the sun. Do not change unless you know exactly what you are doing.*/
public float orbitRadius;
/** Total radius of this planet and all its children. */
public float totalRadius;
/** Time for the planet to orbit around the sun once, in seconds. One year. */
public float orbitTime;
/** Time for the planet to perform a full revolution, in seconds. One day. */
public float rotateTime = 24f * 60f;
/** Whether this planet is tidally locked relative to its parent - see https://en.wikipedia.org/wiki/Tidal_locking */
public boolean tidalLock = false;
/** Parent body that this planet orbits around. If null, this planet is considered to be in the middle of the solar system.*/
public @Nullable Planet parent;
/** All planets orbiting this one, in ascending order of radius. */
public Array<Planet> children = new Array<>();
public Planet(String name, int size){
public Planet(String name, Planet parent, int size, float radius){
super(name);
this.size = 3;
this.radius = radius;
this.parent = parent;
grid = PlanetGrid.create(size);
@ -42,6 +60,18 @@ public class Planet extends UnlockableContent{
sectors.add(new Sector(this, grid.tiles[i], new SectorData()));
}
//get orbit radius by extending past the parent's total radius
orbitRadius = parent == null ? 0f : (parent.totalRadius + orbitSpacing + radius);
//orbit time is based on radius [kepler's third law]
orbitTime = Mathf.pow(orbitRadius, 1.5f) * 1000;
//add this planet to list of children and update parent's radius
if(parent != null){
parent.children.add(this);
parent.updateTotalRadius();
}
//read data
Fi data = Vars.tree.get("planets/" + name + ".dat");
if(data.exists()){
@ -57,6 +87,52 @@ public class Planet extends UnlockableContent{
}
}
public void updateTotalRadius(){
totalRadius = radius;
for(Planet planet : children){
//max with highest outer bound planet
totalRadius = Math.max(totalRadius, planet.orbitRadius + planet.totalRadius);
}
}
/** Calculates orbital rotation based on universe time.*/
public float getOrbitAngle(){
//applies random offset to prevent planets from starting out in a line
float offset = Mathf.randomSeed(id, 360);
return (offset + universe.seconds() / (orbitTime / 360f)) % 360f;
}
/** Calulates rotation on own axis based on universe time.*/
public float getRotation(){
//tidally locked planets always face toward parents
if(tidalLock){
return getOrbitAngle();
}
//random offset for more variability
float offset = Mathf.randomSeed(id+1, 360);
return (offset + universe.seconds() / (rotateTime / 360f)) % 360f;
}
/** Adds this planet's offset relative to its parent to the vector. Used for calculating world positions. */
public Vec3 addParentOffset(Vec3 in){
//planets with no parents are at the center, so they appear at 0,0
if(parent == null || Mathf.zero(orbitRadius)){
return in;
}
float angle = getOrbitAngle();
return in.add(Angles.trnsx(angle, orbitRadius), Angles.trnsy(angle, orbitRadius), 0f);
}
/** Gets the absolute world position of this planet, taking into account all parents. O(n) complexity.*/
public Vec3 getWorldPosition(Vec3 in){
in.setZero();
for(Planet current = this; current != null; current = current.parent){
current.addParentOffset(in);
}
return in;
}
@Override
public void load(){
mesh = new PlanetMesh(detail, generator);

View File

@ -31,10 +31,15 @@ public class PlanetDialog extends FloatingDialog{
private static final float camLength = 4f;
float outlineRad = 1.15f;
//the base planet that's being rendered
private final Planet solarSystem = Planets.sun;
private final PlanetMesh[] outlines = new PlanetMesh[10];
private final Camera3D cam = new Camera3D();
private final VertexBatch3D batch = new VertexBatch3D(false, true, 0);
private final PlaneBatch3D projector = new PlaneBatch3D();
private final Mat3D mat = new Mat3D();
private final SphereMesh sun = new SphereMesh(3, 1.2f);
private final Bloom bloom = new Bloom(false){{
@ -57,7 +62,7 @@ public class PlanetDialog extends FloatingDialog{
projector.setScaling(1f / 300f);
update(() -> {
Ptile tile = outline(planet.size).getTile(cam.getPickRay(Core.input.mouseX(), Core.input.mouseY()));
Ptile tile = outline(planet.grid.size).getTile(cam.getPickRay(Core.input.mouseX(), Core.input.mouseY()));
hovered = tile == null ? null : planet.getSector(tile);
Vec3 v = Tmp.v33.set(Core.input.mouseX(), Core.input.mouseY(), 0);
@ -150,9 +155,10 @@ public class PlanetDialog extends FloatingDialog{
projector.proj(cam.combined());
batch.proj(cam.combined());
renderSun();
renderPlanet();
renderPlanet(solarSystem);
//renderSun();
//renderPlanet();
for(Sector sec : planet.sectors){
if(sec.save == null){
@ -198,11 +204,33 @@ public class PlanetDialog extends FloatingDialog{
}
}
private void renderPlanet(Planet planet){
//render planet at offsetted position in the world
Vec3 position = planet.getWorldPosition(Tmp.v33);
mat.set(cam.combined()).trn(position); //TODO this probably won't give the desired result
planet.mesh.render(mat);
renderOrbit(planet);
for(Planet child : planet.children){
renderPlanet(child);
}
}
private void renderOrbit(Planet planet){
if(planet.parent == null) return;
Vec3 center = planet.parent.getWorldPosition(Tmp.v31);
float radius = planet.radius;
int points = (int)(radius * 10);
Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray));
batch.flush(Gl.lineLoop);
}
private void renderPlanet(){
PlanetMesh outline = outline(planet.size);
PlanetMesh outline = outline(planet.grid.size);
Vec3 tile = outline.intersect(cam.getPickRay(Core.input.mouseX(), Core.input.mouseY()));
Shaders.planetGrid.mouse.lerp(tile == null ? Vec3.Zero : tile, 0.2f);
Shaders.planet.lightDir.set(Shaders.sun.center).nor();
planet.mesh.render(cam.combined());

View File

@ -1,3 +1,3 @@
org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=7b20f312c317d571738e8f2e53501ae00d48f0d0
archash=bff072e2d671c74a32b41353125c2aa6ba8c0314