immersive2/src/util/customPhysics.ts

54 lines
2.3 KiB
TypeScript

import {HavokPlugin, Quaternion, Scene, Vector3} from "@babylonjs/core";
import HavokPhysics from "@babylonjs/havok";
import {AppConfig} from "./appConfig";
import {snapGridVal} from "./functions/snapGridVal";
import {snapRotateVal} from "./functions/snapRotateVal";
import {isDiagramEntity} from "../diagram/functions/isDiagramEntity";
export class CustomPhysics {
private readonly scene: Scene;
private config: AppConfig;
constructor(scene: Scene, config: AppConfig) {
this.scene = scene;
this.config = config;
}
public async initializeAsync() {
const havok = await HavokPhysics();
const havokPlugin = new HavokPlugin(true, havok);
const scene = this.scene;
scene.enablePhysics(new Vector3(0, -9.8, 0), havokPlugin);
scene.collisionsEnabled = true;
scene.onAfterPhysicsObservable.add(() => {
scene.meshes.forEach((mesh) => {
if (isDiagramEntity(mesh) && mesh.physicsBody) {
const body = mesh.physicsBody;
const linearVelocity = new Vector3();
body.getLinearVelocityToRef(linearVelocity);
if (linearVelocity.length() < .1) {
body.disablePreStep = false;
const pos: Vector3 = body.getObjectCenterWorld();
const val: Vector3 = snapGridVal(pos,
this.config.current.gridSnap);
body.transformNode.position.set(val.x, val.y, val.z);
const rot: Quaternion =
Quaternion.FromEulerVector(
snapRotateVal(body.transformNode.rotationQuaternion.toEulerAngles(),
this.config.current.rotateSnap))
body.transformNode.rotationQuaternion.set(
rot.x, rot.y, rot.z, rot.w
);
scene.onAfterRenderObservable.addOnce(() => {
body.disablePreStep = true;
});
}
}
});
}
);
}
}