Camera following position AND rotation?

Hi all!

Newbie question: For a flightsimulator I’d like to have a camera following a target not only concerning its position, but also rotation. Staying always behind the airplane with same orientation, so to say. Even in loopings and rolls. Best connected with a rubberband.

Is there a way to configure the existing cameras for that? Or a snippet on how to realize?

Thank you very much,

. J

Hey @Joerg_Plewe! Check out the Playground in Raycast to check if player is standing on ground for a third-person camera using ArcRotateCamera.

I’m trying out FlyCamera but I’m pretty sure I’m doing it wrong.

I listen to the state of my flight model and place the camera accordingly:

flightmodel.stateObservable.add( (s) => {
// place it behind the plane
this.camera.position = s.position.add( new Vector3(0, 0, 20).rotateByQuaternionToRef(s.orientation, Vector3.Zero()) );
// camera somehow looks backwards, so turn it
const q = Quaternion.FromEulerAngles(0, Math.PI, 0);
s.orientation.multiplyToRef(q, q);
this.camera.rotationQuaternion = q;
});

This way I’m loosing all inertia an such. Anybody has an example on how to use FlyCamera correctly?

@Joerg_Plewe Found this older Question post, where @Wingnut linked an awesome Playground that uses FollowCamera.

1 Like

Hi guys! There is such a thing as followCam and ArcFollowCam… might be useful.

And, with JS, everything is “hack-able”… modify things until they do what you want.

[ link to followCam and arcFollowCam typeScript source ]

Need the JS instead of TS?

https://raw.githubusercontent.com/BabylonJS/Babylon.js/master/dist/babylon.max.js

Search for var followCamera and var arcFollowCamera to find the JS code. It USED TO BE easier to steal code from those areas and paste into projects, but the webpack junk in JS… makes it more difficult these days. Sorry.

Good luck. FollowCameras are quite powerful and feature-packed. Take careful notice of all their properties and methods, and also notice all the things they inherit from their superClass… targetCam.

JP - You might wish to use our playground within-the-code search… for flyCamera.

And don’t forget the camera DOCS.

(I think I saw my friend @JohnK about to post a reminder of the camera docs. I want to win the race.) :smiley:

2 Likes

Some of the original discussions about the flycamera - might give you some insight

https://www.html5gamedevs.com/topic/40130-cameras-discussion-inputs-incongruity/page/2/?tab=comments#comment-230726


2 Likes

I trried FollowCamera which comes close to what I need, although it doesn’t roll.

BUT … FollowCamera introduces significant jitter. Others observed that, too: How to remove Camera Movement Jitter

This is particularly strange bc. I cannot reproduce it in playground. OTOH it remains in my flightsimulator even when I reduce it to the bare minimum of a freefalling box. The jitter reduces the smaller I make the cameraAcceleration parameter. It also seems to vary between browsers and machines. It does not happen with any other camera implementation.

Anybody else observed similar effects?

Hi JP… sorry to hear about the jitter. I’m a bit swamped with real life at the moment… but maybe look into putting camera.update() and/or camera.rebuildAnglesAndRadius() (for arc-Follow) inside the renderLoop (to be done constantly). No promises… and I’m really guessing/speculating, here.

Ensure that camera.applyGravity is NOT set true… because certain cameras (sub-classes of free cams particularly)… might have a camera.ellipse (a collider for when cam hits ground). Just possibly, camera is repeatedly “scrubbing” its collider (camera.ellipse)… against a .checkCollisions = true ground. Also check camera.inertia… might want to set it to 0.

I am just guessing - things to check-for… investigate. I’ll try to think of more ideas.

Use your console.log… to output EVERY CAMERA PROPERTY… to console… while camera is jittering. One of them… should show the jittering in its values.

Sometimes it is difficult to watch values at the JS console. Perhaps use console.clear() at times, and MAYBE… put many GUI-2d textBlock controls… into a GUI stackPanel control… on-screen (Gui 2d system). Then, display many camera properties [maybe with .toFixed(4)]… to those textBlocks… and watch the camera’s data THAT way.

Keep in mind that using .toFixed() causes a numeric value… to become a string value. That is no problem for Gui textBlock controls… they LIKE string dataType.

Perhaps, build a “rack” of camera “readouts” this wa, and feed those readouts with various camera properties… DURING a camera jitter-move. Ssee if you can “watch” a value doing the same “jittering”… and then… you’re on the trail to learning why the jitter is happening.

You might wish to search our OLD FORUM, too… for camera jitter info. https://www.html5gamedevs.com/search/?type=forums_topic&nodes=16,28,29,30,31,38

Good luck… I’ll come visit again when I have a moment.

Off-topic: I’m currently packing/cleaning… for a possible move 70 miles south… into my first-ever owned home… a used house trailer. I’ve hit the big time, eh? :slight_smile: (We anti-capitalism-ists are VERY broke… all the time. We can’t compete, only cooperate, but not cooperate with competing).

So, I’m crawling into, under and atop MANY old house trailers… trying to get max bang-for-buck… very muddy and time consuming. Wingy trying to survive, somehow… but I’m very tired from 40 years of renting and being controlled by greedy, uncaring, and edu-less landlords and rental managers/companies. TMI - sorry.

Maybe other forum helpers will pick-up my slack, for a bit. Thanks, gang. Be well!

1 Like

Thanks @Wingnut!

Unfortunately none of the proposed measure held, alone given the fact that I use plain FollowCamera, which does not have most of the methods/properties you mention.

To help myself I created a camera controller that takes control of a TargetCamera and can also roll. update() needs to get called once per frame (or once per physics update in my case).

import { Mesh } from '@babylonjs/core/Meshes';
import { TargetCamera } from '@babylonjs/core/Cameras/targetCamera';
import { Vector3, Quaternion } from '@babylonjs/core/Maths/math';

const TURN = Quaternion.FromEulerAngles(0, Math.PI, 0);

export class RubberbandCameraController {
  #_radius: number;
  #followTarget: Vector3;

  constructor(private camera: TargetCamera, private follow: Mesh) {
    this.radius = 15;
    camera.rotationQuaternion = TURN.clone();
    camera.position = follow.position.add( this.#followTarget );
  }

  set radius(r: number) {
    this.#_radius = r;
    this.#followTarget = new Vector3(0, 0, this.#_radius);
  }

  public update() {
    const c = this.camera;
    const p = this.follow.position;
    const q = this.follow.rotationQuaternion;
    const t = this.#followTarget.rotateByQuaternionToRef(q, Vector3.Zero() ).addInPlace(p);

    // interpolate position
    c.position = Vector3.Lerp(c.position, t, 0.1);

    // camera somehow looks backwards, so turn it
    const tq = q.multiply(TURN);

    // interpolate rotation
    Quaternion.SlerpToRef(c.rotationQuaternion, tq, 0.03, c.rotationQuaternion);
  }
}
1 Like