Jump to content

[solved] Strange camera rotation behavior, bug?


Hans
 Share

Recommended Posts

Hi @all,

I have a new Demo with strange camera behavior: http://www.babylonjs-playground.com/#2BCRRW

In the Demo is one player again (green box). The player has two children: the camera and a red box. The red box is the view direction of the player. You can move the player with WASD and the camera with the arrowkeys.

Now the Problem: You can rotate the player body by pressing the R key. I rotate also the camera, but the camera.getTarget() is very wrong. You can check it by moving around with the camera after some rotations.

Similar problem if I dont rotate the camera.

I want the vector of the camera view direction if I use camera.getTarget(), like i get if there is still no rotation.

Link to comment
Share on other sites

Hi Hans.  No working-around needed.  Un-parent everything from camera.  Perhaps try followCamera with .lockedTarget to track player.  And... player is a physics object, yes?  So, we don't use .rotation on physics objects, right?  player.physicsImpostor.physicsBody.angularVelocity.y = 5;  :)  (value dependent-upon ground-player friction settings)

You can also use a dual applyImpulse to rotate around a single axis, but that's more difficult.

I had a nice demo playground for ya, but I lost it in a browser crash (didn't save often enough).

FollowCamera has some nice "knobs and dials" to play-with... like acceleration and max speed, as well as rotational and positional offsets.  Crank-up its acceleration, and it will "stay with" a moving player quite nicely.  MAKE SURE you use .lockedTarget and not .target.  AND make sure you set its .lockedTarget AFTER you create its target (player).

Aww heck, I'll remake the PG I lost:  http://www.babylonjs-playground.com/#2BCRRW#1

Now, using a follow camera, which doesn't allow mouse-around, which sucks.  Not sure why that is. 

I am using angularVelocity.y for your 'R' key, now, and I installed a quick skybox to make things prettier.  I removed the gray box... it was too boring.  :D

I also made the ground smaller, so I could see more pretty skybox.  But now your player-move impulses are too powerful.  Player falls easily.  :)

No keys move the camera, now.  But followCamera is also following player MOVES, nicely. 

Anyway, .target and .lockedTarget had some changes, recently.  There was a property name conflict found, I think.  FreeCamera might use .lockedTarget and .target... differently than before.  Some playground examples, forum posts, and documentation... MAY BE outdated/superseded (wrong). 

Under certain circumstances, you might try repeatedly setting .target inside a render loop (perhaps for freeCam or arcCam).  Don't set .lockedTarget inside a render loop, though.  That would probably waste CPU cycles.  :)

Parenting cameras to mesh DOES have uses... but... when physics impostor is the boss of the parent mesh, the parent mesh might NOT be handing-down its .position, .rotation, and .scaling (the big three)... to children.  Parents NORMALLY hand-down "the big three" constantly, but not necessarily true when parent is controlled by physics impostor.  Physics impostor wants to be FAST and might not have time to update big-3.  *shrug*  Not sure.  Something to watch-for.  Install some console.logs of player.position and player.rotation (just AFTER doing a physics move/rotate).  Just possibly, they don't get updated... and so... CHILDREN of them don't get updated either. 

In other words, a camera parented to player might not rotate/move... when you rotate/move player impostor with impulse or velocity.  Perhaps impostor activity is not handed-down thru parent-children.  Test to see.  Hope this helps.  Be well.

Link to comment
Share on other sites

Hi @Wingnut again a lots of good and interesting information.:) Your PG is also prettier than my :D Your camera follows the mesh right, but i need the free view.

My demo works like I want, until I rotate. I want a free mouse-around camera view. It is like a head or an arm of the body. So I can use the camera.getTarget function to get the camera direction to do a lots of things like moving in view direction and so on. BUT: After a rotation the getTarget function gets wrong. The camera do not rotate with the body

Too see what I mean I coded up my demo: http://www.babylonjs-playground.com/#2BCRRW#2

I added a funny crosshair. All like I want and expect .... until I rotate :X
How can I fix the camera rotation / crosshair position with mesh rotation?

Link to comment
Share on other sites

*nod*  Sorry.  I am off-topic.  :)

http://www.babylonjs-playground.com/#2BCRRW#3

See lines 107 and 108.  *shrug*  Console output look any better?

https://github.com/BabylonJS/Babylon.js/blob/master/src/Cameras/babylon.targetCamera.ts#L222

camera.getTarget() simply returns camera._currentTarget property. 

SO, I searched through targetCamera source (free camera's superclass) to see which functions use ._currentTarget property.

camera._getViewMatrix() seems to do LOTS to ._currentTarget, so I tried calling IT in line 107 (and ignoring anything it returned).

It is a kludge, and I don't know if it will improve camera.getTarget results (after a player rotation - when camera is parented to player).

camera._currentTarget might need an update... from somewhere.  And perhaps you might have an issue with world rotation vs. local rotation.  Not sure.

But, really, Hans, why would you rotate the player in line 103 (which rotates the camera because it is a child of player),  and then you rotate the camera itself in line 104?  Seems... odd.  :)

