Jump to content

moveWithCollisions explanation (mesh collisions and gravity)


Kilombo
 Share

Recommended Posts

Good afternoon,

 

I'm trying to implement mesh collisions instead of a physics system (turns out that it costs to much in performance and i don't have the time to implement it right now), at first look it looks simpler.

Although... I wen't looking at the tutorial and at dad72 example, and I'm not beeing able to implement it. I don't understand the concept behind the moveWithCollisions function and the velocity vector3. In my game I don't have a velocity var, the player point and click and the ship moves to that place. So... If i understand the concept, I may adapt it.

At first, i thought.. well, maybe the function will try to calculate the mesh destiny, so I directly putted de ship X and Z coordinates on the velocity vector3 and it didn't work. I pasted a bit of the code.

 

Notice that selectedUnit[a].setVelocity(velocity); is calling the setVelocity method, this method calls moveWithCollisions with the velocit parameter. this is part of the units class and the selectedUnit is one array of Units

 

Thanks in advance for the help.

 

if ((posix!==0)&&(typeof(posix)!=="undefined")&&(isNaN(posix)===false)){
                if (targetx === 0){
                    Number(targetx);
                    targetx = Number(posix)+1;
                    Number(targetz);
                    targetz = Number(posiz)+1;
                }
                camera.target = new BABYLON.Vector3(posix,0,posiz);
                systems[0].calculateSunDistance(camera);
                //calculateSunDistance(systemB1,camera);
                systems[1].calculateSunDistance(camera);
                //calculateSunDistance(systemB2,camera);
            
                dx = targetx - posix;
                dz = targetz - posiz;
 
                rot = Math.atan2(dx, dz); 
                len = Math.sqrt(dx * dx + dz * dz);
                if (len === 0)
                    len = 1;
                dx = dx / len;
                dz = dz / len;
                if (rot!==0){
                    posfy = rot + Math.PI;
                }
                posfx = parseFloat(selectedUnit[a].getShipPosx()) + parseFloat(dx);
                posfz = parseFloat(selectedUnit[a].getShipPosz()) + parseFloat(dz);
                shiproty = posfy;
                shipx = Math.round(posfx, 1);
                shipz = Math.round(posfz, 1);
                shipid = selectedUnit[a].getShipId();
                          
                              
                selectedUnit[a].setShipPos(shipx,shipz,shiproty);   
                ship = selectedUnit[a];
                //velocity = new BABYLON.Vector3(parseFloat(Math.sin(parseFloat(shiproty))) / 1, 0.5, parseFloat(Math.cos(parseFloat(shiproty))) / 1);
                velocity = new BABYLON.Vector3(parseFloat(shipx), 0.5, parseFloat(shipz));
                //console.log(velocity);
                selectedUnit[a].setVelocity(velocity);
Link to comment
Share on other sites

   Hi again, K!  What in the heck are you trying to do with THAT work of art?  ;)

 

Let's talk about space game theory for a moment.  You claim that physics engines are causing performance problems for you, and I can understand that.  But...  :)  ...physics engines are very nice for space games.  It's because applyImpulse is EXACTLY like a space craft thruster, and you get "drift" automatically.

 

Have you seen my goofy flyer?  http://urbanproductions.com/wingy/babylon/thruster/t26/flyer26.htm  (.zip is there too)  Click and hold-down the buttons to perform thrustings.  wasd camera, shift/control-keypad for thrustings, or shift/control-keys-around-L-key... for thrustings, too.

 

Feel the space drift to this physics vehicle?  Feels pretty good, doesn't it?  It uses real low thrust power so its slower than necessary.  Controller.js is the key to it.  Keypresses and buttons.... performing full spacecraft rotations and translations.  Although it appears as if the thrusters/particles are doing the thrusting, its ACTUALLY all done with single and two-at-once (twist) impulse applications... upon an invisible box that surrounds the flyer.  (boring).

 

Now, let's talk about WHY you seem to want to calculate distance to targets.  Why?  :)  Why not... click on the target, and the spacecraft rotates around until it is AIMED at the target.  Then manual fly or auto-pilot after that.  Maybe?

 

In a classic scenario, (and like my flyer)... a thruster repeatedly does tiny thrusting... and they happen at the same rate as the keypress repeat rate.  In my flyer, these repeat tiny thrustings... accumulate.  So, the longer you hold the key or button, the faster stuff goes.  YOUR trip to the target planet or space station... could act the same.

 

How do you do braking thrusters?  I think you can figure that out.  But in standard spacecraft, there are MAIN thrusters and vernier thrusters (tiny adjustings).  My flyer has ONLY vernier thrusters.  MAIN thrusters might ONLY be on the back of the ship, and if you need fast braking, you will need to turn the craft 180 degrees, and then fire the main thrusters until the craft stops.  At least that's one way of doing it.

 

Lets pretend that each of your planets and space stations... have an invisible sphere around them, and its BIGGER than the planet.  Its a "proximity" sphere.  When a spacecraft intersects with this... spacecraft computers can do warnings, auto-landing systems could engage, or you could blow up the ship due to too much heat.  :)  That proximity zone is handy.

 

