Wednesday, January 7, 2026
spot_img

Interpolation within the bodily world – Cocos Creator


I see that varied physics engines are wrapped and never utilized by the engine to their full potential. When experimenting with Box2D – I wrote my very own interpolation logic with autoSimulation turned off, however now I’m testing 3d (CannonJS) and even within the physics engine that has interpolation logic underneath the hood – it’s not used as a result of it’s wrapped in its personal accumulators for calling .step(…) and synchronizes our bodies accordingly via place and never interpolatedPosition. And it looks as if it is going to be tougher to change with out breaking different performance of the wrapper.

My goal units are weak TVs, so decreasing the load by growing the fixedTimeStep and restoring smoothness by interpolation is obligatory.

Are there any plans to replace the strategy to utilizing physics engines?

That is working for me up to now, however wants extra testing. !!! cannon.js !!!

import { _decorator, PhysicsSystem, Element, director, DirectorEvent, Vec3, ERigidBodyType, Quat } from 'cc';
const { ccclass } = _decorator;

@ccclass('PhysicsManager')
export class PhysicsManager extends Element {
    public static occasion: PhysicsManager;

    begin() {
        PhysicsManager.occasion = this;

        const physicsSystem = PhysicsSystem.occasion;
        if(physicsSystem.autoSimulation) {
            console.log('[!!!] Disable auto physics simulation in undertaking settings.');
            physicsSystem.autoSimulation = false;
        }
        
        const cannonWorld = physicsSystem.physicsWorld as any;
        cannonWorld._world.addEventListener('preStep', this.preStep.bind(this));
        cannonWorld._world.addEventListener('postStep', this.postStep.bind(this));
    }

    preStep(){
        //console.log('preStep');
        const physicsSystem = PhysicsSystem.occasion;
        physicsSystem.physicsWorld.syncSceneToPhysics();
        director.emit(DirectorEvent.BEFORE_PHYSICS);
    }
    postStep(){
        //console.log('postStep');
        const physicsSystem = PhysicsSystem.occasion;
        physicsSystem.physicsWorld.emitEvents();
        director.emit(DirectorEvent.AFTER_PHYSICS);
    }

    replace (deltaTime: quantity) {
        const physicsSystem = PhysicsSystem.occasion;

        const cannonWorld = physicsSystem.physicsWorld as any;
        cannonWorld._world.step(physicsSystem.fixedTimeStep, deltaTime, physicsSystem.maxSubSteps);
        
        for (let i = 0; i 
import { _decorator, CCFloat, Element, RigidBody, enter, KeyCode, Vec3, Enter, DirectorEvent, director, PhysicsSystem } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('BallController')
export class BallController extends Element {
    @property(CCFloat)
    pace: quantity = 10;

    physique: RigidBody;

    non-public pressedKeys: Set = new Set();

    begin() {
        this.physique = this.getComponent(RigidBody);
        
    }
    onEnable() {
        enter.on(Enter.EventType.KEY_DOWN, this.onKeyDown, this);
        enter.on(Enter.EventType.KEY_UP, this.onKeyUp, this);
        director.on(DirectorEvent.BEFORE_PHYSICS, this.fixedUpdate, this);
    }
    onDisable() {
        enter.off(Enter.EventType.KEY_DOWN, this.onKeyDown, this);
        enter.off(Enter.EventType.KEY_UP, this.onKeyUp, this);
        director.off(DirectorEvent.BEFORE_PHYSICS, this.fixedUpdate, this);
    }

    onKeyDown(occasion: any) {
        this.pressedKeys.add(occasion.keyCode);
    }

    onKeyUp(occasion: any) {
        this.pressedKeys.delete(occasion.keyCode);
    }

    fixedUpdate() {
        //console.log('fixedUpdate');
        const torque = new Vec3(0, 0, 0);
        
        if (this.pressedKeys.has(KeyCode.ARROW_LEFT)) {
            torque.z += 1;
        }
        else if (this.pressedKeys.has(KeyCode.ARROW_RIGHT)) {
            torque.z -= 1;
        }
        if (this.pressedKeys.has(KeyCode.ARROW_UP)) {
            torque.x -= 1;
        }
        else if (this.pressedKeys.has(KeyCode.ARROW_DOWN)) {
            torque.x += 1;
        }
        
        if (torque.x !== 0 || torque.y !== 0 || torque.z !== 0) {
            torque.normalize();
            this.physique.applyTorque(torque.multiplyScalar(this.pace));
        }
    }
}

Some fixes and polish

import { _decorator, PhysicsSystem, Element, director, DirectorEvent, Vec3, ERigidBodyType, Quat, Node } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('PhysicsManager')
export class PhysicsManager extends Element {
    public static occasion: PhysicsManager;

    @property iterations: quantity = 6;
    @property tolerance: quantity = 0.001;

    non-public _tempVec3 = new Vec3();
    non-public _tempQuat = new Quat();
    
    non-public _stepping: boolean = false;

    onLoad() {
        PhysicsManager.occasion = this;

        const physicsSystem = PhysicsSystem.occasion;
        if(physicsSystem.autoSimulation) {
            console.error('[!!!] Disable Physics -> Auto Simulation in undertaking settings.');
            physicsSystem.autoSimulation = false; // that is by some means damaged and should be outlined within the config
            this.enabled = false; // to make it clear that one thing is improper 
        }
        
        const cannonWorld = physicsSystem.physicsWorld as any;
        cannonWorld._world.solver.iterations = this.iterations;
        cannonWorld._world.solver.tolerance = this.tolerance;
        cannonWorld._world.default_dt = physicsSystem.fixedTimeStep;
        
        cannonWorld._world.addEventListener('preStep', this.preStep.bind(this));
    }

    preStep(){
        if(this._stepping) return; //just for first substep
        this._stepping = true;
        //console.log('preStep');

        const physicsSystem = PhysicsSystem.occasion;
        physicsSystem.physicsWorld.syncSceneToPhysics();
        director.emit(DirectorEvent.BEFORE_PHYSICS);
    }
    postStep(){
        //console.log('postStep');
        const physicsSystem = PhysicsSystem.occasion;
        physicsSystem.physicsWorld.emitEvents(); // wanted?
        director.emit(DirectorEvent.AFTER_PHYSICS);
    }

    replace (deltaTime: quantity) {
        if(this._stepping) {
            this._stepping = false;
        }

        const physicsSystem = PhysicsSystem.occasion;
        const cannonWorld = physicsSystem.physicsWorld as any;
        cannonWorld._world.step(physicsSystem.fixedTimeStep, deltaTime, physicsSystem.maxSubSteps);
        
        for (let i = 0; i  step
            this.postStep();
        }
    }
}

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisement -spot_img

Latest Articles