Updated force field range to double it

Improved force field memory usage
Updated force field stabilisation to increase speed
Added 64 blocks range cap with fusion and inversion upgrades
This commit is contained in:
LemADEC 2017-08-14 16:12:25 +02:00
parent 29ff7c3b3b
commit 9bd098bd4f
4 changed files with 111 additions and 46 deletions

View file

@ -119,9 +119,9 @@ idea {
}
runClient {
jvmArgs "-Xmx1024m", "-Xms1024m", "-ea"
jvmArgs "-Xmx2048m", "-Xms1024m", "-ea"
}
runServer {
jvmArgs "-Xmx1024m", "-Xms1024m", "-ea"
jvmArgs "-Xmx2048m", "-Xms1024m", "-ea"
}

View file

@ -1,6 +1,7 @@
package cr0s.warpdrive.data;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.IForceFieldShape;
import java.util.HashMap;
@ -39,13 +40,51 @@ public enum EnumForceFieldShape implements IForceFieldShape {
@Override
public Map<VectorI, Boolean> getVertexes(ForceFieldSetup forceFieldSetup) {
VectorI vScale = forceFieldSetup.vMax.clone().translateBack(forceFieldSetup.vMin);
Map<VectorI, Boolean> mapVertexes = new HashMap<>(vScale.x * vScale.y * vScale.z);
final VectorI vScale = forceFieldSetup.vMax.clone().translateBack(forceFieldSetup.vMin);
final boolean isFusionOrInverted = forceFieldSetup.hasFusion || forceFieldSetup.isInverted;
final int sizeEstimation;
if (!isFusionOrInverted) {// surface only
// plane surface is r^2
// sphere surface is 4*PI*r^2
// cylinder surface is 2*PI*r^2 + 2*PI*r*h = 2*PI*r^2 * 1.5
// cube surface is 4*6*r^2
final int maxRadius = 1 + (int) Math.ceil(Math.max(vScale.x, Math.max(vScale.y, vScale.z)) / 2.0F);
switch(this) {
case SPHERE:
sizeEstimation = (int) Math.ceil(4 * Math.PI * maxRadius * maxRadius);
break;
case CYLINDER_H:
case CYLINDER_V:
case TUBE:
sizeEstimation = (int) Math.ceil(4 * Math.PI * maxRadius * maxRadius * 1.5F);
break;
case CUBE:
case TUNNEL:
sizeEstimation = 4 * 6 * maxRadius * maxRadius;
break;
case PLANE:
sizeEstimation = maxRadius * maxRadius;
break;
default:
assert(false);
sizeEstimation = 8;
break;
}
} else {
sizeEstimation = vScale.x * vScale.y * vScale.z;
}
final Map<VectorI, Boolean> mapVertexes = new HashMap<>(sizeEstimation);
float radius;
float halfThickness = forceFieldSetup.thickness / 2.0F;
float radiusInterior2;
float radiusPerimeter2;
VectorI vCenter;
boolean isPerimeter;
switch(this) {
case SPHERE:
radius = forceFieldSetup.vMax.y;
@ -53,13 +92,16 @@ public enum EnumForceFieldShape implements IForceFieldShape {
radiusPerimeter2 = (radius + halfThickness) * (radius + halfThickness);
vCenter = new VectorI(0, 0, 0);
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
int y2 = (y - vCenter.y) * (y - vCenter.y);
final int y2 = (y - vCenter.y) * (y - vCenter.y);
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
int x2 = (x - vCenter.x) * (x - vCenter.x);
final int x2 = (x - vCenter.x) * (x - vCenter.x);
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
int z2 = (z - vCenter.z) * (z - vCenter.z);
final int z2 = (z - vCenter.z) * (z - vCenter.z);
if (x2 + y2 + z2 <= radiusPerimeter2) {
mapVertexes.put(new VectorI(x, y, z), x2 + y2 + z2 >= radiusInterior2);
isPerimeter = x2 + y2 + z2 >= radiusInterior2;
if (isPerimeter || isFusionOrInverted) {
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
}
}
}
}
@ -76,9 +118,11 @@ public enum EnumForceFieldShape implements IForceFieldShape {
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
int z2 = (z - vCenter.z) * (z - vCenter.z);
if (y2 + z2 <= radiusPerimeter2) {
boolean isPerimeter = y2 + z2 >= radiusInterior2;
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
isPerimeter = y2 + z2 >= radiusInterior2;
if (isPerimeter || isFusionOrInverted) {
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
}
}
}
}
@ -95,9 +139,11 @@ public enum EnumForceFieldShape implements IForceFieldShape {
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
int y2 = (y - vCenter.y) * (y - vCenter.y);
if (x2 + y2 <= radiusPerimeter2) {
boolean isPerimeter = x2 + y2 >= radiusInterior2;
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
isPerimeter = x2 + y2 >= radiusInterior2;
if (isPerimeter || isFusionOrInverted) {
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
}
}
}
}
@ -114,9 +160,11 @@ public enum EnumForceFieldShape implements IForceFieldShape {
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
int z2 = (z - vCenter.z) * (z - vCenter.z);
if (x2 + z2 <= radiusPerimeter2) {
boolean isPerimeter = x2 + z2 >= radiusInterior2;
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
isPerimeter = x2 + z2 >= radiusInterior2;
if (isPerimeter || isFusionOrInverted) {
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
}
}
}
}
@ -133,7 +181,10 @@ public enum EnumForceFieldShape implements IForceFieldShape {
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
boolean zFace = Math.abs(z - forceFieldSetup.vMin.z) <= halfThickness
|| Math.abs(z - forceFieldSetup.vMax.z) <= halfThickness;
mapVertexes.put(new VectorI(x, y, z), xFace || yFace || zFace);
isPerimeter = xFace || yFace || zFace;
if (isPerimeter || isFusionOrInverted) {
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
}
}
}
}
@ -141,11 +192,13 @@ public enum EnumForceFieldShape implements IForceFieldShape {
case PLANE:
for (int y = forceFieldSetup.vMin.y; y <= forceFieldSetup.vMax.y; y++) {
boolean yFace = Math.abs(y - forceFieldSetup.vMin.y) <= halfThickness
|| Math.abs(y - forceFieldSetup.vMax.y) <= halfThickness;
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
mapVertexes.put(new VectorI(x, y, z), yFace);
isPerimeter = Math.abs(y - forceFieldSetup.vMin.y) <= halfThickness
|| Math.abs(y - forceFieldSetup.vMax.y) <= halfThickness;
if (isPerimeter || isFusionOrInverted) {
for (int x = forceFieldSetup.vMin.x; x <= forceFieldSetup.vMax.x; x++) {
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
}
}
}
}
@ -157,10 +210,12 @@ public enum EnumForceFieldShape implements IForceFieldShape {
boolean xFace = Math.abs(x - forceFieldSetup.vMin.x) <= halfThickness
|| Math.abs(x - forceFieldSetup.vMax.x) <= halfThickness;
for (int z = forceFieldSetup.vMin.z; z <= forceFieldSetup.vMax.z; z++) {
boolean isPerimeter = xFace
|| Math.abs(z - forceFieldSetup.vMin.z) <= halfThickness
|| Math.abs(z - forceFieldSetup.vMax.z) <= halfThickness;
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
isPerimeter = xFace
|| Math.abs(z - forceFieldSetup.vMin.z) <= halfThickness
|| Math.abs(z - forceFieldSetup.vMax.z) <= halfThickness;
if (isPerimeter || isFusionOrInverted) {
mapVertexes.put(new VectorI(x, y, z), isPerimeter);
}
}
}
}
@ -171,6 +226,13 @@ public enum EnumForceFieldShape implements IForceFieldShape {
}
if (mapVertexes.size() > sizeEstimation) {
WarpDrive.logger.warn(String.format("Underestimated memory location lag %d > %d for shape %s with size %s, isFusionOrInverted %s. Please report this to the mod author",
mapVertexes.size(), sizeEstimation,
unlocalizedName,
vScale,
isFusionOrInverted));
}
return mapVertexes;
}
}