So, you see, you don't need to measure distance.  Just aim the ship at the target, and start thrusting, stopping when the "max speed" is reached.  Then we wait... and try to predict when is the best time to apply braking thrusters (per spacecraft mass), etc etc.   Space Trucker!  Space Train!  hehe.

 

I call that turn-around to put the main thrusters forward for braking...  "butt to the wind" mode.  :)  To slow down, put your butt to the wind and start farting thrust.  :)

 

Ok, that's all have.  .moveWithCollision is not easy to do "space drift" with.  And if you use mwc, yes, then you might need to know distance... to calculate an easing/interpolator.  (parabolic velocity curve - gentle acceleration, then go like hell, then gentle braking.)

 

I dunno.  Looks like one heck of a fun project, though, k-man!  Feel free to use anything you like... from my flyer.  It is terrible coding.  I was young and blind... but it sure was fun!  It will advance into a clone of a game called Space Taxi someday, maybe.  :)

Link to comment
Share on other sites

Hello Wingnut,

 

Long time no see :) , Well i tried to implement Oimo.js without success, alot of problems appeared (ships dissapeared, planets falling off in deep space with gravity switched to zero, etc...), the thing is... this is one rts game in a 2D axis (X,0,Z) in a 3D world, not one rpg, so i was not really worried with physics, i thought that there wasn't a real advantage for this type of game, anyway, when i started applying Oimo, things started to really slow down, so i thought.. imbebed babylon.js collision system looks simple, dad72 example seems really simple to implement, so.. let's do it.. then this big issue appeared, i can't seem to understant how this function and parameter really work.

 

Btw wing, what do you prefer, Oimo or cannon ? And do you know where to find some more complete tutorials? To implemet Oimo i had to fly around for a bunch of posts.

 

Thanks in advance.

Link to comment
Share on other sites

Well, for how moveWithCollisions works it's pretty straightforward. You pass it a vector, and BJS moves your mesh along that vector as far as it can go without colliding with another mesh (that has "checkCollisions" set to true).

 

The big gotcha is BJS does not use the actual shape of the mesh being moved for collision checking, it uses an impostor ellipsoid, and you have to set that ellipsoid's size yourself (it's a Vector3 of the ellipsoid's x/y/z dimensions). I think the collisions tutorial is pretty misleading here, since most of the important work is being handled magically inside the camera's built-in controls, so it doesn't really show how you can move things around yourself.

 

With that said, I don't mean to criticize but it's hard to tell what the original code sample is trying to do, as there's some voodoo obscuring it. ;)  Calling parseFloat on numbers, passing two arguments to Math.round (it only takes one), etc. As long as you know what it's doing that's the important thing, but if not feel free to ask.

Link to comment
Share on other sites

K, I don't really have a preference for which physics engine.  I've done more work with cannon than with oimo.  We don't have a very "deep" tutorial for either.  And there's people around who would really like to see the newest version of Cannon... be "turned-on" in BJS.  But, the new CannonJS does heightMaps... and we can't offer support for that new feature, yet.

 

RayCasting cars.  And AltReality's train work... good stuff.  I love crashing trains and watching the tonnage tumble across the landscape.  ALL my locomotives in MS Train Sim... will pull trains over 500 MPH!  Too fun!!  I even built a route dedicated to train jumping and pit-diving.  Yep, physics vehicles and heightMaps play REAL NICELY together.  :)  HOURS of demented dune buggy fun!

 

Anyone remember a game called Stuntcar Racer?  Anyone ever played i-82? Anyone ever overpowered vehicles in Farm Sim and thus gone mountain jumping?  Ever play MotorM4X? 

 

Vehicle jumping!  Yay!  We can do ramps, currently.  Jumping mountains?  We're still a few minutes from that, yet.  A heightMap as an imposter.  Phew.  Can my CPU handle it?  :)  We'll find out, I suspect.  Schteppe's raycast car works pretty nice.

 

Yet another frivolous comment from Wingnut.  :)

Link to comment
Share on other sites

Wing and Fenomas,

Thank you both for your answers. I'll stick with checkcollisions (for now). I have to do further experiences and some small games/demos with it before implement it on my project.

Anyway, I already found the answer to my problems. This demo: http://playground.babylonjs.com/#1NQTNE#11 is quite good. Although, I've got to tell you guys. When I first saw the documentation my first tought was that the moveWithCollisions(); function would make the ellipsoid move within the mesh, and not move the mesh by itself. With that said, i was moving the mesh both with translations and with moveWithCollisions(), of course it woudn't work... It still doesn't work, but at least i know where the problem is :)

Thanks for the help guys. If i sortit out, I'll post the conclusions.

Best regards,

Kilombo

Link to comment
Share on other sites

Hello again,

 

Anyone knows a possible reason to moveWithCollisions() concatenate the existing position with the subtracted vector, instead of in fact do a subtraction for each of the positions (x,y,z) ?

 

Thanks in advance,

Link to comment
Share on other sites

hi delta, nice to see you. i'm not sure what you mean, what's the camera relation with it? if I comment out the movewithcollisions function, the camera stays in bounds and detects all the collisions. please try to explain a little further.

