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;
      }
   }
}