124 lines
No EOL
3.7 KiB
JavaScript
124 lines
No EOL
3.7 KiB
JavaScript
import { getScene } from "./api";
|
|
|
|
require("aframe");
|
|
|
|
// 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");
|
|
this.y = this.getAttribute("y");
|
|
|
|
loadScene(this.scene, this.x, this.y, 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, 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);
|
|
|
|
// 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) {
|
|
rig.setAttribute("rotation", x + " " + y + " " + "0");
|
|
}
|
|
|
|
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 }; |