smatt

Physic with camera not working

Recommended Posts

Hello,

I'm currently working on physics right now and can't get the camera to be a physic-based-object.
How can I handle collisions between player and a scene without using the default camera.ellipsoid or enabling for each mesh the mesh.checkCollissions property?

I'd like to have a basic impostor on my camera with player model (Cylinder, capsule or even box).

Maybe someone can rewrite this http://playground.babylonjs.com/#NVWUF#1 by using a physics plugin 100% :)

It would be so great if this works in the end.
Thanks for every answer, Simon

Share this post


Link to post
Share on other sites

@Deltakosh @davrous @Temechon @RaananW I absolutely love the Babylon.JS engine in combination with Oimo.JS physics and I'm currently getting a lot done for my first person shooter. I'd like to make my player react to the environment in a more realistic and physically correct way.
The problem is: I can't get the camera (the player) to work properly. I've created this playground demo http://playground.babylonjs.com/#NVWUF#13 and it should be only some lines of code that need to be changed. 

The playground demo I've tried to create should simply rotate and translate / move the camera including it's box around the scene.

Recently I helped @Demian solving his First-Person-Camera rotation and pointer locking in this post:

Maybe it's worth a look, because there is a pretty simple implementation of rotation (5 lines of code).


Here is the latest screenshot of this FPS testing other objects :)

I hope you can help me in any imaginable way, because I'm stuck in the physics and can't progress on my project.
Thanks for every answer, Simon.

Share this post


Link to post
Share on other sites

Hi @smatt  You are sounding a bit desperate.  :)   Are you in a hurry?

First, the playground app itself... is acting strange on your playground.  It seems to be running "old code" from the editor window.  I've had this issue before... and I'm not sure what causes it.  Essentially, you can make a change to the editor, removing a line of code... and then hit run, and the line of code that was removed... still runs! 

The way I fix it, is to highlight and copy all the code in the editor window, completely close the playground, re-open a fresh playground, hit clear button, then paste that code back into the editor window, and hit RUN.  Essentially, sometimes you need to "wash" the playground. 

It MIGHT be happening because you have no scene.onDispose( remove event listeners ).  I'll let you use playground search to find examples of scene.onDispose()... which is OFTEN used to remove event listeners so they don't get in the way of newly-loaded playgrounds.

Now, back to your playground code.  First, we'll turn-off the camera parenting and the pointerLock crap, so we can concentrate ONLY upon moving our player box with physics.  The player box is now green, and the ground is now wireframe.

http://playground.babylonjs.com/#NVWUF#14

Get a clean playground and visit #14, and I'll show you some changes.

Line 12 - adjusted camera a bit
Line 14 - Re-attached the camera.  Let's keep a normal camera while we do physics tests on the green player box.
Line 16 - Changed the ground to be a ground mesh, not a box.  No big deal.  We're still using a boxImposter on it.  Changed some sizes and subdivs on ground, too, to make wireframe look cool.  :)
Line 36/37 - made the player box green
Line 38 - picked-up the returned value for the setPhysicsState call... pbody... stands-for physicsBody.  In your #13 demo, line 100, you used...

100 player.physicsImpostor.setLinearVelocity(moveVector);

player.physicsImposter is a different object than my pbody.  player.physicsImposter has no setLinearVelocity() function, or even a linearVelocity property.  My pbody has a linearVelocity property, but not a setLinearVelocity() func.  For my demo, we will use pbody.linearVelocity = value.  You'll see it used in line 118.

Ok, back to the list:
Lines 61-70 - turned off all camera moving stuff.  We are using a standard un-parented camera, for now.
Line 110 - VERY important line, maybe.  Notice I start with the vector3 that is already IN pbody.linearVelocity, and NOT use a new BABYLON.Vector3.  This is because Oimo MIGHT have its own version of vector3-class objects, and BABYLON vector3 class objects MIGHT NOT WORK for setting Oimo values.