How about a nice invisible mesh as a freeCamera target... and move that around, and parent it to various things, etc?  :)  That would be easy, yes?

Not sure if I can help.  Hopefully others will.

Link to comment
Share on other sites

 

1 hour ago, Wingnut said:

See lines 107 and 108.  *shrug*  Console output look any better?

unfortunately not. Problem is still: after a player rotation (with key R) the funny crosshair position (camera.getTarget) is wrong (dont rotate correct with the parent)

 

1 hour ago, Wingnut said:

But, really, Hans, why would you rotate the player in line 103 (which rotates the camera because it is a child of player).  And then you rotate the camera itself in line 104

I tried to fix the vector. Normal rotation from the parent dont work. The invisible mesh dont work too.

I think the camera rotates like the ArcRotateCamera in a small circle. the camera rotation (camera.rotation) influence the camera.getTarget(). But the rotations is not correct. I am buffled .:unsure::wacko:

 

Link to comment
Share on other sites

Playing:  http://www.babylonjs-playground.com/#2BCRRW#4

Camera not parented, player rotation turned off, rotating only camera with 'R' and watching .getTarget() at console... both for key-up and mouse-up.

It all starts fine (see console).  FreeCameras have a default target whose .position is 0, 0, 1, and first click on canvas reports proper numbers to console.

Then I rotate camera with 'r' and watch the getTarget() numbers on each rotate.  The "one-unit-ahead-of-camview-default-target" is rotating-around, too.  Not overly accurate... but it appears to be staying ALMOST 1 unit ahead of current camera view.

Next, maybe I'll try same tests with a (in-render-loop) .setTarget(something.position) or (not in-render-loop) .lockedTarget = something.   I think this PG is "echoing" at the console, too... due to no scene.onDispose removing the eventListeners.  I think we're getting eventListener doubling and tripling after a few RUN's.  *shrug*

Notice I am avoiding parenting the camera to ANYTHING?  I like it better that way.  :)  I want to test .getTarget() and .setTarget() and .lockedTarget first... before I add the complication of a parent.  :)  Ok, I'll shut up now, so the thread doesn't get too long, and others dislike helping us, because of that.

Link to comment
Share on other sites

2 hours ago, Deltakosh said:

The getTarget() returns the position of the target, if you want the direction you can get it by doing:  var direction = camera.getTarget().subtract(camera.position);

Yes I know. I use it for line 135 in the demo from above: http://www.babylonjs-playground.com/#2BCRRW#2 to station the crosshair.
After the player rotation the crosshair is not correct, because camera.getTarget() is not correct anymore.

Link to comment
Share on other sites

I dont know how can Iuse camera.globalPosition to get my behavior. :blink:

Strange for me is: I Set the crosshair in the middle of my camera with camera.getTarget().subtract(camera.position). I rotate the player. The camera rotates like the player because camera.parent = player.

Why leaves the crosshair my view? How can I hold it in the middle undependent from the player rotation?

Link to comment
Share on other sites

12 hours ago, Hans said:

Why leaves the crosshair my view? How can I hold it in the middle undependent from the player rotation?

How about parenting crosshair onto camera (plus some small z value)?  (Essentially, transparent glass over camera lens - with crosshairs/reticle painted on it)

Good conversations, though.  Thanks for helping, DK. 

GlobalPosition is good to learn,  but in #2 demo, camera and player are at origin.  They do not change... with each [r]otation.  Camera.position remains at 0,0,0.  See console on below PG, or test with modified #2 using console.log(camera.position) after each 'r' keypress.

Okay, time for a new BABY playground.  http://www.babylonjs-playground.com/#2BCRRW#7

No event listeners, but instead... rotate every 5 seconds (lines 39-43).  Currently ONLY rotating camera, and not camera parent.   Crosshair alignment code (lines 52-56) working good.

Now activate line 40.  Crosshair code begins failing.  Also... there are now TWO console.logs for each rotation!  Not sure HOW that is happening.  :unsure:

Camera.position seems unchanging and solid... no matter player.rotation or camera.rotation.

So... hmm.  Hans' theory is still true, it seems.  Camera.getTarget() returns incorrect values... after camera.parent is rotated.  (It seems).  Maybe this simpler playground will help.

Link to comment
Share on other sites

1 hour ago, Deltakosh said:

So to get the world value you have the multiply it by the inverse of view matrix

Like you did it above? Is it possible to correct the camera control too after the rotation? I think it based on camera space. So I have to define my own camera control, right?

Link to comment
Share on other sites

I want do simulate a spaceship. In the Spaceship is a player. He can walk like in an egoshooter. The ship can rotate (depends on how the player controls the ship). The ship has his own gravity which always appeals to the ship ground. The player can use his spirit walk/fly skill to visite the ship from outer space to check ship damge or something else (this all works already btw). (For the spirit walk i just remove the camera.parent. So the player can fly.) The player have to rotate with the ship. Otherwise the player glitch through the ship ground into the outer space or/and he cant walk normal. Problem like above: If the player use his spirit walk/fly the control is wrong after player rotation.
Hope it helps :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...