Some SDF functions

This commit is contained in:
paulevsGitch 2020-09-28 20:31:10 +03:00
parent c633fe8549
commit 17663dac02
12 changed files with 197 additions and 0 deletions

View file

@ -60,4 +60,16 @@ public class MHelper {
public static int max(int a, int b) {
return a > b ? a : b;
}
public static float min(float a, float b) {
return a < b ? a : b;
}
public static float max(float a, float b) {
return a > b ? a : b;
}
public static float length(float x, float y, float z) {
return (float) Math.sqrt(x * x + y * y + z * z);
}
}

View file

@ -0,0 +1,5 @@
package ru.betterend.util.sdf;
public interface ISDF {
public float getDistance(float x, float y, float z);
}

View file

@ -0,0 +1,18 @@
package ru.betterend.util.sdf.operator;
import ru.betterend.util.sdf.ISDF;
public abstract class SDFBinary implements ISDF {
protected ISDF sourceA;
protected ISDF sourceB;
public SDFBinary setSourceA(ISDF sourceA) {
this.sourceA = sourceA;
return this;
}
public SDFBinary setSourceB(ISDF sourceB) {
this.sourceB = sourceB;
return this;
}
}

View file

@ -0,0 +1,12 @@
package ru.betterend.util.sdf.operator;
import ru.betterend.util.MHelper;
public class SDFIntersection extends SDFBinary {
@Override
public float getDistance(float x, float y, float z) {
float a = this.sourceA.getDistance(x, y, z);
float b = this.sourceB.getDistance(x, y, z);
return MHelper.max(a, b);
}
}

View file

@ -0,0 +1,23 @@
package ru.betterend.util.sdf.operator;
import ru.betterend.util.sdf.ISDF;
public class SDFScale implements ISDF {
private ISDF source;
private float scale;
public SDFScale setSorce(ISDF source) {
this.source = source;
return this;
}
public SDFScale setScale(float scale) {
this.scale = scale;
return this;
}
@Override
public float getDistance(float x, float y, float z) {
return source.getDistance(x / scale, y / scale, z / scale) * scale;
}
}

View file

@ -0,0 +1,20 @@
package ru.betterend.util.sdf.operator;
import net.minecraft.util.math.MathHelper;
public class SDFSmoothIntersection extends SDFBinary {
private float radius;
public SDFSmoothIntersection setRadius(float radius) {
this.radius = radius;
return this;
}
@Override
public float getDistance(float x, float y, float z) {
float a = this.sourceA.getDistance(x, y, z);
float b = this.sourceB.getDistance(x, y, z);
float h = MathHelper.clamp(0.5F - 0.5F * (b - a) / radius, 0F, 1F);
return MathHelper.lerp(h, b, a) + radius * h * (1F - h);
}
}

View file

@ -0,0 +1,20 @@
package ru.betterend.util.sdf.operator;
import net.minecraft.util.math.MathHelper;
public class SDFSmoothSubtraction extends SDFBinary {
private float radius;
public SDFSmoothSubtraction setRadius(float radius) {
this.radius = radius;
return this;
}
@Override
public float getDistance(float x, float y, float z) {
float a = this.sourceA.getDistance(x, y, z);
float b = this.sourceB.getDistance(x, y, z);
float h = MathHelper.clamp(0.5F - 0.5F * (b + a) / radius, 0F, 1F);
return MathHelper.lerp(h, b, -a) + radius * h * (1F - h);
}
}

View file

@ -0,0 +1,20 @@
package ru.betterend.util.sdf.operator;
import net.minecraft.util.math.MathHelper;
public class SDFSmoothUnion extends SDFBinary {
private float radius;
public SDFSmoothUnion setRadius(float radius) {
this.radius = radius;
return this;
}
@Override
public float getDistance(float x, float y, float z) {
float a = this.sourceA.getDistance(x, y, z);
float b = this.sourceB.getDistance(x, y, z);
float h = MathHelper.clamp(0.5F + 0.5F * (b - a) / radius, 0F, 1F);
return MathHelper.lerp(h, b, a) - radius * h * (1F - h);
}
}

View file

@ -0,0 +1,12 @@
package ru.betterend.util.sdf.operator;
import ru.betterend.util.MHelper;
public class SDFSubtraction extends SDFBinary {
@Override
public float getDistance(float x, float y, float z) {
float a = this.sourceA.getDistance(x, y, z);
float b = this.sourceB.getDistance(x, y, z);
return MHelper.max(-a, b);
}
}

View file

@ -0,0 +1,12 @@
package ru.betterend.util.sdf.operator;
import ru.betterend.util.MHelper;
public class SDFUnion extends SDFBinary {
@Override
public float getDistance(float x, float y, float z) {
float a = this.sourceA.getDistance(x, y, z);
float b = this.sourceB.getDistance(x, y, z);
return MHelper.min(a, b);
}
}

View file

@ -0,0 +1,25 @@
package ru.betterend.util.sdf.primitive;
import net.minecraft.util.math.MathHelper;
import ru.betterend.util.MHelper;
import ru.betterend.util.sdf.ISDF;
public class SDFCapsule implements ISDF {
private float radius;
private float height;
public SDFCapsule setRadius(float radius) {
this.radius = radius;
return this;
}
public SDFCapsule setHeight(float height) {
this.height = height;
return this;
}
@Override
public float getDistance(float x, float y, float z) {
return MHelper.length(x, MathHelper.clamp(y, 0F, height), z) - radius;
}
}

View file

@ -0,0 +1,18 @@
package ru.betterend.util.sdf.primitive;
import ru.betterend.util.MHelper;
import ru.betterend.util.sdf.ISDF;
public class SDFSphere implements ISDF {
private float radius;
public SDFSphere setRadius(float radius) {
this.radius = radius;
return this;
}
@Override
public float getDistance(float x, float y, float z) {
return MHelper.length(x, y, z) - radius;
}
}