Let's go adventuring in the "bad Oimo API" I once made. http://urbanproductions.com/wingy/babylon/misc/j2h02.htm   

Search down thru my bad API until you find the category called com.element.oimo.physics.dynamics.  Look at item #12.  public var linearVelocity:Vec3;  Notice that it doesn't say BABYLON.Vector3.  It says Vec3 data type.  Now search the document for com.element.oimo.math.  See Vec3?  pbody.linearVelocity wants an OIMO version of Vector3, not a BABYLON version.  This is why I did line 110.  I grabbed a copy of the CURRENT linearVelocity (which is x: 0, y: 0, z: 0 anyway, because the green player box has landed and stopped bouncing).  moveVector is now an OIMO version of Vec3. 

Lines 111-114 - these install your vecx and vecz values INTO/ONTO that Oimo vec3... with some "massaging" for sanity reasons.  The linearVelocity was a little fast/powerful.  Player was flying off-of the screen.  :)

And lastly, line 118, re-installing the Oimo Vec3 into the pbody.linearVelocity property.  Yay!

This should get you rolling.  Don't be in ANY hurry to parent the camera to the green box... PLEASE.  Learn to drive the green box, using physics, first. 

Next, you need to learn to use oimo angular velocity  It was seen at com.element.oimo.physics.dynamics #13.  :)  It also uses a Oimo Vec3, so, same procedure.  Make sure that when you SET the angularVelocity property, you use an OIMO Vec3-class value.

You might want to try using a BABYLON FollowCamera real soon.  It will stay focused-upon the green player box as you test-drive it around with your keypresses.  Often, followCameras are also called "chase view" cameras... and they are handy for watching vehicle-like things such as your player box.

Okay, that's enough for one post.  You are off and running, right?  Bookmark my "bad oimo api" doc (feel free to improve it and publish a better version, too.  Not much OIMO documentation to be found on the web, so cherish/improve what we have.)  :)  Give yourself time to do many experiments.  Be patient with yourself, if you can.  Pinging the big dogs... before you have done proper learning YOURSELF... is a good way to get the big dogs to ignore you.  Nobody is paid, here, and nobody here wrote Oimo.  It is a third party add-on, and as you can tell by its API, it is somewhat complicated and poorly documented.  I'll be here to help...a bit.  This post and playground took me four hours to write.  We're here to help, but we also hope that you can help yourself, too.  Experiment, experiment, experiment.  :)  Meantime, perhaps I can research why player.physicsImpostor is not the same object as pbody.  Possibly, pbody is the same object as player.physicsImpostor.body.  Not sure yet, haven't tested.

In Firefox f12 dev tools, console... you can se

Oh yeah, the #14 playground.  You should see some good greenbox movement with the WASD keys, now.  YAY!  Your vecx and vecz are still a bit weird, but you can fiddle with them, as wanted.  I keep vecy at zero, to keep the player on the ground.  Later, we'll talk about making him jump with vecy sometimes.  Sound good?  Good.  Cya soon.  Good luck, have fun.

Update:  Another PG... http://playground.babylonjs.com/#NVWUF#16 

Notice line 122.  I print player.physicsImpostor to console.  Open your browser's F12 dev tools, and see it?  Now, can you click on the starting word "Object"  (before the opening brace)?  If so, you might see an "object inspector" window... come open.  Look through the object inspector... and you will NOT see linearVelocity, or setLinearVelocity().  player.physicsImpostor is somehow the wrong object to do those settings-with.  Not sure why, yet.  I'll keep studying.  kbye again.  :)    

Share this post


Link to post
Share on other sites

First of all @Wingnut: Thank you so much for your time effort and your explanation.
You asked if I'm in a hurry: Yes and no. I'm currently really pissed of by the physics and the LACK OF A SINGLE TUTORIAL explaining a first person camera movement with Physics.
There are excellent tutorials from @Deltakosh and @davrous about Cannon.JS and and Oimo.JS :)
But there is not a single one where the camera is physically effected in any way than the "default" Babylon.JS Physics.

