Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address issues from CG call - hit test results for transient input did not specify input source used #1

Open
wants to merge 2 commits into
base: explainer-merge
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 53 additions & 6 deletions hit-testing-explainer.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,47 @@ The `XRSession.requestHitTestSourceForTransientInput()` method accepts a diction
* `offsetRay` is optional and specifies an `XRRay` for which the hit test should be performed. The ray will be interpreted as if relative to `targetRaySpace` of the transient input source that matches `targetRayMode`.

### Hit test results
To get synchronous hit test results for a particular frame, developers call `XRFrame.getHitTestResults()` passing in a `XRHitTestSource` as the `hitTestSource` parameter. This function will return a `FrozenArray<XRHitTestResult>` in which `XRHitTestResult`s are ordered by distance from the `XRHitTestSource`, with the nearest in the 0th position. If no results exist, the array will have a length of zero. The `XRHitTestResult` interface will expose a method, `getPose(XRSpace baseSpace)` that can be used to query the result's pose. If, in the current frame, the relationship between `XRSpace` passed in to `baseSpace` parameter cannot be located relative to the hit test result, the function will return `null`.
To get synchronous hit test results for a particular frame, developers call `XRFrame.getHitTestResults()` passing in a `XRHitTestSource` as the `hitTestSource` parameter. This function will return a `FrozenArray<XRHitTestResult>` in which `XRHitTestResult`s are ordered by distance along the `XRRay` used to perform the hit test, with the nearest in the 0th position. If no results exist, the array will have a length of zero. The `XRHitTestResult` interface will expose a method, `getPose(XRSpace baseSpace)` that can be used to query the result's pose. If, in the current frame, the relationship between `XRSpace` passed in to `baseSpace` parameter cannot be located relative to the hit test result, the function will return `null`.

```js
// Input source returned from a call to XRSession.requestHitTestSource(...):
let hitTestSource = ...;

function updateScene(timestamp, xrFrame) {
// Scene update logic ...
let hitTestResults = xrFrame.getHitTestResults(hitTestSources[preferredInputSource]);
if (hitTestResults && hitTestResults.length > 0) {
let hitTestResults = xrFrame.getHitTestResults(hitTestSource);
if (hitTestResults.length > 0) {
// Do something with the results
}
// Other scene update logic ...
}
```

In order to obtain hit test results for transient input source hit test subscriptions in a particular frame, developers call `XRFrame.getHitTestResultsForTransientInput()` passing in a `XRTransientInputHitTestSource` as the `hitTestSource` parameter. This function will return a `FrozenArray<XRTransientInputHitTestResult>`. Each element of the array will contain an instance of the input source that was used to obtain the results, and the actual hit test results will be contained in `FrozenArray<XRHitTestResult> results`, ordered by the distance along the ray used to perform the hit test, with the closest result at 0th position.

```js
// Input source returned from a call to
// XRSession.requestHitTestSourceForTransientInput(...):
let transientInputHitTestSource = ...;

function updateScene(timestamp, xrFrame) {
// Scene update logic ...
let hitTestResultsPerInputSource = xrFrame.getHitTestResultsForTransientInput(transientInputHitTestSource);

hitTestResultsPerInputSource.forEach(resultsPerInputSource => {
if(!isInteresting(resultsPerInputSource.inputSource)) {
return; // Application can perform additional
// filtering based on the input source.
}

if (resultsPerInputSource.results.length > 0) {
// Do something with the results
}
});
// Other scene update logic ...
}
```

#### Rays
An `XRRay` object includes both an `origin` and `direction`, both given as `DOMPointReadOnly`s. The `origin` represents a 3D coordinate in space with a `w` component that must be equal to 1, and the `direction` represents a normalized 3D directional vector with a `w` component that must be equal to 0. The `XRRay` also defines a `matrix` which represents the transform from a ray originating at `[0, 0, 0]` and extending down the negative Z axis to the ray described by the `XRRay`'s `origin` and `direction`. This is useful for positioning graphical representations of the ray.

Expand Down Expand Up @@ -128,18 +156,19 @@ This is a partial IDL and is considered additive to the core IDL found in the ma
//
partial interface XRSession {
Promise<XRHitTestSource> requestHitTestSource(XRHitTestOptionsInit options);
Promise<XRHitTestSource> requestHitTestSourceForTransientInput(XRTransientInputHitTestOptionsInit options);
Promise<XRTransientInputHitTestSource> requestHitTestSourceForTransientInput(XRTransientInputHitTestOptionsInit options);
};

//
// Frame
//
partial interface XRFrame {
FrozenArray<XRHitTestResult>? getHitTestResults(XRHitTestSource hitTestSource);
FrozenArray<XRHitTestResult> getHitTestResults(XRHitTestSource hitTestSource);
FrozenArray<XRTransientInputHitTestResult> getHitTestResultsForTransientInput(XRHitTestSource hitTestSource);
};

//
// Hit Testing
// Hit Testing Options
//
dictionary XRHitTestOptionsInit {
required XRSpace space;
Expand All @@ -151,10 +180,28 @@ dictionary XRTransientInputHitTestOptionsInit {
XRRay offsetRay = new XRRay();
};

//
// Hit Test Sources
//

[SecureContext, Exposed=Window]
interface XRHitTestSource {
};

[SecureContext, Exposed=Window]
interface XRTransientInputHitTestSource {
};

//
// Hit Test Results
//

[SecureContext, Exposed=Window]
interface XRTransientInputHitTestResult {
XRInputSource inputSource;
FrozenArray<XRHitTestResult> results;
};

[SecureContext, Exposed=Window]
interface XRHitTestResult {
XRPose? getPose(XRSpace baseSpace);
Expand Down