... | ... | @@ -226,7 +226,7 @@ In your document's **<head>** tag, add three.js' **GLTFLoader**. |
|
|
<!-- three.js -->
|
|
|
<script src="https://unpkg.com/three@0.126.0/build/three.js"></script>
|
|
|
|
|
|
**<script src="https://unpkg.com/three@0.126.0/examples/js/loaders/GLTFLoader.js"></script>**
|
|
|
<script src="https://unpkg.com/three@0.126.0/examples/js/loaders/GLTFLoader.js"></script>
|
|
|
```
|
|
|
|
|
|
## Load GLTF models
|
... | ... | @@ -251,3 +251,64 @@ loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/sunflower/ |
|
|
// Create a render loop that allows us to draw on the AR view.
|
|
|
const onXRFrame = (time, frame) => {
|
|
|
```
|
|
|
## Create a hit test source
|
|
|
To calculate intersections with real-world objects, create a **XRHitTestSource** using **XRSession.requestHitTestSource()**. The ray used for hit testing has the **viewer **reference space as origin, meaning that the hit test is done from the center of the viewport.
|
|
|
|
|
|
To create a hit test source, add this code after creating the **local **reference space:
|
|
|
|
|
|
```
|
|
|
// A 'local' reference space has a native origin that is located
|
|
|
// near the viewer's position at the time the session was created.
|
|
|
const referenceSpace = await session.requestReferenceSpace('local');
|
|
|
|
|
|
// Create another XRReferenceSpace that has the viewer as the origin.
|
|
|
const viewerSpace = await session.requestReferenceSpace('viewer');
|
|
|
// Perform hit testing using the viewer as origin.
|
|
|
const hitTestSource = await session.requestHitTestSource({ space: viewerSpace });
|
|
|
```
|
|
|
|
|
|
## Drawing a targeting reticle
|
|
|
To make it clear where the sunflower will be placed, add a targeting reticle to the scene. This reticle will appear to stick to real-world surfaces, signifying where the sunflower will be anchored.
|
|
|
|
|
|
**XRFrame.getHitTestResults** returns an array of **XRHitTestResult** and exposes intersections with real-world geometry. Use these intersections to position the targeting reticle on every frame.
|
|
|
|
|
|
```
|
|
|
camera.projectionMatrix.fromArray(view.projectionMatrix);
|
|
|
camera.updateMatrixWorld(true);
|
|
|
|
|
|
const hitTestResults = frame.getHitTestResults(hitTestSource);
|
|
|
if (hitTestResults.length > 0 && reticle) {
|
|
|
const hitPose = hitTestResults[0].getPose(referenceSpace);
|
|
|
reticle.visible = true;
|
|
|
reticle.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z)
|
|
|
reticle.updateMatrixWorld(true);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## Adding interactions on tap
|
|
|
**XRSession **receives select events when the user completes a primary action. In an AR session, this corresponds to a tap on the screen.
|
|
|
|
|
|
Make a new sunflower appear when the user taps on the screen by adding this code during initialization:
|
|
|
|
|
|
```
|
|
|
let flower;
|
|
|
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/sunflower/sunflower.gltf", function(gltf) {
|
|
|
flower = gltf.scene;
|
|
|
});
|
|
|
|
|
|
session.addEventListener("select", (event) => {
|
|
|
if (flower) {
|
|
|
const clone = flower.clone();
|
|
|
clone.position.copy(reticle.position);
|
|
|
scene.add(clone);
|
|
|
}
|
|
|
});
|
|
|
```
|
|
|
|
|
|
## Tap to Place results
|
|
|
Use your mobile device to navigate to the page. After WebXR builds an understanding of the environment, the reticle should appear on real-world surfaces. Tap the screen to place a sunflower, which can be viewed from all sides.
|
|
|
|
|
|
** Placeholder For GIF**
|
|
|
The complete code can be downloaded [hit2place.html](uploads/eaa488c6737044ead8a3dc41aaf11489/hit2place.html) and a live demo can be acceded [here](https://transfer.hft-stuttgart.de/pages/muhammad.alfakhori/ar/2-Hit.html).
|
|
|
|
|
|
|