Jump to content

[Cannon.js]Move body in the right direction?


Raggar
 Share

Recommended Posts

I have trouble getting the code to work properly in the playground, so I hope you get an idea of what I mean.

I'm using cannon direcly, and not as the plugin in Babylon.

I have a cannon body and a sphere shape, and I'm controlling the movement on the X and Z axis using keyboard input.

On top of that I have a sphere mesh in order to verify the changes to the body.

 

Now, I use the below handler to rotate the body itself according to the mouse.

window.addEventListener("mousemove", function(e) {
	//	console.log("mouse");
              
              
        var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
        var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;

        this.sphereBody.rotation.y += movementX * 0.002;
        this.sphereBody.rotation.x += movementY * 0.002;
    
	});

 

Now, the problem is, that if I rotate, let's say 50 degrees to the left, and press the key bound to the forward movement, the body moves directly forward, and not in the direction that the body rotated.

I'm a little unsure as of what and how to accomplish this.

 

This should be able to run server-side using node, which it already does, but this has it's limits, as I'm not planning to run babylon on the node server.

I need a way to assign the Z and X axis to the way the body is currently rotated. I guess I could use a camera on the client, but then the rotation has to be useable on the body server-side.

I already checked quite a few examples, one being the Cannon.js FPS example.

I can upload the files somewhere if needed.

Link to comment
Share on other sites

@Raggar I played with some stuff in the PG, this should help you out, whether you are using cannon or babylon the math should be the same.. (note that cannon will probably need to use rotationQuaternion instead of "normal" rotation.)

http://www.babylonjs-playground.com/#1OP2LK#1 //Control box with left, up and right arrow keys.

Link to comment
Share on other sites

Problem is, I'm working with velocities in order to move the object.

 

I just cleaned the code a bit and got rid of all the irrellevant functions and object, and this is a working example:

 

<!doctype html>
<html>
<head>
   <meta charset="utf-8">
   <title>Babylon - Basic scene</title>
   <style>
      html, body {
         overflow: hidden;
         width: 100%;
         height: 100%;
         margin: 0;
         padding: 0;
      }
      #renderCanvas {
         width: 100%;
         height: 100%;
         touch-action: none;
      }
   </style>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/babylonjs/2.4.0/babylon.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.js"></script> <!-- optional physics engine -->
</head>
<body>
   <canvas id="renderCanvas"></canvas>
   <script type="text/javascript">
       var sphere;
     //  var keys;
     //  keys.left=1;
       this.playerDirection = [0,0,0,0];
       quat = new CANNON.Quaternion();

       
       
     //  keys = [0,0,0,0];
      // Get the canvas element from our HTML below
      var canvas = document.querySelector("#renderCanvas");
      // Load the BABYLON 3D engine
      var engine = new BABYLON.Engine(canvas, true);
      // -------------------------------------------------------------
      // Here begins a function that we will 'call' just after it's built
      var createScene = function () {
         // Now create a basic Babylon Scene object
         var scene = new BABYLON.Scene(engine);
         // Change the scene background color to green.
         scene.clearColor = new BABYLON.Color3(0, 1, 0);
         // This creates and positions a free camera
         var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);
         // This targets the camera to scene origin
         camera.setTarget(BABYLON.Vector3.Zero());
         // This attaches the camera to the canvas
         camera.attachControl(canvas, false);
         // This creates a light, aiming 0,1,0 - to the sky.
         var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
         // Dim the light a small amount
         light.intensity = .5;
         // Let's try our built-in 'sphere' shape. Params: name, subdivisions, size, scene
         this.sphere = BABYLON.Mesh.CreateSphere("sphere1", 16, 2, scene);
         this.box = BABYLON.MeshBuilder.CreateBox("box", {height: 5}, scene);
         // Move the sphere upward 1/2 its height
         this.sphere.position.y = 2;
         this.box.position.y = 2.5;
         this.box.position.z = 2;
         this.box.parent = this.sphere;
         // Let's try our built-in 'ground' shape. Params: name, width, depth, subdivisions, scene
         this.ground = BABYLON.Mesh.CreateGround("ground1", 6, 6, 2, scene);
         this.ground.rotation = new CANNON.Vec3(-0,0,0);
         //this.socket = io.connect("http://localhost:4004");
          
        
         
          window.addEventListener("keydown", handleKeyDown, false);
          window.addEventListener("keyup", handleKeyUp, false);
          
          
          
        
          
          
          window.addEventListener("mousemove", function(e) {
	   //	console.log("mouse");
              
              
             var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
             var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;

             this.sphereBody.rotation.y += movementX * 0.002;
             this.sphereBody.rotation.x += movementY * 0.002;

	});

          
          
          
          
          
          
          function handleKeyDown(evt){   
              
              if (evt.keyCode==65){
                  this.playerDirection[0] = 1;
             }
              
             if (evt.keyCode==68){  
                 this.playerDirection[1] = 1;
           
             }
              
              if (evt.keyCode==87){  
                  this.playerDirection[2] = 1;
            
              }
                          
              if (evt.keyCode==83){  
                  this.playerDirection[3] = 1;
        
                                  }
          }
                              
        function handleKeyUp(evt){    
            if (evt.keyCode==65){  
            this.playerDirection[0] = 0;
            }
                                 
            if (evt.keyCode==68){ 
            this.playerDirection[1] = 0;
               
            }
            if (evt.keyCode==87){ 
            this.playerDirection[2] = 0;
           
            }
            if (evt.keyCode==83){  
            this.playerDirection[3] = 0;
            }
                              }
                              
     
         return scene;
      };
       
       
    
       
       
       
 var createPhysics = function(){
  
console.log("createPhysicsFunction Called!");        
world = new CANNON.World();
world.gravity.set(0,-9.82,0);
        world.broadphase = new CANNON.NaiveBroadphase();
        
var mass = 5, radius = 1;
sphereShape = new CANNON.Sphere(radius); // Step 1
sphereBody = new CANNON.Body({mass: 1, shape: sphereShape}); // Step 2
sphereBody.position.set(0,2,2);
sphereBody.rotation = new CANNON.Vec3();    
world.add(sphereBody); // Step 3
console.log("sphereBodyPosition0: " + sphereBody.position);  
     
     //SPHEREQUAT
sphereBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0),-Math.PI/2);     
     
     
     
