Skip to content
Merged
Show file tree
Hide file tree
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
70 changes: 56 additions & 14 deletions samples/modelviewer/ModelViewerScene.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ const PROPRIETARY_ASSETS_BASE_URL =
'https://cdn.jsdelivr.net/gh/xrblocks/proprietary-assets@main/';

export class ModelViewerScene extends xb.Script {
constructor() {
super();
}
loadedObjects = [];
placedObjects = new Set();
sessionStarted = false;
torusMesh = null;

async init() {
xb.core.input.addReticles();
this.addLights();
this.createModelFromObject();
await Promise.all([
return Promise.all([
this.createModelFromGLTF(),
this.createModelFromAnimatedGLTF(),
this.createModelFromSplat(),
Expand All @@ -33,19 +34,55 @@ export class ModelViewerScene extends xb.Script {
this.add(light);
}

update() {
if (this.torusMesh) {
this.torusMesh.rotation.x += 0.015;
this.torusMesh.rotation.y += 0.015;
}
}

onSimulatorStarted() {
this.onXRSessionStarted();
}

onXRSessionStarted() {
this.sessionStarted = true;
this.placeLoadedObjects();
}

placeLoadedObjects() {
for (const model of this.loadedObjects) {
this.placeObject(model);
}
}

placeObject(model) {
if (!this.sessionStarted || this.placedObjects.has(model)) return;
this.placedObjects.add(model);
return xb.world.placeOnHorizontalSurface(model, {
seconds: 30,
});
}

createModelFromObject() {
const model = new xb.ModelViewer({});
model.add(
new THREE.Mesh(
new THREE.CylinderGeometry(0.15, 0.15, 0.4),
new THREE.MeshPhongMaterial({color: 0xdb5461})
)
const torusMesh = new THREE.Mesh(
new THREE.TorusKnotGeometry(0.1, 0.03, 100, 16),
new THREE.MeshPhongMaterial({
color: 0x00f5d4,
shininess: 100,
specular: 0xffffff,
})
);
this.torusMesh = torusMesh;
model.add(torusMesh);
model.setupBoundingBox();
model.setupRaycastCylinder();
model.setupPlatform();
model.position.set(-0.15, 0.75, -1.65);
model.position.set(-0.6, 0.5, -1.5);
this.add(model);
this.loadedObjects.push(model);
this.placeObject(model);
}

async createModelFromGLTF() {
Expand All @@ -59,7 +96,9 @@ export class ModelViewerScene extends xb.Script {
},
renderer: xb.core.renderer,
});
model.position.set(0, 0.78, -1.1);
model.position.set(-0.2, 0.5, -1.5);
this.loadedObjects.push(model);
this.placeObject(model);
}

async createModelFromAnimatedGLTF() {
Expand All @@ -73,7 +112,9 @@ export class ModelViewerScene extends xb.Script {
},
renderer: xb.core.renderer,
});
model.position.set(0.9, 0.68, -0.95);
model.position.set(0.2, 0.5, -1.5);
this.loadedObjects.push(model);
this.placeObject(model);
}

async createModelFromSplat() {
Expand All @@ -86,8 +127,9 @@ export class ModelViewerScene extends xb.Script {
rotation: {x: 0, y: 180, z: 0},
},
});
model.position.set(0.4, 0.78, -1.1);
model.rotation.set(0, -Math.PI / 6, 0);
model.position.set(0.6, 0.5, -1.5);
this.loadedObjects.push(model);
this.placeObject(model);
}

async createModelInPanel() {
Expand Down
1 change: 1 addition & 0 deletions samples/modelviewer/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ document.addEventListener('DOMContentLoaded', async () => {
},
];
options.setAppTitle('Model Viewer');
options.world.enablePlaneDetection();
await xb.init(options);
});
2 changes: 1 addition & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,4 @@ export const DEFAULT_DEVICE_CAMERA_WIDTH = 1280;
export const DEFAULT_DEVICE_CAMERA_HEIGHT = 720;

export const XR_BLOCKS_ASSETS_PATH =
'https://cdn.jsdelivr.net/gh/xrblocks/assets@a500427f2dfc12312df1a75860460244bab3a146/';
'https://cdn.jsdelivr.net/gh/xrblocks/assets@02bbbf2093d20bcefdac18c65d3ff0f2b94b7535/';
17 changes: 12 additions & 5 deletions src/simulator/SimulatorWorld.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as THREE from 'three';
import {Options} from '../core/Options';
import {SimulatorPlane} from '../world/planes/SimulatorPlane';
import {
SimulatorPlane,
SimulatorPlaneType,
} from '../world/planes/SimulatorPlane';
import {World} from '../world/World';

// World sensing for the simulator.
Expand All @@ -12,6 +15,8 @@ export class SimulatorWorld {
async init(options: Options, world: World) {
this.options = options;
this.world = world;
// Wait for World script initialization to complete first
await world.initializedPromise;
const activeEnv =
options.simulator.environments[options.simulator.activeEnvironmentIndex];
if (options.world.planes.enabled && activeEnv?.scenePlanesPath) {
Expand All @@ -28,7 +33,8 @@ export class SimulatorWorld {
response.json()
)) as {
planes: {
type: string;
type: SimulatorPlaneType;
label?: string;
area: number;
position: {
x: number;
Expand All @@ -42,7 +48,7 @@ export class SimulatorWorld {
}[];
}[];
};
const planes = planesData.planes.map((plane) => {
const planes: SimulatorPlane[] = planesData.planes.map((plane) => {
return {
type: plane.type,
area: plane.area,
Expand All @@ -57,8 +63,9 @@ export class SimulatorWorld {
plane.quaternion[2],
plane.quaternion[3]
),
polygon: plane.polygon,
} as unknown as SimulatorPlane;
polygon: plane.polygon.map((p) => new THREE.Vector2(p.x, p.y)),
label: plane.label,
};
});
this.world.planes!.setSimulatorPlanes(planes);
} catch (error) {
Expand Down
29 changes: 29 additions & 0 deletions src/utils/TemporalPolyfill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Temporary polyfill until Chrome 148 is rolled out more widely.
* Converts a Temporal.Duration or Temporal.DurationLike to milliseconds.
*/
export function durationToMs(
duration: Temporal.Duration | Temporal.DurationLike
): number {
if (typeof Temporal !== 'undefined') {
return Temporal.Duration.from(duration).total({unit: 'millisecond'});
}

// If duration is a string (ISO 8601) and native Temporal failed/is absent, fallback to 0
if (typeof duration === 'string') {
return 0;
}

let ms = 0;
if (duration.milliseconds) ms += duration.milliseconds;
if (duration.seconds) ms += duration.seconds * 1000;
if (duration.minutes) ms += duration.minutes * 60 * 1000;
if (duration.hours) ms += duration.hours * 60 * 60 * 1000;
if (duration.days) ms += duration.days * 24 * 60 * 60 * 1000;
if (duration.weeks) ms += duration.weeks * 7 * 24 * 60 * 60 * 1000;
if (duration.months) ms += duration.months * 30 * 24 * 60 * 60 * 1000;
if (duration.years) ms += duration.years * 365 * 24 * 60 * 60 * 1000;
if (duration.microseconds) ms += duration.microseconds / 1000;
if (duration.nanoseconds) ms += duration.nanoseconds / 1000000;
return ms;
}
Loading