public async loadScene()

in packages/xr/src/Providers/SumerianProvider.ts [62:214]


	public async loadScene(
		sceneName: string,
		domElementId: string,
		sceneOptions: SumerianSceneOptions
	) {
		if (!sceneName) {
			const errorMsg = 'No scene name passed into loadScene';
			logger.error(errorMsg);
			throw new XRSceneLoadFailure(errorMsg);
		}

		if (!domElementId) {
			const errorMsg = 'No dom element id passed into loadScene';
			logger.error(errorMsg);
			throw new XRNoDomElement(errorMsg);
		}

		const element = document.getElementById(domElementId);
		if (!element) {
			const errorMsg = `DOM element id, ${domElementId} not found`;
			logger.error(errorMsg);
			throw new XRNoDomElement(errorMsg);
		}

		const scene = this.getScene(sceneName);
		if (!scene.sceneConfig) {
			const errorMsg = `No scene config configured for scene: ${sceneName}`;
			logger.error(errorMsg);
			throw new XRSceneLoadFailure(errorMsg);
		}

		const sceneUrl = scene.sceneConfig.url;
		const sceneId = scene.sceneConfig.sceneId;

		let sceneRegion;
		if (scene.sceneConfig.hasOwnProperty('region')) {
			// Use the scene region on the Sumerian scene configuration
			sceneRegion = scene.sceneConfig.region;
		} else if (this.options.hasOwnProperty('region')) {
			// Use the scene region on the XR category configuration
			sceneRegion = this.options.region;
		} else {
			const errorMsg = `No region configured for scene: ${sceneName}`;
			logger.error(errorMsg);
			throw new XRSceneLoadFailure(errorMsg);
		}

		const awsSDKConfigOverride = {
			region: sceneRegion,
			// This is passed to the AWS clients created in
			// Sumerian's AwsSystem
			// This helps other services(like Lex and Polly) to track
			// traffic coming from Sumerian scenes embedded with Amplify
			customUserAgent: `${Constants.userAgent}-SumerianScene`,
		};

		// We are signing the requests to Sumerian ourselves instead of using the AWS SDK
		// We want to set the user agent header
		const fetchOptions = {
			headers: {
				// This sets the AWS user agent string
				// So the Sumerian service knows this request is
				// from Amplify
				'X-Amz-User-Agent': Constants.userAgent,
			},
		};

		let url = sceneUrl;
		try {
			// Get credentials from Auth and sign the request
			const credentials = await Credentials.get();
			awsSDKConfigOverride['credentials'] = credentials;
			const accessInfo = {
				secret_key: credentials.secretAccessKey,
				access_key: credentials.accessKeyId,
				session_token: credentials.sessionToken,
			};

			const serviceInfo = {
				region: sceneRegion,
				service: SUMERIAN_SERVICE_NAME,
			};
			const request = Signer.sign(
				{ method: 'GET', url: sceneUrl },
				accessInfo,
				serviceInfo
			);
			fetchOptions.headers = { ...fetchOptions.headers, ...request.headers };
			url = request.url;
		} catch (e) {
			logger.debug('No credentials available, the request will be unsigned');
		}

		const apiResponse = await fetch(url, fetchOptions);
		const apiResponseJson = await apiResponse.json();
		if (apiResponse.status === 403) {
			if (apiResponseJson.message) {
				logger.error(
					`Failure to authenticate user: ${apiResponseJson.message}`
				);
				throw new XRSceneLoadFailure(
					`Failure to authenticate user: ${apiResponseJson.message}`
				);
			} else {
				logger.error(`Failure to authenticate user`);
				throw new XRSceneLoadFailure(`Failure to authenticate user`);
			}
		}

		// Get bundle data from scene api response
		const sceneBundleData = apiResponseJson.bundleData[sceneId];
		const sceneBundle = await fetch(sceneBundleData.url, {
			headers: sceneBundleData.headers,
		});
		const sceneBundleJson = await sceneBundle.json();

		try {
			// Load the Sumerian bootstrapper script into the DOM
			await this.loadScript(sceneBundleJson[sceneId].bootstrapperUrl);
		} catch (error) {
			logger.error(error);
			throw new XRSceneLoadFailure(error);
		}

		const progressCallback = sceneOptions.progressCallback
			? sceneOptions.progressCallback
			: undefined;
		const publishParamOverrides = scene.publishParamOverrides
			? scene.publishParamOverrides
			: undefined;

		const sceneLoadParams = {
			element,
			sceneId,
			sceneBundle: sceneBundleJson,
			apiResponse: apiResponseJson,
			progressCallback,
			publishParamOverrides,
			awsSDKConfigOverride,
		};

		// Load the scene into the dom and set the scene controller
		const sceneController = await (<any>window).SumerianBootstrapper.loadScene(
			sceneLoadParams
		);
		scene.sceneController = sceneController;
		scene.isLoaded = true;

		// Log scene warnings
		for (const warning of sceneController.sceneLoadWarnings) {
			logger.warn(`loadScene warning: ${warning}`);
		}
	}