// var worldPoint = new CANNON.Vec3(0,0,0);
// var force = new CANNON.Vec3(5,0,0);
// this.sphereBody.applyForce(force,worldPoint);                                
                                  
groundShape = new CANNON.Plane();
groundBody = new CANNON.Body({ mass: 0, shape: groundShape });
console.log(groundBody.rotation);

groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0),-Math.PI/2);

console.log(groundBody.quaternion);     
world.add(groundBody);
        
        
timeStep = 1.0 / 60.0; // seconds
velocity = sphereBody.velocity;      
        
sphereBody.velocity = new CANNON.Vec3(0,0,0);    

return world; 
     
 }      
       
       
       
       
       
       
     var onsocketConnected = function() {
         
         console.log("connected");
     }  
     
      var onsocketDisconnect = function() {
         
         console.log("connected");
     } 
      
      
       
      // -------------------------------------------------------------
      // Now, call the createScene function that you just finished creating
      var scene = createScene();
      this.world = createPhysics(); 
      // Register a render loop to repeatedly render the scene
       
        inputVelocity = new CANNON.Vec3();
      velocity = sphereBody.velocity;  
       inputVelocity.quaternion = new CANNON.Quaternion();

       
       
      engine.runRenderLoop(function () {
         
    
            euler = sphereBody.rotation;
          
         scene.render();
          world.step(1.0 / 60.0);
          this.sphere.position = sphereBody.position;
          this.sphere.rotation = sphereBody.rotation;
    
        euler.x = sphereBody.rotation.x;
        euler.y = sphereBody.rotation.y;
     
   
          
          
        if (this.playerDirection[0] != 0){
            inputVelocity.x = -5;
        }  
          
          if (this.playerDirection[0] != 1){
            inputVelocity.x = 0;
        }
          
          if (this.playerDirection[1] != 0){
            inputVelocity.x = 5;
        } 
          
            if (this.playerDirection[2] != 0){
            inputVelocity.z = 5;
           
        }
          
             if (this.playerDirection[2] != 1){
            inputVelocity.z = 0;
        }
          
                 if (this.playerDirection[3] != 0){
            inputVelocity.z = -5;
        }
       // sphereBody.quaternion.copy(sphereBody.rotation); 
        console.log(sphereBody.quaternion); //(new CANNON.Vec3(0, 0, 1), 500);
        velocity.x = inputVelocity.x;
        velocity.z = inputVelocity.z;  
          
    
          
      });
      // Watch for browser/canvas resize events
      window.addEventListener("resize", function () {
         engine.resize();
      });
       
    

       
       
   </script>
</body>
</html>

 

If you try it you, you can see what I mean, I want the axis of the object to follow the rotation of the object, so that I can 'walk' in a new forward direction.

It's probably something stupidly easy, as this is basic FPS movement. But for some reason I keep messing it up.

This is what I used for reference: https://schteppe.github.io/cannon.js/examples/js/PointerLockControls.js

And the cannon physics work perfectly on node so far.

 

 

Link to comment
Share on other sites

Problem is, I wanna find the new direction without having a camera present, as this should be running on my node server, with as little code as possible.

I've been trying for a few days now without any progress. I'm new to babylon, but I believe this should be possible.

 

Otherwise, there might be a better way of doing it.

Let's see:

Input is sent to the server using sockets.

So far the basic input is keys pressed (WSAD), which based on the velocity moves the sphere on the server, as well as the client.

I first thought you'd do the same thing with mouse movement in the X and Y directions, but I see this comes with the cost of responsiveness.

