Projection class
Пакет: com.hypixel.hytale.server.npc.movement.controllers
Файл: com/hypixel/hytale/server/npc/movement/controllers/RailPath.java
Поля (4)
| Модификаторы | Тип | Имя |
|---|---|---|
|
private double |
distanceSquared |
|
private final Vector3d |
position |
|
private int |
segmentIndex |
|
private double |
segmentProgress |
Методы (5)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
|
public double |
getDistanceSquaredpublic double getDistanceSquared() |
|
public Vector3dc |
getPositionpublic Vector3dc getPosition() |
|
public int |
getSegmentIndexpublic int getSegmentIndex() |
|
public double |
getSegmentProgresspublic double getSegmentProgress() |
|
private void |
resetprivate void reset() |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.server.npc.movement.controllers;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import java.util.Arrays;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3dc;
class="kw">public class="kw">final class RailPath {
class="kw">private class="kw">static class="kw">final double MIN_WAYPOINT_OFFSET_SQ = 1.0E-12;
class="kw">private class="kw">static class="kw">final double CARRY_OVER_FACTOR = 2.0;
class="kw">private class="kw">static class="kw">final double COLLINEARITY_EPSILON = 1.0E-9;
class="kw">private class="kw">static class="kw">final double SNAP_SLACK = 1.0E-9;
class="kw">private class="kw">static class="kw">final int DEFAULT_INITIAL_CAPACITY = 6;
class="kw">private class="kw">static class="kw">final int GROWTH_INCREMENT = 4;
class="kw">private Vector3d[] waypoints;
class="kw">private RailPath.SegmentCommitType[] segmentCommitTypes;
class="kw">private int waypointCount;
class="kw">private int cursor;
class="kw">private double segmentProgress;
class="kw">private double carryOverDistance;
class="kw">private class="kw">final Vector3d segDirScratch = new Vector3d();
class="kw">private class="kw">final Vector3d referenceDirScratch = new Vector3d();
class="kw">private class="kw">final RailPath.Projection projectionScratch = new RailPath.Projection();
class="kw">public RailPath() {
this(6);
}
class="kw">public RailPath(int var1) {
if (var1 < 1) {
var1 = 1;
}
this.waypoints = new Vector3d[var1];
this.segmentCommitTypes = new RailPath.SegmentCommitType[Math.max(1, var1 - 1)];
for (int var2 = 0; var2 < this.waypoints.length; var2++) {
this.waypoints[var2] = new Vector3d();
}
Arrays.fill(this.segmentCommitTypes, RailPath.SegmentCommitType.NONE);
}
class="kw">public void reset() {
this.waypointCount = 0;
this.cursor = 0;
this.segmentProgress = 0.0;
this.carryOverDistance = 0.0;
Arrays.fill(this.segmentCommitTypes, RailPath.SegmentCommitType.NONE);
}
class="kw">public void capture(@Nonnull Vector3d[] var1, int var2) {
this.capture(var1, null, var2);
}
class="kw">public void capture(@Nonnull Vector3d[] var1, @Nullable RailPath.SegmentCommitType[] var2, int var3) {
this.reset();
if (var3 > 0) {
this.nextWaypoint().set(var1[0]);
for (int var4 = 1; var4 < var3; var4++) {
RailPath.SegmentCommitType var5 = var2 != null && var4 - 1 < var2.length ? var2[var4 - 1] : RailPath.SegmentCommitType.NONE;
this.appendIfDistinct(var1[var4], var5);
}
}
}
class="kw">public void capture(@Nonnull RailPath var1) {
this.capture(var1.waypoints, var1.segmentCommitTypes, var1.waypointCount);
}
class="kw">public void captureSuffixFromProjection(@Nonnull RailPath var1, @Nonnull RailPath.Projection var2) {
this.reset();
if (var1.waypointCount > 0) {
this.nextWaypoint().set(var2.position);
for (int var3 = var2.segmentIndex + 1; var3 < var1.waypointCount; var3++) {
RailPath.SegmentCommitType var4 = var3 - 1 < var1.segmentCommitTypes.length ? var1.segmentCommitTypes[var3 - 1] : RailPath.SegmentCommitType.NONE;
this.appendIfDistinct(var1.waypoints[var3], var4);
}
}
}
class="kw">private void appendIfDistinct(@Nonnull Vector3dc var1, @Nonnull RailPath.SegmentCommitType var2) {
Vector3d var3 = this.waypoints[this.waypointCount - 1];
if (!(var3.distanceSquared(var1) <= 1.0E-12)) {
int var4 = this.waypointCount - 1;
this.nextWaypoint().set(var1);
this.ensureSegmentCommitCapacity(this.waypointCount - 1);
this.segmentCommitTypes[var4] = var2;
}
}
class="kw">public boolean isEmpty() {
class="kw">return this.waypointCount <= 1;
}
class="kw">public boolean isFinished() {
class="kw">return this.isEmpty() || this.cursor >= this.waypointCount - 1;
}
class="kw">public int getWaypointCount() {
class="kw">return this.waypointCount;
}
@Nonnull
class="kw">public Vector3dc getWaypoint(int var1) {
if (var1 >= 0 && var1 < this.waypointCount) {
class="kw">return this.waypoints[var1];
} else {
throw new IndexOutOfBoundsException(var1);
}
}
class="kw">public int getCursor() {
class="kw">return this.cursor;
}
class="kw">public double getSegmentProgress() {
class="kw">return this.segmentProgress;
}
class="kw">public boolean isOnCommittedSegment() {
int var1 = this.getActiveSegmentIndex();
class="kw">return var1 >= 0 && var1 < this.waypointCount - 1 ? this.segmentCommitTypes[var1].isCommitted() : false;
}
class="kw">public int getCommittedSegmentEndWaypointIndex() {
class="kw">return !this.isOnCommittedSegment() ? -1 : this.getActiveSegmentIndex() + 1;
}
@Nonnull
class="kw">public RailPath.SegmentCommitType getActiveSegmentCommitType() {
int var1 = this.getActiveSegmentIndex();
class="kw">return var1 >= 0 && var1 < this.waypointCount - 1 ? this.segmentCommitTypes[var1] : RailPath.SegmentCommitType.NONE;
}
class="kw">public double getRemainingDistance() {
if (this.isFinished()) {
class="kw">return 0.0;
}
double var1 = 0.0;
Vector3d var3 = this.waypoints[this.cursor];
Vector3d var4 = this.waypoints[this.cursor + 1];
var1 += var3.distance(var4) * (1.0 - this.segmentProgress);
for (int var5 = this.cursor + 1; var5 < this.waypointCount - 1; var5++) {
var1 += this.waypoints[var5].distance(this.waypoints[var5 + 1]);
}
class="kw">return var1;
}
class="kw">public boolean projectRemaining(@Nonnull Vector3dc var1, @Nonnull RailPath.Projection var2) {
class="kw">return this.projectFrom(var1, this.cursor, this.segmentProgress, var2);
}
class="kw">public boolean project(@Nonnull Vector3dc var1, @Nonnull RailPath.Projection var2) {
class="kw">return this.projectFrom(var1, 0, 0.0, var2);
}
class="kw">private boolean projectFrom(@Nonnull Vector3dc var1, int var2, double var3, @Nonnull RailPath.Projection var5) {
var5.reset();
if (this.waypointCount <= 0) {
class="kw">return false;
}
if (this.waypointCount != 1 && var2 < this.waypointCount - 1) {
double var6 = Double.POSITIVE_INFINITY;
int var8 = var2;
double var9 = var3;
for (int var11 = var2; var11 < this.waypointCount - 1; var11++) {
Vector3d var12 = this.waypoints[var11];
Vector3d var13 = this.waypoints[var11 + 1];
this.segDirScratch.set(var13).sub(var12);
double var14 = this.segDirScratch.lengthSquared();
if (!(var14 <= 1.0E-12)) {
double var16 = (
(var1.x() - var12.x) * this.segDirScratch.x + (var1.y() - var12.y) * this.segDirScratch.y + (var1.z() - var12.z) * this.segDirScratch.z
)
/ var14;
if (var11 == var2) {
var16 = Math.max(var16, var3);
}
var16 = MathUtil.clamp(var16, 0.0, 1.0);
this.referenceDirScratch.set(var12).fma(var16, this.segDirScratch);
double var18 = this.referenceDirScratch.distanceSquared(var1);
if (var18 < var6) {
var6 = var18;
var8 = var11;
var9 = var16;
var5.position.set(this.referenceDirScratch);
}
}
}
if (!Double.isFinite(var6)) {
class="kw">return false;
}
var5.segmentIndex = var8;
var5.segmentProgress = var9;
var5.distanceSquared = var6;
class="kw">return true;
} else {
var5.position.set(this.waypoints[this.waypointCount - 1]);
var5.segmentIndex = Math.max(0, this.waypointCount - 1);
var5.segmentProgress = 1.0;
var5.distanceSquared = var5.position.distanceSquared(var1);
class="kw">return true;
}
}
class="kw">public boolean remainingEquivalentTo(@Nonnull RailPath var1, @Nonnull Vector3dc var2, double var3) {
double var5 = var3 * var3;
if (var1.waypointCount <= 1) {
class="kw">return this.isFinished();
}
if (this.isFinished()) {
class="kw">return var1.isFinished();
}
if (var1.waypoints[0].distanceSquared(var2) > var5) {
class="kw">return false;
}
int var7 = this.cursor + 1;
if (this.segmentProgress >= 0.999999 && var7 < this.waypointCount - 1) {
var7++;
}
RailPath.Projection var8 = this.projectionScratch;
for (int var9 = var7; var9 < this.waypointCount; var9++) {
if (!var1.project(this.waypoints[var9], var8) || var8.distanceSquared > var5) {
class="kw">return false;
}
}
for (int var10 = 1; var10 < var1.waypointCount; var10++) {
if (!this.projectFrom(var1.waypoints[var10], this.cursor, this.segmentProgress, var8) || var8.distanceSquared > var5) {
class="kw">return false;
}
}
class="kw">return true;
}
class="kw">public void advance(@Nonnull Vector3dc var1, double var2, @Nonnull Vector3d var4) {
var4.zero();
if (this.waypointCount > 1 && !(var2 <= 0.0)) {
double var5 = var2 + this.carryOverDistance;
this.carryOverDistance = 0.0;
this.skipDegenerateSegments();
if (this.cursor < this.waypointCount - 1) {
this.referenceDirScratch.set(this.waypoints[this.cursor + 1]).sub(this.waypoints[this.cursor]);
double var7 = this.referenceDirScratch.length();
boolean var9 = false;
do {
Vector3d var10 = this.waypoints[this.cursor];
Vector3d var11 = this.waypoints[this.cursor + 1];
double var12 = var10.distance(var11);
double var14 = var12 * (1.0 - this.segmentProgress);
if (var5 + 1.0E-9 < var14) {
double var16 = var5 / var12;
this.segDirScratch.set(var11).sub(var10);
var4.fma(var16, this.segDirScratch);
this.segmentProgress += var16;
class="kw">return;
}
if (!var9) {
var4.set(var11).sub(var1);
var9 = true;
} else {
this.segDirScratch.set(var11).sub(var10);
var4.fma(1.0 - this.segmentProgress, this.segDirScratch);
}
this.cursor++;
this.segmentProgress = 0.0;
var5 -= var14;
this.skipDegenerateSegments();
if (this.cursor >= this.waypointCount - 1 || var5 <= 1.0E-9) {
this.carryOverDistance = MathUtil.clamp(var5, 0.0, var2 * 2.0);
class="kw">return;
}
} while (this.collinearWithReference(this.waypoints[this.cursor], this.waypoints[this.cursor + 1], var7));
this.carryOverDistance = Math.min(var5, var2 * 2.0);
}
}
}
class="kw">private void skipDegenerateSegments() {
while (this.cursor < this.waypointCount - 1 && this.waypoints[this.cursor].distanceSquared(this.waypoints[this.cursor + 1]) <= 1.0E-12) {
this.cursor++;
this.segmentProgress = 0.0;
}
}
class="kw">private boolean collinearWithReference(@Nonnull Vector3dc var1, @Nonnull Vector3dc var2, double var3) {
this.segDirScratch.set(var2).sub(var1);
double var5 = this.segDirScratch.length();
if (var5 <= 1.0E-6) {
class="kw">return false;
}
double var7 = this.referenceDirScratch.dot(this.segDirScratch) / (var3 * var5);
class="kw">return var7 >= 0.999999999;
}
class="kw">public void snapY(@Nonnull Vector3d var1) {
if (this.cursor < this.waypointCount - 1) {
Vector3d var2 = this.waypoints[this.cursor];
Vector3d var3 = this.waypoints[this.cursor + 1];
double var4 = var2.y + (var3.y - var2.y) * this.segmentProgress;
if (Math.abs(var1.y - var4) > 1.0E-6) {
var1.y = var4;
}
}
}
class="kw">private Vector3d nextWaypoint() {
if (this.waypointCount == this.waypoints.length) {
int var1 = this.waypoints.length;
this.waypoints = Arrays.copyOf(this.waypoints, var1 + 4);
for (int var2 = var1; var2 < this.waypoints.length; var2++) {
this.waypoints[var2] = new Vector3d();
}
this.ensureSegmentCommitCapacity(this.waypoints.length - 1);
}
class="kw">return this.waypoints[this.waypointCount++];
}
class="kw">private void ensureSegmentCommitCapacity(int var1) {
if (var1 > this.segmentCommitTypes.length) {
int var2 = this.segmentCommitTypes.length;
this.segmentCommitTypes = Arrays.copyOf(this.segmentCommitTypes, var1);
Arrays.fill(this.segmentCommitTypes, var2, this.segmentCommitTypes.length, RailPath.SegmentCommitType.NONE);
}
}
class="kw">private int getActiveSegmentIndex() {
if (this.waypointCount > 1 && this.cursor < this.waypointCount - 1) {
int var1 = this.cursor;
if (this.segmentProgress >= 0.999999 && var1 < this.waypointCount - 2) {
var1++;
}
class="kw">return var1;
} else {
class="kw">return -1;
}
}
class="kw">public class="kw">static class="kw">final class Projection {
class="kw">private class="kw">final Vector3d position = new Vector3d();
class="kw">private int segmentIndex;
class="kw">private double segmentProgress;
class="kw">private double distanceSquared;
class="kw">public Projection() {
}
class="kw">private void reset() {
this.position.zero();
this.segmentIndex = 0;
this.segmentProgress = 0.0;
this.distanceSquared = Double.POSITIVE_INFINITY;
}
@Nonnull
class="kw">public Vector3dc getPosition() {
class="kw">return this.position;
}
class="kw">public int getSegmentIndex() {
class="kw">return this.segmentIndex;
}
class="kw">public double getSegmentProgress() {
class="kw">return this.segmentProgress;
}
class="kw">public double getDistanceSquared() {
class="kw">return this.distanceSquared;
}
}
class="kw">public enum SegmentCommitType {
NONE(false),
SLOPE_UP(true),
SLOPE_DOWN(true),
SKIP_DIP(true);
class="kw">private class="kw">final boolean committed;
SegmentCommitType(boolean nullxx) {
this.committed = nullxx;
}
class="kw">public boolean isCommitted() {
class="kw">return this.committed;
}
}
}