xrblocks 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/build/core/components/ScriptsManager.d.ts +8 -1
- package/build/depth/Depth.d.ts +1 -1
- package/build/depth/DepthTextures.d.ts +4 -4
- package/build/xrblocks.js +84 -75
- package/build/xrblocks.js.map +1 -1
- package/build/xrblocks.min.js +1 -1
- package/build/xrblocks.min.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -74,8 +74,8 @@ code below:
|
|
|
74
74
|
<script type="importmap">
|
|
75
75
|
{
|
|
76
76
|
"imports": {
|
|
77
|
-
"three": "https://cdn.jsdelivr.net/npm/three@0.
|
|
78
|
-
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.
|
|
77
|
+
"three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
|
|
78
|
+
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/",
|
|
79
79
|
"xrblocks": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/xrblocks.js",
|
|
80
80
|
"xrblocks/addons/": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/addons/"
|
|
81
81
|
}
|
|
@@ -14,6 +14,9 @@ export declare class ScriptsManager {
|
|
|
14
14
|
callKeyUpBound: (event: KeyEvent) => void;
|
|
15
15
|
/** The set of scripts currently being initialized. */
|
|
16
16
|
private initializingScripts;
|
|
17
|
+
private seenScripts;
|
|
18
|
+
private syncPromises;
|
|
19
|
+
private checkScriptBound;
|
|
17
20
|
constructor(initScriptFunction: (script: Script) => Promise<void>);
|
|
18
21
|
/**
|
|
19
22
|
* Initializes a script and adds it to the set of scripts which will receive
|
|
@@ -29,13 +32,17 @@ export declare class ScriptsManager {
|
|
|
29
32
|
* @param script - The script to uninitialize.
|
|
30
33
|
*/
|
|
31
34
|
uninitScript(script: Script): void;
|
|
35
|
+
/**
|
|
36
|
+
* Helper for scene traversal to avoid closure allocation.
|
|
37
|
+
*/
|
|
38
|
+
private checkScript;
|
|
32
39
|
/**
|
|
33
40
|
* Finds all scripts in the scene and initializes them or uninitailizes them.
|
|
34
41
|
* Returns a promise which resolves when all new scripts are finished
|
|
35
42
|
* initalizing.
|
|
36
43
|
* @param scene - The main scene which is used to find scripts.
|
|
37
44
|
*/
|
|
38
|
-
syncScriptsWithScene(scene: THREE.Scene): Promise<void>;
|
|
45
|
+
syncScriptsWithScene(scene: THREE.Scene): Promise<PromiseSettledResult<void>[]>;
|
|
39
46
|
callSelectStart(event: SelectEvent): void;
|
|
40
47
|
callSelectEnd(event: SelectEvent): void;
|
|
41
48
|
callSelect(event: SelectEvent): void;
|
package/build/depth/Depth.d.ts
CHANGED
|
@@ -2,14 +2,14 @@ import * as THREE from 'three';
|
|
|
2
2
|
import { DepthOptions } from './DepthOptions';
|
|
3
3
|
export declare class DepthTextures {
|
|
4
4
|
private options;
|
|
5
|
-
private
|
|
5
|
+
private float32Arrays;
|
|
6
6
|
private uint8Arrays;
|
|
7
7
|
private dataTextures;
|
|
8
8
|
private nativeTextures;
|
|
9
9
|
depthData: XRCPUDepthInformation[];
|
|
10
10
|
constructor(options: DepthOptions);
|
|
11
11
|
private createDataDepthTextures;
|
|
12
|
-
updateData(depthData: XRCPUDepthInformation,
|
|
13
|
-
updateNativeTexture(depthData: XRWebGLDepthInformation, renderer: THREE.WebGLRenderer,
|
|
14
|
-
get(
|
|
12
|
+
updateData(depthData: XRCPUDepthInformation, viewId: number): void;
|
|
13
|
+
updateNativeTexture(depthData: XRWebGLDepthInformation, renderer: THREE.WebGLRenderer, viewId: number): void;
|
|
14
|
+
get(viewId: number): THREE.DataTexture | THREE.ExternalTexture;
|
|
15
15
|
}
|
package/build/xrblocks.js
CHANGED
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*
|
|
16
16
|
* @file xrblocks.js
|
|
17
|
-
* @version v0.
|
|
18
|
-
* @commitid
|
|
19
|
-
* @builddate
|
|
17
|
+
* @version v0.7.0
|
|
18
|
+
* @commitid 950b1e5
|
|
19
|
+
* @builddate 2026-01-03T00:05:55.605Z
|
|
20
20
|
* @description XR Blocks SDK, built from source with the above commit ID.
|
|
21
21
|
* @agent When using with Gemini to create XR apps, use **Gemini Canvas** mode,
|
|
22
22
|
* and follow rules below:
|
|
23
23
|
* 1. Include the following importmap for maximum compatibility:
|
|
24
|
-
"three": "https://cdn.jsdelivr.net/npm/three@0.
|
|
25
|
-
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.
|
|
24
|
+
"three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
|
|
25
|
+
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/",
|
|
26
26
|
"troika-three-text": "https://cdn.jsdelivr.net/gh/protectwise/troika@028b81cf308f0f22e5aa8e78196be56ec1997af5/packages/troika-three-text/src/index.js",
|
|
27
27
|
"troika-three-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-three-utils/src/index.js",
|
|
28
28
|
"troika-worker-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-worker-utils/src/index.js",
|
|
@@ -2255,10 +2255,6 @@ class DepthMesh extends MeshScript {
|
|
|
2255
2255
|
const depthY = Math.round(clamp((1.0 - v) * height, 0, height - 1));
|
|
2256
2256
|
const rawDepth = depthArray[depthY * width + depthX];
|
|
2257
2257
|
let depth = depthData.rawValueToMeters * rawDepth;
|
|
2258
|
-
// Workaround for b/382679381.
|
|
2259
|
-
if (this.depthOptions.useFloat32) {
|
|
2260
|
-
depth = rawDepth;
|
|
2261
|
-
}
|
|
2262
2258
|
// Finds global min/max.
|
|
2263
2259
|
if (depth > 0) {
|
|
2264
2260
|
if (depth < this.minDepth) {
|
|
@@ -2502,68 +2498,63 @@ const xrDepthMeshPhysicsOptions = deepFreeze(new DepthOptions({
|
|
|
2502
2498
|
class DepthTextures {
|
|
2503
2499
|
constructor(options) {
|
|
2504
2500
|
this.options = options;
|
|
2505
|
-
this.
|
|
2501
|
+
this.float32Arrays = [];
|
|
2506
2502
|
this.uint8Arrays = [];
|
|
2507
2503
|
this.dataTextures = [];
|
|
2508
2504
|
this.nativeTextures = [];
|
|
2509
2505
|
this.depthData = [];
|
|
2510
2506
|
}
|
|
2511
|
-
createDataDepthTextures(depthData,
|
|
2512
|
-
if (this.dataTextures[
|
|
2513
|
-
this.dataTextures[
|
|
2507
|
+
createDataDepthTextures(depthData, viewId) {
|
|
2508
|
+
if (this.dataTextures[viewId]) {
|
|
2509
|
+
this.dataTextures[viewId].dispose();
|
|
2514
2510
|
}
|
|
2515
2511
|
if (this.options.useFloat32) {
|
|
2516
|
-
const typedArray = new
|
|
2512
|
+
const typedArray = new Float32Array(depthData.width * depthData.height);
|
|
2517
2513
|
const format = THREE.RedFormat;
|
|
2518
|
-
const type = THREE.
|
|
2519
|
-
this.
|
|
2520
|
-
this.dataTextures[
|
|
2514
|
+
const type = THREE.FloatType;
|
|
2515
|
+
this.float32Arrays[viewId] = typedArray;
|
|
2516
|
+
this.dataTextures[viewId] = new THREE.DataTexture(typedArray, depthData.width, depthData.height, format, type);
|
|
2521
2517
|
}
|
|
2522
2518
|
else {
|
|
2523
2519
|
const typedArray = new Uint8Array(depthData.width * depthData.height * 2);
|
|
2524
2520
|
const format = THREE.RGFormat;
|
|
2525
2521
|
const type = THREE.UnsignedByteType;
|
|
2526
|
-
this.uint8Arrays[
|
|
2527
|
-
this.dataTextures[
|
|
2522
|
+
this.uint8Arrays[viewId] = typedArray;
|
|
2523
|
+
this.dataTextures[viewId] = new THREE.DataTexture(typedArray, depthData.width, depthData.height, format, type);
|
|
2528
2524
|
}
|
|
2529
2525
|
}
|
|
2530
|
-
updateData(depthData,
|
|
2531
|
-
if (this.dataTextures.length <
|
|
2532
|
-
this.dataTextures[
|
|
2533
|
-
this.dataTextures[
|
|
2534
|
-
this.createDataDepthTextures(depthData,
|
|
2526
|
+
updateData(depthData, viewId) {
|
|
2527
|
+
if (this.dataTextures.length < viewId + 1 ||
|
|
2528
|
+
this.dataTextures[viewId].image.width !== depthData.width ||
|
|
2529
|
+
this.dataTextures[viewId].image.height !== depthData.height) {
|
|
2530
|
+
this.createDataDepthTextures(depthData, viewId);
|
|
2535
2531
|
}
|
|
2536
2532
|
if (this.options.useFloat32) {
|
|
2537
|
-
|
|
2538
|
-
const float16Data = new Uint16Array(float32Data.length);
|
|
2539
|
-
for (let i = 0; i < float16Data.length; i++) {
|
|
2540
|
-
float16Data[i] = THREE.DataUtils.toHalfFloat(float32Data[i]);
|
|
2541
|
-
}
|
|
2542
|
-
this.uint16Arrays[view_id].set(float16Data);
|
|
2533
|
+
this.float32Arrays[viewId].set(new Float32Array(depthData.data));
|
|
2543
2534
|
}
|
|
2544
2535
|
else {
|
|
2545
|
-
this.uint8Arrays[
|
|
2536
|
+
this.uint8Arrays[viewId].set(new Uint8Array(depthData.data));
|
|
2546
2537
|
}
|
|
2547
|
-
this.dataTextures[
|
|
2548
|
-
this.depthData[
|
|
2538
|
+
this.dataTextures[viewId].needsUpdate = true;
|
|
2539
|
+
this.depthData[viewId] = depthData;
|
|
2549
2540
|
}
|
|
2550
|
-
updateNativeTexture(depthData, renderer,
|
|
2551
|
-
if (this.dataTextures.length <
|
|
2552
|
-
this.nativeTextures[
|
|
2541
|
+
updateNativeTexture(depthData, renderer, viewId) {
|
|
2542
|
+
if (this.dataTextures.length < viewId + 1) {
|
|
2543
|
+
this.nativeTextures[viewId] = new THREE.ExternalTexture(depthData.texture);
|
|
2553
2544
|
}
|
|
2554
2545
|
else {
|
|
2555
|
-
this.nativeTextures[
|
|
2546
|
+
this.nativeTextures[viewId].sourceTexture = depthData.texture;
|
|
2556
2547
|
}
|
|
2557
2548
|
// fixed in newer revision of three
|
|
2558
|
-
const textureProperties = renderer.properties.get(this.nativeTextures[
|
|
2549
|
+
const textureProperties = renderer.properties.get(this.nativeTextures[viewId]);
|
|
2559
2550
|
textureProperties.__webglTexture = depthData.texture;
|
|
2560
2551
|
textureProperties.__version = 1;
|
|
2561
2552
|
}
|
|
2562
|
-
get(
|
|
2553
|
+
get(viewId) {
|
|
2563
2554
|
if (this.dataTextures.length > 0) {
|
|
2564
|
-
return this.dataTextures[
|
|
2555
|
+
return this.dataTextures[viewId];
|
|
2565
2556
|
}
|
|
2566
|
-
return this.nativeTextures[
|
|
2557
|
+
return this.nativeTextures[viewId];
|
|
2567
2558
|
}
|
|
2568
2559
|
}
|
|
2569
2560
|
|
|
@@ -3057,6 +3048,15 @@ const DEFAULT_DEPTH_WIDTH = 160;
|
|
|
3057
3048
|
const DEFAULT_DEPTH_HEIGHT = DEFAULT_DEPTH_WIDTH;
|
|
3058
3049
|
const clipSpacePosition = new THREE.Vector3();
|
|
3059
3050
|
class Depth {
|
|
3051
|
+
get rawValueToMeters() {
|
|
3052
|
+
if (this.cpuDepthData.length) {
|
|
3053
|
+
return this.cpuDepthData[0].rawValueToMeters;
|
|
3054
|
+
}
|
|
3055
|
+
else if (this.gpuDepthData.length) {
|
|
3056
|
+
return this.gpuDepthData[0].rawValueToMeters;
|
|
3057
|
+
}
|
|
3058
|
+
return 0;
|
|
3059
|
+
}
|
|
3060
3060
|
/**
|
|
3061
3061
|
* Depth is a lightweight manager based on three.js to simply prototyping
|
|
3062
3062
|
* with Depth in WebXR.
|
|
@@ -3070,7 +3070,6 @@ class Depth {
|
|
|
3070
3070
|
this.options = new DepthOptions();
|
|
3071
3071
|
this.width = DEFAULT_DEPTH_WIDTH;
|
|
3072
3072
|
this.height = DEFAULT_DEPTH_HEIGHT;
|
|
3073
|
-
this.rawValueToMeters = 0.0010000000474974513;
|
|
3074
3073
|
this.occludableShaders = new Set();
|
|
3075
3074
|
// Whether we're counting the number of depth clients.
|
|
3076
3075
|
this.depthClientsInitialized = false;
|
|
@@ -3180,11 +3179,6 @@ class Depth {
|
|
|
3180
3179
|
}
|
|
3181
3180
|
updateCPUDepthData(depthData, viewId = 0) {
|
|
3182
3181
|
this.cpuDepthData[viewId] = depthData;
|
|
3183
|
-
// Workaround for b/382679381.
|
|
3184
|
-
this.rawValueToMeters = depthData.rawValueToMeters;
|
|
3185
|
-
if (this.options.useFloat32) {
|
|
3186
|
-
this.rawValueToMeters = 1.0;
|
|
3187
|
-
}
|
|
3188
3182
|
// Updates Depth Array.
|
|
3189
3183
|
if (this.depthArray[viewId] == null) {
|
|
3190
3184
|
this.depthArray[viewId] = this.options.useFloat32
|
|
@@ -3210,11 +3204,6 @@ class Depth {
|
|
|
3210
3204
|
}
|
|
3211
3205
|
updateGPUDepthData(depthData, viewId = 0) {
|
|
3212
3206
|
this.gpuDepthData[viewId] = depthData;
|
|
3213
|
-
// Workaround for b/382679381.
|
|
3214
|
-
this.rawValueToMeters = depthData.rawValueToMeters;
|
|
3215
|
-
if (this.options.useFloat32) {
|
|
3216
|
-
this.rawValueToMeters = 1.0;
|
|
3217
|
-
}
|
|
3218
3207
|
// For now, assume that we need cpu depth only if depth mesh is enabled.
|
|
3219
3208
|
// In the future, add a separate option.
|
|
3220
3209
|
const needCpuDepth = this.options.depthMesh.enabled;
|
|
@@ -3291,22 +3280,22 @@ class Depth {
|
|
|
3291
3280
|
if (xrRefSpace) {
|
|
3292
3281
|
const pose = frame.getViewerPose(xrRefSpace);
|
|
3293
3282
|
if (pose) {
|
|
3294
|
-
for (let
|
|
3295
|
-
const view = pose.views[
|
|
3296
|
-
this.view[
|
|
3283
|
+
for (let viewId = 0; viewId < pose.views.length; ++viewId) {
|
|
3284
|
+
const view = pose.views[viewId];
|
|
3285
|
+
this.view[viewId] = view;
|
|
3297
3286
|
if (session.depthUsage === 'gpu-optimized') {
|
|
3298
3287
|
const depthData = binding.getDepthInformation(view);
|
|
3299
3288
|
if (!depthData) {
|
|
3300
3289
|
return;
|
|
3301
3290
|
}
|
|
3302
|
-
this.updateGPUDepthData(depthData,
|
|
3291
|
+
this.updateGPUDepthData(depthData, viewId);
|
|
3303
3292
|
}
|
|
3304
3293
|
else {
|
|
3305
3294
|
const depthData = frame.getDepthInformation(view);
|
|
3306
3295
|
if (!depthData) {
|
|
3307
3296
|
return;
|
|
3308
3297
|
}
|
|
3309
|
-
this.updateCPUDepthData(depthData,
|
|
3298
|
+
this.updateCPUDepthData(depthData, viewId);
|
|
3310
3299
|
}
|
|
3311
3300
|
}
|
|
3312
3301
|
}
|
|
@@ -4185,6 +4174,9 @@ class ScriptsManager {
|
|
|
4185
4174
|
this.callKeyUpBound = this.callKeyUp.bind(this);
|
|
4186
4175
|
/** The set of scripts currently being initialized. */
|
|
4187
4176
|
this.initializingScripts = new Set();
|
|
4177
|
+
this.seenScripts = new Set();
|
|
4178
|
+
this.syncPromises = [];
|
|
4179
|
+
this.checkScriptBound = this.checkScript.bind(this);
|
|
4188
4180
|
}
|
|
4189
4181
|
/**
|
|
4190
4182
|
* Initializes a script and adds it to the set of scripts which will receive
|
|
@@ -4215,29 +4207,33 @@ class ScriptsManager {
|
|
|
4215
4207
|
this.scripts.delete(script);
|
|
4216
4208
|
this.initializingScripts.delete(script);
|
|
4217
4209
|
}
|
|
4210
|
+
/**
|
|
4211
|
+
* Helper for scene traversal to avoid closure allocation.
|
|
4212
|
+
*/
|
|
4213
|
+
checkScript(obj) {
|
|
4214
|
+
if (obj.isXRScript) {
|
|
4215
|
+
const script = obj;
|
|
4216
|
+
this.syncPromises.push(this.initScript(script));
|
|
4217
|
+
this.seenScripts.add(script);
|
|
4218
|
+
}
|
|
4219
|
+
}
|
|
4218
4220
|
/**
|
|
4219
4221
|
* Finds all scripts in the scene and initializes them or uninitailizes them.
|
|
4220
4222
|
* Returns a promise which resolves when all new scripts are finished
|
|
4221
4223
|
* initalizing.
|
|
4222
4224
|
* @param scene - The main scene which is used to find scripts.
|
|
4223
4225
|
*/
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
scene.traverse(
|
|
4228
|
-
if (obj.isXRScript) {
|
|
4229
|
-
const script = obj;
|
|
4230
|
-
promises.push(this.initScript(script));
|
|
4231
|
-
seenScripts.add(script);
|
|
4232
|
-
}
|
|
4233
|
-
});
|
|
4234
|
-
await Promise.allSettled(promises);
|
|
4226
|
+
syncScriptsWithScene(scene) {
|
|
4227
|
+
this.seenScripts.clear();
|
|
4228
|
+
this.syncPromises.length = 0;
|
|
4229
|
+
scene.traverse(this.checkScriptBound);
|
|
4235
4230
|
// Delete missing scripts.
|
|
4236
4231
|
for (const script of this.scripts) {
|
|
4237
|
-
if (!seenScripts.has(script)) {
|
|
4232
|
+
if (!this.seenScripts.has(script)) {
|
|
4238
4233
|
this.uninitScript(script);
|
|
4239
4234
|
}
|
|
4240
4235
|
}
|
|
4236
|
+
return Promise.allSettled(this.syncPromises);
|
|
4241
4237
|
}
|
|
4242
4238
|
callSelectStart(event) {
|
|
4243
4239
|
for (const script of this.scripts) {
|
|
@@ -5830,6 +5826,7 @@ function traverseUtil(node, callback) {
|
|
|
5830
5826
|
return false;
|
|
5831
5827
|
}
|
|
5832
5828
|
|
|
5829
|
+
const tempBox = new THREE.Box3();
|
|
5833
5830
|
/**
|
|
5834
5831
|
* User is an embodied instance to manage hands, controllers, speech, and
|
|
5835
5832
|
* avatars. It extends Script to update human-world interaction.
|
|
@@ -6192,8 +6189,8 @@ class User extends Script {
|
|
|
6192
6189
|
const currentlyTouchedMeshes = [];
|
|
6193
6190
|
this.scene.traverse((object) => {
|
|
6194
6191
|
if (object.isMesh && object.visible) {
|
|
6195
|
-
|
|
6196
|
-
if (
|
|
6192
|
+
tempBox.setFromObject(object);
|
|
6193
|
+
if (tempBox.containsPoint(indexTipPosition)) {
|
|
6197
6194
|
currentlyTouchedMeshes.push(object);
|
|
6198
6195
|
}
|
|
6199
6196
|
}
|
|
@@ -8315,12 +8312,15 @@ class SimulatorDepth {
|
|
|
8315
8312
|
this.simulatorScene.overrideMaterial = null;
|
|
8316
8313
|
this.renderer.setRenderTarget(originalRenderTarget);
|
|
8317
8314
|
}
|
|
8318
|
-
updateDepth() {
|
|
8315
|
+
async updateDepth() {
|
|
8319
8316
|
// We preventively unbind the PIXEL_PACK_BUFFER before reading from the
|
|
8320
8317
|
// render target in case external libraries (Spark.js) left it bound.
|
|
8321
8318
|
const context = this.renderer.getContext();
|
|
8322
8319
|
context.bindBuffer(context.PIXEL_PACK_BUFFER, null);
|
|
8323
|
-
|
|
8320
|
+
// Cache the projection matrix and transform of the rendered depth.
|
|
8321
|
+
const projectionMatrix = this.depthCamera.projectionMatrix.clone();
|
|
8322
|
+
const transform = new XRRigidTransform(this.depthCamera.position, this.depthCamera.quaternion);
|
|
8323
|
+
await this.renderer.readRenderTargetPixelsAsync(this.depthRenderTarget, 0, 0, this.depthWidth, this.depthHeight, this.depthBuffer);
|
|
8324
8324
|
// Flip the depth buffer.
|
|
8325
8325
|
if (this.depthBufferSlice.length != this.depthWidth) {
|
|
8326
8326
|
this.depthBufferSlice = new Float32Array(this.depthWidth);
|
|
@@ -8336,14 +8336,14 @@ class SimulatorDepth {
|
|
|
8336
8336
|
// Copy the temp slice (original row i) to row j
|
|
8337
8337
|
this.depthBuffer.set(this.depthBufferSlice, j_offset);
|
|
8338
8338
|
}
|
|
8339
|
-
|
|
8339
|
+
projectionMatrix.toArray(this.projectionMatrixArray);
|
|
8340
8340
|
const depthData = {
|
|
8341
8341
|
width: this.depthWidth,
|
|
8342
8342
|
height: this.depthHeight,
|
|
8343
8343
|
data: this.depthBuffer.buffer,
|
|
8344
8344
|
rawValueToMeters: 1.0,
|
|
8345
8345
|
projectionMatrix: this.projectionMatrixArray,
|
|
8346
|
-
transform:
|
|
8346
|
+
transform: transform,
|
|
8347
8347
|
};
|
|
8348
8348
|
this.depth.updateCPUDepthData(depthData, 0);
|
|
8349
8349
|
}
|
|
@@ -12459,6 +12459,15 @@ class VideoView extends View {
|
|
|
12459
12459
|
/** The cross-origin setting for the video element. Default is 'anonymous'. */
|
|
12460
12460
|
this.crossOrigin = 'anonymous';
|
|
12461
12461
|
this.videoAspectRatio = 0.0;
|
|
12462
|
+
// set video options if passed in
|
|
12463
|
+
this.autoplay = options.autoplay ?? this.autoplay;
|
|
12464
|
+
this.muted = options.muted ?? this.muted;
|
|
12465
|
+
this.loop = options.loop ?? this.loop;
|
|
12466
|
+
this.playsInline = options.playsInline ?? this.playsInline;
|
|
12467
|
+
if (options.crossOrigin)
|
|
12468
|
+
this.crossOrigin = options.crossOrigin;
|
|
12469
|
+
if (options.mode)
|
|
12470
|
+
this.mode = options.mode;
|
|
12462
12471
|
const videoGeometry = new THREE.PlaneGeometry(1, 1);
|
|
12463
12472
|
const videoMaterial = new THREE.MeshBasicMaterial({
|
|
12464
12473
|
transparent: true,
|