Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cameras: cameraDirection will now properly decrease when gravity is applied #14508

Closed

Conversation

PolygonalSun
Copy link
Contributor

@PolygonalSun PolygonalSun commented Nov 9, 2023

Recently an issue was found where the FreeCamera was not slowing down when gravity was active. This PR modifies the _collideWithWorld function to fix that issue.

Forum Link: https://forum.babylonjs.com/t/bug-free-camera-never-stop/45546/4

Proof for using deltaTime ratio as scaling factor for gravity:
Given the following variables:
r = initial offset
n = inertia
a = relative inertia (with respect to frame deltaTime ratio; currentDeltaTime/standardDeltaTime) = n^t
s = scale factor
t = deltaTime ratio = currentDeltaTime/standardDeltaTime
g = gravity
x = scaling ratio to apply to gravity

Working from our previous proof for relative inertia and scale factor (#14482), we know that a frames worth of work looks something like:
sra = rn^t + ... + rn

When working with gravity applied, the equation will look more like:
sra + xg = (rn^t + g) + ... + (rn + g)

x in this scenario is some ratio to multiply gravity by so that the same amount of gravity is applied to each frame as though it was 60 FPS. Next, let's reorganize things:
sra + xg = rn^t + ... + rn + (g + ... + g) = rn^t + ... + rn + t*g

We know that there are t terms for our geometric sum so that means if we are adding gravity to each, we have t number of g values. Therefore, we have tg at the end. By our first line, we know that sra = rn^t + ... + rn so we can use substitution to make things cleaner:
sra + xg = sra + tg

If we subtract sra from each side, we get:
xg = tg
x = t

Therefore, since gravity is just a constant and is unaffected by inertia, we can just multiply it by t (our deltaTime ratio).

@bjsplat
Copy link
Collaborator

bjsplat commented Nov 9, 2023

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

@bjsplat
Copy link
Collaborator

bjsplat commented Nov 9, 2023

@PolygonalSun PolygonalSun marked this pull request as ready for review November 9, 2023 21:57
packages/dev/core/src/Cameras/flyCamera.ts Outdated Show resolved Hide resolved
@PolygonalSun PolygonalSun marked this pull request as draft November 10, 2023 00:53
Copy link
Member

@RaananW RaananW left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note - if the camera gravity is being changed, so should the mesh moveWithCollision function.

Is there a path where the change is done on the collider level, instead of replicating it for every camera using collisions?

Comment on lines +365 to +371
if (this.inertia === 0) {
this._updatePosition(relativeInertia, scaleFactor);
this.cameraDirection.scaleInPlace(0);
} else {
this.cameraDirection.scaleInPlace(relativeInertia);
this._updatePosition(relativeInertia, scaleFactor);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's technically the only change that was needed to go back to the way things were before

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants