- Use camera.getDirection() instead of manual Euler angle calculation to properly account for camera transform hierarchy - Negate forward offsets to position objects in -Z direction (user faces -Z by design) - Replace expensive HighlightLayer hover effect with lightweight EdgesRenderer (20-50x faster) - Add comprehensive debug logging for position calculations The camera has a parent transform with 180° Y rotation, causing the user to face -Z in world space. Components now correctly position in front of the user when entering XR. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
60 lines
2.3 KiB
TypeScript
60 lines
2.3 KiB
TypeScript
import {
|
|
ActionManager,
|
|
Color4,
|
|
ExecuteCodeAction,
|
|
InstancedMesh,
|
|
Observable,
|
|
} from "@babylonjs/core";
|
|
import log from "loglevel";
|
|
import {DefaultScene} from "../../defaultScene";
|
|
import {ControllerEventType} from "../../controllers/types/controllerEventType";
|
|
import {ControllerEvent} from "../../controllers/types/controllerEvent";
|
|
|
|
export function buildEntityActionManager(controllerObservable: Observable<ControllerEvent>) {
|
|
const logger = log.getLogger('buildEntityActionManager');
|
|
const actionManager = new ActionManager(DefaultScene.Scene);
|
|
/*actionManager.registerAction(
|
|
new PlaySoundAction(ActionManager.OnPointerOverTrigger, sounds.tick));*/
|
|
actionManager.registerAction(
|
|
new ExecuteCodeAction(ActionManager.OnPointerOverTrigger, (evt) => {
|
|
if (evt.meshUnderPointer) {
|
|
try {
|
|
const mesh = evt.meshUnderPointer as InstancedMesh;
|
|
|
|
if (mesh.sourceMesh && !mesh.sourceMesh.edgesRenderer) {
|
|
// Enable edges rendering on the source mesh
|
|
mesh.sourceMesh.enableEdgesRendering(0.99);
|
|
mesh.sourceMesh.edgesWidth = 4.0;
|
|
mesh.sourceMesh.edgesColor = new Color4(1.5, 1.5, 1.5, 1.0);
|
|
|
|
// Track that edges are enabled
|
|
mesh.metadata = mesh.metadata || {};
|
|
mesh.metadata.edgesEnabled = true;
|
|
}
|
|
} catch (e) {
|
|
logger.error(e);
|
|
}
|
|
}
|
|
controllerObservable.notifyObservers({
|
|
type: ControllerEventType.PULSE,
|
|
gripId: evt?.additionalData?.pickResult?.gripTransform?.id
|
|
});
|
|
logger.debug(evt);
|
|
})
|
|
);
|
|
actionManager.registerAction(
|
|
new ExecuteCodeAction(ActionManager.OnPointerOutTrigger, (evt) => {
|
|
try {
|
|
const mesh = evt.source as InstancedMesh;
|
|
if (mesh.metadata?.edgesEnabled && mesh.sourceMesh?.edgesRenderer) {
|
|
mesh.sourceMesh.disableEdgesRendering();
|
|
mesh.metadata.edgesEnabled = false;
|
|
}
|
|
} catch (e) {
|
|
logger.error(e);
|
|
}
|
|
logger.debug(evt);
|
|
})
|
|
);
|
|
return actionManager;
|
|
} |