Skip to content

Commit

Permalink
Release (#1701)
Browse files Browse the repository at this point in the history
* Support left & right eyes (#1697)

* fix: support left & right eyes

* chore: commit changeset

* fix: add hit-testing

* chore: commit changeset

* chore(release): bump version (#1700)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed May 29, 2024
1 parent 0d2b174 commit 538929e
Show file tree
Hide file tree
Showing 26 changed files with 728 additions and 125 deletions.
3 changes: 1 addition & 2 deletions __tests__/demos/3d/cylinder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ export async function cylinder(context) {

const cylinder = new Mesh({
style: {
x: 300,
y: 250,
transform: `translate3d(300, 250, 0)`,
fill: 'white',
opacity: 1,
geometry: cylinderGeometry,
Expand Down
67 changes: 35 additions & 32 deletions __tests__/demos/3d/force.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1709,18 +1709,18 @@ export async function force(context) {
// });
// canvas.appendChild(circle);

// const label = new Text({
// style: {
// x: node.x + 310,
// y: node.y + 250,
// z: node.z + 1,
// fontFamily: 'sans-serif',
// text: node.id,
// fontSize: 6,
// fill: 'black',
// isBillboard: true,
// },
// });
const label = new Text({
style: {
x: node.x + 310,
y: node.y + 250,
z: node.z + 1,
fontFamily: 'sans-serif',
text: node.id,
fontSize: 6,
fill: 'black',
isBillboard: true,
},
});

// const rect = new Rect({
// style: {
Expand All @@ -1735,27 +1735,27 @@ export async function force(context) {
// },
// });
// canvas.appendChild(rect);
// canvas.appendChild(label);
canvas.appendChild(label);
});

// dataset.links.forEach((edge) => {
// const { source, target } = edge;
// const line = new Line({
// style: {
// x1: source.x + 300,
// y1: source.y + 250,
// z1: source.z,
// x2: target.x + 300,
// y2: target.y + 250,
// z2: target.z,
// stroke: 'black',
// lineWidth: 2,
// opacity: 0.5,
// isBillboard: true, // 始终面向屏幕
// },
// });
// canvas.appendChild(line);
// });
dataset.links.forEach((edge) => {
const { source, target } = edge;
const line = new Line({
style: {
x1: source.x + 300,
y1: source.y + 250,
z1: source.z,
x2: target.x + 300,
y2: target.y + 250,
z2: target.z,
stroke: 'black',
lineWidth: 2,
opacity: 0.5,
isBillboard: true, // 始终面向屏幕
},
});
canvas.appendChild(line);
});

// add a directional light into scene
const light = new DirectionalLight({
Expand All @@ -1777,7 +1777,10 @@ export async function force(context) {

canvas.getConfig().disableHitTesting = true;

const $button = ARButton.createButton(canvas, renderer, {});
const $button = ARButton.createButton(canvas, renderer, {
// @see https://github.com/immersive-web/webxr-samples/blob/main/hit-test.html
requiredFeatures: ['local', 'hit-test'],
});
container.appendChild($button);
}

Expand Down
183 changes: 183 additions & 0 deletions __tests__/demos/3d/hit-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import { CanvasEvent, Canvas } from '../../../packages/g';
import {
CubeGeometry,
CylinderGeometry,
MeshPhongMaterial,
MeshBasicMaterial,
DirectionalLight,
Mesh,
Plugin as Plugin3D,
} from '../../../packages/g-plugin-3d';
import { ARButton, Renderer } from '../../../packages/g-webgl';

/**
* @see https://github.com/immersive-web/webxr-samples/blob/main/hit-test.html
*/
export async function hit_test(context: {
canvas: Canvas;
renderer: Renderer;
container: HTMLDivElement;
}) {
const { canvas, renderer, container } = context;

// wait for canvas' initialization complete
await canvas.ready;

// use GPU device
const plugin = renderer.getPlugin('device-renderer');
const device = plugin.getDevice();

// create a sphere geometry
const cylinderGeometry = new CylinderGeometry(device, {
radius: 100,
height: 50,
});
// create a material with Phong lighting model
const material = new MeshPhongMaterial(device, {
shininess: 30,
});

// 1. load texture with URL
const map = plugin.loadTexture(
'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*_aqoS73Se3sAAAAAAAAAAAAAARQnAQ',
);
const cubeGeometry = new CubeGeometry(device, {
width: 200,
height: 200,
depth: 200,
});
const basicMaterial = new MeshBasicMaterial(device, {
// wireframe: true,
map,
});

const reticle = new Mesh({
style: {
fill: 'red',
opacity: 1,
geometry: cylinderGeometry,
material,
},
});
reticle.setPosition(300, 300, 0);
canvas.appendChild(reticle);

// add a directional light into scene
const light = new DirectionalLight({
style: {
fill: 'white',
direction: [-1, 0, 1],
},
});
canvas.appendChild(light);

// adjust camera's position
const camera = canvas.getCamera();
camera.setPerspective(0.1, 1000, 45, 640 / 640);

let hitTestSource: XRHitTestSource | null = null;
let hitTestSourceRequested = false;
let xrViewerSpace: XRReferenceSpace | null = null;
canvas.addEventListener(CanvasEvent.BEFORE_RENDER, (e) => {
const frame = e.detail as XRFrame;
if (frame) {
const referenceSpace = renderer.xr.getReferenceSpace();
const session = renderer.xr.getSession();
let pose = frame.getViewerPose(referenceSpace);

reticle.style.visibility = 'hidden';

if (hitTestSourceRequested === false) {
session.requestReferenceSpace('viewer').then(function (referenceSpace) {
xrViewerSpace = referenceSpace;
session
.requestHitTestSource?.({ space: referenceSpace })
?.then(function (source) {
hitTestSource = source;
});
});

session.addEventListener('end', function () {
hitTestSourceRequested = false;
hitTestSource = null;
});

hitTestSourceRequested = true;
}

if (hitTestSource && pose) {
const hitTestResults = frame.getHitTestResults(hitTestSource);

if (hitTestResults.length) {
const hit = hitTestResults[0];
reticle.style.visibility = 'visible';
reticle.setLocalTransform(
hit.getPose(referenceSpace)?.transform.matrix,
);

// console.log('position', reticle.getLocalPosition());
// console.log('rotation', reticle.getRotation());
// console.log('scale', reticle.getScale());

const [x, y, z] = reticle.getLocalPosition();

const width =
session.renderState.baseLayer?.framebufferWidth! /
window.devicePixelRatio;
const height =
session.renderState.baseLayer?.framebufferHeight! /
window.devicePixelRatio;

$domOverlay.innerHTML = `${x}, ${y}, ${z}, ${width}, ${height}`;

// console.log(`${x}, ${y}, ${z}, ${width}, ${height}`);

reticle.setLocalPosition(
x * width + width / 2,
height - y * height - height / 2,
z,
);
} else {
reticle.style.visibility = 'hidden';
}
}
}
// sphere.rotate(0, 0.1, 0);
});

canvas.getConfig().disableHitTesting = true;

const $domOverlay = document.createElement('div');
$domOverlay.id = 'overlay';
document.body.appendChild($domOverlay);

const $button = ARButton.createButton(canvas, renderer, {
// @see https://github.com/immersive-web/webxr-samples/blob/main/hit-test.html
requiredFeatures: ['local', 'hit-test', 'dom-overlay'],
domOverlay: {
root: document.getElementById('overlay')!,
},
});
container.appendChild($button);

const controller = renderer.xr.getController(0);
controller.addEventListener('select', (e) => {
if (reticle.style.visibility === 'visible') {
const cube = new Mesh({
style: {
fill: '#1890FF',
opacity: 1,
geometry: cubeGeometry,
material: basicMaterial,
},
});
cube.setLocalTransform(reticle.getLocalTransform());
canvas.appendChild(cube);
}
});
canvas.appendChild(controller);
}

hit_test.initRenderer = (renderer) => {
renderer.registerPlugin(new Plugin3D());
};
1 change: 1 addition & 0 deletions __tests__/demos/3d/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export { torus } from './torus';
export { cylinder } from './cylinder';
export { force } from './force';
export { ar } from './webar';
export { hit_test } from './hit-test';
4 changes: 1 addition & 3 deletions __tests__/demos/3d/sphere.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ export async function sphere(context) {
// create a mesh
const sphere = new Mesh({
style: {
x: 320,
y: 320,
z: 0,
transform: `translate3d(320, 320, 0)`,
transformOrigin: 'center',
fill: '#1890FF',
opacity: 1,
Expand Down
3 changes: 1 addition & 2 deletions __tests__/demos/3d/torus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ export async function torus(context) {

const torus = new Mesh({
style: {
x: 300,
y: 250,
transform: `translate3d(320, 250, 0)`,
fill: 'white',
opacity: 1,
geometry: torusGeometry,
Expand Down
4 changes: 2 additions & 2 deletions __tests__/demos/bugfix/1636.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export async function image(context) {
y: 0,
width: 100,
height: 100,
img,
src: img,
},
});
const image2 = new Image({
Expand All @@ -36,7 +36,7 @@ export async function image(context) {
y: 0,
width: 100,
height: 100,
img,
src: img,
},
});
group.appendChild(image);
Expand Down
Loading

0 comments on commit 538929e

Please sign in to comment.