Help With Grenade Throwing (Almost Implemented)

Hello all,

Any physics guys/gals out there? I need some help implementing throwing a grenade…I have it almost figured out. Basically I have a scene successfully set up with CannonJS physics working via:

let gravityVector: Vector3 = new Vector3(0, -500, 0);
let physicsPlugin: CannonJSPlugin = new CannonJSPlugin(undefined, undefined, CANNON);
this.scene.enablePhysics(gravityVector, physicsPlugin);

And on G key pressed i create a sphere that will spawn at the current position of the camera with the appropriate aim vector (NOTE: The line of code I need help with is commented out):

document.addEventListener('keydown', event => { 
      if (this.isSceneLocked && event.code == 'KeyG') {

        let wm = this.camera.getWorldMatrix();
        let aimVector = Vector3.TransformNormal(Vector3.Forward(), wm).normalize();

        let sphere = Mesh.CreateSphere("sphere", 16, 10, this.scene);
        sphere.physicsImpostor = new PhysicsImpostor(sphere, PhysicsImpostor.SphereImpostor, { mass: 1, restitution: 0.9 }, this.scene);
        sphere.position = this.camera.position.add(aimVector);

        // NEED HELP WITH THIS ---> sphere.physicsImpostor.applyImpulse(this.camera.position.add(aimVector), this.camera.position);


      } 

});

which produces this result:

My goal is to be able to apply an impulse or force so that the “grenade” flies off towards the direction I am aiming with the crosshairs. But I cant seem to get the applyImpulse() code correct. And I want to be able to control the distance and arc of the grenade a bit.

As for the landing of the grenade I already know to add some linearDamping and angularDamping but I left that part out of my code snippet for brevity.

Check out the Holiday demo from 2020. That has the same idea but with snowballs!

You should be able to borrow right from that!

Thanks man Ill take a look now!

If you just need a bit of juice, scaling the impulse should do the trick
sphere.physicsImpostor.applyImpulse(aimVector.scale(20), sphere.position);

1 Like

So scaling it does make it launch nicely. However…no matter where I am facing it seems to launch in the Z direction (from the position of the camera) but not the direction i am facing

Make sure you try the edited code, and not the one I posted at first

Just tried the updated code… and it is producing this result:

The ball spins like crazy lol. Its fire from the correct vector it seems though. I tried scaling more but it just produced more spinning. The video may be a bit laggy but they are spinning super fast

It does seem to be working pretty well tho if i scale up to 500. Just lots of spin lol

UPDATE: This is the cleanest solution for me. Added some linearDamping to simulate friction and angularDamping to prevent the infinite spinning after contact with the ground. Also i changed the contactPoint to be new Vector3(0, .5, 0) to produce just a little bit of spin on impulse. On G Press:

    let wm = this.camera.getWorldMatrix();
    let aimVector = Vector3.TransformNormal(Vector3.Forward(), wm).normalize();

    let sphere = Mesh.CreateSphere("sphere", 16, 10, this.scene);
    sphere.physicsImpostor = new PhysicsImpostor(sphere, PhysicsImpostor.SphereImpostor, { mass: 1, restitution: 0.9 }, this.scene);
    sphere.position = this.camera.position.add(aimVector);

    sphere.physicsImpostor.physicsBody.linearDamping = .5; //friction
    sphere.physicsImpostor.physicsBody.angularDamping = .4; // prevent infinite spinning
    sphere.position = this.camera.position.add(aimVector);

    sphere.physicsImpostor.applyImpulse(aimVector.scale(1000), new Vector3(0, .5, 0))

Thanks @PirateJC and @Raggar for the help!

Final Result:

1 Like