Renderer/src/main/java/electrosphere/util/math/GeomUtils.java
austin 1b5d6c1795
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Terrain optimizations
2024-11-11 10:23:49 -05:00

386 lines
19 KiB
Java

package electrosphere.util.math;
import org.joml.Vector3d;
import org.joml.Vector3i;
/**
* Utilities for dealing with geometry
*/
public class GeomUtils {
/**
* Gets the minimum distance from a point to an axis aligned cube
* @param pos the position to check against
* @param cubeMin The min position of the cube
* @param cubeMax The max position of the cube
* @return the distance
*/
public static double getMinDistanceAABB(Vector3d pos, Vector3d cubeMin, Vector3d cubeMax){
double minX = cubeMin.x;
double minY = cubeMin.y;
double minZ = cubeMin.z;
double maxX = cubeMax.x;
double maxY = cubeMax.y;
double maxZ = cubeMax.z;
if(pos.x > minX && pos.x < maxX){
if(pos.y > minY && pos.y < maxY){
if(pos.z > minZ && pos.z < maxZ){
return 0;
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distance(pos.x,pos.y,minZ);
} else {
return pos.distance(pos.x,pos.y,maxZ);
}
} else if(Math.abs(pos.y - minY) < Math.abs(pos.y - maxY)){
if(pos.z > minZ && pos.z < maxZ){
return pos.distance(pos.x,minY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distance(pos.x,minY,minZ);
} else {
return pos.distance(pos.x,minY,maxZ);
}
} else {
if(pos.z > minZ && pos.z < maxZ){
return pos.distance(pos.x,maxY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distance(pos.x,maxY,minZ);
} else {
return pos.distance(pos.x,maxY,maxZ);
}
}
} else if(Math.abs(pos.x - minX) < Math.abs(pos.x - maxX)){
if(pos.y > minY && pos.y < maxY){
if(pos.z > minZ && pos.z < maxZ){
return pos.distance(minX,pos.y,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distance(minX,pos.y,minZ);
} else {
return pos.distance(minX,pos.y,maxZ);
}
} else if(Math.abs(pos.y - minY) < Math.abs(pos.y - maxY)){
if(pos.z > minZ && pos.z < maxZ){
return pos.distance(minX,minY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distance(minX,minY,minZ);
} else {
return pos.distance(minX,minY,maxZ);
}
} else {
if(pos.z > minZ && pos.z < maxZ){
return pos.distance(minX,maxY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distance(minX,maxY,minZ);
} else {
return pos.distance(minX,maxY,maxZ);
}
}
} else {
if(pos.y > minY && pos.y < maxY){
if(pos.z > minZ && pos.z < maxZ){
return pos.distance(maxX,pos.y,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distance(maxX,pos.y,minZ);
} else {
return pos.distance(maxX,pos.y,maxZ);
}
} else if(Math.abs(pos.y - minY) < Math.abs(pos.y - maxY)){
if(pos.z > minZ && pos.z < maxZ){
return pos.distance(maxX,minY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distance(maxX,minY,minZ);
} else {
return pos.distance(maxX,minY,maxZ);
}
} else {
if(pos.z > minZ && pos.z < maxZ){
return pos.distance(maxX,maxY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distance(maxX,maxY,minZ);
} else {
return pos.distance(maxX,maxY,maxZ);
}
}
}
}
/**
* Gets the minimum squared distance from a point to an axis aligned cube
* @param pos the position to check against
* @param cubeMin The min position of the cube
* @param cubeMax The max position of the cube
* @return the distance
*/
public static double getMinSquaredDistanceAABB(Vector3d pos, Vector3d cubeMin, Vector3d cubeMax){
double minX = cubeMin.x;
double minY = cubeMin.y;
double minZ = cubeMin.z;
double maxX = cubeMax.x;
double maxY = cubeMax.y;
double maxZ = cubeMax.z;
if(pos.x > minX && pos.x < maxX){
if(pos.y > minY && pos.y < maxY){
if(pos.z > minZ && pos.z < maxZ){
return 0;
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(pos.x,pos.y,minZ);
} else {
return pos.distanceSquared(pos.x,pos.y,maxZ);
}
} else if(Math.abs(pos.y - minY) < Math.abs(pos.y - maxY)){
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(pos.x,minY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(pos.x,minY,minZ);
} else {
return pos.distanceSquared(pos.x,minY,maxZ);
}
} else {
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(pos.x,maxY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(pos.x,maxY,minZ);
} else {
return pos.distanceSquared(pos.x,maxY,maxZ);
}
}
} else if(Math.abs(pos.x - minX) < Math.abs(pos.x - maxX)){
if(pos.y > minY && pos.y < maxY){
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(minX,pos.y,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(minX,pos.y,minZ);
} else {
return pos.distanceSquared(minX,pos.y,maxZ);
}
} else if(Math.abs(pos.y - minY) < Math.abs(pos.y - maxY)){
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(minX,minY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(minX,minY,minZ);
} else {
return pos.distanceSquared(minX,minY,maxZ);
}
} else {
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(minX,maxY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(minX,maxY,minZ);
} else {
return pos.distanceSquared(minX,maxY,maxZ);
}
}
} else {
if(pos.y > minY && pos.y < maxY){
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(maxX,pos.y,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(maxX,pos.y,minZ);
} else {
return pos.distanceSquared(maxX,pos.y,maxZ);
}
} else if(Math.abs(pos.y - minY) < Math.abs(pos.y - maxY)){
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(maxX,minY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(maxX,minY,minZ);
} else {
return pos.distanceSquared(maxX,minY,maxZ);
}
} else {
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(maxX,maxY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(maxX,maxY,minZ);
} else {
return pos.distanceSquared(maxX,maxY,maxZ);
}
}
}
}
/**
* Gets the minimum squared distance from a point to an axis aligned cube
* @param pos the position to check against
* @param cubeMin The min position of the cube
* @param cubeMax The max position of the cube
* @return the distance
*/
public static double getMinSquaredDistanceAABB(Vector3i pos, Vector3i cubeMin, Vector3i cubeMax){
int minX = cubeMin.x;
int minY = cubeMin.y;
int minZ = cubeMin.z;
int maxX = cubeMax.x;
int maxY = cubeMax.y;
int maxZ = cubeMax.z;
if(pos.x > minX && pos.x < maxX){
if(pos.y > minY && pos.y < maxY){
if(pos.z > minZ && pos.z < maxZ){
return 0;
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(pos.x,pos.y,minZ);
} else {
return pos.distanceSquared(pos.x,pos.y,maxZ);
}
} else if(Math.abs(pos.y - minY) < Math.abs(pos.y - maxY)){
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(pos.x,minY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(pos.x,minY,minZ);
} else {
return pos.distanceSquared(pos.x,minY,maxZ);
}
} else {
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(pos.x,maxY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(pos.x,maxY,minZ);
} else {
return pos.distanceSquared(pos.x,maxY,maxZ);
}
}
} else if(Math.abs(pos.x - minX) < Math.abs(pos.x - maxX)){
if(pos.y > minY && pos.y < maxY){
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(minX,pos.y,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(minX,pos.y,minZ);
} else {
return pos.distanceSquared(minX,pos.y,maxZ);
}
} else if(Math.abs(pos.y - minY) < Math.abs(pos.y - maxY)){
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(minX,minY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(minX,minY,minZ);
} else {
return pos.distanceSquared(minX,minY,maxZ);
}
} else {
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(minX,maxY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(minX,maxY,minZ);
} else {
return pos.distanceSquared(minX,maxY,maxZ);
}
}
} else {
if(pos.y > minY && pos.y < maxY){
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(maxX,pos.y,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(maxX,pos.y,minZ);
} else {
return pos.distanceSquared(maxX,pos.y,maxZ);
}
} else if(Math.abs(pos.y - minY) < Math.abs(pos.y - maxY)){
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(maxX,minY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(maxX,minY,minZ);
} else {
return pos.distanceSquared(maxX,minY,maxZ);
}
} else {
if(pos.z > minZ && pos.z < maxZ){
return pos.distanceSquared(maxX,maxY,pos.z);
} else if(Math.abs(pos.z - minZ) < Math.abs(pos.z - maxZ)){
return pos.distanceSquared(maxX,maxY,minZ);
} else {
return pos.distanceSquared(maxX,maxY,maxZ);
}
}
}
}
/**
* Gets the minimum squared distance from a point to an axis aligned cube
* @param pos the position to check against
* @param cubeMin The min position of the cube
* @param cubeMax The max position of the cube
* @return the distance
*/
public static double getMinSquaredDistanceAABBUnrolled(int posX, int posY, int posZ, int minX, int minY, int minZ, int maxX, int maxY, int maxZ){
if(posX > minX && posX < maxX){
if(posY > minY && posY < maxY){
if(posZ > minZ && posZ < maxZ){
return 0;
} else if(Math.abs(posZ - minZ) < Math.abs(posZ - maxZ)){
return (posZ - minZ) * (posZ - minZ);// pos.distanceSquared(posX,posY,minZ);
} else {
return (posZ - maxZ) * (posZ - maxZ);//pos.distanceSquared(posX,posY,maxZ);
}
} else if(Math.abs(posY - minY) < Math.abs(posY - maxY)){
if(posZ > minZ && posZ < maxZ){
return (posY - minY) * (posY - minY);//pos.distanceSquared(posX,minY,posZ);
} else if(Math.abs(posZ - minZ) < Math.abs(posZ - maxZ)){
return (posY - minY) * (posY - minY) + (posZ - minZ) * (posZ - minZ);//pos.distanceSquared(posX,minY,minZ);
} else {
return (posY - minY) * (posY - minY) + (posZ - maxZ) * (posZ - maxZ);//pos.distanceSquared(posX,minY,maxZ);
}
} else {
if(posZ > minZ && posZ < maxZ){
return (posY - maxY) * (posY - maxY);//pos.distanceSquared(posX,maxY,posZ);
} else if(Math.abs(posZ - minZ) < Math.abs(posZ - maxZ)){
return (posY - maxY) * (posY - maxY) + (posZ - minZ) * (posZ - minZ);//pos.distanceSquared(posX,maxY,minZ);
} else {
return (posY - maxY) * (posY - maxY) + (posZ - maxZ) * (posZ - maxZ);//pos.distanceSquared(posX,maxY,maxZ);
}
}
} else if(Math.abs(posX - minX) < Math.abs(posX - maxX)){
if(posY > minY && posY < maxY){
if(posZ > minZ && posZ < maxZ){
return (posX - minX) * (posX - minX);//pos.distanceSquared(minX,posY,posZ);
} else if(Math.abs(posZ - minZ) < Math.abs(posZ - maxZ)){
return (posX - minX) * (posX - minX) + (posZ - minZ) * (posZ - minZ);//pos.distanceSquared(minX,posY,minZ);
} else {
return (posX - minX) * (posX - minX) + (posZ - maxZ) * (posZ - maxZ);//pos.distanceSquared(minX,posY,maxZ);
}
} else if(Math.abs(posY - minY) < Math.abs(posY - maxY)){
if(posZ > minZ && posZ < maxZ){
return (posX - minX) * (posX - minX);//pos.distanceSquared(minX,minY,posZ);
} else if(Math.abs(posZ - minZ) < Math.abs(posZ - maxZ)){
return (posX - minX) * (posX - minX) + (posY - minY) * (posY - minY) + (posZ - minZ) * (posZ - minZ);//pos.distanceSquared(minX,minY,minZ);
} else {
return (posX - minX) * (posX - minX) + (posY - minY) * (posY - minY) + (posZ - maxZ) * (posZ - maxZ);//pos.distanceSquared(minX,minY,maxZ);
}
} else {
if(posZ > minZ && posZ < maxZ){
return (posX - minX) * (posX - minX) + (posY - maxY) * (posY - maxY);//pos.distanceSquared(minX,maxY,posZ);
} else if(Math.abs(posZ - minZ) < Math.abs(posZ - maxZ)){
return (posX - minX) * (posX - minX) + (posY - maxY) * (posY - maxY) + (posZ - minZ) * (posZ - minZ);//pos.distanceSquared(minX,maxY,minZ);
} else {
return (posX - minX) * (posX - minX) + (posY - maxY) * (posY - maxY) + (posZ - maxZ) * (posZ - maxZ);//pos.distanceSquared(minX,maxY,maxZ);
}
}
} else {
if(posY > minY && posY < maxY){
if(posZ > minZ && posZ < maxZ){
return (posX - maxX) * (posX - maxX);//pos.distanceSquared(maxX,posY,posZ);
} else if(Math.abs(posZ - minZ) < Math.abs(posZ - maxZ)){
return (posX - maxX) * (posX - maxX) + (posZ - minZ) * (posZ - minZ);//pos.distanceSquared(maxX,posY,minZ);
} else {
return (posX - maxX) * (posX - maxX) + (posZ - maxZ) * (posZ - maxZ);//pos.distanceSquared(maxX,posY,maxZ);
}
} else if(Math.abs(posY - minY) < Math.abs(posY - maxY)){
if(posZ > minZ && posZ < maxZ){
return (posX - maxX) * (posX - maxX);//pos.distanceSquared(maxX,minY,posZ);
} else if(Math.abs(posZ - minZ) < Math.abs(posZ - maxZ)){
return (posX - maxX) * (posX - maxX) + (posY - minY) * (posY - minY) + (posZ - minZ) * (posZ - minZ);//pos.distanceSquared(maxX,minY,minZ);
} else {
return (posX - maxX) * (posX - maxX) + (posY - minY) * (posY - minY) + (posZ - maxZ) * (posZ - maxZ);//pos.distanceSquared(maxX,minY,maxZ);
}
} else {
if(posZ > minZ && posZ < maxZ){
return (posX - maxX) * (posX - maxX) + (posY - maxY) * (posY - maxY);//pos.distanceSquared(maxX,maxY,posZ);
} else if(Math.abs(posZ - minZ) < Math.abs(posZ - maxZ)){
return (posX - maxX) * (posX - maxX) + (posY - maxY) * (posY - maxY) + (posZ - minZ) * (posZ - minZ);//pos.distanceSquared(maxX,maxY,minZ);
} else {
return (posX - maxX) * (posX - maxX) + (posY - maxY) * (posY - maxY) + (posZ - maxZ) * (posZ - maxZ);//pos.distanceSquared(maxX,maxY,maxZ);
}
}
}
}
}