Made Gravity Models configurable with packets
This commit is contained in:
parent
f4311fb27c
commit
f28c765e3f
@ -17,6 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
package ru.windcorp.progressia.common.world;
|
package ru.windcorp.progressia.common.world;
|
||||||
|
|
||||||
|
import java.io.DataInput;
|
||||||
|
import java.io.DataOutput;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
@ -165,5 +168,63 @@ public abstract class GravityModel extends Namespaced {
|
|||||||
* specified chunk. Never {@code null}.
|
* specified chunk. Never {@code null}.
|
||||||
*/
|
*/
|
||||||
protected abstract AbsFace doGetDiscreteUp(Vec3i chunkPos);
|
protected abstract AbsFace doGetDiscreteUp(Vec3i chunkPos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the settings from the provided {@link DataInput} and configures this object appropriately. This method will not necessarily exhaust the input.
|
||||||
|
* @param input a stream to read the settings from
|
||||||
|
* @throws IOException if an I/O error occurs
|
||||||
|
* @throws DecodingException if the settings could not be parsed from input
|
||||||
|
*/
|
||||||
|
public void readSettings(DataInput input) throws IOException, DecodingException {
|
||||||
|
Objects.requireNonNull(input, "input");
|
||||||
|
|
||||||
|
try {
|
||||||
|
doReadSettings(input);
|
||||||
|
} catch (IOException | DecodingException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw CrashReports.report(
|
||||||
|
e,
|
||||||
|
"%s failed to read its settings",
|
||||||
|
this
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the settings of this model into the provided {@link DataOutput}.
|
||||||
|
* @param output a stream to write the settings into
|
||||||
|
* @throws IOException if an I/O error occurs
|
||||||
|
*/
|
||||||
|
public void writeSettings(DataOutput output) throws IOException {
|
||||||
|
Objects.requireNonNull(output, "output");
|
||||||
|
|
||||||
|
try {
|
||||||
|
doWriteSettings(output);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw CrashReports.report(
|
||||||
|
e,
|
||||||
|
"%s failed to write its settings",
|
||||||
|
this
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the settings from the provided {@link DataInput} and configures this object appropriately. This method will not necessarily exhaust the input.
|
||||||
|
* @param input a stream to read the settings from
|
||||||
|
* @throws IOException if an I/O error occurs
|
||||||
|
* @throws DecodingException if the settings could not be parsed from input
|
||||||
|
*/
|
||||||
|
protected abstract void doReadSettings(DataInput input) throws IOException, DecodingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the settings of this model into the provided {@link DataOutput}.
|
||||||
|
* @param output a stream to write the settings into
|
||||||
|
* @throws IOException if an I/O error occurs
|
||||||
|
*/
|
||||||
|
protected abstract void doWriteSettings(DataOutput output) throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
package ru.windcorp.progressia.common.world;
|
package ru.windcorp.progressia.common.world;
|
||||||
|
|
||||||
import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry;
|
import ru.windcorp.progressia.common.util.namespaces.NamespacedFactoryRegistry;
|
||||||
|
|
||||||
public class GravityModelRegistry extends NamespacedInstanceRegistry<GravityModel> {
|
public class GravityModelRegistry extends NamespacedFactoryRegistry<GravityModel> {
|
||||||
|
|
||||||
public static final GravityModelRegistry INSTANCE = new GravityModelRegistry();
|
public static final GravityModelRegistry INSTANCE = new GravityModelRegistry();
|
||||||
|
|
||||||
|
@ -21,9 +21,13 @@ import java.io.DataInput;
|
|||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.util.DataBuffer;
|
||||||
|
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||||
|
|
||||||
public class PacketSetGravityModel extends PacketAffectWorld {
|
public class PacketSetGravityModel extends PacketAffectWorld {
|
||||||
|
|
||||||
private String gravityModelId;
|
private String gravityModelId;
|
||||||
|
private final DataBuffer settings = new DataBuffer();
|
||||||
|
|
||||||
public PacketSetGravityModel() {
|
public PacketSetGravityModel() {
|
||||||
this("Core:SetGravityModel");
|
this("Core:SetGravityModel");
|
||||||
@ -35,22 +39,38 @@ public class PacketSetGravityModel extends PacketAffectWorld {
|
|||||||
|
|
||||||
public void set(GravityModel model) {
|
public void set(GravityModel model) {
|
||||||
this.gravityModelId = model.getId();
|
this.gravityModelId = model.getId();
|
||||||
|
|
||||||
|
try {
|
||||||
|
model.writeSettings(settings.getWriter());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw CrashReports.report(e, "%s has errored when writing its settings", model);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(DataInput input) throws IOException, DecodingException {
|
public void read(DataInput input) throws IOException, DecodingException {
|
||||||
gravityModelId = input.readUTF();
|
gravityModelId = input.readUTF();
|
||||||
|
settings.fill(input, input.readInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutput output) throws IOException {
|
public void write(DataOutput output) throws IOException {
|
||||||
output.writeUTF(gravityModelId);
|
output.writeUTF(gravityModelId);
|
||||||
|
output.writeInt(settings.getSize());
|
||||||
|
settings.flush(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(WorldData world) {
|
public void apply(WorldData world) {
|
||||||
GravityModel model = GravityModelRegistry.getInstance().get(gravityModelId);
|
GravityModel model = GravityModelRegistry.getInstance().create(gravityModelId);
|
||||||
world.setGravityModel(model);
|
world.setGravityModel(model);
|
||||||
|
try {
|
||||||
|
model.readSettings(settings.getReader());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw CrashReports.report(e, "%s has errored when reading its settings", model);
|
||||||
|
} catch (DecodingException e) {
|
||||||
|
throw CrashReports.report(e, "%s has failed to parse its settings", model);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ public class Server {
|
|||||||
private final TickingSettings tickingSettings = new TickingSettings();
|
private final TickingSettings tickingSettings = new TickingSettings();
|
||||||
|
|
||||||
public Server(WorldData world) {
|
public Server(WorldData world) {
|
||||||
this.world = new WorldLogic(world, this, w -> new TestPlanetGenerator("Test:PlanetGenerator", new Planet(4, 16f, 9.8f, 16f), w));
|
this.world = new WorldLogic(world, this, w -> new TestPlanetGenerator("Test:PlanetGenerator", new Planet(4, 9.8f, 16f, 16f), w));
|
||||||
this.serverThread = new ServerThread(this);
|
this.serverThread = new ServerThread(this);
|
||||||
|
|
||||||
this.clientManager = new ClientManager(this);
|
this.clientManager = new ClientManager(this);
|
||||||
|
@ -37,7 +37,7 @@ public abstract class AbstractWorldGenerator<H> extends WorldGenerator {
|
|||||||
public AbstractWorldGenerator(String id, Class<H> hintClass, String gravityModelId) {
|
public AbstractWorldGenerator(String id, Class<H> hintClass, String gravityModelId) {
|
||||||
super(id);
|
super(id);
|
||||||
this.hintClass = Objects.requireNonNull(hintClass, "hintClass");
|
this.hintClass = Objects.requireNonNull(hintClass, "hintClass");
|
||||||
this.gravityModel = GravityModelRegistry.getInstance().get(Objects.requireNonNull(gravityModelId, "gravityModelId"));
|
this.gravityModel = GravityModelRegistry.getInstance().create(Objects.requireNonNull(gravityModelId, "gravityModelId"));
|
||||||
|
|
||||||
if (this.gravityModel == null) {
|
if (this.gravityModel == null) {
|
||||||
throw new IllegalArgumentException("Gravity model with ID \"" + gravityModelId + "\" not found");
|
throw new IllegalArgumentException("Gravity model with ID \"" + gravityModelId + "\" not found");
|
||||||
|
@ -422,8 +422,8 @@ public class TestContent {
|
|||||||
private static void registerMisc() {
|
private static void registerMisc() {
|
||||||
ChunkIO.registerCodec(new TestChunkCodec());
|
ChunkIO.registerCodec(new TestChunkCodec());
|
||||||
ChunkRenderOptimizerRegistry.getInstance().register("Core:SurfaceOptimizer", ChunkRenderOptimizerSurface::new);
|
ChunkRenderOptimizerRegistry.getInstance().register("Core:SurfaceOptimizer", ChunkRenderOptimizerSurface::new);
|
||||||
GravityModelRegistry.getInstance().register(new TestGravityModel());
|
GravityModelRegistry.getInstance().register("Test:TheGravityModel", TestGravityModel::new);
|
||||||
GravityModelRegistry.getInstance().register(new TestPlanetGravityModel());
|
GravityModelRegistry.getInstance().register("Test:PlanetGravityModel", TestPlanetGravityModel::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,15 +17,20 @@
|
|||||||
*/
|
*/
|
||||||
package ru.windcorp.progressia.test.gen;
|
package ru.windcorp.progressia.test.gen;
|
||||||
|
|
||||||
|
import java.io.DataInput;
|
||||||
|
import java.io.DataOutput;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
import glm.vec._3.i.Vec3i;
|
import glm.vec._3.i.Vec3i;
|
||||||
|
import ru.windcorp.progressia.common.world.DecodingException;
|
||||||
import ru.windcorp.progressia.common.world.GravityModel;
|
import ru.windcorp.progressia.common.world.GravityModel;
|
||||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||||
|
|
||||||
public class TestGravityModel extends GravityModel {
|
public class TestGravityModel extends GravityModel {
|
||||||
|
|
||||||
public TestGravityModel() {
|
public TestGravityModel(String id) {
|
||||||
super("Test:TheGravityModel");
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -39,4 +44,14 @@ public class TestGravityModel extends GravityModel {
|
|||||||
return rounded == null ? AbsFace.POS_Z : rounded;
|
return rounded == null ? AbsFace.POS_Z : rounded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doReadSettings(DataInput input) throws IOException, DecodingException {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doWriteSettings(DataOutput output) throws IOException {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,20 +23,20 @@ public class Planet {
|
|||||||
|
|
||||||
private final int radiusInChunks;
|
private final int radiusInChunks;
|
||||||
|
|
||||||
private final float curvature;
|
private final TestPlanetGravityModel.Settings gravityModelSettings;
|
||||||
private final float surfaceGravitationalAcceleration;
|
|
||||||
private final float innerGravityRadius;
|
|
||||||
|
|
||||||
public Planet(
|
public Planet(
|
||||||
int radiusInChunks,
|
int radiusInChunks,
|
||||||
float curvature,
|
|
||||||
float surfaceGravitationalAcceleration,
|
float surfaceGravitationalAcceleration,
|
||||||
|
float curvature,
|
||||||
float innerGravityRadius
|
float innerGravityRadius
|
||||||
) {
|
) {
|
||||||
this.radiusInChunks = radiusInChunks;
|
this.radiusInChunks = radiusInChunks;
|
||||||
this.curvature = curvature;
|
this.gravityModelSettings = new TestPlanetGravityModel.Settings(
|
||||||
this.surfaceGravitationalAcceleration = surfaceGravitationalAcceleration;
|
surfaceGravitationalAcceleration,
|
||||||
this.innerGravityRadius = innerGravityRadius;
|
curvature,
|
||||||
|
innerGravityRadius
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,21 +62,28 @@ public class Planet {
|
|||||||
* @return the curvature
|
* @return the curvature
|
||||||
*/
|
*/
|
||||||
public float getCurvature() {
|
public float getCurvature() {
|
||||||
return curvature;
|
return gravityModelSettings.curvature;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the innerGravityRadius
|
* @return the innerGravityRadius
|
||||||
*/
|
*/
|
||||||
public float getInnerGravityRadius() {
|
public float getInnerGravityRadius() {
|
||||||
return innerGravityRadius;
|
return gravityModelSettings.innerRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the surfaceGravitationalAcceleration
|
* @return the surfaceGravitationalAcceleration
|
||||||
*/
|
*/
|
||||||
public float getSurfaceGravitationalAcceleration() {
|
public float getSurfaceGravitationalAcceleration() {
|
||||||
return surfaceGravitationalAcceleration;
|
return gravityModelSettings.surfaceGravitationalAcceleration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the gravityModelSettings
|
||||||
|
*/
|
||||||
|
public TestPlanetGravityModel.Settings getGravityModelSettings() {
|
||||||
|
return gravityModelSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,12 @@ public class TestPlanetGenerator extends AbstractWorldGenerator<Boolean> {
|
|||||||
|
|
||||||
public TestPlanetGenerator(String id, Planet planet, WorldLogic world) {
|
public TestPlanetGenerator(String id, Planet planet, WorldLogic world) {
|
||||||
super(id, Boolean.class, "Test:PlanetGravityModel");
|
super(id, Boolean.class, "Test:PlanetGravityModel");
|
||||||
|
|
||||||
this.planet = planet;
|
this.planet = planet;
|
||||||
|
|
||||||
|
TestPlanetGravityModel model = (TestPlanetGravityModel) this.getGravityModel();
|
||||||
|
model.configure(planet.getGravityModelSettings());
|
||||||
|
|
||||||
this.terrainGenerator = new PlanetTerrainGenerator(this);
|
this.terrainGenerator = new PlanetTerrainGenerator(this);
|
||||||
this.scatterGenerator = new PlanetScatterGenerator(this);
|
this.scatterGenerator = new PlanetScatterGenerator(this);
|
||||||
}
|
}
|
||||||
|
@ -19,36 +19,86 @@ package ru.windcorp.progressia.test.gen.planet;
|
|||||||
|
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
import glm.vec._3.i.Vec3i;
|
import glm.vec._3.i.Vec3i;
|
||||||
import ru.windcorp.progressia.common.Units;
|
|
||||||
import ru.windcorp.progressia.common.world.ChunkData;
|
import ru.windcorp.progressia.common.world.ChunkData;
|
||||||
|
import ru.windcorp.progressia.common.world.DecodingException;
|
||||||
import ru.windcorp.progressia.common.world.GravityModel;
|
import ru.windcorp.progressia.common.world.GravityModel;
|
||||||
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||||
|
|
||||||
import static java.lang.Math.*;
|
import static java.lang.Math.*;
|
||||||
|
|
||||||
|
import java.io.DataInput;
|
||||||
|
import java.io.DataOutput;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class TestPlanetGravityModel extends GravityModel {
|
public class TestPlanetGravityModel extends GravityModel {
|
||||||
|
|
||||||
private static final float GRAVITATIONAL_ACCELERATION = Units.get("9.8 m/s^2");
|
public static class Settings {
|
||||||
private static final float ROUNDNESS = Units.get("16 m");
|
public float surfaceGravitationalAcceleration;
|
||||||
private static final float INNER_RADIUS = Units.get("16 m");
|
public float curvature;
|
||||||
|
public float innerRadius;
|
||||||
|
|
||||||
|
public Settings() {}
|
||||||
|
|
||||||
|
public Settings(float surfaceGravitationalAcceleration, float curvature, float innerRadius) {
|
||||||
|
this.surfaceGravitationalAcceleration = surfaceGravitationalAcceleration;
|
||||||
|
this.curvature = curvature;
|
||||||
|
this.innerRadius = innerRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyFrom(Settings copyFrom) {
|
||||||
|
this.surfaceGravitationalAcceleration = copyFrom.surfaceGravitationalAcceleration;
|
||||||
|
this.curvature = copyFrom.curvature;
|
||||||
|
this.innerRadius = copyFrom.innerRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void read(DataInput input) throws IOException, DecodingException {
|
||||||
|
surfaceGravitationalAcceleration = input.readFloat();
|
||||||
|
curvature = input.readFloat();
|
||||||
|
innerRadius = input.readFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(DataOutput output) throws IOException {
|
||||||
|
output.writeFloat(surfaceGravitationalAcceleration);
|
||||||
|
output.writeFloat(curvature);
|
||||||
|
output.writeFloat(innerRadius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public TestPlanetGravityModel() {
|
private Settings settings = new Settings();
|
||||||
this("Test:PlanetGravityModel");
|
|
||||||
|
public TestPlanetGravityModel(String id) {
|
||||||
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TestPlanetGravityModel(String id) {
|
public float getSurfaceGravitationalAcceleration() {
|
||||||
super(id);
|
return settings.surfaceGravitationalAcceleration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getCurvature() {
|
||||||
|
return settings.curvature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getInnerRadius() {
|
||||||
|
return settings.innerRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configure(Settings settings) {
|
||||||
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGetGravity(Vec3 pos, Vec3 output) {
|
protected void doGetGravity(Vec3 pos, Vec3 output) {
|
||||||
|
float r = getInnerRadius();
|
||||||
|
float c = getCurvature();
|
||||||
|
float g = getSurfaceGravitationalAcceleration();
|
||||||
|
|
||||||
// Change to a CS where (0;0;0) is the center of the center chunk
|
// Change to a CS where (0;0;0) is the center of the center chunk
|
||||||
float px = pos.x - ChunkData.CHUNK_RADIUS + 0.5f;
|
float px = pos.x - ChunkData.CHUNK_RADIUS + 0.5f;
|
||||||
float py = pos.y - ChunkData.CHUNK_RADIUS + 0.5f;
|
float py = pos.y - ChunkData.CHUNK_RADIUS + 0.5f;
|
||||||
float pz = pos.z - ChunkData.CHUNK_RADIUS + 0.5f;
|
float pz = pos.z - ChunkData.CHUNK_RADIUS + 0.5f;
|
||||||
|
|
||||||
// Assume weightlessness when too close to center
|
// Assume weightlessness when too close to center
|
||||||
if ((px*px + py*py + pz*pz) < INNER_RADIUS*INNER_RADIUS) {
|
if ((px*px + py*py + pz*pz) < r*r) {
|
||||||
output.set(0, 0, 0);
|
output.set(0, 0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -81,24 +131,26 @@ public class TestPlanetGravityModel extends GravityModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
output.x = maxAbs - ax < ROUNDNESS ? (px > 0 ? +1 : -1) : 0;
|
output.x = maxAbs - ax < c ? (px > 0 ? +1 : -1) : 0;
|
||||||
output.y = maxAbs - ay < ROUNDNESS ? (py > 0 ? +1 : -1) : 0;
|
output.y = maxAbs - ay < c ? (py > 0 ? +1 : -1) : 0;
|
||||||
output.z = maxAbs - az < ROUNDNESS ? (pz > 0 ? +1 : -1) : 0;
|
output.z = maxAbs - az < c ? (pz > 0 ? +1 : -1) : 0;
|
||||||
|
|
||||||
if (maxAbs - midAbs < ROUNDNESS) {
|
if (maxAbs - midAbs < c) {
|
||||||
output.normalize();
|
output.normalize();
|
||||||
computeEdgeGravity(output.x, output.y, output.z, px, py, pz, output);
|
computeEdgeGravity(output.x, output.y, output.z, px, py, pz, output);
|
||||||
} else {
|
} else {
|
||||||
assert output.dot(output) == 1 : "maxAbs - midAbs = " + maxAbs + " - " + midAbs + " > " + ROUNDNESS + " yet l*l != 1";
|
assert output.dot(output) == 1 : "maxAbs - midAbs = " + maxAbs + " - " + midAbs + " > " + c + " yet l*l != 1";
|
||||||
}
|
}
|
||||||
|
|
||||||
output.mul(-GRAVITATIONAL_ACCELERATION);
|
output.mul(-g);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeEdgeGravity(float lx, float ly, float lz, float rx, float ry, float rz, Vec3 output) {
|
private void computeEdgeGravity(float lx, float ly, float lz, float rx, float ry, float rz, Vec3 output) {
|
||||||
// da math is gud, no worry
|
// da math is gud, no worry
|
||||||
// - Javapony
|
// - Javapony
|
||||||
|
|
||||||
|
float r = getInnerRadius();
|
||||||
|
|
||||||
if (lx == 0) rx = 0;
|
if (lx == 0) rx = 0;
|
||||||
if (ly == 0) ry = 0;
|
if (ly == 0) ry = 0;
|
||||||
if (lz == 0) rz = 0;
|
if (lz == 0) rz = 0;
|
||||||
@ -107,10 +159,10 @@ public class TestPlanetGravityModel extends GravityModel {
|
|||||||
float rSquared = rx*rx + ry*ry + rz*rz;
|
float rSquared = rx*rx + ry*ry + rz*rz;
|
||||||
|
|
||||||
float distanceAlongEdge = scalarProduct - (float) sqrt(
|
float distanceAlongEdge = scalarProduct - (float) sqrt(
|
||||||
scalarProduct*scalarProduct - rSquared + ROUNDNESS*ROUNDNESS
|
scalarProduct*scalarProduct - rSquared + r*r
|
||||||
);
|
);
|
||||||
|
|
||||||
output.set(lx, ly, lz).mul(-distanceAlongEdge).add(rx, ry, rz).div(ROUNDNESS);
|
output.set(lx, ly, lz).mul(-distanceAlongEdge).add(rx, ry, rz).div(r);
|
||||||
|
|
||||||
final float f = (float) sqrt(3.0/2);
|
final float f = (float) sqrt(3.0/2);
|
||||||
|
|
||||||
@ -128,5 +180,15 @@ public class TestPlanetGravityModel extends GravityModel {
|
|||||||
AbsFace rounded = AbsFace.roundToFace(chunkPos.x, chunkPos.y, chunkPos.z);
|
AbsFace rounded = AbsFace.roundToFace(chunkPos.x, chunkPos.y, chunkPos.z);
|
||||||
return rounded == null ? AbsFace.POS_Z : rounded;
|
return rounded == null ? AbsFace.POS_Z : rounded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doReadSettings(DataInput input) throws IOException, DecodingException {
|
||||||
|
this.settings.read(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doWriteSettings(DataOutput output) throws IOException {
|
||||||
|
this.settings.write(output);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Progressia
|
||||||
|
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package ru.windcorp.progressia.test.gen.surface;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
|
||||||
|
import ru.windcorp.progressia.common.world.rels.AbsFace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A scalar field defined on a plane. For each pair of {@code float}s (north; west) a single {@code float} is defined by this object.
|
||||||
|
*/
|
||||||
|
public abstract class SurfaceCachingFloatField extends Namespaced implements SurfaceFloatField {
|
||||||
|
|
||||||
|
private final int levels;
|
||||||
|
|
||||||
|
private SurfaceFieldRegistry registry = null;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public SurfaceCachingFloatField(String id, int levels) {
|
||||||
|
super(id);
|
||||||
|
this.levels = levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getIndex() {
|
||||||
|
if (getRegistry() == null) {
|
||||||
|
throw new IllegalStateException("No registry assigned to field " + this);
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIndex(int index) {
|
||||||
|
if (getRegistry() == null) {
|
||||||
|
throw new IllegalStateException("No registry assigned to field " + this);
|
||||||
|
}
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
SurfaceFieldRegistry getRegistry() {
|
||||||
|
return registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRegistry(SurfaceFieldRegistry registry) {
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevels() {
|
||||||
|
return levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract float computeDetailAt(AbsFace surface, int level, float north, float west);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float get(AbsFace surface, float north, float west) {
|
||||||
|
float result = 0;
|
||||||
|
|
||||||
|
for (int level = 0; level < getLevels(); ++level) {
|
||||||
|
result += computeDetailAt(surface, level, north, west);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Progressia
|
||||||
|
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package ru.windcorp.progressia.test.gen.surface;
|
||||||
|
|
||||||
|
public class SurfaceFieldRegistry {
|
||||||
|
|
||||||
|
private int nextIndex = 0;
|
||||||
|
|
||||||
|
public void register(SurfaceCachingFloatField field) {
|
||||||
|
field.setIndex(nextIndex);
|
||||||
|
nextIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Progressia
|
||||||
|
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package ru.windcorp.progressia.test.gen.surface;
|
||||||
|
|
||||||
|
import java.io.DataInput;
|
||||||
|
import java.io.DataOutput;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import gnu.trove.map.TLongObjectMap;
|
||||||
|
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||||
|
import ru.windcorp.progressia.common.util.CoordinatePacker;
|
||||||
|
import ru.windcorp.progressia.common.world.DecodingException;
|
||||||
|
|
||||||
|
public class SurfaceNodeStorage {
|
||||||
|
|
||||||
|
public static class Node {
|
||||||
|
// private float[] floats;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final TLongObjectMap<Node> map = new TLongObjectHashMap<>();
|
||||||
|
|
||||||
|
public Node getNode(int north, int west) {
|
||||||
|
return map.get(CoordinatePacker.pack2IntsIntoLong(north, west));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNode(int north, int west) {
|
||||||
|
return map.containsKey(CoordinatePacker.pack2IntsIntoLong(north, west));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(int north, int west, Node node) {
|
||||||
|
map.put(CoordinatePacker.pack2IntsIntoLong(north, west), node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void read(DataInput input) throws IOException, DecodingException {
|
||||||
|
System.err.println("PlaneNodeMap.read did nothing because nobody implemented it yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(DataOutput output) throws IOException {
|
||||||
|
System.err.println("PlaneNodeMap.write did nothing because nobody implemented it yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user