Link to comment
Share on other sites

Well... I have different files.

In the first one there's what i call the main engine, in the second one there's the units class, in mainengine i've got a start() function that has this line:

 

selectedUnit[a].setVelocity(parseFloat(tempx), parseFloat(tempz), parseFloat(posix), parseFloat(posiz));

 

The selectedUnit is one array of Units that is runned by a for cicle, so that it can set each of the existent units movement and direction (it does a lot more things but it's not important now).

What it counts is that the setVelocity receives has parameters the mouseX and mouseY (the mesh destination cordinates) and the initial mesh cords.

The setVelocity method is like this:

 

unit.prototype.setVelocity = function (targetx, targetz, posix, posiz){
    
        
        this.destination = new BABYLON.Vector3(targetx,0,targetz);
        this.origin = new BABYLON.Vector3(posix,0,posiz);
    
        this.origin.x = posix;
        this.origin.z = posiz;
    
        this.movevector = this.destination.subtract(this.origin);
        
            this.movevector = this.movevector.normalize();
            this.movevector = this.movevector.scale(0.2);
           
            if (this.mesh){this.updateMesh(this.mesh);}    
       
};
 
This method calls another one called updateMesh, there's this one:
 
unit.prototype.updateMesh = function (mesh){
    
    this.mesh = mesh;
    if (typeof(this.movevector) !== "undefined"){
        if(this.movevector.length() > 0.09) {
            this.mesh.moveWithCollisions(this.movevector);
        }
    }
   
    this.mesh.rotation.y = this.getShipRotation();
    this.mesh.position.y = 0;
    this.x = this.mesh.position.x;
    this.z = this.mesh.position.z;    
};

 

So... I made a lot of "console.log()" to almost all of the variables, and my first conclusion is that there's something wrong with this method "this.mesh.moveWithCollisions(this.movevector);".

Because this results in a BABYLON Vector3 concatenation, instead of a subtraction in each of the coords position.

 

Delta... Sorry for such a long post, but i hope i'm explaining my self a bit better this time.

 

Thanks in advance for your help.

Link to comment
Share on other sites

I think something like this would agree better :

this.speed = 8;this.forward = new BABYLON.Vector3(parseFloat(Math.sin(parseFloat(this.mesh.rotation.y))) / this.speed , -0.12, parseFloat(Math.cos(parseFloat(this.mesh.rotation.y))) / this.speed );this.mesh.moveWithCollisions(this.forward);

The character depending that rotation always go forward

Link to comment
Share on other sites

moveWithCollisions will update the position of your mesh. So this is expected to add a vector to your position( vector3):

this.position.addInPlace(this._diffPositionForCollisions);

 

I don't get why you want a subtraction

Good morning Delta,

 

Well, the add in place should replace the original cords by new cords in each frame, right? What is happening is that it is concatenating the new vector to the old one in each frame. I'm not getting why..

 

Thanks,

Link to comment
Share on other sites

On 4/26/2015 at 5:16 PM, dad72 said:

I think something like this would agree better :


this.speed = 8;this.forward = new BABYLON.Vector3(parseFloat(Math.sin(parseFloat(this.mesh.rotation.y))) / this.speed , -0.12, parseFloat(Math.cos(parseFloat(this.mesh.rotation.y))) / this.speed );this.mesh.moveWithCollisions(this.forward);

The character depending that rotation always go forward

Good morning Dad72,

The example you are giving me is the one that i first started looking, but where do you put the destination mouseX and mouseY (from the scene.pick) in there?

I'm using this example http://playground.babylonjs.com/#1NQTNE#11 this one is similar to what i want to get.

Thanks in advance.

Link to comment
Share on other sites

Hi Kilombo,

 

Your example is the right way to do it. my way is to control with the keyboard and mouse, not in relation to click.
 
I do not understand your problem in this case in your demo. (It works right)

 

-------
And for what fenomas said about the parseFloat. I put twice by error/inattention, but that does not stop the operation and I do not use Math.round but : Math.sin and Math.cos.
 
this.forward = new BABYLON.Vector3(parseFloat(Math.sin(parseFloat(this.mesh.rotation.y))) / this.speed , -0.12, parseFloat(Math.cos(parseFloat(this.mesh.rotation.y))) / this.speed );
 

fixe :  :)

this.forward = new BABYLON.Vector3(parseFloat(Math.sin(this.mesh.rotation.y)) / this.speed , -0.12, parseFloat(Math.cos(this.mesh.rotation.y)) / this.speed );

Link to comment
Share on other sites

Ok... I got it (finnaly), there where 3 mistakes that i was making:

First i was updating the mesh twice, that was messing everyting up, and was the major problem.

The second problem was the mesh's sizes and proportions vs the world and the ellipsoid.

The third was that cords need to be floats, but in database they where int's, and that was also messing up.

I still have 2 issues:

- player mesh is always resetting to (0,0,0), and then starts moving to the is original cord (the one that gets from the database).

- i just finded that all mesh's appear in a really small size in (0,0,0), how can i make this dissapear?

 

Thanks guys.

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...