I've worked with your playground (Download as a zip) in my local testing environment for about a hour and still doing no progress on physics.
These OIMO Vec3 are a bit strange for me too :D 

Your playground is a good step forward to my goal but I can't achieve my goal. As you said I should first understand physics 100% and then move on to camera physics. But at the moment I have so many ideas. There is just one obstacle between the ideas and the implementations of them.
As you can see in my twitter posts I'm doing good progress. 
I've worked the past 3 days on implementing the physics engine and I'm now so frustrated because everything is working perfectly and there no errors.
Just the camera isn't working. I'm seeking for a simple solution so I can get back to work again and do real progress instead of googling my way through Three.JS examples where everything works as it should.
The current progress is so large for me that I don't want to go with Three.JS... :( 


Does someone have a simple and straight forward solution or even a working example using Oimo.JS?

Share this post


Link to post
Share on other sites

"Still no progress with physics"?  You got some documentation on the OIMO physics package, you got the camera "gizmo" (green box) doing .position moves, you get to essentially copy the same method for rotation, you've learned that camera.ellipse, camera.applyGravity and mesh.checkCollisions are used for a DIFFERENT type of collision system, not for physics engines.  Man, that's a lot of learning for one 24 hour period.

I hope you are starting to understand... that camera are NOT mesh.  You cannot apply physics to the camera. You apply it to an invisible mesh and then parent the camera to the invisible mesh (green box).  But first, green box has to "drive" beautifully.... right?  Program green box to drive-around exactly like you want the camera to operate... and THEN.... last thing... parent the camera to the box (and maybe set box.isVisible = false.  (don't quote me on that)  :)

But learn to drive the camera's future invisible gizmo, first (the green box)... moving it and turning it with the physics engine.

I hope you understand.  Work on green box.  Learn to walk it, slew it, fly it, throttle on, throttle off, yaw pitch and roll, rotationQuaternions instead of vector3's.  You have DAYS of work practicing green box controls and keypresses, turn speeds, forward-reverse sensitivities, dead zones, mousedrags, etc.  Get the greenbox driving beautifully, and then 3 days from now... when you parent the camera to it, and set greenbox.visibility = 0... you'll have one nice-navving character/camera with physics.

With me?  Make sense?  You have come MUCH further than you THINK you have.  You just have some kind of brain tumor that makes you think you can apply physics to a camera that isn't a mesh.  None of the cameras are mesh.  So, you get the best control of cameras when you build a green box, teach it to do miracles, and then, LATER, parent the camera to it.  Physics on the camera... but ONLY with the help of mister invisible greenbox.  :)

Share this post


Link to post
Share on other sites

I put a link to read about quaternions... in the previous post.  Generally speaking, quaternions (specifically mesh.rotationQuaternion, which is only created IF needed)... can be used to contain the same information as mesh.rotation.  Let's say you need to check the current rotation of your player gizmo (green box).  Physics engines ALWAYS heavily use Quaternions.  Quats have 4 values, not 3.  I've heard that you can think of Quats... as 3 numbers to aim an arrow, 4th value is for how much mesh rotation AROUND that arrow shaft.  :)

so...  AFTER box.rotationQuaternion exists, you will check its rotation with...

var currentBoxRot = box.rotationQuaternion.toEulerAngles();  Checking box.rotation... will get bad numbers, cuzzzz... the physics engine has been tumbling this object all over heck, and box.rotation hasn't been kept updated.  But box.rotationQuaterion is always updated... and .toEulerAngles() will convert it to a vector3. for you.

==========

On another subject, bookmark this... http://www.html5gamedevs.com/topic/20350-moving-and-rotate-a-physic-object-from-a-newbie/#comment-115583

See the "special func"?  You will need something similar to that... after you start turning the green box (spinning your player around to face a new direction) (if you allow that in your game).  This function (or similar) will allow your "go forward" direction... to turn... whenever the player turns.  Essentially, it ensures that the applyImpulse or linearVelocity that you have pushing on the player's butt... is always pushing directly AT the players butt, no matter which way they are turned.  It is a "transformer"  :)

You'll be needing it soon (if you need player turning/rotation).  Party on!

Share this post


Link to post
Share on other sites

Hi Simon,

this is not an easy task (but, might I say, a very interesting one!). I am not sure why the native collision system of babylon is not enough, but I guess you already considered that.

A few pointers, as I sadly don't have the time to actually sit and develop this:

  1. You can try using the bidirectional body update feature, if you set a physics impostor's position to be the same object as the camera's position - http://playground.babylonjs.com/#NVWUF#17 . This has a few downsides (as you notice when playing with this demo) - the collisions don't fully work (this is just a position update). but you will collide against objects, and won't go through the floor (unless you force it).
  2. Very important - the impulse / velocity you provide must be relative to the current state of the camera-box-impostor. you will have to use the box's rotation when applying the impulse. Simply put - when the box is flipped, going forward will actually mean going backwards.
  3. check if applying impulse (instead of setting the velocity) will work better. I think the movement will be more fluent and will react better with the rest of the objects.
  4. General - When adding native javascript events to the playground, make sure you also remove them in the onDispose function of the scene, otherwise they will execute N times (as many ties as you press run).
  5. Have you considered a hybrid solution? babylon's native collision and a physics impostor connected to the camera? What do you actually expect that will happen? will you throw objects at the camera, or do you expect the camera to react to surfaces with which it collides?

Share this post


Link to post
Share on other sites

Hi @RaananW,

thanks for your quick answer it helped me understand my own problem much better.
Some quick questions:

1. Your playground example doesn't collide with the crate in there. I can move through it. Why? How can we prevent this?
EDIT: Why is the collision with the ground working and not with the other box? Shouldn't be it the same?

2.1. Camera-Box-Impostor? Is this like camera.parent = box ? How can I link these two examples. Currently I have no Idea how to connect camera and mesh together in the correct way.
2.2. Is it possible to get this directions directly from Babylon.JS or do I have to calculate them manually?

3. I'll have to try this one!
4. I'm should have done this much earlier :D

5. I think about this solution over night and this can be our go-to-solution! I want to push around objects as a player and throw objects in a physically way. BUT(!) the most important thing and the beginning of my physic-testings was the reason that the player should walk on slopes / stairs in a nice way.

Thank you so much for your help, this is giving me great progress on the physics in my game! :)

