immersive2/src/util/customPhysics.ts
Michael Mainguy c66da87401 Migrate from legacy config to new AppConfig singleton system
Remove dual config system and migrate all code to use appConfigInstance.

**Phase 1: Update VR Controller Code**
- snapAll.ts: Replace getAppConfig() with appConfigInstance.current
  - Use `rotateSnap > 0` instead of rotationSnapEnabled flag
  - Use `locationSnap > 0` instead of locationSnapEnabled flag
  - Remove parseFloat() calls (values already numbers)
- groundMeshObserver.ts: Direct property replacement
  - flyModeEnabled → flyMode
  - snapTurnSnap → turnSnap (remove parseFloat)
- customPhysics.ts: Add enabled checks and update
  - Add `> 0` checks (was applying unconditionally)
  - Use locationSnap and rotateSnap directly

**Phase 2: Remove Legacy Config Bridge**
- vrConfigPanel.ts: Remove syncLegacyConfig() method and all calls
- configModal.tsx: Remove legacy localStorage 'config' writes

**Phase 3: Cleanup**
- appConfig.ts: Remove legacy code (ConfigType, getAppConfig(), setAppConfig())
- Remove unused log import

**Benefits:**
- Eliminates dual config system confusion
- Fixes precision error from string "0" values
- Single source of truth via appConfigInstance
- Reactive updates via Observable pattern
- Cleaner, simpler codebase

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 13:20:18 -06:00

63 lines
2.5 KiB
TypeScript

import {HavokPlugin, Quaternion, Scene, Vector3} from "@babylonjs/core";
import HavokPhysics from "@babylonjs/havok";
import {snapGridVal} from "./functions/snapGridVal";
import {snapRotateVal} from "./functions/snapRotateVal";
import {isDiagramEntity} from "../diagram/functions/isDiagramEntity";
import {appConfigInstance} from "./appConfig";
export class CustomPhysics {
private readonly scene: Scene;
constructor(scene: Scene) {
this.scene = scene;
}
public async initializeAsync() {
const havok = await HavokPhysics();
const havokPlugin = new HavokPlugin(true, havok);
const scene = this.scene;
const physicsEnable = scene.enablePhysics(new Vector3(0, -9.8, 0), havokPlugin);
scene.collisionsEnabled = true;
scene.onAfterPhysicsObservable.add(() => {
const config = appConfigInstance.current;
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;
// Apply location snap if enabled
if (config.locationSnap > 0) {
const pos: Vector3 = body.getObjectCenterWorld();
const val: Vector3 = snapGridVal(pos, config.locationSnap);
body.transformNode.position.set(val.x, val.y, val.z);
}
// Apply rotation snap if enabled
if (config.rotateSnap > 0) {
const rot: Quaternion =
Quaternion.FromEulerVector(
snapRotateVal(body.transformNode.rotationQuaternion.toEulerAngles(),
config.rotateSnap));
body.transformNode.rotationQuaternion.set(
rot.x, rot.y, rot.z, rot.w
);
}
scene.onAfterRenderObservable.addOnce(() => {
body.disablePreStep = true;
});
}
}
});
}
);
}
}