HitSide enum

Пакет: com.hypixel.hytale.server.npc.movement.controllers

Файл: com/hypixel/hytale/server/npc/movement/controllers/RailPathSmoother.java

Поля (1)

МодификаторыТипИмя
BEFORE_TARGET, AFTER_TARGET, UNKNOWN

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.npc.movement.controllers;

class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import java.util.Arrays;
class="kw">import java.util.Locale;
class="kw">import java.util.logging.Level;
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 RailPathSmoother {
   class="kw">private class="kw">static class="kw">final int DEFAULT_INITIAL_CAPACITY = 8;
   class="kw">private class="kw">static class="kw">final int GROWTH_INCREMENT = 4;
   class="kw">private class="kw">static class="kw">final double VERTICAL_EPSILON = 1.0E-6;
   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 INITIAL_DIP_COLLAPSE_MAX_DISTANCE = 1.0;
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">private Vector3d[] waypoints;
   class="kw">private RailPath.SegmentCommitType[] waypointSegmentCommitTypes;
   class="kw">private int waypointCount;
   class="kw">private double[] horizontalRunEndDistance;
   class="kw">private double[] horizontalRunY;
   class="kw">private RailPath.SegmentCommitType[] horizontalRunTransitionCommitTypes;
   class="kw">private int horizontalRunCount;
   class="kw">private boolean debug;
   class="kw">private class="kw">final Vector3d startPos = new Vector3d();
   class="kw">private class="kw">final Vector3d horizDir = new Vector3d();
   class="kw">private class="kw">final Vector3d waypointScratch = new Vector3d();
   class="kw">private class="kw">final Vector3d projectionScratch = new Vector3d();

   class="kw">public RailPathSmoother() {
      this(8);
   }

   class="kw">public RailPathSmoother(int var1) {
      if (var1 < 1) {
         var1 = 1;
      }

      this.waypoints = new Vector3d[var1];

      for (int var2 = 0; var2 < this.waypoints.length; var2++) {
         this.waypoints[var2] = new Vector3d();
      }

      this.waypointSegmentCommitTypes = new RailPath.SegmentCommitType[Math.max(1, var1 - 1)];
      Arrays.fill(this.waypointSegmentCommitTypes, RailPath.SegmentCommitType.NONE);
      this.horizontalRunEndDistance = new double[var1];
      this.horizontalRunY = new double[var1];
      this.horizontalRunTransitionCommitTypes = new RailPath.SegmentCommitType[Math.max(1, var1 - 1)];
      Arrays.fill(this.horizontalRunTransitionCommitTypes, RailPath.SegmentCommitType.NONE);
   }

   class="kw">public void reset() {
      this.waypointCount = 0;
      this.horizontalRunCount = 0;
      Arrays.fill(this.waypointSegmentCommitTypes, RailPath.SegmentCommitType.NONE);
      Arrays.fill(this.horizontalRunTransitionCommitTypes, RailPath.SegmentCommitType.NONE);
   }

   class="kw">public void setDebug(boolean var1) {
      this.debug = var1;
   }

   @Nonnull
   class="kw">public Vector3d[] getWaypoints() {
      class="kw">return this.waypoints;
   }

   class="kw">public int getWaypointCount() {
      class="kw">return this.waypointCount;
   }

   @Nonnull
   class="kw">public RailPath.SegmentCommitType[] getWaypointSegmentCommitTypes() {
      class="kw">return this.waypointSegmentCommitTypes;
   }

   class="kw">public void smooth(
      @Nonnull ProbeMoveData var1, @Nonnull MotionController var2, @Nonnull RailPathSmoother.Config var3, @Nullable RailPathSmoother.ContactContext var4
   ) {
      this.reset();
      ProbeMoveData.Segment[] var5 = var1.segments;
      int var6 = var1.segmentCount;
      if (var5 != null && var6 > 0) {
         if (var6 == 1) {
            this.emitWaypoint(var5[0].position, RailPath.SegmentCommitType.NONE);
            this.logDebugOutput(var1, var2, var4);
         } else if (!var2.is2D()) {
            this.emitWaypoint(var5[0].position, RailPath.SegmentCommitType.NONE);
            this.emitWaypoint(var5[var6 - 1].position, RailPath.SegmentCommitType.NONE);
            this.logDebugOutput(var1, var2, var4);
         } else {
            double var7 = computeProjectedDirection(var1.initialPosition, var1.targetPosition, var2.getComponentSelector(), this.horizDir);
            if (var7 > 1.0E-6) {
               this.horizDir.div(var7);
            } else {
               this.horizDir.zero();
            }

            this.startPos.set(var5[0].position);
            this.buildHorizontalRuns(var5, var6);
            this.collapseInitialZeroDistanceDip();
            this.skipShortDipRuns(var3, var4);
            this.emitWaypoint(var5[0].position, RailPath.SegmentCommitType.NONE);
            int var9 = 0;

            while (var9 < this.horizontalRunCount - 1) {
               double var10 = var9 <= 0 ? 0.0 : this.horizontalRunEndDistance[var9 - 1];
               double var12 = this.horizontalRunEndDistance[var9];
               double var14 = this.horizontalRunY[var9];
               double var16 = this.horizontalRunY[var9 + 1];
               boolean var18 = var16 < var14 - 1.0E-6;
               boolean var19 = var16 > var14 + 1.0E-6;
               boolean var20 = false;
               if (var18 && var9 + 2 < this.horizontalRunCount && this.horizontalRunY[var9 + 2] > var16 + 1.0E-6) {
                  double var21 = this.computeDropEndDistance(var9, var3, var4);
                  double var23 = this.computeClimbStartDistance(var9 + 1, var3, var4);
                  if (var21 > var23 + 1.0E-6 && var3.dropSlope > 0.0 && var3.climbSlope > 0.0) {
                     double var25 = this.computeDropClimbIntersectionDistance(var9, var3);
                     double var27 = var12;
                     double var29 = this.horizontalRunEndDistance[var9 + 1];
                     if (var25 < var27) {
                        var25 = var27;
                     } else if (var25 > var29) {
                        var25 = var29;
                     }

                     if (isDistanceInsideRun(var4, var27, var29)) {
                        var25 = var4.hitDistanceS;
                     }

                     this.emitWaypoint(var12, var14, RailPath.SegmentCommitType.NONE);
                     this.emitWaypoint(var25, var16, RailPath.SegmentCommitType.SLOPE_DOWN);
                     this.emitWaypoint(this.horizontalRunEndDistance[var9 + 1], this.horizontalRunY[var9 + 2], RailPath.SegmentCommitType.SLOPE_UP);
                     var9 += 2;
                     var20 = true;
                  }
               }

               if (!var20) {
                  if (var19 && var3.climbSlope > 0.0) {
                     double var33 = var16 - var14;
                     double var34 = var33 * var3.climbSlope;
                     double var35 = var12 - var34;
                     if (var35 < var10) {
                        var35 = var10;
                     }

                     if (isDistanceInsideRun(var4, var10, var12)) {
                        var35 = Math.max(var35, var4.hitDistanceS);
                     }

                     this.emitWaypoint(var35, var14, this.horizontalRunTransitionCommitTypes[var9]);
                     this.emitWaypoint(var12, var16, RailPath.SegmentCommitType.SLOPE_UP);
                  } else if (var18 && var3.dropSlope > 0.0) {
                     double var32 = this.computeDropEndDistance(var9, var3, var4);
                     this.emitWaypoint(var12, var14, this.horizontalRunTransitionCommitTypes[var9]);
                     this.emitWaypoint(var32, var16, RailPath.SegmentCommitType.SLOPE_DOWN);
                  } else {
                     this.emitWaypoint(var12, var14, this.horizontalRunTransitionCommitTypes[var9]);
                     this.emitWaypoint(var12, var16, RailPath.SegmentCommitType.NONE);
                  }

                  var9++;
               }
            }

            RailPath.SegmentCommitType var31 = this.horizontalRunCount == 1 ? this.horizontalRunTransitionCommitTypes[0] : RailPath.SegmentCommitType.NONE;
            this.emitWaypoint(this.horizontalRunEndDistance[this.horizontalRunCount - 1], this.horizontalRunY[this.horizontalRunCount - 1], var31);
            this.emitFinalWaypoint(var5[var6 - 1], var3);
            this.logDebugOutput(var1, var2, var4);
         }
      }
   }

   class="kw">private void emitFinalWaypoint(@Nonnull ProbeMoveData.Segment var1, @Nonnull RailPathSmoother.Config var2) {
      if (var1.type == ProbeMoveData.Segment.Type.BLOCKED_WALL && !(var2.blockedWallEndOffset <= 0.0)) {
         this.waypointScratch.set(var1.position).fma(var2.blockedWallEndOffset, this.horizDir);
         this.emitWaypoint(this.waypointScratch, RailPath.SegmentCommitType.NONE);
      } else {
         this.emitWaypoint(var1.position, RailPath.SegmentCommitType.NONE);
      }
   }

   class="kw">private void buildHorizontalRuns(@Nonnull ProbeMoveData.Segment[] var1, int var2) {
      this.ensureHorizontalRunCapacity(var2);
      this.horizontalRunCount = 0;
      double var3 = var1[0].position.y;
      double var5 = var1[0].distance;

      for (int var7 = 1; var7 < var2; var7++) {
         Vector3d var8 = var1[var7 - 1].position;
         Vector3d var9 = var1[var7].position;
         if (!(Math.abs(var9.y - var8.y) <= 1.0E-6)) {
            double var10 = var1[var7 - 1].distance;
            boolean var12 = this.horizontalRunCount == 0 && var10 == var5;
            if (var10 > var5 + 1.0E-6 || var12) {
               this.addHorizontalRun(var10, var3);
               var5 = var10;
            }

            var3 = var9.y;
         }
      }

      double var13 = var1[var2 - 1].distance;
      if (var13 > var5 + 1.0E-6 || this.horizontalRunCount == 0) {
         this.addHorizontalRun(var13, var3);
      }

      int var14 = Math.max(0, this.horizontalRunCount - 1);
      if (var14 > 0) {
         Arrays.fill(this.horizontalRunTransitionCommitTypes, 0, var14, RailPath.SegmentCommitType.NONE);
      }
   }

   class="kw">private void addHorizontalRun(double var1, double var3) {
      if (this.horizontalRunCount > 0) {
         double var5 = this.horizontalRunEndDistance[this.horizontalRunCount - 1];
         assert var1 >= var5 : "Malformed ProbeMoveData: horizontal run end distances must be non-decreasing";
      }

      this.horizontalRunEndDistance[this.horizontalRunCount] = var1;
      this.horizontalRunY[this.horizontalRunCount] = var3;
      this.horizontalRunCount++;
   }

   class="kw">private void ensureHorizontalRunCapacity(int var1) {
      if (this.horizontalRunEndDistance.length < var1) {
         this.horizontalRunEndDistance = Arrays.copyOf(this.horizontalRunEndDistance, var1);
         this.horizontalRunY = Arrays.copyOf(this.horizontalRunY, var1);
         int var2 = Math.max(1, var1 - 1);
         int var3 = this.horizontalRunTransitionCommitTypes.length;
         this.horizontalRunTransitionCommitTypes = Arrays.copyOf(this.horizontalRunTransitionCommitTypes, var2);
         Arrays.fill(this.horizontalRunTransitionCommitTypes, var3, this.horizontalRunTransitionCommitTypes.length, RailPath.SegmentCommitType.NONE);
      }
   }

   class="kw">private void collapseInitialZeroDistanceDip() {
      if (this.horizontalRunCount >= 3) {
         if (!(this.horizontalRunEndDistance[0] > 1.0E-6)) {
            double var1 = this.horizontalRunEndDistance[1] - this.horizontalRunEndDistance[0];
            boolean var3 = var1 <= 1.000001;
            boolean var4 = this.horizontalRunY[1] < this.horizontalRunY[0] - 1.0E-6 && this.horizontalRunY[2] > this.horizontalRunY[1] + 1.0E-6;
            boolean var5 = this.horizontalRunY[2] >= this.horizontalRunY[0] - 1.0E-6;
            if (var4 && var3 && var5) {
               for (int var6 = 1; var6 < this.horizontalRunCount - 1; var6++) {
                  this.horizontalRunEndDistance[var6] = this.horizontalRunEndDistance[var6 + 1];
                  this.horizontalRunY[var6] = this.horizontalRunY[var6 + 1];
               }

               if (this.horizontalRunCount > 2) {
                  this.horizontalRunTransitionCommitTypes[0] = mergeCommitTypes(
                     mergeCommitTypes(this.horizontalRunTransitionCommitTypes[0], this.horizontalRunTransitionCommitTypes[1]),
                     RailPath.SegmentCommitType.SKIP_DIP
                  );
                  int var8 = this.horizontalRunCount - 2;

                  for (int var7 = 1; var7 < var8; var7++) {
                     this.horizontalRunTransitionCommitTypes[var7] = this.horizontalRunTransitionCommitTypes[var7 + 1];
                  }

                  this.horizontalRunTransitionCommitTypes[var8] = RailPath.SegmentCommitType.NONE;
               }

               this.horizontalRunCount--;
            }
         }
      }
   }

   class="kw">private void skipShortDipRuns(@Nonnull RailPathSmoother.Config var1, @Nullable RailPathSmoother.ContactContext var2) {
      if (this.horizontalRunCount >= 3) {
         boolean var3 = var2 != null && var2.valid && Double.isFinite(var2.hitDistanceS);
         int var4 = 1;

         while (var4 < this.horizontalRunCount - 1) {
            double var5 = this.horizontalRunY[var4 - 1];
            double var7 = this.horizontalRunY[var4];
            double var9 = this.horizontalRunY[var4 + 1];
            boolean var11 = Math.abs(var5 - var9) <= 1.0E-6 && var5 > var7 + 1.0E-6;
            if (!var11) {
               var4++;
            } else {
               double var12 = this.horizontalRunEndDistance[var4 - 1];
               double var14 = this.horizontalRunEndDistance[var4];
               double var16 = var14 - var12;
               boolean var18 = var3 && var2.hitDistanceS >= var12 - 1.0E-6 && var2.hitDistanceS <= var14 + 1.0E-6;
               if (!(var16 > var1.horizontalSkipGapWidth + 1.0E-6) && !var18) {
                  this.horizontalRunTransitionCommitTypes[var4 - 1] = mergeCommitTypes(
                     mergeCommitTypes(this.horizontalRunTransitionCommitTypes[var4 - 1], this.horizontalRunTransitionCommitTypes[var4]),
                     RailPath.SegmentCommitType.SKIP_DIP
                  );
                  this.horizontalRunEndDistance[var4 - 1] = this.horizontalRunEndDistance[var4 + 1];
                  int var19 = this.horizontalRunCount - 2;

                  for (int var20 = var4; var20 < var19; var20++) {
                     this.horizontalRunEndDistance[var20] = this.horizontalRunEndDistance[var20 + 2];
                     this.horizontalRunY[var20] = this.horizontalRunY[var20 + 2];
                     this.horizontalRunTransitionCommitTypes[var20] = this.horizontalRunTransitionCommitTypes[var20 + 2];
                  }

                  this.horizontalRunCount = var19;
                  int var21 = Math.max(0, this.horizontalRunCount - 1);
                  if (var21 > 0 && var21 < this.horizontalRunTransitionCommitTypes.length) {
                     this.horizontalRunTransitionCommitTypes[var21] = RailPath.SegmentCommitType.NONE;
                  }

                  if (var4 > 1) {
                     var4--;
                  }
               } else {
                  var4++;
               }
            }
         }
      }
   }

   class="kw">private class="kw">static boolean isDistanceInsideRun(@Nullable RailPathSmoother.ContactContext var0, double var1, double var3) {
      class="kw">return var0 != null && var0.valid && Double.isFinite(var0.hitDistanceS) && var0.hitDistanceS >= var1 - 1.0E-6 && var0.hitDistanceS <= var3 + 1.0E-6;
   }

   class="kw">private double computeClimbStartDistance(int var1, @Nonnull RailPathSmoother.Config var2, @Nullable RailPathSmoother.ContactContext var3) {
      double var4 = var1 <= 0 ? 0.0 : this.horizontalRunEndDistance[var1 - 1];
      double var6 = this.horizontalRunEndDistance[var1];
      double var8 = this.horizontalRunY[var1];
      double var10 = this.horizontalRunY[var1 + 1];
      if (var2.climbSlope <= 0.0) {
         class="kw">return var6;
      }

      double var12 = var10 - var8;
      double var14 = var6 - var12 * var2.climbSlope;
      if (var14 < var4) {
         var14 = var4;
      }

      if (isDistanceInsideRun(var3, var4, var6)) {
         var14 = Math.max(var14, var3.hitDistanceS);
      }

      class="kw">return var14;
   }

   class="kw">private double computeDropEndDistance(int var1, @Nonnull RailPathSmoother.Config var2, @Nullable RailPathSmoother.ContactContext var3) {
      double var4 = this.horizontalRunEndDistance[var1];
      double var6 = this.horizontalRunEndDistance[var1 + 1];
      double var8 = this.horizontalRunY[var1];
      double var10 = this.horizontalRunY[var1 + 1];
      if (var2.dropSlope <= 0.0) {
         class="kw">return var4;
      }

      double var12 = var8 - var10;
      double var14 = var4 + var12 * var2.dropSlope;
      if (var14 > var6) {
         var14 = var6;
      }

      if (isDistanceInsideRun(var3, var4, var6)) {
         var14 = Math.min(var14, var3.hitDistanceS);
      }

      class="kw">return var14;
   }

   class="kw">private double computeDropClimbIntersectionDistance(int var1, @Nonnull RailPathSmoother.Config var2) {
      double var3 = this.horizontalRunEndDistance[var1];
      double var5 = this.horizontalRunY[var1];
      double var7 = this.horizontalRunEndDistance[var1 + 1];
      double var9 = this.horizontalRunY[var1 + 2];
      double var11 = 1.0 / var2.dropSlope + 1.0 / var2.climbSlope;
      class="kw">return Math.abs(var11) <= 1.0E-6 ? var3 : (var5 - var9 + var3 / var2.dropSlope + var7 / var2.climbSlope) / var11;
   }

   class="kw">private void emitWaypoint(double var1, double var3, @Nonnull RailPath.SegmentCommitType var5) {
      this.waypointScratch.set(this.startPos).fma(var1, this.horizDir);
      this.waypointScratch.y = var3;
      this.emitWaypoint(this.waypointScratch, var5);
   }

   class="kw">private void emitWaypoint(@Nonnull Vector3dc var1, @Nonnull RailPath.SegmentCommitType var2) {
      if (this.waypointCount <= 0 || !(this.waypoints[this.waypointCount - 1].distanceSquared(var1) <= 1.0E-12)) {
         int var3 = this.waypointCount - 1;
         this.nextWaypoint().set(var1);
         if (var3 >= 0) {
            this.ensureWaypointSegmentCommitCapacity(this.waypointCount - 1);
            this.waypointSegmentCommitTypes[var3] = var2;
         }
      }
   }

   @Nonnull
   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.ensureWaypointSegmentCommitCapacity(this.waypoints.length - 1);
      }

      class="kw">return this.waypoints[this.waypointCount++];
   }

   class="kw">private void ensureWaypointSegmentCommitCapacity(int var1) {
      if (var1 > this.waypointSegmentCommitTypes.length) {
         int var2 = this.waypointSegmentCommitTypes.length;
         this.waypointSegmentCommitTypes = Arrays.copyOf(this.waypointSegmentCommitTypes, var1);
         Arrays.fill(this.waypointSegmentCommitTypes, var2, this.waypointSegmentCommitTypes.length, RailPath.SegmentCommitType.NONE);
      }
   }

   @Nonnull
   class="kw">private class="kw">static RailPath.SegmentCommitType mergeCommitTypes(@Nonnull RailPath.SegmentCommitType var0, @Nonnull RailPath.SegmentCommitType var1) {
      if (var0 == RailPath.SegmentCommitType.SKIP_DIP || var1 == RailPath.SegmentCommitType.SKIP_DIP) {
         class="kw">return RailPath.SegmentCommitType.SKIP_DIP;
      } else {
         class="kw">return var0 != RailPath.SegmentCommitType.NONE ? var0 : var1;
      }
   }

   class="kw">private void logDebugOutput(@Nonnull ProbeMoveData var1, @Nonnull MotionController var2, @Nullable RailPathSmoother.ContactContext var3) {
      if (this.debug) {
         ProbeMoveData.Segment[] var4 = var1.segments;
         if (var4 != null && var1.segmentCount > 0) {
            boolean var5 = var3 != null && var3.valid && Double.isFinite(var3.hitDistanceS);
            double var6 = var5 ? var3.hitDistanceS : Double.NaN;
            StringBuilder var8 = new StringBuilder();
            var8.append("RailPathSmoother segments")
               .append('\n')
               .append(String.format(Locale.ROOT, "%-6s %-12s %-18s %-12s", "index", "distance", "type", "y"));

            for (int var9 = 0; var9 < var1.segmentCount; var9++) {
               ProbeMoveData.Segment var10 = var4[var9];
               double var11 = var9 <= 0 ? 0.0 : var4[var9 - 1].distance;
               double var13 = var10.distance;
               boolean var15 = var5 && var6 >= Math.min(var11, var13) - 1.0E-6 && var6 <= Math.max(var11, var13) + 1.0E-6;
               var8.append('\n').append(String.format(Locale.ROOT, "%-6d %-12.4f %-18s %-12.4f", var9, var10.distance, var10.type, var10.position.y));
               if (var15) {
                  var8.append(String.format(Locale.ROOT, " hitDistance=%s hitSide=%s", var6, var3.hitSide));
               }
            }

            LOGGER.at(Level.INFO).log("%s", var8);
            StringBuilder var17 = new StringBuilder();
            var17.append("RailPathSmoother horizontal runs").append('\n').append(String.format(Locale.ROOT, "%-6s %-12s %-12s", "index", "endDistance", "y"));

            for (int var18 = 0; var18 < this.horizontalRunCount; var18++) {
               double var20 = var18 <= 0 ? 0.0 : this.horizontalRunEndDistance[var18 - 1];
               double var21 = this.horizontalRunEndDistance[var18];
               assert var21 >= var20 : "Malformed ProbeMoveData: run end distance cannot be smaller than run start distance";
               boolean var23 = var5 && var6 >= var20 - 1.0E-6 && var6 <= var21 + 1.0E-6;
               var17.append('\n')
                  .append(String.format(Locale.ROOT, "%-6d %-12.4f %-12.4f", var18, this.horizontalRunEndDistance[var18], this.horizontalRunY[var18]));
               if (var23) {
                  var17.append(String.format(Locale.ROOT, " hitDistance=%s hitSide=%s", var6, var3.hitSide));
               }
            }

            LOGGER.at(Level.INFO).log("%s", var17);
            double var19 = computeProjectedDirection(
               var4[0].position, var4[var1.segmentCount - 1].position, var2.getComponentSelector(), this.projectionScratch
            );
            StringBuilder var12 = new StringBuilder();
            var12.append("RailPathSmoother waypoints").append('\n').append(String.format(Locale.ROOT, "%-6s %-12s %-12s", "index", "distance", "y"));

            for (int var22 = 0; var22 < this.waypointCount; var22++) {
               Vector3d var14 = this.waypoints[var22];
               double var24 = var19 <= 1.0E-6
                  ? 0.0
                  : computeProjectedDirection(var4[0].position, var14, var2.getComponentSelector(), this.projectionScratch)
                     / var19
                     * var4[var1.segmentCount - 1].distance;
               var12.append('\n').append(String.format(Locale.ROOT, "%-6d %-12.4f %-12.4f", var22, var24, var14.y));
            }

            LOGGER.at(Level.INFO).log("%s", var12);
         }
      }
   }

   class="kw">private class="kw">static double computeProjectedDirection(@Nonnull Vector3dc var0, @Nonnull Vector3dc var1, @Nonnull Vector3dc var2, @Nonnull Vector3d var3) {
      var3.set((var1.x() - var0.x()) * var2.x(), (var1.y() - var0.y()) * var2.y(), (var1.z() - var0.z()) * var2.z());
      class="kw">return var3.length();
   }

   class="kw">public class="kw">static class="kw">final class Config {
      class="kw">public double climbSlope;
      class="kw">public double dropSlope;
      class="kw">public double horizontalSkipGapWidth;
      class="kw">public double blockedWallEndOffset;

      class="kw">public Config() {
      }

      class="kw">public void reset() {
         this.climbSlope = 0.0;
         this.dropSlope = 0.0;
         this.horizontalSkipGapWidth = 0.0;
         this.blockedWallEndOffset = 0.0;
      }
   }

   class="kw">public class="kw">static class="kw">final class ContactContext {
      class="kw">public boolean valid;
      class="kw">public double hitDistanceS;
      class="kw">public double hitY;
      class="kw">public int hitSegmentIndex;
      @Nonnull
      class="kw">public RailPathSmoother.HitSide hitSide = RailPathSmoother.HitSide.UNKNOWN;
      class="kw">public double contactWindowHalfWidth;

      class="kw">public ContactContext() {
      }

      class="kw">public void reset() {
         this.valid = false;
         this.hitDistanceS = Double.NaN;
         this.hitY = Double.NaN;
         this.hitSegmentIndex = -1;
         this.hitSide = RailPathSmoother.HitSide.UNKNOWN;
         this.contactWindowHalfWidth = Double.NaN;
      }

      class="kw">public void setFrom(@Nonnull RailPathSmoother.ContactContext var1) {
         this.valid = var1.valid;
         this.hitDistanceS = var1.hitDistanceS;
         this.hitY = var1.hitY;
         this.hitSegmentIndex = var1.hitSegmentIndex;
         this.hitSide = var1.hitSide;
         this.contactWindowHalfWidth = var1.contactWindowHalfWidth;
      }
   }

   class="kw">public enum HitSide {
      BEFORE_TARGET,
      AFTER_TARGET,
      UNKNOWN;

      HitSide() {
      }
   }
}