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();
}
}
}


