quackscape/assets/js/scene.js
Kumi 635ab177dc
Add iOS texture size limit
Added a workaround to limit texture size on iOS devices to prevent
issues with rendering performance. This change introduces a detection
mechanism for iOS and caps the maximum texture size to 8192 when an iOS
device is identified.
2024-03-11 19:49:48 +01:00

138 lines
4 KiB
JavaScript

import { getScene } from "./api";
require("aframe");
// Detect iOS devices
// There is probably a better way to handle issues there, but...
var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
// Define the <quackscape-scene> element
class QuackscapeScene extends HTMLElement {
connectedCallback() {
// When one is created, automatically load the scene
this.scene = this.getAttribute("scene");
this.x = this.getAttribute("x") | 0;
this.y = this.getAttribute("y") | 0;
this.z = this.getAttribute("z") | 0;
console.log(this.x);
console.log(this.y);
console.log(this.z);
loadScene(this.scene, this.x, this.y, this.z, this);
}
}
document.addEventListener("contextmenu", function (event) {
event.preventDefault();
});
customElements.define("quackscape-scene", QuackscapeScene);
// Function to load a scene into a destination object
// x and y signify the initial looking direction, -1 for the scene's default
async function loadScene(scene_id, x = -1, y = -1, z = -1, destination = null) {
// Get WebGL maximum texture size
var canvas = document.createElement("canvas");
var gl =
canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
if (!gl) {
alert("Unable to initialize WebGL. Your browser may not support it.");
return;
}
var maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
if (iOS) {
maxTextureSize = Math.min(8192, maxTextureSize);
}
// Get scene information from API
getScene(scene_id).then((response) => {
var scene = response.obj;
// Get largest image that will fit in the texture size from scene.resolutions
// First, order the resolutions by width
var resolutions = scene.base_content.resolutions.sort(
(a, b) => b.width - a.width
);
// Then, find the first resolution that is less than or equal to the max texture size
var content = resolutions.find(
(resolution) => resolution.width <= maxTextureSize
);
// Select a destination element if not specified
if (!destination) {
destination = document.getElementsByTagName("quackscape-scene")[0];
}
destination.setAttribute("id", scene_id);
// Start by removing any existing scenes
var scenes = document.getElementsByTagName("a-scene");
if (scenes.length > 0) {
scenes[0].remove();
}
// Now, build the scene element
var a_scene = document.createElement("a-scene");
a_scene.setAttribute("cursor", "rayOrigin: mouse");
// Create a-camera element
var rig = document.createElement("a-entity");
rig.setAttribute("id", "rig");
// Rotate camera if requested
if (x != -1 && y != -1 && z != -1) {
rig.setAttribute("rotation", x + " " + y + " " + z);
}
var camera = document.createElement("a-camera");
camera.setAttribute("wasd-controls-enabled", "false"); // TODO: Find a more elegant way to disable z axis movement
rig.appendChild(camera);
a_scene.appendChild(rig);
// Create a-assets element
var assets = document.createElement("a-assets");
a_scene.appendChild(assets);
// Add background image as sky
var sky = document.createElement("a-sky");
sky.setAttribute("src", "#" + content.id);
a_scene.appendChild(sky);
// Add img element to assets
var background = document.createElement("img");
background.setAttribute("id", content.id);
background.setAttribute("src", content.file);
assets.appendChild(background);
// Add elements to scene
scene.elements.forEach((element) => {
var node = document.createElement(element.data.tag);
node.setAttribute("id", element.data.id);
for (const [key, value] of Object.entries(element.data.attributes)) {
node.setAttribute(key, value);
}
// Add node to scene
a_scene.appendChild(node);
});
destination.appendChild(a_scene);
// Dispatch a signal for the editor to pick up
const loaded_event = new CustomEvent("loadedQuackscapeScene");
document.dispatchEvent(loaded_event);
});
}
window.loadScene = loadScene;
export { loadScene };