Instead, sending the actual rotations should be used. Now, in the above code, let's say I rotate to the left about 25%/90 degrees. If I then press the forward(W) key, I now actually move left, instead of forward, in the new direction.

Is there any smart way of doing this, so I can send only the rotation to the server, and the server then, as the client, calculated the new direction as being Z or something.

Does it have anything to do with world vs. local space?

Link to comment
Share on other sites

Im assuming your trying to track position with websockets?

if so, you should do some research because the actual manipulation of the object should be client side, and most of the operations as well, you have the server validate every once and a while and just confirm if things can happen or not.

Link to comment
Share on other sites

I'd prefer having it the way it is now. With input being sent to the server -> server moves the 'player' object -> then sends the new position back to the client. The client runs the same calculations, but the server is the authority. I know your suggested model might be easier, but I prefer this model. Lag compensation, inter/extrapolation etc. comes later. I'm in no rush.

Link to comment
Share on other sites

But if you read the linked articles from that tutorial, they discuss the authoritative client-server model, and the fact that the server should handle physics(movement) based on input, and send the states to the clients. And that is what I'm trying to achieve. I might misunderstand you?

And if the client handles movement and hit registration, then any player will be able to teleport and fake kill between server checks.

Link to comment
Share on other sites

In case I expressed myself in some odd way, here's a little illustrative way of showing what I want to accomplish:

[zZglgDm.png

A1 is the starting rotation and position.

A2 is the rotation after I move the mouse a bit to the left.

Now, if I press the forward(W) key, I want the body to move in the direction it is facing, and end up in the position of that of Illustration B.

However, it is moving in the Z direction, and thereby ending up in the position of C.

 

Here is the rotation and the quaternion of the cannon body after I move the mouse and thereby rotate the object:

gBDOLWS.png

How do I translate these into new directions for the object to move?

 

The box is just a way of telling which way it is facing btw. Nothing of importance here.

 

I would prefer to be able to calculate these directions purely with Cannon and Javascript, as I would like it to run server-side on Node.js.

But at this point, anything is appreciated.

Link to comment
Share on other sites

I understand what you are trying to do, and have told you several ways your doing i wrong posted information that also supported that. You can keep trying to do something that no one else is doing and for good reason, or you could learn the correct way and do it.

Yes no server in the world can handle that much information, why do you think there are wall hacks and aim bots...

Im not trying to come off rude, but why even ask for help if you just know better?
 

Link to comment
Share on other sites

Hmm. I think we have some kind of communication problem here. :)

What I'm trying to achieve is the following:

Player1 presses the 'forward' key for 5 seconds while using the mouse to look around.

What he sends to the server is: 

'W-key pressed' and 5 seconds later 'W-key released' while sending his rotational data. 

The server now applies these inputs to the light-weight physics world, and sends back the position to make sure they are synced.

The client updates its position accordingly to the information from the server.

There is no need to apply new rotational data on the client, as long as the server is the authority of the position.

Otherwise you might end up with laggy mouse movement, and we don't want that.

Based on what I've read, this is how it's done in most fast-paced shooters. Battlefield even uses actual bullets instead of rays. 

Of course this won't prevent wall-hacks and aimbots. 

Let me know where it is you think I am dead wrong.

 

Link to comment
Share on other sites

15 hours ago, Pryme8 said:

Ok so you let the client handle all movements, and then just send the position at intervals back to the server to make sure they are not "out of bounds"

 

No I don't. That would require coding bounds for every single wall, box etc. in the game.

19 hours ago, Raggar said:

'W-key pressed' and 5 seconds later 'W-key released' while sending his rotational data.

 

 

Link to comment
Share on other sites

8 hours ago, RaananW said:

Maybe this will come in handy? http://buildnewgames.com/real-time-multiplayer/

Already read it a few times. And having someone host a lobby is of course one way of doing it. It is the way I'm planning on doing my current project (If I ever get this far).

However, I wanted to see if it's possible to run the actual physics on the server, as I'm a fan of that model.

 

I figured out a solution to my problem by using sin and cos to calculate the new positions. I'm sure this is a bad solution, as I'm now moving the physics body directly instead of using velocity/forces. But it works, and still collides with other bodies in the cannon world. So I'll leave it at this for the moment.

Link to comment
Share on other sites

  • 5 years later...
On 8/23/2016 at 3:42 AM, Raggar said:

Already read it a few times. And having someone host a lobby is of course one way of doing it. It is the way I'm planning on doing my current project (If I ever get this far).

However, I wanted to see if it's possible to run the actual physics on the server, as I'm a fan of that model.

 

I figured out a solution to my problem by using sin and cos to calculate the new positions. I'm sure this is a bad solution, as I'm now moving the physics body directly instead of using velocity/forces. But it works, and still collides with other bodies in the cannon world. So I'll leave it at this for the moment.

Hey..what was the solution for this using sin and cos? can you just ping it here

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