Skip to content

Commit

Permalink
Fix path fixture having issues on the end (reported by Agirres) and f…
Browse files Browse the repository at this point in the history
…ix void on first tick
  • Loading branch information
mchorse committed May 14, 2019
1 parent ef4b77b commit 5c05fee
Showing 1 changed file with 37 additions and 16 deletions.
53 changes: 37 additions & 16 deletions src/main/java/mchorse/aperture/camera/fixtures/PathFixture.java
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ public void applyFixture(long ticks, float partialTicks, CameraProfile profile,
float tick = ticks + partialTicks;

/* Just calculate enough for the speed for the difference */
if (tick != this.lastTick)
if (tick != this.lastTick || tick == 0)
{
this.applyPoint(this.lastPoint, 0, 0);
this.recalculate(tick, pos.angle);
Expand All @@ -305,11 +305,17 @@ public void applyFixture(long ticks, float partialTicks, CameraProfile profile,
}

/**
* Recalculate speed based thing
* Recalculate the point and given angle based on the keyframe-able
* constant speed feature.
*
* This is a quite fascinating piece of code. Hopefully, the
* comments below will help you
*/
private void recalculate(float tick, Angle angle)
{
/* Calculate the distance which must be reached */
/* Calculate the distance which must be reached at given tick
* (the target distance may exceed path's distance, see more
* comments below) */
float target = 0F;

for (int i = 0, c = (int) tick; i < c; i++)
Expand All @@ -320,8 +326,14 @@ private void recalculate(float tick, Angle angle)
target += this.speed.interpolate(tick) * (tick % 1);
target /= 20F;

/* Try to calculate the actual distance traveled */
/* Try to calculate the actual distance traveled.
*
* The loop below doesn't yield *exact* position based on ticks
* but rather an approximation. It starts from beginning, and
* tries to calculate the point that is close enough to the
* target */
int index = 0;
int size = this.points.size() - 1;
float progress = 0;
float distance = 0;
float factor = 0.1F;
Expand All @@ -331,6 +343,8 @@ private void recalculate(float tick, Angle angle)
{
progress += factor;

/* To avoid infinite loop, we break things here. Factor with
* every iteration is definitely getting smaller */
if (factor == 0 || Math.abs(factor) < 0.0000001F)
{
this.applyPoint(this.lastPoint, index, progress);
Expand All @@ -339,14 +353,13 @@ private void recalculate(float tick, Angle angle)
return;
}

/* Navigate progress into correct direction */
if (progress > 1)
{
if (index >= this.points.size() - 1)
if (index >= size)
{
this.applyPoint(this.lastPoint, index, 1);
this.applyAngle(angle, index, progress);

break;
progress = 1;
factor *= -0.5F;
}
else
{
Expand All @@ -360,11 +373,6 @@ else if (progress < 0)
{
progress = 0;
factor *= -0.5F;

if (factor == 0 || factor == -0)
{
factor = 0.05F;
}
}
else
{
Expand All @@ -373,20 +381,33 @@ else if (progress < 0)
}
}

/* Calculate distance and delta from previous iteration */
this.applyPoint(this.tmpPoint, index, progress);
float dx = this.tmpPoint.x - this.lastPoint.x;
float dy = this.tmpPoint.y - this.lastPoint.y;
float dz = this.tmpPoint.z - this.lastPoint.z;
this.lastPoint.set(this.tmpPoint.x, this.tmpPoint.y, this.tmpPoint.z);

distance += Math.sqrt(dx * dx + dy * dy + dz * dz) * (factor > 0 ? 1 : -1);
float delta = Math.abs(target - distance);

/* This piece makes sure that if the path's distance is less
* than targets, that means that we reached the end of the
* path, so there is no point getting closet to the target */
if (progress == 1 && index >= size && distance < target)
{
break;
}

if (diff < Math.abs(target - distance))
/* If last difference is less than new delta between target
* distance and path distance, then we're going away from
* target, align factor back into target's direction */
if (diff < delta)
{
factor *= -0.5F;
}

diff = Math.abs(target - distance);
diff = delta;
}

this.applyAngle(angle, index, progress);
Expand Down

0 comments on commit 5c05fee

Please sign in to comment.