# Continuous Collision Detection with Havok

**URL:** <https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458>\
**Category:** Questions\
**Created:** [April 8, 2024, 9:37am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458 "2024-04-08T09:37:41Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![extremety1989](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/extremety1989/32/38171_2.png) [@extremety1989](https://forum.babylonjs.com/u/extremety1989)\
**Post date:** [April 8, 2024, 9:37am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/1 "2024-04-08T09:37:42Z")

</div>

Playground: [https://playground.babylonjs.com/#Z8HTUN#944](https://playground.babylonjs.com/#Z8HTUN#944)

Hey guys, i need help with CCD (to simulate Table tennis paddle with ball collision) how can i properly implement it in Havok ? In the current playground when i move fast with Box the Sphere passes through the Box.

---

<div class="post-metadata">

**Author:** ![AncientA](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/ancienta/32/46615_2.png) [@AncientA](https://forum.babylonjs.com/u/AncientA)\
**Post date:** [April 8, 2024, 10:05am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/2 "2024-04-08T10:05:27Z")

</div>

I’m not an expert but it seems like what’s happening is that when you press the up key to move the ground, it basically moves above the sphere.

If you reduce the amount you move the ground by, it works perfectly fine:

```auto
 window.addEventListener('keydown', function(event) {
        switch (event.key) {
            case 'ArrowUp':
                // Move the ground up
                ground.position.y += 0.02; // Adjust 0.1 to the step size you prefer
                break;
            case 'ArrowDown':
                // Move the ground down
                ground.position.y -= 0.02; // Adjust 0.1 to the step size you prefer
                break;
        }
        ground.physicsBody.updatePosition(ground.position);
    });

```

---

<div class="post-metadata">

**Author:** ![extremety1989](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/extremety1989/32/38171_2.png) [@extremety1989](https://forum.babylonjs.com/u/extremety1989)\
**Post date:** [April 8, 2024, 10:09am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/4 "2024-04-08T10:09:26Z")

</div>

@AncientA hey, well this is just a prototype code, in reality i want to apply it to simulate physics where tabble-tennis-paddle hits with ball , where i move very fast with paddle.

---

<div class="post-metadata">

**Author:** ![AncientA](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/ancienta/32/46615_2.png) [@AncientA](https://forum.babylonjs.com/u/AncientA)\
**Post date:** [April 8, 2024, 10:21am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/5 "2024-04-08T10:21:33Z")

</div>

I see!

In this case I’d recommend not adjusting the position of the paddle like you are doing now, but rather apply a new velocity or impulses. This is how I manage movement in my 3rd person controller template:

For managing inputs:

```auto
import { Scene, Vector3, DeviceSourceManager, DeviceType, DeviceSource, Nullable } from "@babylonjs/core";

export class InputControls {
    private deviceSourceManager: DeviceSourceManager;
    private keyboard: Nullable<DeviceSource<DeviceType.Keyboard>> = null;
    public currentAnimation: string = "idle"; // Default to idle animation

    constructor(scene: Scene) {
        this.deviceSourceManager = new DeviceSourceManager(scene.getEngine());

        // Listen for when a keyboard becomes active
        this.deviceSourceManager.onDeviceConnectedObservable.add((deviceSource) => {
            if (deviceSource.deviceType === DeviceType.Keyboard) {
                this.keyboard = deviceSource;
            }
        });

        // Optionally, listen for when a keyboard is disconnected
        this.deviceSourceManager.onDeviceDisconnectedObservable.add((deviceSource) => {
            if (deviceSource.deviceType === DeviceType.Keyboard) {
                this.keyboard = null;
            }
        });
    }

    public getInputVector(): Vector3 {
        let inputVector = Vector3.Zero();
        let moving = false;

        // Ensure that the keyboard is connected
        if (this.keyboard) {
            if (this.keyboard.getInput(87) || this.keyboard.getInput(38)) { // W
                inputVector.addInPlace(Vector3.Forward());
                moving = true;
                this.currentAnimation = "forward";
            }
            if (this.keyboard.getInput(83) || this.keyboard.getInput(40)) { // S
                inputVector.addInPlace(Vector3.Backward());
                moving = true;
                this.currentAnimation = "backward"; // Assuming you have a backward animation
            }
            if (this.keyboard.getInput(65) || this.keyboard.getInput(37)) { // A
                inputVector.addInPlace(Vector3.Left());
                moving = true;
                this.currentAnimation = "left";
            }
            if (this.keyboard.getInput(68) || this.keyboard.getInput(39)) { // D
                inputVector.addInPlace(Vector3.Right());
                moving = true;
                this.currentAnimation = "right";
            }
        }

        // If no movement keys are pressed, revert to idle animation
        if (!moving) {
            this.currentAnimation = "idle";
        }

        return inputVector.normalize();
    }
       

```

For movement:

public move(inputVector: Vector3, isSprinting: boolean, animationRatio: number) {

```
    let forward = this.camera.getForwardRay().direction;
    forward.y = 0; // Ensure horizontal movement only
    forward.normalize();
    const right = Vector3.Cross(Vector3.Up(), forward).normalize();

    let moveDirection = forward.scale(inputVector.z).add(right.scale(inputVector.x));
    if (!moveDirection.equals(Vector3.Zero())) {
        moveDirection = moveDirection.normalize();
    }

    // Apply animation ratio directly to base speed for frame rate independence
    const baseSpeed = 25; // Base speed adjusted by animation ratio
    const sprintMultiplier = isSprinting && this.stamina > 0 ? 2 : 1; // Determine sprint multiplier

    let adjustedSpeed = baseSpeed * sprintMultiplier; // Adjusted speed based on sprinting

    // Consume stamina if sprinting
    if (isSprinting && this.stamina > 0) {
        this.stamina -= this.sprintStaminaConsumptionRate * animationRatio;
    }

    // Apply the adjusted speed to the movement direction
    let velocity = this.mesh.physicsBody.getLinearVelocity();
    let newVelocity = new Vector3(moveDirection.x * adjustedSpeed, velocity.y, moveDirection.z * adjustedSpeed);
    this.mesh.physicsBody.setLinearVelocity(newVelocity);

    // Logging
    const currentTime = performance.now();
    if (currentTime - this.lastLogTime > 3000) {

    console.log(`Sprint Multiplier: ${sprintMultiplier}`);
    console.log(`Base Speed: ${baseSpeed}`);
    console.log(`Adjusted Speed: ${adjustedSpeed}`);
    console.log(`New Velocity: ${newVelocity}`);
    this.lastLogTime = currentTime; // Update the last log time
    }
}

```

I know your use-case is different, but the idea will be the same. You can manage the movement of the paddle by listening to the keyboard events, then apply a move logic that uses velocity or forces.

---

<div class="post-metadata">

**Author:** ![extremety1989](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/extremety1989/32/38171_2.png) [@extremety1989](https://forum.babylonjs.com/u/extremety1989)\
**Post date:** [April 9, 2024, 6:00am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/6 "2024-04-09T06:00:48Z")

</div>

Hey, thanks for the code. I will see what i can do with it. But the problem is that im using VR hand controller to control paddle, so it moves very fast. I need to figure if i could get Paddles forward direction without ray casting, the same with a ball

---

<div class="post-metadata">

**Author:** ![AncientA](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/ancienta/32/46615_2.png) [@AncientA](https://forum.babylonjs.com/u/AncientA)\
**Post date:** [April 9, 2024, 11:57am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/7 "2024-04-09T11:57:10Z")

</div>

Ahhh okay, sorry i don’t have any knowledge about the VR stuff, but it is definitely doable.

Maybe you’ll find the answer on this page?

[https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRInputControllerSupport](https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRInputControllerSupport)

---

<div class="post-metadata">

**Author:** ![extremety1989](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/extremety1989/32/38171_2.png) [@extremety1989](https://forum.babylonjs.com/u/extremety1989)\
**Post date:** [April 11, 2024, 11:03am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/8 "2024-04-11T11:03:24Z")

</div>

sadly no, the thing is it just does not detect paddle if i wing fast… i do not know if it my code or the physics just does not work properly. here is part of the code

```auto
    const ballPhysics = new PhysicsAggregate(pingPongBall,
      PhysicsShapeType.SPHERE, { mass: 0.0027, restitution: 0.85, friction: 0 }, scene);
    pingPongBall.physicsBody = ballPhysics.body;
    pingPongBall.physicsBody.disablePreStep = false;
    pingPongBall.physicsBody.setCollisionCallbackEnabled(true)
    const observable = pingPongBall.physicsBody.getCollisionObservable()
    observable.add(async (collisionEvent) => {
      const name = collisionEvent.collidedAgainst.transformNode.name
      if (name === "paddle") {
            const object = collisionEvent.collidedAgainst.transformNode;
            const forward = controller.grip.forward.normalize();
            let ballVelocity = pingPongBall.physicsBody.getLinearVelocity();
            let paddleVelocity = object.physicsBody.getLinearVelocity();
            let relativeVelocity = ballVelocity.subtract(paddleVelocity);
            let impulse = forward.scale(0.0001);
            impulse = impulse.addInPlace(relativeVelocity.scale(0.0001));
            impulse = impulse.addInPlace(paddleVelocity.scale(0.0001));
            pingPongBall.physicsBody.applyImpulse(impulse, pingPongBall.getAbsolutePosition());
            
      }
    });

```

---

<div class="post-metadata">

**Author:** ![AncientA](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/ancienta/32/46615_2.png) [@AncientA](https://forum.babylonjs.com/u/AncientA)\
**Post date:** [April 11, 2024, 11:46am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/9 "2024-04-11T11:46:35Z")

</div>

Are you saying it works at normal speeds, but not when you are swinging very fast?

I’m a noob, but for me your code seems correct. Having said that, I found this on the forums:

> [@Havok Physics max velocity / force?](https://forum.babylonjs.com/t/havok-physics-max-velocity-force/40763/3):
>
> Much appreciated, thanks. Been searching the forums like 2 weeks ago, missed your thread slight_smile

There is a limit on velocity on physics objects in Havok, which is meant to be pretty fast, but maybe not fast enough for your use-case. There is a way to override this though however:

```auto
function setMaxLinVel(havokPlugin, maxLinVel, maxAngVel) {
        const heap = havokPlugin._hknp.HEAP8.buffer;
        const world1 = new Int32Array(heap, Number(havokPlugin.world), 100);
        const world2 = new Int32Array(heap, world1[9], 500);
        const mplib = new Int32Array(heap, world2[428], 100);
        const tsbuf = new Float32Array(heap, mplib[8], 300);

        tsbuf[32] = maxLinVel;
        tsbuf[33] = maxAngVel;
        tsbuf[60] = maxLinVel;
        tsbuf[61] = maxAngVel;
        tsbuf[88] = maxLinVel;
        tsbuf[89] = maxAngVel;
        tsbuf[144] = maxLinVel;
        tsbuf[145] = maxAngVel;
        tsbuf[172] = maxLinVel;
        tsbuf[173] = maxAngVel;
        tsbuf[200] = maxLinVel;
        tsbuf[201] = maxAngVel;
        tsbuf[228] = maxLinVel;
        tsbuf[229] = maxAngVel;
    }

```

I recommend looking through the post, and maybe someone else can jump in from the community to help out if this doesn’t work.

Best of luck, let me know how it goes and hopefully see your project in action soon 🙂

---

<div class="post-metadata">

**Author:** ![extremety1989](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/extremety1989/32/38171_2.png) [@extremety1989](https://forum.babylonjs.com/u/extremety1989)\
**Post date:** [April 11, 2024, 12:07pm UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/10 "2024-04-11T12:07:04Z")

</div>

I just recorded how it looks, ok i will see maybe i can change velocity of physics, thanks

---

<div class="post-metadata">

**Author:** ![extremety1989](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/extremety1989/32/38171_2.png) [@extremety1989](https://forum.babylonjs.com/u/extremety1989)\
**Post date:** [April 11, 2024, 12:22pm UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/11 "2024-04-11T12:22:43Z")

</div>

Made this changes, nothing has changed same thing.

```auto
function setMaxLinVel(havokPlugin, maxLinVel, maxAngVel) {
  const heap = havokPlugin._hknp.HEAP8.buffer;
  const world1 = new Int32Array(heap, Number(havokPlugin.world), 100);
  const world2 = new Int32Array(heap, world1[8], 500);
  const mplib = new Int32Array(heap, world2[428], 100);
  const tsbuf = new Float32Array(heap, mplib[8], 300);

  tsbuf[32] = maxLinVel;
  tsbuf[33] = maxAngVel;
  tsbuf[60] = maxLinVel;
  tsbuf[61] = maxAngVel;
  tsbuf[88] = maxLinVel;
  tsbuf[89] = maxAngVel;
  tsbuf[144] = maxLinVel;
  tsbuf[145] = maxAngVel;
  tsbuf[172] = maxLinVel;
  tsbuf[173] = maxAngVel;
  tsbuf[200] = maxLinVel;
  tsbuf[201] = maxAngVel;
  tsbuf[228] = maxLinVel;
}  
const plugin = new HavokPlugin(true, await HavokPhysics());
  setMaxLinVel(plugin, 4000, 4000);
  const gravity = new Vector3(0, -9.81, 0);
  scene.enablePhysics(gravity, plugin);
  scene.getPhysicsEngine().setTimeStep(1 / 600);

```

---

<div class="post-metadata">

**Author:** ![AncientA](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/ancienta/32/46615_2.png) [@AncientA](https://forum.babylonjs.com/u/AncientA)\
**Post date:** [April 11, 2024, 1:39pm UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/12 "2024-04-11T13:39:01Z")

</div>

Oh man sorry to hear! It looks so sick btw, I really hope you get it sorted out somehow!

@Cedric has been very nice to help me out when I had some issues (hope you don’t mind me tagging you here Cedric!) He might be able to help out, or he might know someone who knows more about the VR stuff!

---

<div class="post-metadata">

**Author:** ![Joe\_Kerr](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/joe_kerr/32/39017_2.png) [@Joe\_Kerr](https://forum.babylonjs.com/u/Joe_Kerr)\
**Post date:** [April 11, 2024, 1:46pm UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/13 "2024-04-11T13:46:03Z")

</div>

Not sure if this is transferable to VR but I tried with pointer drag: [https://playground.babylonjs.com/#Z8HTUN#947](https://playground.babylonjs.com/#Z8HTUN#947) I can punch the box with the ball even if I move the mouse very quickly. The dragging is a bit weird - a top down camera angle worked best.

---

<div class="post-metadata">

**Author:** ![extremety1989](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/extremety1989/32/38171_2.png) [@extremety1989](https://forum.babylonjs.com/u/extremety1989)\
**Post date:** [April 11, 2024, 6:53pm UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/14 "2024-04-11T18:53:55Z")

</div>

Tried, the same thing and even worse to control…

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [April 12, 2024, 12:03am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/15 "2024-04-12T00:03:22Z")

</div>

Let me add @Cedric to the thread

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [April 12, 2024, 8:03am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/16 "2024-04-12T08:03:47Z")

</div>

I would try to use shape cast  
some docs here : [Character Controller with Physics V2 | by Babylon.js | Mar, 2024 | Medium](https://babylonjs.medium.com/character-controller-with-physics-v2-1df5d8b0d244)

and here : [Babylon.js docs](https://doc.babylonjs.com/features/featuresDeepDive/physics/shapeCast)

basically, before setting new raquet postion/orientation, cast it to see if it collides with the ball. and add impulse accordingly. it would be like a pre broadphase collision detection.  
Other solution: increase collision shape at the back of the racket accordingly to its motion speed.

---

<div class="post-metadata">

**Author:** ![extremety1989](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/extremety1989/32/38171_2.png) [@extremety1989](https://forum.babylonjs.com/u/extremety1989)\
**Post date:** [April 12, 2024, 8:26am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/17 "2024-04-12T08:26:35Z")

</div>

Hey thanks for resources, i will have a glance,

i added collisionMargin and set continuousCollisionDetection to true , it kinda works, but not sure. At the begining i thought about raycast, but i had trouble to place raycast on ball or paddle.

```auto
      const ballPhysics = new PhysicsAggregate(pingPongBall,
        PhysicsShapeType.SPHERE, { mass: 0.0027, restitution: 0.85, friction: 0, collisionMargin: 0.05 }, 
      scene);
      pingPongBall.physicsBody = ballPhysics.body;
      pingPongBall.physicsBody.disablePreStep = false;
      pingPongBall.physicsBody.checkCollisions = true;
      pingPongBall.physicsBody.continuousCollisionDetection = true;

```

---

<div class="post-metadata">

**Author:** ![extremety1989](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/extremety1989/32/38171_2.png) [@extremety1989](https://forum.babylonjs.com/u/extremety1989)\
**Post date:** [April 22, 2024, 5:59am UTC](https://forum.babylonjs.com/t/continuous-collision-detection-with-havok/49458/18 "2024-04-22T05:59:21Z")

</div>

well, i found the problem, is that the ball is 0.04 diam, and Havok cannot detect fast collision. I need to do raycast from ball, that what works. Im closing the issue