View file

@ -39,13 +39,13 @@ public enum EnumForceFieldUpgrade implements IForceFieldUpgrade, IForceFieldUpgr
INVERSION ("inversion" , 1, 0, 1.0F, 1.0F, 1.250F, 1.250F, 0.000F, 0.000F, 1500.0F, 0.150F, 0.150F, 20.0F, "value is boolean"),
ITEM_PORT ("item_port" , 0, 1, 1.0F, 10.0F, 0.000F, 0.000F, 0.950F, 0.900F, 50.0F, 0.120F, 0.500F, 2.0F, "value is boolean"),
PUMPING ("pumping" , 0, 1, 1000.0F, 50000.0F, 0.800F, 1.000F, 0.400F, 1.000F, 800.0F, 0.150F, 4.500F, 0.0F, "value is viscosity"),
RANGE ("range" , 4, 1, 8.0F, 56.0F, 1.150F, 0.800F, 1.150F, 0.800F, 10.0F, 0.300F, 0.750F, 12.0F, "value is bonus blocks"),
RANGE ("range" , 4, 1, 8.0F, 128.0F, 1.150F, 0.450F, 1.150F, 0.450F, 10.0F, 0.300F, 0.750F, 12.0F, "value is bonus blocks"),
REPULSION ("repulsion" , 0, 1, 1.0F, 4.0F, 0.000F, 0.000F, 0.000F, 0.000F, 50.0F, 0.150F, 0.000F, 5.0F, "value is acceleration"),
ROTATION ("rotation" , 1, 0, 1.0F, 1.0F, 0.000F, 0.000F, 0.000F, 0.000F, 100.0F, 0.000F, 0.000F, 0.0F, "value is boolean"),
SHOCK ("shock" , 3, 1, 1.0F, 10.0F, 0.800F, 0.800F, 0.800F, 0.800F, 300.0F, 0.600F, 4.000F, 30.0F, "value is damage points"),
SILENCER ("silencer" , 1, 0, 1.0F, 1.0F, 0.000F, 0.000F, 0.000F, 0.000F, 0.0F, 0.120F, 0.620F, 0.0F, "value is boolean"),
SPEED ("speed" , 4, 1, 1.0F, 20.0F, 1.250F, 6.000F, 1.200F, 5.000F, 200.0F, 0.135F, 1.250F, 15.0F, "value is not used (just a counter)"),
STABILIZATION("stabilization", 0, 1, 1.0F, 6.0F, 0.250F, 0.550F, 0.025F, 0.150F, 400.0F, 0.050F, 73.600F, 0.0F, "value is boolean"),
STABILIZATION("stabilization", 0, 1, 1.0F, 9.0F, 0.250F, 0.850F, 0.025F, 0.450F, 400.0F, 0.050F, 73.600F, 0.0F, "value is boolean"),
THICKNESS ("thickness" , 5, 1, 0.2F, 1.0F, 0.800F, 1.600F, 0.900F, 1.500F, 100.0F, 0.400F, 2.200F, 5.0F, "value is bonus ratio"),
TRANSLATION ("translation" , 1, 0, 1.0F, 1.0F, 0.000F, 0.000F, 0.000F, 0.000F, 100.0F, 0.000F, 0.000F, 0.0F, "value is boolean"),
;

