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}`);
}
}