One last question: You give the Oimo plugin a "100" as an parameter.

scene.enablePhysics(new BABYLON.Vector3(0, -10, 0), new BABYLON.OimoJSPlugin(100));

The file on GitHub ( https://github.com/BabylonJS/Babylon.js/blob/eb47e20935c48ffae139ef69a46f7034c2da7d7b/src/Physics/Plugins/babylon.oimoJSPlugin.js ) takes a parameter "iterations". What is the use of it and how does it influence my game?
 

Edited by smatt
Collision of ground is working

Share this post


Link to post
Share on other sites

Hi Smatt,

 

to your last question - the engines work iteratively. Each iteration improves the result of the next step. Oimo's default is 10, but I find that it handles joints/constraints better with a higher number of iterations. I usually set 100 as the initial number and lower it until I get satisfactory results. A note (that should be clear :) ) - the more iterations, the longer it takes to calculate. 

1) The collision does work. But updating the camera's position (and thus the box's position) "forces" the box to get into the other box. try moving slowly and you will notice you can't really walk into the crate. Or try looking down and moving forward, you will go through the floor. This is the down-side of position updating (as opposed to the physics engine calculating your position).

2) Calculating the direction is rather simple, it is the vector that goes from the camera's position and its target.

5) Again, I would recommend doing that if you need quick and stable results. It will take some time if you want the camera to be fully controlled by the physics engine. 

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.