Phuein

Cameras Discussion - Inputs Incongruity

Recommended Posts

This is the order in which the cameras (relevant to me) extend each other, but also often override each other:

UniversalCamera extends TouchCamera extends FreeCamera extends TargetCamera [extends Camera.]

How come FreeCamera doesn't use rotationQauternion and allow rotation around its Z (roll) axis by default? After all, TargetCamera does use quaternions, even though it ignores the Z axis by design. But a FreeCamera should be that much free, right? Wrong?

I saw that FreeCamera abstracts its inputs. It would make sense for the mouse input to use quaternions for full freedom of rotation in all axis. Desu ne?

I'm itching to make a pull request that, while keeping backwards compatibility, adds more freedom to rotation (Z axis roll) and movement (QE for In/Out.) :P But I'm new, so I don't want to code stuff and then get denied.

 

Visualization aid:

Image result for roll pitch yaw

Share this post


Link to post
Share on other sites

No one will never get denied if the PR is good. There is no notion of new / old people :)

Btw, the FreeCamera is intended to be a FPS camera where you do not control the roll.

In your case I would suggest to create a new mouse input controller (BABYLON.freeCameraRollMouseInput ?) for the camera that can replace the current one so your change won't impact any user while serving the good purpose of supporting more features (I guess the roll is required if you want to use the camera to fly for instance)

Also please note that we are closing 3.3 now and so no feature PR will be merged until the release (oct 2)

Share this post


Link to post
Share on other sites
1 hour ago, Deltakosh said:

(BABYLON.freeCameraRollMouseInput ?) 

BABYLON.flightCamera😵😎as a new camera instead of new input controller?

Share this post


Link to post
Share on other sites

Would it be better to make the change to FreeCamera, with the default behaviour unchanged? and keep the number of different classes at a minimum?

I mean I am not a code designer at all, and I can't figure out what's best.

Share this post


Link to post
Share on other sites
2 minutes ago, Nodragem said:

Would it be better to make the change to FreeCamera, with the default behaviour unchanged? 

Quite possibly. I am just throwing the idea out there. In my opinion the camera for a FPS project would be controlled differently than one for a flying project.

5 minutes ago, Nodragem said:

and keep the number of different classes at a minimum

You could well be right. Let's see what further reactions there are.

Share this post


Link to post
Share on other sites

I see. So, both the new UniversalCamera and its predecessor FreeCamera are really FPSCamera. :P

FreeCamera doesn't have rotationQuaternion in its class, unlike TargetCamera (doesn't extend that part eh), and adding class properties to an input file would break logic. I actually like the InputsManager logic.

Then I agree. BABYLON.FlyCamera with its own inputs. It's a shame (on coders) to duplicate some of the movement code (such as some of the keyboard movement), but mixing everything up is a big bad salad, indeed.

I'll start working on my fork then, towards a PR. Any input welcome. 👌 

Share this post


Link to post
Share on other sites

(Pun not intended! I am just that funny.)

Wait a second. Why did the OrientationInput use rotationQuaternion, but not the normal MouseInput?? After all, rotationQuaternion works better for moving in 3 axis. (Keeping those options open, eh.)

Screenie shows why it seems like FreeCamera doesn't support it.

image.png

Share this post


Link to post
Share on other sites

[Link removed. FlyCamera is now available in BJS for experimenting.]

So, I've setup the new FlyCamera. I've put in two suggested methods of rotating and started testing. The first, which takes from the engine, seems broken. No Roll, and after turning around and over, the mouse movement is reversed.

The second, inspired from the engine and taken from forum user coolroar mostly works, but suffers from a mysterious bug where moving the camera in a circle will slowly Roll it.

I brought the whole experiment online and put overrides so it's testable and editable from my playground. 🙂 Feel free to play with it.

Any ideas for why these bugs occur, and how we can achieve a non-buggy FlyCamera? I'm pretty lost.

Share this post


Link to post
Share on other sites

"...suffers from a mysterious bug where moving the camera in a circle will slowly Roll it."

 Do you know that you will get roll naturally as you yaw when pitch != 0  ?

Test with pitch locked to zero: https://www.babylonjs-playground.com/index.html#Q1RH6C#2

Try locking pitch to 0.01 etc. (line 80).

😲 

Share this post


Link to post
Share on other sites

Hah, already responded to you on the 3D Camera topic, as well. :P

The goal isn't a locked camera. So no locking any axis.

And why do you get a roll from doing yaw and pitch? I can take an object and apply yaw and pitch without it rolling.

Share this post


Link to post
Share on other sites

Clarification of my previous post:

"... you will get roll as you yaw when pitch != 0"  should be:

" the horizon will tilt (relative to your craft) as you yaw when pitch != 0".

The tilted horizon makes you think your craft rolled.  (Since at computer we lack the physical sensations of yaw, pitch, & roll).

