@coconut-xr/natuerlich
Advanced tools
Comparing version 0.0.8 to 0.0.9
@@ -136,2 +136,3 @@ /// <reference types="webxr" resolution-mode="require"/> | ||
}, distance: number, smallestDistance: number, highestDistance: number, cursorOpacity: number): void; | ||
export * from "./canvas.js"; | ||
export * from "./grab-controller.js"; | ||
@@ -138,0 +139,0 @@ export * from "./grab-hand.js"; |
@@ -65,2 +65,3 @@ import { MeshBasicMaterial, Quaternion, Vector3, } from "three"; | ||
} | ||
export * from "./canvas.js"; | ||
export * from "./grab-controller.js"; | ||
@@ -67,0 +68,0 @@ export * from "./grab-hand.js"; |
@@ -1,1 +0,23 @@ | ||
export {}; | ||
import React from "react"; | ||
import { Group } from "three"; | ||
export declare const TrackedImage: React.ForwardRefExoticComponent<Omit<{ | ||
image: ImageBitmap; | ||
} & Omit<import("@react-three/fiber").ExtendedColors<import("@react-three/fiber").Overwrite<Partial<Group>, import("@react-three/fiber").NodeProps<Group, typeof Group>>>, import("@react-three/fiber").NonFunctionKeys<{ | ||
position?: import("@react-three/fiber").Vector3 | undefined; | ||
up?: import("@react-three/fiber").Vector3 | undefined; | ||
scale?: import("@react-three/fiber").Vector3 | undefined; | ||
rotation?: import("@react-three/fiber").Euler | undefined; | ||
matrix?: import("@react-three/fiber").Matrix4 | undefined; | ||
quaternion?: import("@react-three/fiber").Quaternion | undefined; | ||
layers?: import("@react-three/fiber").Layers | undefined; | ||
dispose?: (() => void) | null | undefined; | ||
}>> & { | ||
position?: import("@react-three/fiber").Vector3 | undefined; | ||
up?: import("@react-three/fiber").Vector3 | undefined; | ||
scale?: import("@react-three/fiber").Vector3 | undefined; | ||
rotation?: import("@react-three/fiber").Euler | undefined; | ||
matrix?: import("@react-three/fiber").Matrix4 | undefined; | ||
quaternion?: import("@react-three/fiber").Quaternion | undefined; | ||
layers?: import("@react-three/fiber").Layers | undefined; | ||
dispose?: (() => void) | null | undefined; | ||
} & import("@react-three/fiber/dist/declarations/src/core/events.js").EventHandlers, "ref"> & React.RefAttributes<Group>>; |
@@ -1,4 +0,34 @@ | ||
export {}; | ||
/*export const TrackedImage = forwardRef<Group, {}>(() => { | ||
return null; | ||
});*/ | ||
/* eslint-disable react/display-name */ | ||
import { useFrame } from "@react-three/fiber"; | ||
import React, { forwardRef, useImperativeHandle, useMemo, useRef } from "react"; | ||
import { useXR } from "./state.js"; | ||
import { applySpace } from "./space.js"; | ||
export const TrackedImage = forwardRef(({ image, children, ...props }, ref) => { | ||
const internalRef = useRef(null); | ||
const requestedImages = useXR(({ requestedTrackedImages }) => requestedTrackedImages); | ||
const imageIndex = useMemo(() => { | ||
if (requestedImages == null) { | ||
return undefined; | ||
} | ||
const index = requestedImages.findIndex(({ image: requestedImage }) => requestedImage === image); | ||
if (index === -1) { | ||
throw new Error(`Unknown image provided to TrackedImage. Images that should be tracked must be provided to "trackedImages" inside the XRSessionInit options`); | ||
} | ||
return index; | ||
}, [image, requestedImages]); | ||
useFrame((state, _delta, frame) => { | ||
if (internalRef.current == null || imageIndex == null) { | ||
return; | ||
} | ||
const space = useXR.getState().trackedImages?.get(imageIndex)?.imageSpace; | ||
if (space == null) { | ||
return; | ||
} | ||
applySpace(state, frame, internalRef.current, space); | ||
}); | ||
useImperativeHandle(ref, () => internalRef.current, []); | ||
if (imageIndex == null) { | ||
return null; | ||
} | ||
return (React.createElement("group", { ...props, ref: internalRef }, children)); | ||
}); |
@@ -22,6 +22,3 @@ /// <reference types="webxr" resolution-mode="require"/> | ||
export declare function useHeighestAvailableFrameRate(): number | undefined; | ||
/** | ||
* must be positioned somewhere inside the canvas | ||
*/ | ||
export declare function XR({ foveation, frameRate, referenceSpace, frameBufferScaling, }: { | ||
export type XRProps = { | ||
foveation?: number; | ||
@@ -31,2 +28,6 @@ frameRate?: number; | ||
frameBufferScaling?: number; | ||
}): null; | ||
}; | ||
/** | ||
* must be positioned somewhere inside the canvas | ||
*/ | ||
export declare function XR({ foveation, frameRate, referenceSpace, frameBufferScaling, }: XRProps): null; |
@@ -1,2 +0,2 @@ | ||
import { useStore, useThree } from "@react-three/fiber"; | ||
import { useFrame, useStore, useThree } from "@react-three/fiber"; | ||
import { useEffect, useMemo } from "react"; | ||
@@ -67,3 +67,17 @@ import { useXR } from "./state.js"; | ||
}, [xrManager, referenceSpace]); | ||
useFrame((_state, _delta, frame) => { | ||
if (frame == null || !("getImageTrackingResults" in frame)) { | ||
return; | ||
} | ||
const trackedImages = useXR.getState().trackedImages; | ||
if (trackedImages == null) { | ||
return; | ||
} | ||
trackedImages.clear(); | ||
const results = frame.getImageTrackingResults(); | ||
for (const result of results) { | ||
trackedImages.set(result.index, result); | ||
} | ||
}); | ||
return null; | ||
} |
@@ -74,3 +74,3 @@ /* eslint-disable react/display-name */ | ||
const eventProps = useMeshForwardEventsFromStore(store, dragDistance); | ||
useImperativeHandle(ref, () => eventProps.ref.current); | ||
useImperativeHandle(ref, () => eventProps.ref.current, []); | ||
return (React.createElement(React.Fragment, null, | ||
@@ -77,0 +77,0 @@ reconciler.createPortal(React.createElement(context.Provider, { value: store }, children), store, null), |
@@ -65,3 +65,3 @@ /* eslint-disable react/display-name */ | ||
const eventProps = useMeshForwardEventsFromStore(store.getState, dragDistance); | ||
useImperativeHandle(ref, () => eventProps.ref.current); | ||
useImperativeHandle(ref, () => eventProps.ref.current, []); | ||
return (React.createElement(React.Fragment, null, | ||
@@ -68,0 +68,0 @@ reconciler.createPortal(React.createElement(context.Provider, { value: store }, children), store, null), |
@@ -36,3 +36,5 @@ /* eslint-disable react/display-name */ | ||
shape.setFromPoints(polygon.map(({ x, z }) => new Vector2(x, z))); | ||
return new ShapeGeometry(shape); | ||
const geometry = new ShapeGeometry(shape); | ||
geometry.rotateX(-Math.PI / 2); | ||
return geometry; | ||
} | ||
@@ -54,3 +56,3 @@ export const TrackedPlane = forwardRef(({ plane, children, ...props }, ref) => { | ||
useApplySpace(internalRef, plane.planeSpace); | ||
return (React.createElement("mesh", { matrixAutoUpdate: false, ...props, ref: internalRef }, children)); | ||
return (React.createElement("mesh", { ...props, matrixAutoUpdate: false, ref: internalRef }, children)); | ||
}); |
@@ -9,2 +9,3 @@ /// <reference types="webxr" resolution-mode="require"/> | ||
export declare function useApplySpace(ref: RefObject<Object3D>, space: XRSpace, onFrame?: (rootState: RootState, delta: number, frame: XRFrame | undefined, object: Object3D) => void): void; | ||
export declare function applySpace(state: RootState, frame: XRFrame | undefined, object: Object3D, space: XRSpace): void; | ||
export declare const SpaceGroup: React.ForwardRefExoticComponent<{ | ||
@@ -11,0 +12,0 @@ space: XRSpace; |
@@ -14,14 +14,3 @@ /* eslint-disable react/display-name */ | ||
} | ||
const referenceSpace = rootState.gl.xr.getReferenceSpace(); | ||
if (referenceSpace == null || frame == null) { | ||
group.visible = false; | ||
return; | ||
} | ||
const pose = frame.getPose(space, referenceSpace); | ||
if (pose == null) { | ||
group.visible = false; | ||
return; | ||
} | ||
group.visible = true; | ||
group.matrix.fromArray(pose.transform.matrix); | ||
applySpace(rootState, frame, group, space); | ||
if (onFrame != null) { | ||
@@ -33,2 +22,16 @@ group.updateMatrixWorld(); | ||
} | ||
export function applySpace(state, frame, object, space) { | ||
const referenceSpace = state.gl.xr.getReferenceSpace(); | ||
if (referenceSpace == null || frame == null) { | ||
object.visible = false; | ||
return; | ||
} | ||
const pose = frame.getPose(space, referenceSpace); | ||
if (pose == null) { | ||
object.visible = false; | ||
return; | ||
} | ||
object.visible = true; | ||
object.matrix.fromArray(pose.transform.matrix); | ||
} | ||
export const SpaceGroup = forwardRef(({ space, children, onFrame }, ref) => { | ||
@@ -35,0 +38,0 @@ const internalRef = useRef(null); |
@@ -5,3 +5,16 @@ /// <reference types="webxr" resolution-mode="require"/> | ||
import { StoreApi } from "zustand"; | ||
export type XRImageTrackingScore = "untrackable" | "trackable"; | ||
export type XRImageTrackingState = "tracked" | "emulated"; | ||
export type XRImageTrackingResult = { | ||
readonly imageSpace: XRSpace; | ||
readonly index: number; | ||
readonly trackingState: XRImageTrackingState; | ||
readonly measuredWidthInMeters: number; | ||
}; | ||
export type XRTrackedImageInit = { | ||
image: ImageBitmap; | ||
widthInMeters: number; | ||
}; | ||
export type XRInputSourceMap = Map<number, XRInputSource>; | ||
export type TrackedImagesMap = Map<number, XRImageTrackingResult>; | ||
export type ExtendedXRSessionMode = XRState["mode"]; | ||
@@ -17,2 +30,4 @@ export type XRState = ({ | ||
}>; | ||
trackedImages: TrackedImagesMap; | ||
requestedTrackedImages?: ReadonlyArray<XRTrackedImageInit>; | ||
} | { | ||
@@ -24,2 +39,4 @@ mode: "none"; | ||
layers?: undefined; | ||
trackedImages?: undefined; | ||
requestedTrackedImages?: undefined; | ||
}) & { | ||
@@ -35,3 +52,3 @@ store?: StoreApi<RootState>; | ||
onXREnd(e: XRSessionEvent): void; | ||
setSession(session: XRSession, mode: XRSessionMode): Promise<void>; | ||
setSession(session: XRSession, mode: XRSessionMode, requestedTrackedImages?: ReadonlyArray<XRTrackedImageInit>): Promise<void>; | ||
}>>; |
@@ -60,2 +60,4 @@ import { create } from "zustand"; | ||
layers: undefined, | ||
requestedTrackedImages: undefined, | ||
trackedImages: undefined, | ||
}); | ||
@@ -68,3 +70,11 @@ const { camera } = store.getState(); | ||
}, | ||
async setSession(session, mode) { | ||
async setSession(session, mode, requestedTrackedImages) { | ||
if ("getTrackedImageScores" in session) { | ||
const scores = await session.getTrackedImageScores(); | ||
for (let index = 0; index < scores.length; ++index) { | ||
if (scores[index] == "untrackable") { | ||
console.error(`Provided image at index "${index}" is untrackable.`, requestedTrackedImages?.[index]); | ||
} | ||
} | ||
} | ||
//clear old event listeners | ||
@@ -101,2 +111,4 @@ const oldSession = get().session; | ||
initialCamera: camera, | ||
trackedImages: new Map(), | ||
requestedTrackedImages, | ||
layers: [{ index: 0, layer: gl.xr.getBaseLayer() }], | ||
@@ -103,0 +115,0 @@ }); |
/// <reference types="webxr" resolution-mode="require"/> | ||
export declare function useEnterXR(mode: XRSessionMode, options?: XRSessionInit): () => Promise<void>; | ||
import { XRTrackedImageInit } from "./index.js"; | ||
export declare function useEnterXR(mode: XRSessionMode, options?: XRSessionInit & { | ||
trackedImages?: ReadonlyArray<XRTrackedImageInit>; | ||
}): () => Promise<void>; |
@@ -10,4 +10,4 @@ import { useCallback } from "react"; | ||
const session = await xrSystem.requestSession(mode, options); | ||
useXR.getState().setSession(session, mode); | ||
useXR.getState().setSession(session, mode, options?.trackedImages); | ||
}, [mode, options]); | ||
} |
/// <reference types="webxr" resolution-mode="require"/> | ||
export declare function useSessionGrant(options?: XRSessionInit | undefined): void; | ||
export declare function useSessionGrant(options?: (XRSessionInit & { | ||
trackedImages?: Array<{ | ||
image: ImageBitmap; | ||
widthInMeters: number; | ||
}>; | ||
}) | undefined): void; |
@@ -11,7 +11,7 @@ import { useEffect } from "react"; | ||
const session = await xrSystem.requestSession(e.session.mode, options); | ||
useXR.getState().setSession(session, e.session.mode); | ||
useXR.getState().setSession(session, e.session.mode, options?.trackedImages); | ||
}; | ||
xrSystem.addEventListener("sessiongranted", listener); | ||
return () => xrSystem.removeEventListener("sessiongranted", listener); | ||
}, []); | ||
}, [options]); | ||
} |
{ | ||
"name": "@coconut-xr/natuerlich", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"main": "dist/index.js", | ||
@@ -5,0 +5,0 @@ "repository": { |
144485
2884