View file

@ -256,23 +256,6 @@ public class ForceFieldSetup extends GlobalPosition {
scanSpeed = Math.min(FORCEFIELD_MAX_SCAN_SPEED_BLOCKS_PER_SECOND, scanSpeed);
placeSpeed = Math.min(FORCEFIELD_MAX_PLACE_SPEED_BLOCKS_PER_SECOND, placeSpeed);
// range is maximum distance
double range = getScaledUpgrade(EnumForceFieldUpgrade.RANGE);
if (range == 0.0D) {
range = 8.0D;
v3Min = new Vector3(-1.0D, -1.0D, -1.0D);
v3Max = new Vector3( 1.0D, 1.0D, 1.0D);
}
vMin.x = (int) Math.round(Math.min(0.0D, Math.max(-1.0D, v3Min.x)) * range);
vMin.y = (int) Math.round(Math.min(0.0D, Math.max(-1.0D, v3Min.y)) * range);
vMin.z = (int) Math.round(Math.min(0.0D, Math.max(-1.0D, v3Min.z)) * range);
vMax.x = (int) Math.round(Math.min(1.0D, Math.max( 0.0D, v3Max.x)) * range);
vMax.y = (int) Math.round(Math.min(1.0D, Math.max( 0.0D, v3Max.y)) * range);
vMax.z = (int) Math.round(Math.min(1.0D, Math.max( 0.0D, v3Max.z)) * range);
vTranslation.x += (int) Math.round(Math.min(1.0D, Math.max(-1.0D, v3Translation.x)) * range);
vTranslation.y += (int) Math.round(Math.min(1.0D, Math.max(-1.0D, v3Translation.y)) * range);
vTranslation.z += (int) Math.round(Math.min(1.0D, Math.max(-1.0D, v3Translation.z)) * range);
// acceleration is a compound of attraction and repulsion
accelerationLevel = getScaledUpgrade(EnumForceFieldUpgrade.ATTRACTION) - getScaledUpgrade(EnumForceFieldUpgrade.REPULSION);
@ -289,6 +272,26 @@ public class ForceFieldSetup extends GlobalPosition {
breaking_maxHardness = getScaledUpgrade(EnumForceFieldUpgrade.BREAKING);
pumping_maxViscosity = getScaledUpgrade(EnumForceFieldUpgrade.PUMPING);
thickness = 1.0F + getScaledUpgrade(EnumForceFieldUpgrade.THICKNESS);
// range is maximum distance
double range = getScaledUpgrade(EnumForceFieldUpgrade.RANGE);
if (range == 0.0D) {
range = 8.0D;
v3Min = new Vector3(-1.0D, -1.0D, -1.0D);
v3Max = new Vector3( 1.0D, 1.0D, 1.0D);
}
if (hasFusion || isInverted) {
range = Math.min(64.0D, range);
}
vMin.x = (int) Math.round(Math.min(0.0D, Math.max(-1.0D, v3Min.x)) * range);
vMin.y = (int) Math.round(Math.min(0.0D, Math.max(-1.0D, v3Min.y)) * range);
vMin.z = (int) Math.round(Math.min(0.0D, Math.max(-1.0D, v3Min.z)) * range);
vMax.x = (int) Math.round(Math.min(1.0D, Math.max( 0.0D, v3Max.x)) * range);
vMax.y = (int) Math.round(Math.min(1.0D, Math.max( 0.0D, v3Max.y)) * range);
vMax.z = (int) Math.round(Math.min(1.0D, Math.max( 0.0D, v3Max.z)) * range);
vTranslation.x += (int) Math.round(Math.min(1.0D, Math.max(-1.0D, v3Translation.x)) * range);
vTranslation.y += (int) Math.round(Math.min(1.0D, Math.max(-1.0D, v3Translation.y)) * range);
vTranslation.z += (int) Math.round(Math.min(1.0D, Math.max(-1.0D, v3Translation.z)) * range);
}
public double getEntityEnergyCost(final int countEntityInteractions) {