Imagine:

  1. You are heading North, straight and level.
  2. Then you pitch to straight up.
  3. Then you yaw PI/2 to the left.

What is your heading? Describe the horizon as seen looking straight ahead.

You are headed West, the horizon appears vertical with the ground out the left window. With no craft roll!

Pitch(PI/2), Yaw(PI/2) = Roll(PI/2), Pitch(PI/2) = Yaw(PI/2), Roll(PI/2)

A series of yaws and pitches can equal a roll: Roll(PI/2) =  Pitch(PI/2),  Yaw(PI/2),  Pitch(-PI/2).

(Check my work? 🙄)

I hope I'm not blathering stuff you already know.  😏

For the benefit of others, I'll also post this to

 

Share this post


Link to post
Share on other sites

PHEW Yikes. Your Imagine example is excellent! I've had trouble struggling to comprehend this issue in 3D rotations. Look up. Immediately look left. Yup, no roll but looks like a roll.

Okay, so the FlyCamera needs to mimic how humans maintain global Roll, when looking around. No Roll unless Rolled.

Share this post


Link to post
Share on other sites

Just some further thoughts on a FlyCamera. In your topic mentioned above by coolroar you talk about wanting your camera for a spaceship whereas (I think) coolroar is talking about an aircraft. Why is the difference important? What coolroar was saying about yaw, pitch and roll is still true, however in a spaceship pitch and roll can be zero when the yaw changes, this is not possible in an aircraft since physically an aircraft needs to use the air to bank when turning but for a spaceship there is no air and would use thrusters to turn. So a FlyCamera could have an airdensity parameter, with 0 for no air, getting larger for denser air which sets a roll when you try to yaw.

http://wtamu.edu/~cbaird/sq/2013/02/16/what-kind-of-space-ships-can-make-banking-turns/

Share this post


Link to post
Share on other sites

Weighing in re.  @JohnK  's post:
I regard camera.yawPitchRoll(y,p,r) in https://www.babylonjs-playground.com/index.html#Q1RH6C to be applicable to either aircraft, spacecraft, submarines, or ?.

Aircraft example:
The aircraft's bank indicator points in the direction of the vectorSum(gravity,  lateralAcceleration).
(lateralAcceleration derived from aircraft's turn rate.)
The pilot in real time controls yaw and roll for the desired turn, keeping the aircraft's roll aligned with the bank indicator.
I don't try to calculate yaw, pitch, & roll; I am in the loop, increasing or decreasing yaw, pitch, & roll according to
the bank indicator, the view, and where I want to go.

Although https://www.babylonjs-playground.com/index.html#Q1RH6C has no gravity, it does show how to control yaw, pitch, roll with mouse and arrow keys.

Spacecraft example:
I have quibbles with the info at http://wtamu.edu/~cbaird/sq/2013/02/16/what-kind-of-space-ships-can-make-banking-turns/ .
Baird says: "A space ship turns by reorienting and then firing its engines in the desired direction..."
If the spaceship was flying "west" the intended turn to "south" as illustrated does not remove the "westward" velocity component.

At some point the ship must have a thrust component opposite the original velocity.

This illustration shows my speculation of the most efficient way to change course:

spaceshipsrm.png.b0ce248fb20b5033269ec75290dcae5e.png

So the pilot would use "attitude thrusters" to continuously orient the main thrusters perpendicular to the current course until achieving the desired course.

But in sci-fi movies and games people want to bank and swoop and dog-fight etc.
Here is a PG that uses an arbitrary bank: https://www.babylonjs-playground.com/#UL7W2M 
The terrain and stuff is just decoration; without it the PG would resemble typical s.f. fictional physics.

😏

Share this post


Link to post
Share on other sites

Agreed about having an option for banking/air-density.

Also, an option to mimic a spaceship's momentum in space is valid, as well.

However, I find myself stumped at figuring out how to add the [option for] Roll-correction (maintain Roll when Yawing and Pitching.) Boosting up my reading on Quaternions, but it's still not clear to me. Just like our heads do, the default for FlyCamera is to enable Roll-correction, so when users move around (like a ghost!) their view of the world only Rolls when they choose it to do so. Without locking them when Pitching at 90°!

The logic would be: When the FlyCamera is Pitched beyond 0° (or Math.PI/2),  and then any Yaw is applied, the necessary Roll is applied so that when the Yaw is at 0° -> Roll is also at 0°, and when Yaw is at 90° -> Roll is not modified from its current angle.

Just like our human heads do it. :) Stumped... I made a slowCorrect option, which works nicely, but it's not the smart solution for this... So, stumped...

To talk in code, here is slowCorrect:

