Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* DEVKIT — global mutable store for fake controller inputs.
|
||||
*
|
||||
* Lives outside React (plain object + listeners) so useControllerGrab can
|
||||
* read it from inside useFrame with zero re-render cost. Mirrors the shape
|
||||
* of a real WebXR XRInputSource just enough to feed our grab logic.
|
||||
*/
|
||||
import * as THREE from 'three';
|
||||
|
||||
export interface FakeHandState {
|
||||
gripValue: number; // 0..1
|
||||
triggerValue: number; // 0..1
|
||||
hasPose: boolean; // true if controller is "tracked"
|
||||
gripWorld: THREE.Matrix4; // world pose of the gripSpace
|
||||
}
|
||||
|
||||
export interface FakeInputState {
|
||||
active: boolean;
|
||||
left: FakeHandState;
|
||||
right: FakeHandState;
|
||||
}
|
||||
|
||||
function makeHand(): FakeHandState {
|
||||
return {
|
||||
gripValue: 0,
|
||||
triggerValue: 0,
|
||||
hasPose: true,
|
||||
gripWorld: new THREE.Matrix4(),
|
||||
};
|
||||
}
|
||||
|
||||
export const fakeInput: FakeInputState = {
|
||||
active: false,
|
||||
left: makeHand(),
|
||||
right: makeHand(),
|
||||
};
|
||||
|
||||
// Initial poses — a bit in front of the camera, hands apart at chest height
|
||||
fakeInput.left.gripWorld.makeTranslation(-0.25, 1.2, -0.5);
|
||||
fakeInput.right.gripWorld.makeTranslation(0.25, 1.2, -0.5);
|
||||
|
||||
export function setFakeActive(on: boolean) {
|
||||
fakeInput.active = on;
|
||||
}
|
||||
|
||||
export function isFakeActive(): boolean {
|
||||
return fakeInput.active;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* DEVKIT entry point. The whole devkit is gated by this single flag.
|
||||
*
|
||||
* Activation: append `?devkit=1` to URL OR run in console:
|
||||
* localStorage.setItem('devkit', '1')
|
||||
* Deactivation: `?devkit=0` OR localStorage.removeItem('devkit')
|
||||
*
|
||||
* To remove DevKit from the project entirely:
|
||||
* 1. rm -rf src/devkit/
|
||||
* 2. Strip `// DEVKIT:` blocks in XRSession.tsx & useControllerGrab.ts
|
||||
*/
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const KEY = 'devkit';
|
||||
|
||||
function readFlag(): boolean {
|
||||
if (typeof window === 'undefined') return false;
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const urlVal = params.get(KEY);
|
||||
if (urlVal === '1') {
|
||||
localStorage.setItem(KEY, '1');
|
||||
return true;
|
||||
}
|
||||
if (urlVal === '0') {
|
||||
localStorage.removeItem(KEY);
|
||||
return false;
|
||||
}
|
||||
return localStorage.getItem(KEY) === '1';
|
||||
}
|
||||
|
||||
export function useDevKit(): boolean {
|
||||
const [enabled, setEnabled] = useState(readFlag);
|
||||
useEffect(() => {
|
||||
const onStorage = () => setEnabled(readFlag());
|
||||
window.addEventListener('storage', onStorage);
|
||||
return () => window.removeEventListener('storage', onStorage);
|
||||
}, []);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
export function isDevKit(): boolean {
|
||||
return readFlag();
|
||||
}
|
||||
Reference in New Issue
Block a user