quackscape/assets/js/scene.js
Kumi 304cb8f63d
Introduce Z-axis handling across the app
This update introduces support for a third dimension (Z-axis) in scene
positioning and orientation, enhancing 3D scene rendering capabilities.
Changes include parsing the Z-coordinate attribute in scene elements,
updating the `loadScene` function to accommodate the new axis, and
extending the models to store this additional data. This pivotal
enhancement allows a more refined and immersive user experience by
enabling depth control in scene navigation and interactivity. The
modification paves the way for future developments in 3D scene
manipulation and interaction within the application.
2024-03-11 16:29:47 +01:00

129 lines
3.8 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") | 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);
// 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 };