this._rollObserver = this.camera.getScene().onBeforeRenderObservable.add(
    () => {
        if (!this.camera.slowCorrect) return;

        let limit = Math.round(_this._trackRoll * 10000) / 10000; // Target Roll.
        let z = Math.round(_this.camera.rotation.z * 10000) / 10000; // Current Roll.
        let delta = limit - z;
        let rate = 100; // Higher means more time to rotate before fixed Roll.

        if (z !== limit) {
            // Change Z rotation towards the target Roll.
            _this.camera.rotation.z += delta / rate;

            // Match when near enough.
            if (Math.abs(limit - _this.camera.rotation.z) <= 0.001) {
                _this.camera.rotation.z = limit;
            }
        }
    }
);

 

And here's some mess (DOES NOT WORK) from me experimenting with trying to apply Roll correction instantly, relying on coolroar's code:

(Can play with FlyCamera and this function {look at bottom of PG code for "function rotateCameraTest"} at [Link removed. FlyCamera is now available in BJS for experimenting.])

var x = offsetX / this.angularSensibility;
var y = offsetY / this.angularSensibility;

// Initialize to current rotation.
var currentRotation = BABYLON.Quaternion.RotationYawPitchRoll(camera.rotation.y, camera.rotation.x, camera.rotation.z);
var rotationChange: BABYLON.Quaternion;

// Yaw and Pitch by default.
// Maintain global Roll.
if (this.activeButton !== 2) {
    // Apply change in Radians to vector Angle.
    rotationChange = BABYLON.Quaternion.RotationAxis(BABYLON.Axis.Y, x);
    // Apply Yaw to quaternion.
    currentRotation.multiplyInPlace(rotationChange);

    // Apply change in Radians to vector Angle.
    rotationChange = BABYLON.Quaternion.RotationAxis(BABYLON.Axis.X, y);
    // Apply Pitch to quaternion.
    currentRotation.multiplyInPlace(rotationChange);

    // I could make it slowly auto-correct the Roll, but that would be stupid.
    if (!camera.slowCorrect) {
        // I want it to correct Roll live, like human heads do.
        // The problem is that immediate correction locks the Roll axis!
        // Pitch all the way up, and you can't Yaw to the side at all.

        // trackRoll is Roll.
        // Roll is 0 when Yaw is 0.
        // If Pitched, when Yawing correct the Roll to the same degree.
        // If Pitched, reduce the Yaw from the Roll to flatness.
        // let testRotation = camera.rotation.y()
        // let rx = testRotation.x;
        // let ry = testRotation.y;
        // let flat = Math.PI;
        // if (Math.PI % camera.rotation.x !== 0) {
            // y + z = flat
            // z = flat - y
            // + tracked roll
            // x = 1.5707963267948966       (Math.PI / 180) * 90           90°
            // y = 0.017453292519943295     (Math.PI / 180) * 1            1°       z = 1°
            // y = 1.5707963267948966       (Math.PI / 180) * 90           90°      z = 0°
            // testRotation.z = Math.abs(flat % ry) + this._trackRoll;
            // let delta = Math.abs(camera.rotation.z - testRotation.z);

            // Apply change in Radians to vector Angle.
            rotationChange = BABYLON.Quaternion.RotationAxis(BABYLON.Axis.Z, Math.PI % x);
            // Apply Roll to quaternion.
            currentRotation.multiplyInPlace(rotationChange);
        // }
    }

    // Apply rotationQuaternion to Euler camera.rotation.
    currentRotation.toEulerAnglesToRef(camera.rotation);
}

 

Share this post


Link to post
Share on other sites

This has already been done, it's called  BABYLON.UniversalCamera(...)!

I believe that if you successfully automatically adjust roll continuously so that the horizon stays level, you'll have BABYLON.UniversalCamera the hard way.

Hmm...  I may be going out on a limb with that.

See my  April 3 post: 

 

💡 !

Share this post


Link to post
Share on other sites

UniversalCamera is just an added layer on top of FreeCamera that draws from the same MouseInput file. So it doesn't do that.

I'm still experimenting, but still very stumped. I can't figure out how to produce mathematically the relationship between Pitch and Yaw with Roll, so that it fixes itself in the given conditions (as described above.)

Share this post


Link to post
Share on other sites

Roll correction and [non-physical] banking seem to work nicely. I still have no idea on how to figure out human-like Roll correction. Hopefully, more experienced coders can provide their input.

[Link removed. FlyCamera is now available in BJS for experimenting.]

Share this post


Link to post
Share on other sites

FlyCamera as first draft is getting merged, so everyone can see and edit and suggest. :)

https://github.com/BabylonJS/Babylon.js/pull/5286

https://github.com/BabylonJS/Babylon.js/tree/master/src/Cameras (notice "fly" prefix.)

It doesn't have inertia yet. It doesn't have Touch controls support yet. I'm back into my own project for the moment, so I'm still stumped with immediate Roll correction (mimic human head) too. Taking a break tends to help.

You can make a PR, or post code suggestions here that I'll edit and integrate. 👻

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.