From a20a45ebd039dba1c4b6c21de8aac5392acad73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Dobrovoljc?= Date: Sat, 28 Dec 2024 19:58:17 +0100 Subject: [PATCH] Naloga 3 WIP --- naloga_3/Light.js | 7 + naloga_3/Renderer.js | 319 ++++++++++++ naloga_3/engine/WebGPU.js | 73 +++ naloga_3/engine/animators/EasingFunctions.js | 47 ++ naloga_3/engine/animators/LinearAnimator.js | 54 ++ naloga_3/engine/animators/RotateAnimator.js | 54 ++ .../controllers/FirstPersonController.js | 131 +++++ .../engine/controllers/OrbitController.js | 74 +++ .../engine/controllers/TouchController.js | 143 ++++++ .../engine/controllers/TurntableController.js | 88 ++++ naloga_3/engine/core.js | 11 + naloga_3/engine/core/Accessor.js | 132 +++++ naloga_3/engine/core/Camera.js | 46 ++ naloga_3/engine/core/Material.js | 33 ++ naloga_3/engine/core/Mesh.js | 11 + naloga_3/engine/core/MeshUtils.js | 43 ++ naloga_3/engine/core/Model.js | 9 + naloga_3/engine/core/Node.js | 69 +++ naloga_3/engine/core/Primitive.js | 11 + naloga_3/engine/core/Sampler.js | 21 + naloga_3/engine/core/SceneUtils.js | 42 ++ naloga_3/engine/core/Texture.js | 21 + naloga_3/engine/core/Transform.js | 30 ++ naloga_3/engine/core/Vertex.js | 15 + naloga_3/engine/core/VertexUtils.js | 35 ++ naloga_3/engine/loaders/GLTFLoader.js | 483 ++++++++++++++++++ naloga_3/engine/loaders/ImageLoader.js | 10 + naloga_3/engine/loaders/JSONLoader.js | 24 + naloga_3/engine/loaders/OBJLoader.js | 70 +++ naloga_3/engine/renderers/BaseRenderer.js | 75 +++ naloga_3/engine/renderers/UnlitRenderer.js | 236 +++++++++ naloga_3/engine/renderers/UnlitRenderer.wgsl | 56 ++ naloga_3/engine/style.css | 56 ++ naloga_3/engine/systems/ResizeSystem.js | 84 +++ naloga_3/engine/systems/UpdateSystem.js | 49 ++ naloga_3/index.html | 23 + naloga_3/lib/dat.js | 22 + naloga_3/lib/glm.js | 1 + naloga_3/main.js | 98 ++++ naloga_3/models/cone/base.png | Bin 0 -> 61635 bytes naloga_3/models/cone/cone.bin | Bin 0 -> 4468 bytes naloga_3/models/cone/cone.gltf | 149 ++++++ naloga_3/models/cube.obj | 40 ++ naloga_3/models/monkey/base.png | Bin 0 -> 61635 bytes naloga_3/models/monkey/monkey.bin | Bin 0 -> 32496 bytes naloga_3/models/monkey/monkey.gltf | 190 +++++++ naloga_3/models/monkey/normal.webp | Bin 0 -> 63472 bytes naloga_3/shader.wgsl | 98 ++++ vaja_1/base.png | Bin 0 -> 61635 bytes vaja_1/main.js | 41 +- vaja_1/shader.wgsl | 31 +- 51 files changed, 3327 insertions(+), 28 deletions(-) create mode 100644 naloga_3/Light.js create mode 100644 naloga_3/Renderer.js create mode 100644 naloga_3/engine/WebGPU.js create mode 100644 naloga_3/engine/animators/EasingFunctions.js create mode 100644 naloga_3/engine/animators/LinearAnimator.js create mode 100644 naloga_3/engine/animators/RotateAnimator.js create mode 100644 naloga_3/engine/controllers/FirstPersonController.js create mode 100644 naloga_3/engine/controllers/OrbitController.js create mode 100644 naloga_3/engine/controllers/TouchController.js create mode 100644 naloga_3/engine/controllers/TurntableController.js create mode 100644 naloga_3/engine/core.js create mode 100644 naloga_3/engine/core/Accessor.js create mode 100644 naloga_3/engine/core/Camera.js create mode 100644 naloga_3/engine/core/Material.js create mode 100644 naloga_3/engine/core/Mesh.js create mode 100644 naloga_3/engine/core/MeshUtils.js create mode 100644 naloga_3/engine/core/Model.js create mode 100644 naloga_3/engine/core/Node.js create mode 100644 naloga_3/engine/core/Primitive.js create mode 100644 naloga_3/engine/core/Sampler.js create mode 100644 naloga_3/engine/core/SceneUtils.js create mode 100644 naloga_3/engine/core/Texture.js create mode 100644 naloga_3/engine/core/Transform.js create mode 100644 naloga_3/engine/core/Vertex.js create mode 100644 naloga_3/engine/core/VertexUtils.js create mode 100644 naloga_3/engine/loaders/GLTFLoader.js create mode 100644 naloga_3/engine/loaders/ImageLoader.js create mode 100644 naloga_3/engine/loaders/JSONLoader.js create mode 100644 naloga_3/engine/loaders/OBJLoader.js create mode 100644 naloga_3/engine/renderers/BaseRenderer.js create mode 100644 naloga_3/engine/renderers/UnlitRenderer.js create mode 100644 naloga_3/engine/renderers/UnlitRenderer.wgsl create mode 100644 naloga_3/engine/style.css create mode 100644 naloga_3/engine/systems/ResizeSystem.js create mode 100644 naloga_3/engine/systems/UpdateSystem.js create mode 100644 naloga_3/index.html create mode 100644 naloga_3/lib/dat.js create mode 100644 naloga_3/lib/glm.js create mode 100644 naloga_3/main.js create mode 100644 naloga_3/models/cone/base.png create mode 100644 naloga_3/models/cone/cone.bin create mode 100644 naloga_3/models/cone/cone.gltf create mode 100644 naloga_3/models/cube.obj create mode 100644 naloga_3/models/monkey/base.png create mode 100644 naloga_3/models/monkey/monkey.bin create mode 100644 naloga_3/models/monkey/monkey.gltf create mode 100644 naloga_3/models/monkey/normal.webp create mode 100644 naloga_3/shader.wgsl create mode 100644 vaja_1/base.png diff --git a/naloga_3/Light.js b/naloga_3/Light.js new file mode 100644 index 0000000..5d6174c --- /dev/null +++ b/naloga_3/Light.js @@ -0,0 +1,7 @@ +export class Light { + constructor({ ambient, cutoffAngle, intensity }) { + this.ambient = ambient; + this.cutoffAngle = cutoffAngle; + this.intensity = intensity; + } +} diff --git a/naloga_3/Renderer.js b/naloga_3/Renderer.js new file mode 100644 index 0000000..5c6cc02 --- /dev/null +++ b/naloga_3/Renderer.js @@ -0,0 +1,319 @@ +import { vec3, mat4 } from 'glm'; + +import * as WebGPU from 'engine/WebGPU.js'; + +import { Camera, Transform } from 'engine/core.js'; + +import { + getLocalModelMatrix, + getGlobalModelMatrix, + getGlobalViewMatrix, + getProjectionMatrix, + getModels, +} from 'engine/core/SceneUtils.js'; + +import { BaseRenderer } from 'engine/renderers/BaseRenderer.js'; + +import { Light } from './Light.js'; + +const vertexBufferLayout = { + arrayStride: 32, + attributes: [ + { + name: 'position', + shaderLocation: 0, + offset: 0, + format: 'float32x3', + }, + { + name: 'texcoords', + shaderLocation: 1, + offset: 12, + format: 'float32x2', + }, + { + name: 'normal', + shaderLocation: 2, + offset: 20, + format: 'float32x3', + }, + ], +}; + +export class Renderer extends BaseRenderer { + constructor(canvas) { + super(canvas); + } + + async initialize() { + await super.initialize(); + + const code = await fetch(new URL('shader.wgsl', import.meta.url)).then( + (response) => response.text(), + ); + const module = this.device.createShaderModule({ code }); + + this.pipeline = await this.device.createRenderPipelineAsync({ + layout: 'auto', + vertex: { + module, + buffers: [vertexBufferLayout], + }, + fragment: { + module, + targets: [{ format: this.format }], + }, + depthStencil: { + format: 'depth24plus', + depthWriteEnabled: true, + depthCompare: 'less', + }, + }); + + this.recreateDepthTexture(); + } + + recreateDepthTexture() { + this.depthTexture?.destroy(); + this.depthTexture = this.device.createTexture({ + format: 'depth24plus', + size: [this.canvas.width, this.canvas.height], + usage: GPUTextureUsage.RENDER_ATTACHMENT, + }); + } + + prepareNode(node) { + if (this.gpuObjects.has(node)) { + return this.gpuObjects.get(node); + } + + const modelUniformBuffer = this.device.createBuffer({ + label: 'modelUniformBuffer', + size: 128, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); + + const modelBindGroup = this.device.createBindGroup({ + label: 'modelBindGroup', + layout: this.pipeline.getBindGroupLayout(1), + entries: [{ binding: 0, resource: { buffer: modelUniformBuffer } }], + }); + + const gpuObjects = { modelUniformBuffer, modelBindGroup }; + this.gpuObjects.set(node, gpuObjects); + return gpuObjects; + } + + prepareCamera(camera) { + if (this.gpuObjects.has(camera)) { + return this.gpuObjects.get(camera); + } + + const cameraUniformBuffer = this.device.createBuffer({ + label: 'cameraUniformBuffer', + size: 144, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); + + const cameraBindGroup = this.device.createBindGroup({ + label: 'cameraBindGroup', + layout: this.pipeline.getBindGroupLayout(0), + entries: [ + { binding: 0, resource: { buffer: cameraUniformBuffer } }, + ], + }); + + const gpuObjects = { cameraUniformBuffer, cameraBindGroup }; + this.gpuObjects.set(camera, gpuObjects); + return gpuObjects; + } + + prepareLight(light) { + if (this.gpuObjects.has(light)) { + return this.gpuObjects.get(light); + } + + const lightUniformBuffer = this.device.createBuffer({ + label: 'lightUniformBuffer', + size: 48, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); + + const lightBindGroup = this.device.createBindGroup({ + label: 'lightBindGroup', + layout: this.pipeline.getBindGroupLayout(3), + entries: [{ binding: 0, resource: { buffer: lightUniformBuffer } }], + }); + + const gpuObjects = { lightUniformBuffer, lightBindGroup }; + this.gpuObjects.set(light, gpuObjects); + return gpuObjects; + } + + prepareMaterial(material) { + if (this.gpuObjects.has(material)) { + return this.gpuObjects.get(material); + } + + const baseTexture = this.prepareImage( + material.baseTexture.image, + ).gpuTexture; + const baseSampler = this.prepareSampler( + material.baseTexture.sampler, + ).gpuSampler; + + const materialUniformBuffer = this.device.createBuffer({ + size: 64, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); + + const materialBindGroup = this.device.createBindGroup({ + label: 'materialBindGroup', + layout: this.pipeline.getBindGroupLayout(2), + entries: [ + { binding: 0, resource: { buffer: materialUniformBuffer } }, + { binding: 1, resource: baseTexture.createView() }, + { binding: 2, resource: baseSampler }, + ], + }); + + const gpuObjects = { materialUniformBuffer, materialBindGroup }; + this.gpuObjects.set(material, gpuObjects); + return gpuObjects; + } + + calculateLightDirection(lightMatrix) { + // const lightDirection = mat4.getTranslation(vec3.create(), lightMatrix); + + const lightDirection = vec3.fromValues( + lightMatrix[4], + lightMatrix[5], + lightMatrix[6], + ); + + vec3.negate(lightDirection, lightDirection); + vec3.normalize(lightDirection, lightDirection); + + return lightDirection; + } + + render(scene, camera) { + if ( + this.depthTexture.width !== this.canvas.width || + this.depthTexture.height !== this.canvas.height + ) { + this.recreateDepthTexture(); + } + + const encoder = this.device.createCommandEncoder(); + this.renderPass = encoder.beginRenderPass({ + colorAttachments: [ + { + view: this.context.getCurrentTexture().createView(), + clearValue: [1, 1, 1, 1], + loadOp: 'clear', + storeOp: 'store', + }, + ], + depthStencilAttachment: { + view: this.depthTexture.createView(), + depthClearValue: 1, + depthLoadOp: 'clear', + depthStoreOp: 'discard', + }, + }); + this.renderPass.setPipeline(this.pipeline); + + const cameraComponent = camera.getComponentOfType(Camera); + const cameraMatrix = getGlobalModelMatrix(camera); + const cameraPosition = mat4.getTranslation(vec3.create(), cameraMatrix); + const viewMatrix = getGlobalViewMatrix(camera); + const projectionMatrix = getProjectionMatrix(camera); + const { cameraUniformBuffer, cameraBindGroup } = + this.prepareCamera(cameraComponent); + this.device.queue.writeBuffer(cameraUniformBuffer, 0, viewMatrix); + this.device.queue.writeBuffer( + cameraUniformBuffer, + 64, + projectionMatrix, + ); + this.device.queue.writeBuffer(cameraUniformBuffer, 128, cameraPosition); + this.renderPass.setBindGroup(0, cameraBindGroup); + + const light = scene.find((node) => node.getComponentOfType(Light)); + const lightComponent = light.getComponentOfType(Light); + const lightMatrix = getGlobalModelMatrix(light); + const lightPosition = mat4.getTranslation(vec3.create(), lightMatrix); + const lightDirection = this.calculateLightDirection(lightMatrix); + const { lightUniformBuffer, lightBindGroup } = + this.prepareLight(lightComponent); + this.device.queue.writeBuffer(lightUniformBuffer, 0, lightPosition); + this.device.queue.writeBuffer(lightUniformBuffer, 12, lightDirection); + this.device.queue.writeBuffer( + lightUniformBuffer, + 24, + new Float32Array([ + 1.0, + Math.cos(lightComponent.cutoffAngle), + lightComponent.ambient, + lightComponent.intensity, + ]), + ); + this.renderPass.setBindGroup(3, lightBindGroup); + + this.renderNode(scene); + + this.renderPass.end(); + this.device.queue.submit([encoder.finish()]); + } + + renderNode(node, modelMatrix = mat4.create()) { + const localMatrix = getLocalModelMatrix(node); + modelMatrix = mat4.multiply(mat4.create(), modelMatrix, localMatrix); + + const { modelUniformBuffer, modelBindGroup } = this.prepareNode(node); + const normalMatrix = mat4.normalFromMat4(mat4.create(), modelMatrix); + this.device.queue.writeBuffer(modelUniformBuffer, 0, modelMatrix); + this.device.queue.writeBuffer(modelUniformBuffer, 64, normalMatrix); + this.renderPass.setBindGroup(1, modelBindGroup); + + for (const model of getModels(node)) { + this.renderModel(model); + } + + for (const child of node.children) { + this.renderNode(child, modelMatrix); + } + } + + renderModel(model) { + for (const primitive of model.primitives) { + this.renderPrimitive(primitive); + } + } + + renderPrimitive(primitive) { + const { materialUniformBuffer, materialBindGroup } = + this.prepareMaterial(primitive.material); + this.device.queue.writeBuffer( + materialUniformBuffer, + 0, + new Float32Array(primitive.material.baseFactor), + ); + this.device.queue.writeBuffer( + materialUniformBuffer, + 16, + new Float32Array([1, 1]), + ); + this.renderPass.setBindGroup(2, materialBindGroup); + + const { vertexBuffer, indexBuffer } = this.prepareMesh( + primitive.mesh, + vertexBufferLayout, + ); + this.renderPass.setVertexBuffer(0, vertexBuffer); + this.renderPass.setIndexBuffer(indexBuffer, 'uint32'); + + this.renderPass.drawIndexed(primitive.mesh.indices.length); + } +} diff --git a/naloga_3/engine/WebGPU.js b/naloga_3/engine/WebGPU.js new file mode 100644 index 0000000..393c797 --- /dev/null +++ b/naloga_3/engine/WebGPU.js @@ -0,0 +1,73 @@ +export function createBuffer(device, { data, usage }) { + const buffer = device.createBuffer({ + size: Math.ceil(data.byteLength / 4) * 4, + mappedAtCreation: true, + usage, + }); + if (ArrayBuffer.isView(data)) { + new data.constructor(buffer.getMappedRange()).set(data); + } else { + new Uint8Array(buffer.getMappedRange()).set(new Uint8Array(data)); + } + buffer.unmap(); + return buffer; +} + +export function createTextureFromSource(device, { + source, + format = 'rgba8unorm', + usage = 0, + mipLevelCount = 1, + flipY = false, +}) { + const size = [source.width, source.height]; + const texture = device.createTexture({ + format, + size, + mipLevelCount, + usage: usage | + GPUTextureUsage.TEXTURE_BINDING | + GPUTextureUsage.COPY_DST | + GPUTextureUsage.RENDER_ATTACHMENT, + }); + device.queue.copyExternalImageToTexture( + { source, flipY }, + { texture }, + size, + ); + return texture; +} + +export function createTextureFromData(device, { + data, + size, + bytesPerRow, + rowsPerImage, + format = 'rgba8unorm', + dimension = '2d', + usage = 0, + mipLevelCount = 1, + flipY = false, +}) { + const texture = device.createTexture({ + format, + size, + mipLevelCount, + usage: usage | GPUTextureUsage.COPY_DST, + }); + device.queue.writeTexture( + { texture }, + data, + { bytesPerRow, rowsPerImage }, + size, + ); + return texture; +} + +export function createTexture(device, options) { + if (options.source) { + return createTextureFromSource(device, options); + } else { + return createTextureFromData(device, options); + } +} diff --git a/naloga_3/engine/animators/EasingFunctions.js b/naloga_3/engine/animators/EasingFunctions.js new file mode 100644 index 0000000..849be3a --- /dev/null +++ b/naloga_3/engine/animators/EasingFunctions.js @@ -0,0 +1,47 @@ +export function swap(f, t, ...args) { return 1 - f(1 - t, ...args); } +export function inout(f, t, ...args) { return t < 0.5 ? f(2 * t, ...args) / 2 : 1 - f(2 * (1 - t), ...args) / 2; } + +export function step(t, p = 0) { return t < p ? 0 : 1; } +export function stepEaseIn(...args) { return step(...args); } +export function stepEaseOut(...args) { return swap(step, ...args); } +export function stepEaseInOut(...args) { return inout(step, ...args); } + +export function linear(t) { return t; } +export function linearEaseIn(...args) { return linear(...args); } +export function linearEaseOut(...args) { return swap(linear, ...args); } +export function linearEaseInOut(...args) { return inout(linear, ...args); } + +export function poly(t, p = 2) { return Math.pow(t, p); } +export function polyEaseIn(...args) { return poly(...args); } +export function polyEaseOut(...args) { return swap(poly, ...args); } +export function polyEaseInOut(...args) { return inout(poly, ...args); } + +export function expo(t, p = 5) { return (Math.exp(p * t) - 1) / (Math.exp(p) - 1); } +export function expoEaseIn(...args) { return expo(...args); } +export function expoEaseOut(...args) { return swap(expo, ...args); } +export function expoEaseInOut(...args) { return inout(expo, ...args); } + +export function sine(t, n = 1) { return 1 - Math.cos(n * t * Math.PI / 2); } +export function sineEaseIn(...args) { return sine(...args); } +export function sineEaseOut(...args) { return swap(sine, ...args); } +export function sineEaseInOut(...args) { return inout(sine, ...args); } + +export function circ(t) { return 1 - Math.sqrt(1 - t * t); } +export function circEaseIn(...args) { return circ(...args); } +export function circEaseOut(...args) { return swap(circ, ...args); } +export function circEaseInOut(...args) { return inout(circ, ...args); } + +export function back(t, p = 2) { return t * t * ((p + 1) * t - p); } +export function backEaseIn(...args) { return back(...args); } +export function backEaseOut(...args) { return swap(back, ...args); } +export function backEaseInOut(...args) { return inout(back, ...args); } + +export function elastic(t, p = 5, n = 5) { return expo(t, p) * (1 - sine(t, 4 * n)); } +export function elasticEaseIn(...args) { return elastic(...args); } +export function elasticEaseOut(...args) { return swap(elastic, ...args); } +export function elasticEaseInOut(...args) { return inout(elastic, ...args); } + +export function bounce(t, p = 2, n = 2) { return Math.abs(poly(t, p) * (1 - sine(t, 4 * n))); } +export function bounceEaseIn(...args) { return bounce(...args); } +export function bounceEaseOut(...args) { return swap(bounce, ...args); } +export function bounceEaseInOut(...args) { return inout(bounce, ...args); } diff --git a/naloga_3/engine/animators/LinearAnimator.js b/naloga_3/engine/animators/LinearAnimator.js new file mode 100644 index 0000000..f67bc68 --- /dev/null +++ b/naloga_3/engine/animators/LinearAnimator.js @@ -0,0 +1,54 @@ +import { vec3 } from 'glm'; + +import { Transform } from '../core/Transform.js'; + +export class LinearAnimator { + + constructor(node, { + startPosition = [0, 0, 0], + endPosition = [0, 0, 0], + startTime = 0, + duration = 1, + loop = false, + } = {}) { + this.node = node; + + this.startPosition = startPosition; + this.endPosition = endPosition; + + this.startTime = startTime; + this.duration = duration; + this.loop = loop; + + this.playing = true; + } + + play() { + this.playing = true; + } + + pause() { + this.playing = false; + } + + update(t, dt) { + if (!this.playing) { + return; + } + + const linearInterpolation = (t - this.startTime) / this.duration; + const clampedInterpolation = Math.min(Math.max(linearInterpolation, 0), 1); + const loopedInterpolation = ((linearInterpolation % 1) + 1) % 1; + this.updateNode(this.loop ? loopedInterpolation : clampedInterpolation); + } + + updateNode(interpolation) { + const transform = this.node.getComponentOfType(Transform); + if (!transform) { + return; + } + + vec3.lerp(transform.translation, this.startPosition, this.endPosition, interpolation); + } + +} diff --git a/naloga_3/engine/animators/RotateAnimator.js b/naloga_3/engine/animators/RotateAnimator.js new file mode 100644 index 0000000..c25de0b --- /dev/null +++ b/naloga_3/engine/animators/RotateAnimator.js @@ -0,0 +1,54 @@ +import { quat, vec3 } from 'glm'; + +import { Transform } from '../core/Transform.js'; + +export class RotateAnimator { + + constructor(node, { + startRotation = [0, 0, 0, 1], + endRotation = [0, 0, 0, 1], + startTime = 0, + duration = 1, + loop = false, + } = {}) { + this.node = node; + + this.startRotation = startRotation; + this.endRotation = endRotation; + + this.startTime = startTime; + this.duration = duration; + this.loop = loop; + + this.playing = true; + } + + play() { + this.playing = true; + } + + pause() { + this.playing = false; + } + + update(t, dt) { + if (!this.playing) { + return; + } + + const linearInterpolation = (t - this.startTime) / this.duration; + const clampedInterpolation = Math.min(Math.max(linearInterpolation, 0), 1); + const loopedInterpolation = ((linearInterpolation % 1) + 1) % 1; + this.updateNode(this.loop ? loopedInterpolation : clampedInterpolation); + } + + updateNode(interpolation) { + const transform = this.node.getComponentOfType(Transform); + if (!transform) { + return; + } + + quat.slerp(transform.rotation, this.startRotation, this.endRotation, interpolation); + } + +} diff --git a/naloga_3/engine/controllers/FirstPersonController.js b/naloga_3/engine/controllers/FirstPersonController.js new file mode 100644 index 0000000..afdbfc5 --- /dev/null +++ b/naloga_3/engine/controllers/FirstPersonController.js @@ -0,0 +1,131 @@ +import { quat, vec3, mat4 } from 'glm'; + +import { Transform } from '../core/Transform.js'; + +export class FirstPersonController { + + constructor(node, domElement, { + pitch = 0, + yaw = 0, + velocity = [0, 0, 0], + acceleration = 50, + maxSpeed = 5, + decay = 0.99999, + pointerSensitivity = 0.002, + } = {}) { + this.node = node; + this.domElement = domElement; + + this.keys = {}; + + this.pitch = pitch; + this.yaw = yaw; + + this.velocity = velocity; + this.acceleration = acceleration; + this.maxSpeed = maxSpeed; + this.decay = decay; + this.pointerSensitivity = pointerSensitivity; + + this.initHandlers(); + } + + initHandlers() { + this.pointermoveHandler = this.pointermoveHandler.bind(this); + this.keydownHandler = this.keydownHandler.bind(this); + this.keyupHandler = this.keyupHandler.bind(this); + + const element = this.domElement; + const doc = element.ownerDocument; + + doc.addEventListener('keydown', this.keydownHandler); + doc.addEventListener('keyup', this.keyupHandler); + + element.addEventListener('click', e => element.requestPointerLock()); + doc.addEventListener('pointerlockchange', e => { + if (doc.pointerLockElement === element) { + doc.addEventListener('pointermove', this.pointermoveHandler); + } else { + doc.removeEventListener('pointermove', this.pointermoveHandler); + } + }); + } + + update(t, dt) { + // Calculate forward and right vectors. + const cos = Math.cos(this.yaw); + const sin = Math.sin(this.yaw); + const forward = [-sin, 0, -cos]; + const right = [cos, 0, -sin]; + + // Map user input to the acceleration vector. + const acc = vec3.create(); + if (this.keys['KeyW']) { + vec3.add(acc, acc, forward); + } + if (this.keys['KeyS']) { + vec3.sub(acc, acc, forward); + } + if (this.keys['KeyD']) { + vec3.add(acc, acc, right); + } + if (this.keys['KeyA']) { + vec3.sub(acc, acc, right); + } + + // Update velocity based on acceleration. + vec3.scaleAndAdd(this.velocity, this.velocity, acc, dt * this.acceleration); + + // If there is no user input, apply decay. + if (!this.keys['KeyW'] && + !this.keys['KeyS'] && + !this.keys['KeyD'] && + !this.keys['KeyA']) + { + const decay = Math.exp(dt * Math.log(1 - this.decay)); + vec3.scale(this.velocity, this.velocity, decay); + } + + // Limit speed to prevent accelerating to infinity and beyond. + const speed = vec3.length(this.velocity); + if (speed > this.maxSpeed) { + vec3.scale(this.velocity, this.velocity, this.maxSpeed / speed); + } + + const transform = this.node.getComponentOfType(Transform); + if (transform) { + // Update translation based on velocity. + vec3.scaleAndAdd(transform.translation, + transform.translation, this.velocity, dt); + + // Update rotation based on the Euler angles. + const rotation = quat.create(); + quat.rotateY(rotation, rotation, this.yaw); + quat.rotateX(rotation, rotation, this.pitch); + transform.rotation = rotation; + } + } + + pointermoveHandler(e) { + const dx = e.movementX; + const dy = e.movementY; + + this.pitch -= dy * this.pointerSensitivity; + this.yaw -= dx * this.pointerSensitivity; + + const twopi = Math.PI * 2; + const halfpi = Math.PI / 2; + + this.pitch = Math.min(Math.max(this.pitch, -halfpi), halfpi); + this.yaw = ((this.yaw % twopi) + twopi) % twopi; + } + + keydownHandler(e) { + this.keys[e.code] = true; + } + + keyupHandler(e) { + this.keys[e.code] = false; + } + +} diff --git a/naloga_3/engine/controllers/OrbitController.js b/naloga_3/engine/controllers/OrbitController.js new file mode 100644 index 0000000..adc6df8 --- /dev/null +++ b/naloga_3/engine/controllers/OrbitController.js @@ -0,0 +1,74 @@ +import { quat, vec3 } from 'glm'; + +import { Transform } from '../core/Transform.js'; + +export class OrbitController { + + constructor(node, domElement, { + rotation = [0, 0, 0, 1], + distance = 2, + moveSensitivity = 0.004, + zoomSensitivity = 0.002, + } = {}) { + this.node = node; + this.domElement = domElement; + + this.rotation = rotation; + this.distance = distance; + + this.moveSensitivity = moveSensitivity; + this.zoomSensitivity = zoomSensitivity; + + this.initHandlers(); + } + + initHandlers() { + this.pointerdownHandler = this.pointerdownHandler.bind(this); + this.pointerupHandler = this.pointerupHandler.bind(this); + this.pointermoveHandler = this.pointermoveHandler.bind(this); + this.wheelHandler = this.wheelHandler.bind(this); + + this.domElement.addEventListener('pointerdown', this.pointerdownHandler); + this.domElement.addEventListener('wheel', this.wheelHandler); + } + + pointerdownHandler(e) { + this.domElement.setPointerCapture(e.pointerId); + this.domElement.requestPointerLock(); + this.domElement.removeEventListener('pointerdown', this.pointerdownHandler); + this.domElement.addEventListener('pointerup', this.pointerupHandler); + this.domElement.addEventListener('pointermove', this.pointermoveHandler); + } + + pointerupHandler(e) { + this.domElement.releasePointerCapture(e.pointerId); + this.domElement.ownerDocument.exitPointerLock(); + this.domElement.addEventListener('pointerdown', this.pointerdownHandler); + this.domElement.removeEventListener('pointerup', this.pointerupHandler); + this.domElement.removeEventListener('pointermove', this.pointermoveHandler); + } + + pointermoveHandler(e) { + const dx = e.movementX; + const dy = e.movementY; + + quat.rotateX(this.rotation, this.rotation, -dy * this.moveSensitivity); + quat.rotateY(this.rotation, this.rotation, -dx * this.moveSensitivity); + quat.normalize(this.rotation, this.rotation); + } + + wheelHandler(e) { + this.distance *= Math.exp(this.zoomSensitivity * e.deltaY); + } + + update() { + const transform = this.node.getComponentOfType(Transform); + if (!transform) { + return; + } + + quat.copy(transform.rotation, this.rotation); + vec3.transformQuat(transform.translation, [0, 0, this.distance], this.rotation); + } + +} diff --git a/naloga_3/engine/controllers/TouchController.js b/naloga_3/engine/controllers/TouchController.js new file mode 100644 index 0000000..e6dd5c9 --- /dev/null +++ b/naloga_3/engine/controllers/TouchController.js @@ -0,0 +1,143 @@ +import { quat, vec2, vec3 } from 'glm'; + +import { Transform } from 'engine/core/Transform.js'; + +export class TouchController { + + constructor(node, domElement, { + translation = [0, 0, 0], + rotation = [0, 0, 0, 1], + distance = 2, + translateSensitivity = 0.001, + rotateSensitivity = 0.004, + wheelSensitivity = 0.002, + } = {}) { + this.node = node; + this.domElement = domElement; + + this.translation = translation; + this.rotation = rotation; + this.distance = distance; + + this.translateSensitivity = translateSensitivity; + this.rotateSensitivity = rotateSensitivity; + this.wheelSensitivity = wheelSensitivity; + + this.pointers = new Map(); + this.initHandlers(); + } + + initHandlers() { + this.pointerdownHandler = this.pointerdownHandler.bind(this); + this.pointerupHandler = this.pointerupHandler.bind(this); + this.pointermoveHandler = this.pointermoveHandler.bind(this); + this.wheelHandler = this.wheelHandler.bind(this); + + this.domElement.addEventListener('pointerdown', this.pointerdownHandler); + this.domElement.addEventListener('pointerup', this.pointerupHandler); + this.domElement.addEventListener('pointercancel', this.pointerupHandler); + this.domElement.addEventListener('pointermove', this.pointermoveHandler); + this.domElement.addEventListener('wheel', this.wheelHandler); + } + + pointerdownHandler(e) { + this.pointers.set(e.pointerId, e); + this.domElement.setPointerCapture(e.pointerId); + this.domElement.requestPointerLock(); + } + + pointerupHandler(e) { + this.pointers.delete(e.pointerId); + this.domElement.releasePointerCapture(e.pointerId); + this.domElement.ownerDocument.exitPointerLock(); + } + + pointermoveHandler(e) { + if (!this.pointers.has(e.pointerId)) { + return; + } + + if (this.pointers.size === 1) { + if (e.shiftKey) { + this.translate(e.movementX, e.movementY); + } else { + this.rotate(e.movementX, e.movementY); + } + this.pointers.set(e.pointerId, e); + } else { + const N = this.pointers.size; + + // Points before movement + const A = [...this.pointers.values()].map(e => [e.clientX, e.clientY]); + + this.pointers.set(e.pointerId, e); + + // Points after movement + const B = [...this.pointers.values()].map(e => [e.clientX, e.clientY]); + + const centroidA = A.reduce((a, v) => vec2.scaleAndAdd(a, a, v, 1 / N), [0, 0]); + const centroidB = B.reduce((a, v) => vec2.scaleAndAdd(a, a, v, 1 / N), [0, 0]); + + const translation = vec2.subtract(vec2.create(), centroidB, centroidA); + + const centeredA = A.map(v => vec2.subtract(vec2.create(), v, centroidA)); + const centeredB = B.map(v => vec2.subtract(vec2.create(), v, centroidB)); + + const scaleA = centeredA.reduce((a, v) => a + vec2.length(v) / N, 0); + const scaleB = centeredB.reduce((a, v) => a + vec2.length(v) / N, 0); + + const scale = scaleA / scaleB; + + const normalizedA = centeredA.map(v => vec2.normalize(vec2.create(), v)); + const normalizedB = centeredB.map(v => vec2.normalize(vec2.create(), v)); + + let sin = 0; + for (let i = 0; i < A.length; i++) { + const a = normalizedA[i]; + const b = normalizedB[i]; + sin += (a[0] * b[1] - a[1] * b[0]) / N; + } + const angle = Math.asin(sin); + + this.translate(...translation); + this.scale(scale); + this.screw(angle); + } + } + + wheelHandler(e) { + this.scale(Math.exp(e.deltaY * this.wheelSensitivity)); + } + + screw(amount) { + quat.rotateZ(this.rotation, this.rotation, amount); + } + + rotate(dx, dy) { + quat.rotateX(this.rotation, this.rotation, -dy * this.rotateSensitivity); + quat.rotateY(this.rotation, this.rotation, -dx * this.rotateSensitivity); + quat.normalize(this.rotation, this.rotation); + } + + translate(dx, dy) { + const translation = [-dx, dy, 0]; + vec3.transformQuat(translation, translation, this.rotation); + vec3.scaleAndAdd(this.translation, this.translation, translation, this.distance * this.translateSensitivity); + } + + scale(amount) { + this.distance *= amount; + } + + update() { + const transform = this.node.getComponentOfType(Transform); + if (!transform) { + return; + } + + quat.copy(transform.rotation, this.rotation); + vec3.transformQuat(transform.translation, [0, 0, this.distance], this.rotation); + vec3.add(transform.translation, transform.translation, this.translation); + } + +} diff --git a/naloga_3/engine/controllers/TurntableController.js b/naloga_3/engine/controllers/TurntableController.js new file mode 100644 index 0000000..d560662 --- /dev/null +++ b/naloga_3/engine/controllers/TurntableController.js @@ -0,0 +1,88 @@ +import { quat, vec3 } from 'glm'; + +import { Transform } from '../core/Transform.js'; + +export class TurntableController { + + constructor(node, domElement, { + pitch = 0, + yaw = 0, + distance = 1, + moveSensitivity = 0.004, + zoomSensitivity = 0.002, + } = {}) { + this.node = node; + this.domElement = domElement; + + this.pitch = pitch; + this.yaw = yaw; + this.distance = distance; + + this.moveSensitivity = moveSensitivity; + this.zoomSensitivity = zoomSensitivity; + + this.initHandlers(); + } + + initHandlers() { + this.pointerdownHandler = this.pointerdownHandler.bind(this); + this.pointerupHandler = this.pointerupHandler.bind(this); + this.pointermoveHandler = this.pointermoveHandler.bind(this); + this.wheelHandler = this.wheelHandler.bind(this); + + this.domElement.addEventListener('pointerdown', this.pointerdownHandler); + this.domElement.addEventListener('wheel', this.wheelHandler); + } + + pointerdownHandler(e) { + this.domElement.setPointerCapture(e.pointerId); + this.domElement.requestPointerLock(); + this.domElement.removeEventListener('pointerdown', this.pointerdownHandler); + this.domElement.addEventListener('pointerup', this.pointerupHandler); + this.domElement.addEventListener('pointermove', this.pointermoveHandler); + } + + pointerupHandler(e) { + this.domElement.releasePointerCapture(e.pointerId); + this.domElement.ownerDocument.exitPointerLock(); + this.domElement.addEventListener('pointerdown', this.pointerdownHandler); + this.domElement.removeEventListener('pointerup', this.pointerupHandler); + this.domElement.removeEventListener('pointermove', this.pointermoveHandler); + } + + pointermoveHandler(e) { + const dx = e.movementX; + const dy = e.movementY; + + this.pitch -= dy * this.moveSensitivity; + this.yaw -= dx * this.moveSensitivity; + + const twopi = Math.PI * 2; + const halfpi = Math.PI / 2; + + this.pitch = Math.min(Math.max(this.pitch, -halfpi), halfpi); + this.yaw = ((this.yaw % twopi) + twopi) % twopi; + } + + wheelHandler(e) { + this.distance *= Math.exp(this.zoomSensitivity * e.deltaY); + } + + update() { + const transform = this.node.getComponentOfType(Transform); + if (!transform) { + return; + } + + const rotation = quat.create(); + quat.rotateY(rotation, rotation, this.yaw); + quat.rotateX(rotation, rotation, this.pitch); + transform.rotation = rotation; + + const translation = [0, 0, this.distance]; + vec3.rotateX(translation, translation, [0, 0, 0], this.pitch); + vec3.rotateY(translation, translation, [0, 0, 0], this.yaw); + transform.translation = translation; + } + +} diff --git a/naloga_3/engine/core.js b/naloga_3/engine/core.js new file mode 100644 index 0000000..f780e30 --- /dev/null +++ b/naloga_3/engine/core.js @@ -0,0 +1,11 @@ +export * from './core/Accessor.js'; +export * from './core/Camera.js'; +export * from './core/Material.js'; +export * from './core/Mesh.js'; +export * from './core/Model.js'; +export * from './core/Node.js'; +export * from './core/Primitive.js'; +export * from './core/Sampler.js'; +export * from './core/Texture.js'; +export * from './core/Transform.js'; +export * from './core/Vertex.js'; diff --git a/naloga_3/engine/core/Accessor.js b/naloga_3/engine/core/Accessor.js new file mode 100644 index 0000000..766222c --- /dev/null +++ b/naloga_3/engine/core/Accessor.js @@ -0,0 +1,132 @@ +export class Accessor { + + constructor({ + buffer, + viewLength, + viewOffset = 0, + offset = 0, + stride = componentSize, + + componentType = 'int', + componentCount = 1, + componentSize = 1, + componentSigned = false, + componentNormalized = false, + } = {}) { + this.buffer = buffer; + this.offset = offset; + this.stride = stride; + + this.componentType = componentType; + this.componentCount = componentCount; + this.componentSize = componentSize; + this.componentSigned = componentSigned; + this.componentNormalized = componentNormalized; + + const viewType = this.getViewType({ + componentType, + componentSize, + componentSigned, + }); + + if (viewLength !== undefined) { + this.view = new viewType(buffer, viewOffset, viewLength / viewType.BYTES_PER_ELEMENT); + } else { + this.view = new viewType(buffer, viewOffset); + } + + this.offsetInElements = offset / viewType.BYTES_PER_ELEMENT; + this.strideInElements = stride / viewType.BYTES_PER_ELEMENT; + + this.count = Math.floor((this.view.length - this.offsetInElements) / this.strideInElements); + + this.normalize = this.getNormalizer({ + componentType, + componentSize, + componentSigned, + componentNormalized, + }); + + this.denormalize = this.getDenormalizer({ + componentType, + componentSize, + componentSigned, + componentNormalized, + }); + } + + get(index) { + const start = index * this.strideInElements + this.offsetInElements; + const end = start + this.componentCount; + return [...this.view.slice(start, end)].map(this.normalize); + } + + set(index, value) { + const start = index * this.strideInElements + this.offsetInElements; + this.view.set(value.map(this.denormalize), start); + } + + getNormalizer({ + componentType, + componentSize, + componentSigned, + componentNormalized, + }) { + if (!componentNormalized || componentType === 'float') { + return x => x; + } + + const multiplier = componentSigned + ? 2 ** ((componentSize * 8) - 1) - 1 + : 2 ** (componentSize * 8) - 1; + + return x => Math.max(x / multiplier, -1); + } + + getDenormalizer({ + componentType, + componentSize, + componentSigned, + componentNormalized, + }) { + if (!componentNormalized || componentType === 'float') { + return x => x; + } + + const multiplier = componentSigned + ? 2 ** ((componentSize * 8) - 1) - 1 + : 2 ** (componentSize * 8) - 1; + + const min = componentSigned ? -1 : 0; + const max = 1; + + return x => Math.floor(0.5 + multiplier * Math.min(Math.max(x, min), max)); + } + + getViewType({ + componentType, + componentSize, + componentSigned, + }) { + if (componentType === 'float') { + if (componentSize === 4) { + return Float32Array; + } + } else if (componentType === 'int') { + if (componentSigned) { + switch (componentSize) { + case 1: return Int8Array; + case 2: return Int16Array; + case 4: return Int32Array; + } + } else { + switch (componentSize) { + case 1: return Uint8Array; + case 2: return Uint16Array; + case 4: return Uint32Array; + } + } + } + } + +} diff --git a/naloga_3/engine/core/Camera.js b/naloga_3/engine/core/Camera.js new file mode 100644 index 0000000..1f7616c --- /dev/null +++ b/naloga_3/engine/core/Camera.js @@ -0,0 +1,46 @@ +import { mat4 } from 'glm'; + +export class Camera { + + constructor({ + orthographic = 0, + aspect = 1, + fovy = 1, + halfy = 1, + near = 0.01, + far = 1000, + } = {}) { + this.orthographic = orthographic; + this.aspect = aspect; + this.fovy = fovy; + this.halfy = halfy; + this.near = near; + this.far = far; + } + + get projectionMatrix() { + if (this.orthographic === 0) { + return this.perspectiveMatrix; + } else if (this.orthographic === 1) { + return this.orthographicMatrix; + } else { + const a = this.orthographicMatrix; + const b = this.perspectiveMatrix; + return mat4.add(mat4.create(), + mat4.multiplyScalar(a, a, this.orthographic), + mat4.multiplyScalar(b, b, 1 - this.orthographic)); + } + } + + get orthographicMatrix() { + const { halfy, aspect, near, far } = this; + const halfx = halfy * aspect; + return mat4.orthoZO(mat4.create(), -halfx, halfx, -halfy, halfy, near, far); + } + + get perspectiveMatrix() { + const { fovy, aspect, near, far } = this; + return mat4.perspectiveZO(mat4.create(), fovy, aspect, near, far); + } + +} diff --git a/naloga_3/engine/core/Material.js b/naloga_3/engine/core/Material.js new file mode 100644 index 0000000..88d3f86 --- /dev/null +++ b/naloga_3/engine/core/Material.js @@ -0,0 +1,33 @@ +export class Material { + + constructor({ + baseTexture, + emissionTexture, + normalTexture, + occlusionTexture, + roughnessTexture, + metalnessTexture, + + baseFactor = [1, 1, 1, 1], + emissionFactor = [0, 0, 0], + normalFactor = 1, + occlusionFactor = 1, + roughnessFactor = 1, + metalnessFactor = 1, + } = {}) { + this.baseTexture = baseTexture; + this.emissionTexture = emissionTexture; + this.normalTexture = normalTexture; + this.occlusionTexture = occlusionTexture; + this.roughnessTexture = roughnessTexture; + this.metalnessTexture = metalnessTexture; + + this.baseFactor = baseFactor; + this.emissionFactor = emissionFactor; + this.normalFactor = normalFactor; + this.occlusionFactor = occlusionFactor; + this.roughnessFactor = roughnessFactor; + this.metalnessFactor = metalnessFactor; + } + +} diff --git a/naloga_3/engine/core/Mesh.js b/naloga_3/engine/core/Mesh.js new file mode 100644 index 0000000..e57145a --- /dev/null +++ b/naloga_3/engine/core/Mesh.js @@ -0,0 +1,11 @@ +export class Mesh { + + constructor({ + vertices = [], + indices = [], + } = {}) { + this.vertices = vertices; + this.indices = indices; + } + +} diff --git a/naloga_3/engine/core/MeshUtils.js b/naloga_3/engine/core/MeshUtils.js new file mode 100644 index 0000000..d5a8c1d --- /dev/null +++ b/naloga_3/engine/core/MeshUtils.js @@ -0,0 +1,43 @@ +import { quat, vec3, vec4, mat3, mat4 } from 'glm'; + +export function transformVertex(vertex, matrix, + normalMatrix = mat3.normalFromMat4(mat3.create(), matrix), + tangentMatrix = mat3.fromMat4(mat3.create(), matrix), +) { + vec3.transformMat4(vertex.position, vertex.position, matrix); + vec3.transformMat3(vertex.normal, vertex.normal, normalMatrix); + vec3.transformMat3(vertex.tangent, vertex.tangent, tangentMatrix); +} + +export function transformMesh(mesh, matrix, + normalMatrix = mat3.normalFromMat4(mat3.create(), matrix), + tangentMatrix = mat3.fromMat4(mat3.create(), matrix), +) { + for (const vertex of mesh.vertices) { + transformVertex(vertex, matrix, normalMatrix, tangentMatrix); + } +} + +export function calculateAxisAlignedBoundingBox(mesh) { + const initial = { + min: vec3.clone(mesh.vertices[0].position), + max: vec3.clone(mesh.vertices[0].position), + }; + + return { + min: mesh.vertices.reduce((a, b) => vec3.min(a, a, b.position), initial.min), + max: mesh.vertices.reduce((a, b) => vec3.max(a, a, b.position), initial.max), + }; +} + +export function mergeAxisAlignedBoundingBoxes(boxes) { + const initial = { + min: vec3.clone(boxes[0].min), + max: vec3.clone(boxes[0].max), + }; + + return { + min: boxes.reduce(({ min: amin }, { min: bmin }) => vec3.min(amin, amin, bmin), initial), + max: boxes.reduce(({ max: amax }, { max: bmax }) => vec3.max(amax, amax, bmax), initial), + }; +} diff --git a/naloga_3/engine/core/Model.js b/naloga_3/engine/core/Model.js new file mode 100644 index 0000000..fc88d41 --- /dev/null +++ b/naloga_3/engine/core/Model.js @@ -0,0 +1,9 @@ +export class Model { + + constructor({ + primitives = [], + } = {}) { + this.primitives = primitives; + } + +} diff --git a/naloga_3/engine/core/Node.js b/naloga_3/engine/core/Node.js new file mode 100644 index 0000000..a5b2f86 --- /dev/null +++ b/naloga_3/engine/core/Node.js @@ -0,0 +1,69 @@ +export class Node { + + constructor() { + this.children = []; + this.parent = null; + this.components = []; + } + + addChild(node) { + node.parent?.removeChild(node); + this.children.push(node); + node.parent = this; + } + + removeChild(node) { + const index = this.children.indexOf(node); + if (index >= 0) { + this.children.splice(index, 1); + node.parent = null; + } + } + + traverse(before, after) { + before?.(this); + for (const child of this.children) { + child.traverse(before, after); + } + after?.(this); + } + + linearize() { + const array = []; + this.traverse(node => array.push(node)); + return array; + } + + filter(predicate) { + return this.linearize().filter(predicate); + } + + find(predicate) { + return this.linearize().find(predicate); + } + + map(transform) { + return this.linearize().map(transform); + } + + addComponent(component) { + this.components.push(component); + } + + removeComponent(component) { + this.components = this.components.filter(c => c !== component); + } + + removeComponentsOfType(type) { + this.components = this.components.filter(component => !(component instanceof type)); + } + + getComponentOfType(type) { + return this.components.find(component => component instanceof type); + } + + getComponentsOfType(type) { + return this.components.filter(component => component instanceof type); + } + +} diff --git a/naloga_3/engine/core/Primitive.js b/naloga_3/engine/core/Primitive.js new file mode 100644 index 0000000..653da28 --- /dev/null +++ b/naloga_3/engine/core/Primitive.js @@ -0,0 +1,11 @@ +export class Primitive { + + constructor({ + mesh, + material, + } = {}) { + this.mesh = mesh; + this.material = material; + } + +} diff --git a/naloga_3/engine/core/Sampler.js b/naloga_3/engine/core/Sampler.js new file mode 100644 index 0000000..e8c6a3a --- /dev/null +++ b/naloga_3/engine/core/Sampler.js @@ -0,0 +1,21 @@ +export class Sampler { + + constructor({ + minFilter = 'linear', + magFilter = 'linear', + mipmapFilter = 'linear', + addressModeU = 'clamp-to-edge', + addressModeV = 'clamp-to-edge', + addressModeW = 'clamp-to-edge', + maxAnisotropy = 1, + } = {}) { + this.minFilter = minFilter; + this.magFilter = magFilter; + this.mipmapFilter = mipmapFilter; + this.addressModeU = addressModeU; + this.addressModeV = addressModeV; + this.addressModeW = addressModeW; + this.maxAnisotropy = maxAnisotropy; + } + +} diff --git a/naloga_3/engine/core/SceneUtils.js b/naloga_3/engine/core/SceneUtils.js new file mode 100644 index 0000000..594aae8 --- /dev/null +++ b/naloga_3/engine/core/SceneUtils.js @@ -0,0 +1,42 @@ +import { mat4 } from 'glm'; + +import { Camera } from './Camera.js'; +import { Model } from './Model.js'; +import { Transform } from './Transform.js'; + +export function getLocalModelMatrix(node) { + const matrix = mat4.create(); + for (const transform of node.getComponentsOfType(Transform)) { + mat4.mul(matrix, matrix, transform.matrix); + } + return matrix; +} + +export function getGlobalModelMatrix(node) { + if (node.parent) { + const parentMatrix = getGlobalModelMatrix(node.parent); + const modelMatrix = getLocalModelMatrix(node); + return mat4.multiply(parentMatrix, parentMatrix, modelMatrix); + } else { + return getLocalModelMatrix(node); + } +} + +export function getLocalViewMatrix(node) { + const matrix = getLocalModelMatrix(node); + return mat4.invert(matrix, matrix); +} + +export function getGlobalViewMatrix(node) { + const matrix = getGlobalModelMatrix(node); + return mat4.invert(matrix, matrix); +} + +export function getProjectionMatrix(node) { + const camera = node.getComponentOfType(Camera); + return camera ? camera.projectionMatrix : mat4.create(); +} + +export function getModels(node) { + return node.getComponentsOfType(Model); +} diff --git a/naloga_3/engine/core/Texture.js b/naloga_3/engine/core/Texture.js new file mode 100644 index 0000000..0412456 --- /dev/null +++ b/naloga_3/engine/core/Texture.js @@ -0,0 +1,21 @@ +export class Texture { + + constructor({ + image, + sampler, + isSRGB = false, + } = {}) { + this.image = image; + this.sampler = sampler; + this.isSRGB = isSRGB; + } + + get width() { + return this.image.width; + } + + get height() { + return this.image.height; + } + +} diff --git a/naloga_3/engine/core/Transform.js b/naloga_3/engine/core/Transform.js new file mode 100644 index 0000000..8742ff7 --- /dev/null +++ b/naloga_3/engine/core/Transform.js @@ -0,0 +1,30 @@ +import { mat4 } from 'glm'; + +export class Transform { + + constructor({ + rotation = [0, 0, 0, 1], + translation = [0, 0, 0], + scale = [1, 1, 1], + matrix, + } = {}) { + this.rotation = rotation; + this.translation = translation; + this.scale = scale; + if (matrix) { + this.matrix = matrix; + } + } + + get matrix() { + return mat4.fromRotationTranslationScale(mat4.create(), + this.rotation, this.translation, this.scale); + } + + set matrix(matrix) { + mat4.getRotation(this.rotation, matrix); + mat4.getTranslation(this.translation, matrix); + mat4.getScaling(this.scale, matrix); + } + +} diff --git a/naloga_3/engine/core/Vertex.js b/naloga_3/engine/core/Vertex.js new file mode 100644 index 0000000..8191c34 --- /dev/null +++ b/naloga_3/engine/core/Vertex.js @@ -0,0 +1,15 @@ +export class Vertex { + + constructor({ + position = [0, 0, 0], + texcoords = [0, 0], + normal = [0, 0, 0], + tangent = [0, 0, 0], + } = {}) { + this.position = position; + this.texcoords = texcoords; + this.normal = normal; + this.tangent = tangent; + } + +} diff --git a/naloga_3/engine/core/VertexUtils.js b/naloga_3/engine/core/VertexUtils.js new file mode 100644 index 0000000..47149f1 --- /dev/null +++ b/naloga_3/engine/core/VertexUtils.js @@ -0,0 +1,35 @@ +import { Accessor } from './Accessor.js'; + +export function parseFormat(format) { + const regex = /(?float|((?u|s)(?int|norm)))(?\d+)x(?\d+)/; + const groups = format.match(regex).groups; + + return { + componentType: groups.type === 'float' ? 'float' : 'int', + componentNormalized: groups.norm === 'norm', + componentSigned: groups.sign === 's', + componentSize: Number(groups.bits) / 8, + componentCount: Number(groups.count), + }; +} + +export function createVertexBuffer(vertices, layout) { + const buffer = new ArrayBuffer(layout.arrayStride * vertices.length); + const accessors = layout.attributes.map(attribute => new Accessor({ + buffer, + stride: layout.arrayStride, + ...parseFormat(attribute.format), + ...attribute, + })); + + for (let i = 0; i < vertices.length; i++) { + const vertex = vertices[i]; + for (let j = 0; j < layout.attributes.length; j++) { + const accessor = accessors[j]; + const attribute = layout.attributes[j].name; + accessor.set(i, vertex[attribute]); + } + } + + return buffer; +} diff --git a/naloga_3/engine/loaders/GLTFLoader.js b/naloga_3/engine/loaders/GLTFLoader.js new file mode 100644 index 0000000..ee0396d --- /dev/null +++ b/naloga_3/engine/loaders/GLTFLoader.js @@ -0,0 +1,483 @@ +import { + Accessor, + Camera, + Material, + Mesh, + Model, + Node, + Primitive, + Sampler, + Texture, + Transform, + Vertex, +} from '../core.js'; + +// TODO: GLB support +// TODO: accessors with no buffer views (zero-initialized) +// TODO: image from buffer view +// TODO: mipmaps +// TODO: material texcoord sets +// TODO: material alpha, doubleSided + +export class GLTFLoader { + + // Loads the GLTF JSON file and all buffers and images that it references. + // It also creates a cache for all future resource loading. + async load(url) { + this.gltfUrl = new URL(url, window.location); + this.gltf = await this.fetchJson(this.gltfUrl); + this.defaultScene = this.gltf.scene ?? 0; + this.cache = new Map(); + + await Promise.all(this.gltf.buffers?.map(buffer => this.preloadBuffer(buffer)) ?? []); + await Promise.all(this.gltf.images?.map(image => this.preloadImage(image)) ?? []); + } + + // Finds an object in list at the given index, or if the 'name' + // property matches the given name. + findByNameOrIndex(list, nameOrIndex) { + if (typeof nameOrIndex === 'number') { + return list[nameOrIndex]; + } else { + return list.find(element => element.name === nameOrIndex); + } + } + + fetchJson(url) { + return fetch(url) + .then(response => response.json()); + } + + fetchBuffer(url) { + return fetch(url) + .then(response => response.arrayBuffer()); + } + + fetchImage(url) { + return fetch(url) + .then(response => response.blob()) + .then(blob => createImageBitmap(blob)); + } + + async preloadImage(gltfSpec) { + if (this.cache.has(gltfSpec)) { + return this.cache.get(gltfSpec); + } + + if (gltfSpec.uri) { + const url = new URL(gltfSpec.uri, this.gltfUrl); + const image = await this.fetchImage(url); + this.cache.set(gltfSpec, image); + return image; + } else { + const bufferView = this.gltf.bufferViews[gltfSpec.bufferView]; + const buffer = this.loadBuffer(bufferView.buffer); + const dataView = new DataView(buffer, bufferView.byteOffset ?? 0, bufferView.byteLength); + const blob = new Blob([dataView], { type: gltfSpec.mimeType }); + const url = URL.createObjectURL(blob); + const image = await this.fetchImage(url); + URL.revokeObjectURL(url); + this.cache.set(gltfSpec, image); + return image; + } + } + + async preloadBuffer(gltfSpec) { + if (this.cache.has(gltfSpec)) { + return this.cache.get(gltfSpec); + } + + const url = new URL(gltfSpec.uri, this.gltfUrl); + const buffer = await this.fetchBuffer(url); + this.cache.set(gltfSpec, buffer); + return buffer; + } + + loadImage(nameOrIndex) { + const gltfSpec = this.findByNameOrIndex(this.gltf.images, nameOrIndex); + if (!gltfSpec) { + return null; + } + + return this.cache.get(gltfSpec); + } + + loadBuffer(nameOrIndex) { + const gltfSpec = this.findByNameOrIndex(this.gltf.buffers, nameOrIndex); + if (!gltfSpec) { + return null; + } + + return this.cache.get(gltfSpec); + } + + loadSampler(nameOrIndex) { + const gltfSpec = this.findByNameOrIndex(this.gltf.samplers, nameOrIndex); + if (!gltfSpec) { + return null; + } + if (this.cache.has(gltfSpec)) { + return this.cache.get(gltfSpec); + } + + const minFilter = { + 9728: 'nearest', + 9729: 'linear', + 9984: 'nearest', + 9985: 'linear', + 9986: 'nearest', + 9987: 'linear', + }; + + const magFilter = { + 9728: 'nearest', + 9729: 'linear', + }; + + const mipmapFilter = { + 9728: 'nearest', + 9729: 'linear', + 9984: 'nearest', + 9985: 'nearest', + 9986: 'linear', + 9987: 'linear', + }; + + const addressMode = { + 33071: 'clamp-to-edge', + 33648: 'mirror-repeat', + 10497: 'repeat', + }; + + const sampler = new Sampler({ + minFilter: minFilter[gltfSpec.minFilter ?? 9729], + magFilter: magFilter[gltfSpec.magFilter ?? 9729], + mipmapFilter: mipmapFilter[gltfSpec.minFilter ?? 9729], + addressModeU: addressMode[gltfSpec.wrapS ?? 10497], + addressModeV: addressMode[gltfSpec.wrapT ?? 10497], + }); + + this.cache.set(gltfSpec, sampler); + return sampler; + } + + loadTexture(nameOrIndex) { + const gltfSpec = this.findByNameOrIndex(this.gltf.textures, nameOrIndex); + if (!gltfSpec) { + return null; + } + if (this.cache.has(gltfSpec)) { + return this.cache.get(gltfSpec); + } + + const options = {}; + if (gltfSpec.source !== undefined) { + options.image = this.loadImage(gltfSpec.source); + } + if (gltfSpec.sampler !== undefined) { + options.sampler = this.loadSampler(gltfSpec.sampler); + } else { + options.sampler = new Sampler(); + } + + const texture = new Texture(options); + + this.cache.set(gltfSpec, texture); + return texture; + } + + loadMaterial(nameOrIndex) { + const gltfSpec = this.findByNameOrIndex(this.gltf.materials, nameOrIndex); + if (!gltfSpec) { + return null; + } + if (this.cache.has(gltfSpec)) { + return this.cache.get(gltfSpec); + } + + const options = {}; + const pbr = gltfSpec.pbrMetallicRoughness; + if (pbr) { + if (pbr.baseColorTexture) { + options.baseTexture = this.loadTexture(pbr.baseColorTexture.index); + options.baseTexture.isSRGB = true; + } + if (pbr.metallicRoughnessTexture) { + options.metalnessTexture = this.loadTexture(pbr.metallicRoughnessTexture.index); + options.roughnessTexture = this.loadTexture(pbr.metallicRoughnessTexture.index); + } + options.baseFactor = pbr.baseColorFactor; + options.metalnessFactor = pbr.metallicFactor; + options.roughnessFactor = pbr.roughnessFactor; + } + + if (gltfSpec.normalTexture) { + options.normalTexture = this.loadTexture(gltfSpec.normalTexture.index); + options.normalFactor = gltfSpec.normalTexture.scale; + } + + if (gltfSpec.emissiveTexture) { + options.emissionTexture = this.loadTexture(gltfSpec.emissiveTexture.index); + options.emissionTexture.isSRGB = true; + options.emissionFactor = gltfSpec.emissiveFactor; + } + + if (gltfSpec.occlusionTexture) { + options.occlusionTexture = this.loadTexture(gltfSpec.occlusionTexture.index); + options.occlusionFactor = gltfSpec.occlusionTexture.strength; + } + + const material = new Material(options); + + this.cache.set(gltfSpec, material); + return material; + } + + loadAccessor(nameOrIndex) { + const gltfSpec = this.findByNameOrIndex(this.gltf.accessors, nameOrIndex); + if (!gltfSpec) { + return null; + } + if (this.cache.has(gltfSpec)) { + return this.cache.get(gltfSpec); + } + + if (gltfSpec.bufferView === undefined) { + console.warn('Accessor does not reference a buffer view'); + return null; + } + + const bufferView = this.gltf.bufferViews[gltfSpec.bufferView]; + const buffer = this.loadBuffer(bufferView.buffer); + + const componentType = { + 5120: 'int', + 5121: 'int', + 5122: 'int', + 5123: 'int', + 5124: 'int', + 5125: 'int', + 5126: 'float', + }[gltfSpec.componentType]; + + const componentSize = { + 5120: 1, + 5121: 1, + 5122: 2, + 5123: 2, + 5124: 4, + 5125: 4, + 5126: 4, + }[gltfSpec.componentType]; + + const componentSigned = { + 5120: true, + 5121: false, + 5122: true, + 5123: false, + 5124: true, + 5125: false, + 5126: false, + }[gltfSpec.componentType]; + + const componentCount = { + SCALAR: 1, + VEC2: 2, + VEC3: 3, + VEC4: 4, + MAT2: 4, + MAT3: 9, + MAT4: 16, + }[gltfSpec.type]; + + const componentNormalized = gltfSpec.normalized ?? false; + + const stride = bufferView.byteStride ?? (componentSize * componentCount); + const offset = gltfSpec.byteOffset ?? 0; + const viewOffset = bufferView.byteOffset ?? 0; + const viewLength = bufferView.byteLength; + + const accessor = new Accessor({ + buffer, + viewLength, + viewOffset, + offset, + stride, + + componentType, + componentCount, + componentSize, + componentSigned, + componentNormalized, + }); + + this.cache.set(gltfSpec, accessor); + return accessor; + } + + createMeshFromPrimitive(spec) { + if (spec.attributes.POSITION === undefined) { + console.warn('No position in mesh'); + return new Mesh(); + } + + if (spec.indices === undefined) { + console.warn('No indices in mesh'); + return new Mesh(); + } + + const accessors = {}; + for (const attribute in spec.attributes) { + accessors[attribute] = this.loadAccessor(spec.attributes[attribute]); + } + + const position = accessors.POSITION; + const texcoords = accessors.TEXCOORD_0; + const normal = accessors.NORMAL; + const tangent = accessors.TANGENT; + + const vertexCount = position.count; + const vertices = []; + + for (let i = 0; i < vertexCount; i++) { + const options = {}; + + if (position) { options.position = position.get(i); } + if (texcoords) { options.texcoords = texcoords.get(i); } + if (normal) { options.normal = normal.get(i); } + if (tangent) { options.tangent = tangent.get(i); } + + vertices.push(new Vertex(options)); + } + + const indices = []; + const indicesAccessor = this.loadAccessor(spec.indices); + const indexCount = indicesAccessor.count; + + for (let i = 0; i < indexCount; i++) { + indices.push(indicesAccessor.get(i)); + } + + return new Mesh({ vertices, indices }); + } + + loadMesh(nameOrIndex) { + const gltfSpec = this.findByNameOrIndex(this.gltf.meshes, nameOrIndex); + if (!gltfSpec) { + return null; + } + if (this.cache.has(gltfSpec)) { + return this.cache.get(gltfSpec); + } + + const primitives = []; + for (const primitiveSpec of gltfSpec.primitives) { + if (primitiveSpec.mode !== 4 && primitiveSpec.mode !== undefined) { + console.warn(`GLTFLoader: skipping primitive with mode ${primitiveSpec.mode}`); + continue; + } + + const options = {}; + options.mesh = this.createMeshFromPrimitive(primitiveSpec); + + if (primitiveSpec.material !== undefined) { + options.material = this.loadMaterial(primitiveSpec.material); + } + + primitives.push(new Primitive(options)); + } + + const model = new Model({ primitives }); + + this.cache.set(gltfSpec, model); + return model; + } + + loadCamera(nameOrIndex) { + const gltfSpec = this.findByNameOrIndex(this.gltf.cameras, nameOrIndex); + if (!gltfSpec) { + return null; + } + if (this.cache.has(gltfSpec)) { + return this.cache.get(gltfSpec); + } + + const options = {}; + if (gltfSpec.type === 'perspective') { + const { aspectRatio, yfov, znear, zfar } = gltfSpec.perspective; + Object.assign(options, { + orthographic: 0, + aspect: aspectRatio, + fovy: yfov, + near: znear, + far: zfar, + }); + } else if (gltfSpec.type === 'orthographic') { + const { xmag, ymag, znear, zfar } = gltfSpec.orthographic; + Object.assign(options, { + orthographic: 1, + aspect: xmag / ymag, + halfy: ymag, + near: znear, + far: zfar, + }); + } + + const camera = new Camera(options); + + this.cache.set(gltfSpec, camera); + return camera; + } + + loadNode(nameOrIndex) { + const gltfSpec = this.findByNameOrIndex(this.gltf.nodes, nameOrIndex); + if (!gltfSpec) { + return null; + } + if (this.cache.has(gltfSpec)) { + return this.cache.get(gltfSpec); + } + + const node = new Node(); + + node.addComponent(new Transform(gltfSpec)); + + if (gltfSpec.children) { + for (const childIndex of gltfSpec.children) { + node.addChild(this.loadNode(childIndex)); + } + } + + if (gltfSpec.camera !== undefined) { + node.addComponent(this.loadCamera(gltfSpec.camera)); + } + + if (gltfSpec.mesh !== undefined) { + node.addComponent(this.loadMesh(gltfSpec.mesh)); + } + + this.cache.set(gltfSpec, node); + return node; + } + + loadScene(nameOrIndex) { + const gltfSpec = this.findByNameOrIndex(this.gltf.scenes, nameOrIndex); + if (!gltfSpec) { + return null; + } + if (this.cache.has(gltfSpec)) { + return this.cache.get(gltfSpec); + } + + const scene = new Node(); + if (gltfSpec.nodes) { + for (const nodeIndex of gltfSpec.nodes) { + scene.addChild(this.loadNode(nodeIndex)); + } + } + + this.cache.set(gltfSpec, scene); + return scene; + } + +} diff --git a/naloga_3/engine/loaders/ImageLoader.js b/naloga_3/engine/loaders/ImageLoader.js new file mode 100644 index 0000000..b22ef5b --- /dev/null +++ b/naloga_3/engine/loaders/ImageLoader.js @@ -0,0 +1,10 @@ +export class ImageLoader { + + async load(url) { + const response = await fetch(url); + const blob = await response.blob(); + const imageBitmap = await createImageBitmap(blob); + return imageBitmap; + } + +} diff --git a/naloga_3/engine/loaders/JSONLoader.js b/naloga_3/engine/loaders/JSONLoader.js new file mode 100644 index 0000000..1205bbc --- /dev/null +++ b/naloga_3/engine/loaders/JSONLoader.js @@ -0,0 +1,24 @@ +import { Mesh, Vertex } from '../core.js'; + +export class JSONLoader { + + async loadMesh(url) { + const response = await fetch(url); + const json = await response.json(); + + const vertices = []; + const vertexCount = json.positions.length / 3; + for (let i = 0; i < vertexCount; i++) { + const position = json?.positions?.slice(i * 3, (i + 1) * 3); + const texcoords = json?.texcoords?.slice(i * 2, (i + 1) * 2); + const normal = json?.normals?.slice(i * 3, (i + 1) * 3); + const tangent = json?.tangents?.slice(i * 3, (i + 1) * 3); + vertices.push(new Vertex({ position, texcoords, normal, tangent })); + } + + const indices = json.indices; + + return new Mesh({ vertices, indices }); + } + +} diff --git a/naloga_3/engine/loaders/OBJLoader.js b/naloga_3/engine/loaders/OBJLoader.js new file mode 100644 index 0000000..a2d1c71 --- /dev/null +++ b/naloga_3/engine/loaders/OBJLoader.js @@ -0,0 +1,70 @@ +import { Mesh, Vertex } from '../core.js'; + +export class OBJLoader { + + async loadMesh(url) { + const response = await fetch(url); + const text = await response.text(); + + const lines = text.split('\n'); + + const vRegex = /v\s+(\S+)\s+(\S+)\s+(\S+)\s*/; + const vData = lines + .filter(line => vRegex.test(line)) + .map(line => [...line.match(vRegex)].slice(1)) + .map(entry => entry.map(entry => Number(entry))); + + const vnRegex = /vn\s+(\S+)\s+(\S+)\s+(\S+)\s*/; + const vnData = lines + .filter(line => vnRegex.test(line)) + .map(line => [...line.match(vnRegex)].slice(1)) + .map(entry => entry.map(entry => Number(entry))); + + const vtRegex = /vt\s+(\S+)\s+(\S+)\s*/; + const vtData = lines + .filter(line => vtRegex.test(line)) + .map(line => [...line.match(vtRegex)].slice(1)) + .map(entry => entry.map(entry => Number(entry))); + + function triangulate(list) { + const triangles = []; + for (let i = 2; i < list.length; i++) { + triangles.push(list[0], list[i - 1], list[i]); + } + return triangles; + } + + const fRegex = /f\s+(.*)/; + const fData = lines + .filter(line => fRegex.test(line)) + .map(line => line.match(fRegex)[1]) + .map(line => line.trim().split(/\s+/)) + .flatMap(face => triangulate(face)); + + const vertices = []; + const indices = []; + const cache = {}; + let cacheLength = 0; + const indicesRegex = /(\d+)(\/(\d+))?(\/(\d+))?/; + + for (const id of fData) { + if (id in cache) { + indices.push(cache[id]); + } else { + cache[id] = cacheLength; + indices.push(cacheLength); + const [,vIndex,,vtIndex,,vnIndex] = [...id.match(indicesRegex)] + .map(entry => Number(entry) - 1); + vertices.push(new Vertex({ + position: vData[vIndex], + normal: vnData[vnIndex], + texcoords: vtData[vtIndex], + })); + cacheLength++; + } + } + + return new Mesh({ vertices, indices }); + } + +} diff --git a/naloga_3/engine/renderers/BaseRenderer.js b/naloga_3/engine/renderers/BaseRenderer.js new file mode 100644 index 0000000..4be22d2 --- /dev/null +++ b/naloga_3/engine/renderers/BaseRenderer.js @@ -0,0 +1,75 @@ +import { mat4 } from 'glm'; + +import * as WebGPU from '../WebGPU.js'; + +import { createVertexBuffer } from '../core/VertexUtils.js'; + +export class BaseRenderer { + + constructor(canvas) { + this.canvas = canvas; + this.gpuObjects = new WeakMap(); + } + + async initialize() { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + const context = this.canvas.getContext('webgpu'); + const format = navigator.gpu.getPreferredCanvasFormat(); + context.configure({ device, format }); + + this.device = device; + this.context = context; + this.format = format; + } + + prepareImage(image, isSRGB = false) { + if (this.gpuObjects.has(image)) { + return this.gpuObjects.get(image); + } + + const gpuTexture = WebGPU.createTexture(this.device, { + source: image, + format: isSRGB ? 'rgba8unorm-srgb' : 'rgba8unorm', + }); + + const gpuObjects = { gpuTexture }; + this.gpuObjects.set(image, gpuObjects); + return gpuObjects; + } + + prepareSampler(sampler) { + if (this.gpuObjects.has(sampler)) { + return this.gpuObjects.get(sampler); + } + + const gpuSampler = this.device.createSampler(sampler); + + const gpuObjects = { gpuSampler }; + this.gpuObjects.set(sampler, gpuObjects); + return gpuObjects; + } + + prepareMesh(mesh, layout) { + if (this.gpuObjects.has(mesh)) { + return this.gpuObjects.get(mesh); + } + + const vertexBufferArrayBuffer = createVertexBuffer(mesh.vertices, layout); + const vertexBuffer = WebGPU.createBuffer(this.device, { + data: vertexBufferArrayBuffer, + usage: GPUBufferUsage.VERTEX, + }); + + const indexBufferArrayBuffer = new Uint32Array(mesh.indices).buffer; + const indexBuffer = WebGPU.createBuffer(this.device, { + data: indexBufferArrayBuffer, + usage: GPUBufferUsage.INDEX, + }); + + const gpuObjects = { vertexBuffer, indexBuffer }; + this.gpuObjects.set(mesh, gpuObjects); + return gpuObjects; + } + +} diff --git a/naloga_3/engine/renderers/UnlitRenderer.js b/naloga_3/engine/renderers/UnlitRenderer.js new file mode 100644 index 0000000..740ccbd --- /dev/null +++ b/naloga_3/engine/renderers/UnlitRenderer.js @@ -0,0 +1,236 @@ +import { mat4 } from 'glm'; + +import * as WebGPU from '../WebGPU.js'; + +import { Camera } from '../core.js'; + +import { + getLocalModelMatrix, + getGlobalViewMatrix, + getProjectionMatrix, + getModels, +} from '../core/SceneUtils.js'; + +import { BaseRenderer } from './BaseRenderer.js'; + +const vertexBufferLayout = { + arrayStride: 20, + attributes: [ + { + name: 'position', + shaderLocation: 0, + offset: 0, + format: 'float32x3', + }, + { + name: 'texcoords', + shaderLocation: 1, + offset: 12, + format: 'float32x2', + }, + ], +}; + +export class UnlitRenderer extends BaseRenderer { + + constructor(canvas) { + super(canvas); + } + + async initialize() { + await super.initialize(); + + const code = await fetch(new URL('UnlitRenderer.wgsl', import.meta.url)) + .then(response => response.text()); + const module = this.device.createShaderModule({ code }); + + this.pipeline = await this.device.createRenderPipelineAsync({ + layout: 'auto', + vertex: { + module, + entryPoint: 'vertex', + buffers: [ vertexBufferLayout ], + }, + fragment: { + module, + entryPoint: 'fragment', + targets: [{ format: this.format }], + }, + depthStencil: { + format: 'depth24plus', + depthWriteEnabled: true, + depthCompare: 'less', + }, + }); + + this.recreateDepthTexture(); + } + + recreateDepthTexture() { + this.depthTexture?.destroy(); + this.depthTexture = this.device.createTexture({ + format: 'depth24plus', + size: [this.canvas.width, this.canvas.height], + usage: GPUTextureUsage.RENDER_ATTACHMENT, + }); + } + + prepareNode(node) { + if (this.gpuObjects.has(node)) { + return this.gpuObjects.get(node); + } + + const modelUniformBuffer = this.device.createBuffer({ + size: 128, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); + + const modelBindGroup = this.device.createBindGroup({ + layout: this.pipeline.getBindGroupLayout(1), + entries: [ + { binding: 0, resource: { buffer: modelUniformBuffer } }, + ], + }); + + const gpuObjects = { modelUniformBuffer, modelBindGroup }; + this.gpuObjects.set(node, gpuObjects); + return gpuObjects; + } + + prepareCamera(camera) { + if (this.gpuObjects.has(camera)) { + return this.gpuObjects.get(camera); + } + + const cameraUniformBuffer = this.device.createBuffer({ + size: 128, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); + + const cameraBindGroup = this.device.createBindGroup({ + layout: this.pipeline.getBindGroupLayout(0), + entries: [ + { binding: 0, resource: { buffer: cameraUniformBuffer } }, + ], + }); + + const gpuObjects = { cameraUniformBuffer, cameraBindGroup }; + this.gpuObjects.set(camera, gpuObjects); + return gpuObjects; + } + + prepareTexture(texture) { + if (this.gpuObjects.has(texture)) { + return this.gpuObjects.get(texture); + } + + const { gpuTexture } = this.prepareImage(texture.image); // ignore sRGB + const { gpuSampler } = this.prepareSampler(texture.sampler); + + const gpuObjects = { gpuTexture, gpuSampler }; + this.gpuObjects.set(texture, gpuObjects); + return gpuObjects; + } + + prepareMaterial(material) { + if (this.gpuObjects.has(material)) { + return this.gpuObjects.get(material); + } + + const baseTexture = this.prepareTexture(material.baseTexture); + + const materialUniformBuffer = this.device.createBuffer({ + size: 16, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); + + const materialBindGroup = this.device.createBindGroup({ + layout: this.pipeline.getBindGroupLayout(2), + entries: [ + { binding: 0, resource: { buffer: materialUniformBuffer } }, + { binding: 1, resource: baseTexture.gpuTexture.createView() }, + { binding: 2, resource: baseTexture.gpuSampler }, + ], + }); + + const gpuObjects = { materialUniformBuffer, materialBindGroup }; + this.gpuObjects.set(material, gpuObjects); + return gpuObjects; + } + + render(scene, camera) { + if (this.depthTexture.width !== this.canvas.width || this.depthTexture.height !== this.canvas.height) { + this.recreateDepthTexture(); + } + + const encoder = this.device.createCommandEncoder(); + this.renderPass = encoder.beginRenderPass({ + colorAttachments: [ + { + view: this.context.getCurrentTexture().createView(), + clearValue: [1, 1, 1, 1], + loadOp: 'clear', + storeOp: 'store', + }, + ], + depthStencilAttachment: { + view: this.depthTexture.createView(), + depthClearValue: 1, + depthLoadOp: 'clear', + depthStoreOp: 'discard', + }, + }); + this.renderPass.setPipeline(this.pipeline); + + const cameraComponent = camera.getComponentOfType(Camera); + const viewMatrix = getGlobalViewMatrix(camera); + const projectionMatrix = getProjectionMatrix(camera); + const { cameraUniformBuffer, cameraBindGroup } = this.prepareCamera(cameraComponent); + this.device.queue.writeBuffer(cameraUniformBuffer, 0, viewMatrix); + this.device.queue.writeBuffer(cameraUniformBuffer, 64, projectionMatrix); + this.renderPass.setBindGroup(0, cameraBindGroup); + + this.renderNode(scene); + + this.renderPass.end(); + this.device.queue.submit([encoder.finish()]); + } + + renderNode(node, modelMatrix = mat4.create()) { + const localMatrix = getLocalModelMatrix(node); + modelMatrix = mat4.multiply(mat4.create(), modelMatrix, localMatrix); + + const { modelUniformBuffer, modelBindGroup } = this.prepareNode(node); + const normalMatrix = mat4.normalFromMat4(mat4.create(), modelMatrix); + this.device.queue.writeBuffer(modelUniformBuffer, 0, modelMatrix); + this.device.queue.writeBuffer(modelUniformBuffer, 64, normalMatrix); + this.renderPass.setBindGroup(1, modelBindGroup); + + for (const model of getModels(node)) { + this.renderModel(model); + } + + for (const child of node.children) { + this.renderNode(child, modelMatrix); + } + } + + renderModel(model) { + for (const primitive of model.primitives) { + this.renderPrimitive(primitive); + } + } + + renderPrimitive(primitive) { + const { materialUniformBuffer, materialBindGroup } = this.prepareMaterial(primitive.material); + this.device.queue.writeBuffer(materialUniformBuffer, 0, new Float32Array(primitive.material.baseFactor)); + this.renderPass.setBindGroup(2, materialBindGroup); + + const { vertexBuffer, indexBuffer } = this.prepareMesh(primitive.mesh, vertexBufferLayout); + this.renderPass.setVertexBuffer(0, vertexBuffer); + this.renderPass.setIndexBuffer(indexBuffer, 'uint32'); + + this.renderPass.drawIndexed(primitive.mesh.indices.length); + } + +} diff --git a/naloga_3/engine/renderers/UnlitRenderer.wgsl b/naloga_3/engine/renderers/UnlitRenderer.wgsl new file mode 100644 index 0000000..21e8598 --- /dev/null +++ b/naloga_3/engine/renderers/UnlitRenderer.wgsl @@ -0,0 +1,56 @@ +struct VertexInput { + @location(0) position: vec3f, + @location(1) texcoords: vec2f, +} + +struct VertexOutput { + @builtin(position) position: vec4f, + @location(1) texcoords: vec2f, +} + +struct FragmentInput { + @location(1) texcoords: vec2f, +} + +struct FragmentOutput { + @location(0) color: vec4f, +} + +struct CameraUniforms { + viewMatrix: mat4x4f, + projectionMatrix: mat4x4f, +} + +struct ModelUniforms { + modelMatrix: mat4x4f, + normalMatrix: mat3x3f, +} + +struct MaterialUniforms { + baseFactor: vec4f, +} + +@group(0) @binding(0) var camera: CameraUniforms; +@group(1) @binding(0) var model: ModelUniforms; +@group(2) @binding(0) var material: MaterialUniforms; +@group(2) @binding(1) var baseTexture: texture_2d; +@group(2) @binding(2) var baseSampler: sampler; + +@vertex +fn vertex(input: VertexInput) -> VertexOutput { + var output: VertexOutput; + + output.position = camera.projectionMatrix * camera.viewMatrix * model.modelMatrix * vec4(input.position, 1); + output.texcoords = input.texcoords; + + return output; +} + +@fragment +fn fragment(input: FragmentInput) -> FragmentOutput { + var output: FragmentOutput; + + output.color = textureSample(baseTexture, baseSampler, input.texcoords) * material.baseFactor; + + return output; +} diff --git a/naloga_3/engine/style.css b/naloga_3/engine/style.css new file mode 100644 index 0000000..0df89ea --- /dev/null +++ b/naloga_3/engine/style.css @@ -0,0 +1,56 @@ +body, html { + margin: 0; + padding: 0; +} + +* { + font-family: sans-serif; +} + +.fullscreen { + width: 100vw; + height: 100vh; + overflow: hidden; +} + +.fullscreen > * { + width: 100%; + height: 100%; +} + +.overlay { + position: fixed; + left: 0; + top: 0; +} + +.no-touch { + touch-action: none; +} + +.pixelated { + image-rendering: pixelated; +} + +.loader-container { + display: flex; + align-items: center; + justify-content: center; +} + +.loader { + width: 100px; + height: 100px; + + border: 15px solid transparent; + border-radius: 50%; + border-top-color: #999; + border-bottom-color: #999; + + animation: spin 2s ease-in-out infinite; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(1800deg); } +} diff --git a/naloga_3/engine/systems/ResizeSystem.js b/naloga_3/engine/systems/ResizeSystem.js new file mode 100644 index 0000000..3ca6730 --- /dev/null +++ b/naloga_3/engine/systems/ResizeSystem.js @@ -0,0 +1,84 @@ +export class ResizeSystem { + + constructor({ + canvas, + resize, + resolutionFactor = 1, + minWidth = 1, + minHeight = 1, + maxWidth = Infinity, + maxHeight = Infinity, + } = {}) { + this._resize = this._resize.bind(this); + + this.canvas = canvas; + this.resize = resize; + + this.resolutionFactor = resolutionFactor; + this.minCanvasSize = { + width: minWidth, + height: minHeight, + }; + this.maxCanvasSize = { + width: maxWidth, + height: maxHeight, + }; + this.lastSize = { + width: null, + height: null, + }; + } + + start() { + if (this._resizeFrame) { + return; + } + + this._resizeFrame = requestAnimationFrame(this._resize); + } + + stop() { + if (!this._resizeFrame) { + return; + } + + this._resizeFrame = cancelAnimationFrame(this._resizeFrame); + } + + _resize() { + this._resizeFrame = requestAnimationFrame(this._resize); + + const displayRect = this.canvas.getBoundingClientRect(); + if (displayRect.width === this.lastSize.width && displayRect.height === this.lastSize.height) { + return; + } + + this.lastSize = { + width: displayRect.width, + height: displayRect.height, + }; + + const displaySize = { + width: displayRect.width * devicePixelRatio, + height: displayRect.height * devicePixelRatio, + }; + + const unclampedSize = { + width: Math.round(displaySize.width * this.resolutionFactor), + height: Math.round(displaySize.height * this.resolutionFactor), + }; + + const canvasSize = { + width: Math.min(Math.max(unclampedSize.width, this.minCanvasSize.width), this.maxCanvasSize.width), + height: Math.min(Math.max(unclampedSize.height, this.minCanvasSize.height), this.maxCanvasSize.height), + }; + + if (this.canvas.width !== canvasSize.width || this.canvas.height !== canvasSize.height) { + this.canvas.width = canvasSize.width; + this.canvas.height = canvasSize.height; + } + + this.resize?.({ displaySize, canvasSize }); + } + +} diff --git a/naloga_3/engine/systems/UpdateSystem.js b/naloga_3/engine/systems/UpdateSystem.js new file mode 100644 index 0000000..f64a70d --- /dev/null +++ b/naloga_3/engine/systems/UpdateSystem.js @@ -0,0 +1,49 @@ +export class UpdateSystem { + + constructor(application) { + this._update = this._update.bind(this); + this._render = this._render.bind(this); + + this.application = application; + this.running = false; + } + + start() { + if (this.running) { + return; + } + + this.application.start?.(); + + this._time = performance.now() / 1000; + + this._updateFrame = setInterval(this._update, 0); + this._renderFrame = requestAnimationFrame(this._render); + } + + stop() { + if (!this.running) { + return; + } + + this.application.stop?.(); + + this._updateFrame = clearInterval(this._updateFrame); + this._renderFrame = cancelAnimationFrame(this._render); + } + + _update() { + const time = performance.now() / 1000; + const dt = time - this._time; + this._time = time; + + this.application.update?.(time, dt); + } + + _render() { + this._renderFrame = requestAnimationFrame(this._render); + + this.application.render?.(); + } + +} diff --git a/naloga_3/index.html b/naloga_3/index.html new file mode 100644 index 0000000..cc1ffb3 --- /dev/null +++ b/naloga_3/index.html @@ -0,0 +1,23 @@ + + + + + Naloga 3 + + + + + +
+ +
+ + diff --git a/naloga_3/lib/dat.js b/naloga_3/lib/dat.js new file mode 100644 index 0000000..628bfd7 --- /dev/null +++ b/naloga_3/lib/dat.js @@ -0,0 +1,22 @@ +function xe(n){if(n&&!(typeof window>"u")){var e=document.createElement("style");return e.setAttribute("type","text/css"),e.innerHTML=n,document.head.appendChild(e),n}}function B(n,e){var t=n.__state.conversionName.toString(),i=Math.round(n.r),o=Math.round(n.g),r=Math.round(n.b),d=n.a,l=Math.round(n.h),u=n.s.toFixed(1),f=n.v.toFixed(1);if(e||t==="THREE_CHAR_HEX"||t==="SIX_CHAR_HEX"){for(var m=n.hex.toString(16);m.length<6;)m="0"+m;return"#"+m}else{if(t==="CSS_RGB")return"rgb("+i+","+o+","+r+")";if(t==="CSS_RGBA")return"rgba("+i+","+o+","+r+","+d+")";if(t==="HEX")return"0x"+n.hex.toString(16);if(t==="RGB_ARRAY")return"["+i+","+o+","+r+"]";if(t==="RGBA_ARRAY")return"["+i+","+o+","+r+","+d+"]";if(t==="RGB_OBJ")return"{r:"+i+",g:"+o+",b:"+r+"}";if(t==="RGBA_OBJ")return"{r:"+i+",g:"+o+",b:"+r+",a:"+d+"}";if(t==="HSV_OBJ")return"{h:"+l+",s:"+u+",v:"+f+"}";if(t==="HSVA_OBJ")return"{h:"+l+",s:"+u+",v:"+f+",a:"+d+"}"}return"unknown format"}var re=Array.prototype.forEach,H=Array.prototype.slice,s={BREAK:{},extend:function(e){return this.each(H.call(arguments,1),function(t){var i=this.isObject(t)?Object.keys(t):[];i.forEach(function(o){this.isUndefined(t[o])||(e[o]=t[o])}.bind(this))},this),e},defaults:function(e){return this.each(H.call(arguments,1),function(t){var i=this.isObject(t)?Object.keys(t):[];i.forEach(function(o){this.isUndefined(e[o])&&(e[o]=t[o])}.bind(this))},this),e},compose:function(){var e=H.call(arguments);return function(){for(var t=H.call(arguments),i=e.length-1;i>=0;i--)t=[e[i].apply(this,t)];return t[0]}},each:function(e,t,i){if(e){if(re&&e.forEach&&e.forEach===re)e.forEach(t,i);else if(e.length===e.length+0){var o=void 0,r=void 0;for(o=0,r=e.length;o1?s.toArray(arguments):arguments[0];return s.each(Ce,function(t){if(t.litmus(e))return s.each(t.conversions,function(i,o){if(D=i.read(e),G===!1&&D!==!1)return G=D,D.conversionName=o,D.conversion=i,s.BREAK}),s.BREAK}),G},ae=void 0,M={hsv_to_rgb:function(e,t,i){var o=Math.floor(e/60)%6,r=e/60-Math.floor(e/60),d=i*(1-t),l=i*(1-r*t),u=i*(1-(1-r)*t),f=[[i,u,d],[l,i,d],[d,i,u],[d,l,i],[u,d,i],[i,d,l]][o];return{r:f[0]*255,g:f[1]*255,b:f[2]*255}},rgb_to_hsv:function(e,t,i){var o=Math.min(e,t,i),r=Math.max(e,t,i),d=r-o,l=void 0,u=void 0;if(r!==0)u=d/r;else return{h:NaN,s:0,v:0};return e===r?l=(t-i)/d:t===r?l=2+(i-e)/d:l=4+(e-t)/d,l/=6,l<0&&(l+=1),{h:l*360,s:u,v:r/255}},rgb_to_hex:function(e,t,i){var o=this.hex_with_component(0,2,e);return o=this.hex_with_component(o,1,t),o=this.hex_with_component(o,0,i),o},component_from_hex:function(e,t){return e>>t*8&255},hex_with_component:function(e,t,i){return i<<(ae=t*8)|e&~(255<-1?e.length-e.indexOf(".")-1:0}var ne=function(n){A(e,n);function e(t,i,o){w(this,e);var r=S(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t,i)),d=o||{};return r.__min=d.min,r.__max=d.max,r.__step=d.step,s.isUndefined(r.__step)?r.initialValue===0?r.__impliedStep=1:r.__impliedStep=Math.pow(10,Math.floor(Math.log(Math.abs(r.initialValue))/Math.LN10))/10:r.__impliedStep=r.__step,r.__precision=se(r.__impliedStep),r}return x(e,[{key:"setValue",value:function(i){var o=i;return this.__min!==void 0&&othis.__max&&(o=this.__max),this.__step!==void 0&&o%this.__step!==0&&(o=Math.round(o/this.__step)*this.__step),E(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"setValue",this).call(this,o)}},{key:"min",value:function(i){return this.__min=i,this}},{key:"max",value:function(i){return this.__max=i,this}},{key:"step",value:function(i){return this.__step=i,this.__impliedStep=i,this.__precision=se(i),this}}]),e}(k);function ke(n,e){var t=Math.pow(10,e);return Math.round(n*t)/t}var z=function(n){A(e,n);function e(t,i,o){w(this,e);var r=S(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t,i,o));r.__truncationSuspended=!1;var d=r,l=void 0;function u(){var b=parseFloat(d.__input.value);s.isNaN(b)||d.setValue(b)}function f(){d.__onFinishChange&&d.__onFinishChange.call(d,d.getValue())}function m(){f()}function c(b){var _=l-b.clientY;d.setValue(d.getValue()+_*d.__impliedStep),l=b.clientY}function h(){a.unbind(window,"mousemove",c),a.unbind(window,"mouseup",h),f()}function y(b){a.bind(window,"mousemove",c),a.bind(window,"mouseup",h),l=b.clientY}return r.__input=document.createElement("input"),r.__input.setAttribute("type","text"),a.bind(r.__input,"change",u),a.bind(r.__input,"blur",m),a.bind(r.__input,"mousedown",y),a.bind(r.__input,"keydown",function(b){b.keyCode===13&&(d.__truncationSuspended=!0,this.blur(),d.__truncationSuspended=!1,f())}),r.updateDisplay(),r.domElement.appendChild(r.__input),r}return x(e,[{key:"updateDisplay",value:function(){return this.__input.value=this.__truncationSuspended?this.getValue():ke(this.getValue(),this.__precision),E(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"updateDisplay",this).call(this)}}]),e}(ne);function de(n,e,t,i,o){return i+(o-i)*((n-e)/(t-e))}var j=function(n){A(e,n);function e(t,i,o,r,d){w(this,e);var l=S(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t,i,{min:o,max:r,step:d})),u=l;l.__background=document.createElement("div"),l.__foreground=document.createElement("div"),a.bind(l.__background,"mousedown",f),a.bind(l.__background,"touchstart",h),a.addClass(l.__background,"slider"),a.addClass(l.__foreground,"slider-fg");function f(_){document.activeElement.blur(),a.bind(window,"mousemove",m),a.bind(window,"mouseup",c),m(_)}function m(_){_.preventDefault();var v=u.__background.getBoundingClientRect();return u.setValue(de(_.clientX,v.left,v.right,u.__min,u.__max)),!1}function c(){a.unbind(window,"mousemove",m),a.unbind(window,"mouseup",c),u.__onFinishChange&&u.__onFinishChange.call(u,u.getValue())}function h(_){_.touches.length===1&&(a.bind(window,"touchmove",y),a.bind(window,"touchend",b),y(_))}function y(_){var v=_.touches[0].clientX,O=u.__background.getBoundingClientRect();u.setValue(de(v,O.left,O.right,u.__min,u.__max))}function b(){a.unbind(window,"touchmove",y),a.unbind(window,"touchend",b),u.__onFinishChange&&u.__onFinishChange.call(u,u.getValue())}return l.updateDisplay(),l.__background.appendChild(l.__foreground),l.domElement.appendChild(l.__background),l}return x(e,[{key:"updateDisplay",value:function(){var i=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=i*100+"%",E(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"updateDisplay",this).call(this)}}]),e}(ne),ie=function(n){A(e,n);function e(t,i,o){w(this,e);var r=S(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t,i)),d=r;return r.__button=document.createElement("div"),r.__button.innerHTML=o===void 0?"Fire":o,a.bind(r.__button,"click",function(l){return l.preventDefault(),d.fire(),!1}),a.addClass(r.__button,"button"),r.domElement.appendChild(r.__button),r}return x(e,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),e}(k),Y=function(n){A(e,n);function e(t,i){w(this,e);var o=S(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t,i));o.__color=new g(o.getValue()),o.__temp=new g(0);var r=o;o.domElement=document.createElement("div"),a.makeSelectable(o.domElement,!1),o.__selector=document.createElement("div"),o.__selector.className="selector",o.__saturation_field=document.createElement("div"),o.__saturation_field.className="saturation-field",o.__field_knob=document.createElement("div"),o.__field_knob.className="field-knob",o.__field_knob_border="2px solid ",o.__hue_knob=document.createElement("div"),o.__hue_knob.className="hue-knob",o.__hue_field=document.createElement("div"),o.__hue_field.className="hue-field",o.__input=document.createElement("input"),o.__input.type="text",o.__input_textShadow="0 1px 1px ",a.bind(o.__input,"keydown",function(_){_.keyCode===13&&c.call(this)}),a.bind(o.__input,"blur",c),a.bind(o.__selector,"mousedown",function(){a.addClass(this,"drag").bind(window,"mouseup",function(){a.removeClass(r.__selector,"drag")})}),a.bind(o.__selector,"touchstart",function(){a.addClass(this,"drag").bind(window,"touchend",function(){a.removeClass(r.__selector,"drag")})});var d=document.createElement("div");s.extend(o.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),s.extend(o.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:o.__field_knob_border+(o.__color.v<.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),s.extend(o.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),s.extend(o.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),s.extend(d.style,{width:"100%",height:"100%",background:"none"}),le(d,"top","rgba(0,0,0,0)","#000"),s.extend(o.__hue_field.style,{width:"15px",height:"100px",border:"1px solid #555",cursor:"ns-resize",position:"absolute",top:"3px",right:"3px"}),Te(o.__hue_field),s.extend(o.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:o.__input_textShadow+"rgba(0,0,0,0.7)"}),a.bind(o.__saturation_field,"mousedown",l),a.bind(o.__saturation_field,"touchstart",l),a.bind(o.__field_knob,"mousedown",l),a.bind(o.__field_knob,"touchstart",l),a.bind(o.__hue_field,"mousedown",u),a.bind(o.__hue_field,"touchstart",u);function l(_){y(_),a.bind(window,"mousemove",y),a.bind(window,"touchmove",y),a.bind(window,"mouseup",f),a.bind(window,"touchend",f)}function u(_){b(_),a.bind(window,"mousemove",b),a.bind(window,"touchmove",b),a.bind(window,"mouseup",m),a.bind(window,"touchend",m)}function f(){a.unbind(window,"mousemove",y),a.unbind(window,"touchmove",y),a.unbind(window,"mouseup",f),a.unbind(window,"touchend",f),h()}function m(){a.unbind(window,"mousemove",b),a.unbind(window,"touchmove",b),a.unbind(window,"mouseup",m),a.unbind(window,"touchend",m),h()}function c(){var _=X(this.value);_!==!1?(r.__color.__state=_,r.setValue(r.__color.toOriginal())):this.value=r.__color.toString()}function h(){r.__onFinishChange&&r.__onFinishChange.call(r,r.__color.toOriginal())}o.__saturation_field.appendChild(d),o.__selector.appendChild(o.__field_knob),o.__selector.appendChild(o.__saturation_field),o.__selector.appendChild(o.__hue_field),o.__hue_field.appendChild(o.__hue_knob),o.domElement.appendChild(o.__input),o.domElement.appendChild(o.__selector),o.updateDisplay();function y(_){_.type.indexOf("touch")===-1&&_.preventDefault();var v=r.__saturation_field.getBoundingClientRect(),O=_.touches&&_.touches[0]||_,K=O.clientX,T=O.clientY,N=(K-v.left)/(v.right-v.left),F=1-(T-v.top)/(v.bottom-v.top);return F>1?F=1:F<0&&(F=0),N>1?N=1:N<0&&(N=0),r.__color.v=F,r.__color.s=N,r.setValue(r.__color.toOriginal()),!1}function b(_){_.type.indexOf("touch")===-1&&_.preventDefault();var v=r.__hue_field.getBoundingClientRect(),O=_.touches&&_.touches[0]||_,K=O.clientY,T=1-(K-v.top)/(v.bottom-v.top);return T>1?T=1:T<0&&(T=0),r.__color.h=T*360,r.setValue(r.__color.toOriginal()),!1}return o}return x(e,[{key:"updateDisplay",value:function(){var i=X(this.getValue());if(i!==!1){var o=!1;s.each(g.COMPONENTS,function(l){if(!s.isUndefined(i[l])&&!s.isUndefined(this.__color.__state[l])&&i[l]!==this.__color.__state[l])return o=!0,{}},this),o&&s.extend(this.__color.__state,i)}s.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var r=this.__color.v<.5||this.__color.s>.5?255:0,d=255-r;s.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toHexString(),border:this.__field_knob_border+"rgb("+r+","+r+","+r+")"}),this.__hue_knob.style.marginTop=(1-this.__color.h/360)*100+"px",this.__temp.s=1,this.__temp.v=1,le(this.__saturation_field,"left","#fff",this.__temp.toHexString()),this.__input.value=this.__color.toString(),s.extend(this.__input.style,{backgroundColor:this.__color.toHexString(),color:"rgb("+r+","+r+","+r+")",textShadow:this.__input_textShadow+"rgba("+d+","+d+","+d+",.7)"})}}]),e}(k),Oe=["-moz-","-o-","-webkit-","-ms-",""];function le(n,e,t,i){n.style.background="",s.each(Oe,function(o){n.style.cssText+="background: "+o+"linear-gradient("+e+", "+t+" 0%, "+i+" 100%); "})}function Te(n){n.style.background="",n.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",n.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",n.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",n.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",n.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}var Re={load:function(e,t){var i=t||document,o=i.createElement("link");o.type="text/css",o.rel="stylesheet",o.href=e,i.getElementsByTagName("head")[0].appendChild(o)},inject:function(e,t){var i=t||document,o=document.createElement("style");o.type="text/css",o.innerHTML=e;var r=i.getElementsByTagName("head")[0];try{r.appendChild(o)}catch{}}},Le=`
+ + Here's the new load parameter for your GUI's constructor: + + + +
+ + Automatically save + values to localStorage on exit. + +
The values saved to localStorage will + override those passed to dat.GUI's constructor. This makes it + easier to work incrementally, but localStorage is fragile, + and your friends may not see the same values you do. + +
+ +
+ +
`,Be=function(e,t){var i=e[t];return s.isArray(arguments[2])||s.isObject(arguments[2])?new ge(e,t,arguments[2]):s.isNumber(i)?s.isNumber(arguments[2])&&s.isNumber(arguments[3])?s.isNumber(arguments[4])?new j(e,t,arguments[2],arguments[3],arguments[4]):new j(e,t,arguments[2],arguments[3]):s.isNumber(arguments[4])?new z(e,t,{min:arguments[2],max:arguments[3],step:arguments[4]}):new z(e,t,{min:arguments[2],max:arguments[3]}):s.isString(i)?new be(e,t):s.isFunction(i)?new ie(e,t,""):s.isBoolean(i)?new te(e,t):null};function Ne(n){setTimeout(n,1e3/60)}var Fe=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||Ne,He=function(){function n(){w(this,n),this.backgroundElement=document.createElement("div"),s.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear",transition:"opacity 0.2s linear"}),a.makeFullscreen(this.backgroundElement),this.backgroundElement.style.position="fixed",this.domElement=document.createElement("div"),s.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear",transition:"transform 0.2s ease-out, opacity 0.2s linear"}),document.body.appendChild(this.backgroundElement),document.body.appendChild(this.domElement);var e=this;a.bind(this.backgroundElement,"click",function(){e.hide()})}return x(n,[{key:"show",value:function(){var t=this;this.backgroundElement.style.display="block",this.domElement.style.display="block",this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)",this.layout(),s.defer(function(){t.backgroundElement.style.opacity=1,t.domElement.style.opacity=1,t.domElement.style.webkitTransform="scale(1)"})}},{key:"hide",value:function(){var t=this,i=function o(){t.domElement.style.display="none",t.backgroundElement.style.display="none",a.unbind(t.domElement,"webkitTransitionEnd",o),a.unbind(t.domElement,"transitionend",o),a.unbind(t.domElement,"oTransitionEnd",o)};a.bind(this.domElement,"webkitTransitionEnd",i),a.bind(this.domElement,"transitionend",i),a.bind(this.domElement,"oTransitionEnd",i),this.backgroundElement.style.opacity=0,this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)"}},{key:"layout",value:function(){this.domElement.style.left=window.innerWidth/2-a.getWidth(this.domElement)/2+"px",this.domElement.style.top=window.innerHeight/2-a.getHeight(this.domElement)/2+"px"}}]),n}(),De=xe(`.dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .cr.function .property-name{width:100%}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda} +`);Re.inject(De);var ue="dg",ce=72,fe=20,U="Default",P=function(){try{return!!window.localStorage}catch{return!1}}(),V=void 0,_e=!0,R=void 0,W=!1,ve=[],p=function n(e){var t=this,i=e||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),a.addClass(this.domElement,ue),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],i=s.defaults(i,{closeOnTop:!1,autoPlace:!0,width:n.DEFAULT_WIDTH}),i=s.defaults(i,{resizable:i.autoPlace,hideable:i.autoPlace}),s.isUndefined(i.load)?i.load={preset:U}:i.preset&&(i.load.preset=i.preset),s.isUndefined(i.parent)&&i.hideable&&ve.push(this),i.resizable=s.isUndefined(i.parent)&&i.resizable,i.autoPlace&&s.isUndefined(i.scrollable)&&(i.scrollable=!0);var o=P&&localStorage.getItem(L(this,"isLocal"))==="true",r=void 0,d=void 0;if(Object.defineProperties(this,{parent:{get:function(){return i.parent}},scrollable:{get:function(){return i.scrollable}},autoPlace:{get:function(){return i.autoPlace}},closeOnTop:{get:function(){return i.closeOnTop}},preset:{get:function(){return t.parent?t.getRoot().preset:i.load.preset},set:function(h){t.parent?t.getRoot().preset=h:i.load.preset=h,Me(this),t.revert()}},width:{get:function(){return i.width},set:function(h){i.width=h,q(t,h)}},name:{get:function(){return i.name},set:function(h){i.name=h,d&&(d.innerHTML=i.name)}},closed:{get:function(){return i.closed},set:function(h){i.closed=h,i.closed?a.addClass(t.__ul,n.CLASS_CLOSED):a.removeClass(t.__ul,n.CLASS_CLOSED),this.onResize(),t.__closeButton&&(t.__closeButton.innerHTML=h?n.TEXT_OPEN:n.TEXT_CLOSED)}},load:{get:function(){return i.load}},useLocalStorage:{get:function(){return o},set:function(h){P&&(o=h,h?a.bind(window,"unload",r):a.unbind(window,"unload",r),localStorage.setItem(L(t,"isLocal"),h))}}}),s.isUndefined(i.parent)){if(this.closed=i.closed||!1,a.addClass(this.domElement,n.CLASS_MAIN),a.makeSelectable(this.domElement,!1),P&&o){t.useLocalStorage=!0;var l=localStorage.getItem(L(this,"gui"));l&&(i.load=JSON.parse(l))}this.__closeButton=document.createElement("div"),this.__closeButton.innerHTML=n.TEXT_CLOSED,a.addClass(this.__closeButton,n.CLASS_CLOSE_BUTTON),i.closeOnTop?(a.addClass(this.__closeButton,n.CLASS_CLOSE_TOP),this.domElement.insertBefore(this.__closeButton,this.domElement.childNodes[0])):(a.addClass(this.__closeButton,n.CLASS_CLOSE_BOTTOM),this.domElement.appendChild(this.__closeButton)),a.bind(this.__closeButton,"click",function(){t.closed=!t.closed})}else{i.closed===void 0&&(i.closed=!0);var u=document.createTextNode(i.name);a.addClass(u,"controller-name"),d=oe(t,u);var f=function(h){return h.preventDefault(),t.closed=!t.closed,!1};a.addClass(this.__ul,n.CLASS_CLOSED),a.addClass(d,"title"),a.bind(d,"click",f),i.closed||(this.closed=!1)}i.autoPlace&&(s.isUndefined(i.parent)&&(_e&&(R=document.createElement("div"),a.addClass(R,ue),a.addClass(R,n.CLASS_AUTO_PLACE_CONTAINER),document.body.appendChild(R),_e=!1),R.appendChild(this.domElement),a.addClass(this.domElement,n.CLASS_AUTO_PLACE)),this.parent||q(t,i.width)),this.__resizeHandler=function(){t.onResizeDebounced()},a.bind(window,"resize",this.__resizeHandler),a.bind(this.__ul,"webkitTransitionEnd",this.__resizeHandler),a.bind(this.__ul,"transitionend",this.__resizeHandler),a.bind(this.__ul,"oTransitionEnd",this.__resizeHandler),this.onResize(),i.resizable&&Ie(this),r=function(){P&&localStorage.getItem(L(t,"isLocal"))==="true"&&localStorage.setItem(L(t,"gui"),JSON.stringify(t.getSaveObject()))},this.saveToLocalStorageIfPossible=r;function m(){var c=t.getRoot();c.width+=1,s.defer(function(){c.width-=1})}i.parent||m()};p.toggleHide=function(){W=!W,s.each(ve,function(n){n.domElement.style.display=W?"none":""})};p.CLASS_AUTO_PLACE="a";p.CLASS_AUTO_PLACE_CONTAINER="ac";p.CLASS_MAIN="main";p.CLASS_CONTROLLER_ROW="cr";p.CLASS_TOO_TALL="taller-than-window";p.CLASS_CLOSED="closed";p.CLASS_CLOSE_BUTTON="close-button";p.CLASS_CLOSE_TOP="close-top";p.CLASS_CLOSE_BOTTOM="close-bottom";p.CLASS_DRAG="drag";p.DEFAULT_WIDTH=245;p.TEXT_CLOSED="Close Controls";p.TEXT_OPEN="Open Controls";p._keydownHandler=function(n){document.activeElement.type!=="text"&&(n.which===ce||n.keyCode===ce)&&p.toggleHide()};a.bind(window,"keydown",p._keydownHandler,!1);s.extend(p.prototype,{add:function(e,t){return I(this,e,t,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(e,t){return I(this,e,t,{color:!0})},remove:function(e){this.__ul.removeChild(e.__li),this.__controllers.splice(this.__controllers.indexOf(e),1);var t=this;s.defer(function(){t.onResize()})},destroy:function(){if(this.parent)throw new Error("Only the root GUI should be removed with .destroy(). For subfolders, use gui.removeFolder(folder) instead.");this.autoPlace&&R.removeChild(this.domElement);var e=this;s.each(this.__folders,function(t){e.removeFolder(t)}),a.unbind(window,"keydown",p._keydownHandler,!1),he(this)},addFolder:function(e){if(this.__folders[e]!==void 0)throw new Error('You already have a folder in this GUI by the name "'+e+'"');var t={name:e,parent:this};t.autoPlace=this.autoPlace,this.load&&this.load.folders&&this.load.folders[e]&&(t.closed=this.load.folders[e].closed,t.load=this.load.folders[e]);var i=new p(t);this.__folders[e]=i;var o=oe(this,i.domElement);return a.addClass(o,"folder"),i},removeFolder:function(e){this.__ul.removeChild(e.domElement.parentElement),delete this.__folders[e.name],this.load&&this.load.folders&&this.load.folders[e.name]&&delete this.load.folders[e.name],he(e);var t=this;s.each(e.__folders,function(i){e.removeFolder(i)}),s.defer(function(){t.onResize()})},open:function(){this.closed=!1},close:function(){this.closed=!0},hide:function(){this.domElement.style.display="none"},show:function(){this.domElement.style.display=""},onResize:function(){var e=this.getRoot();if(e.scrollable){var t=a.getOffset(e.__ul).top,i=0;s.each(e.__ul.childNodes,function(o){e.autoPlace&&o===e.__save_row||(i+=a.getHeight(o))}),window.innerHeight-t-fe0&&(e.preset=this.preset,e.remembered||(e.remembered={}),e.remembered[this.preset]=$(this)),e.folders={},s.each(this.__folders,function(t,i){e.folders[i]=t.getSaveObject()}),e},save:function(){this.load.remembered||(this.load.remembered={}),this.load.remembered[this.preset]=$(this),J(this,!1),this.saveToLocalStorageIfPossible()},saveAs:function(e){this.load.remembered||(this.load.remembered={},this.load.remembered[U]=$(this,!0)),this.load.remembered[e]=$(this),this.preset=e,Q(this,e,!0),this.saveToLocalStorageIfPossible()},revert:function(e){s.each(this.__controllers,function(t){this.getRoot().load.remembered?ye(e||this.getRoot(),t):t.setValue(t.initialValue),t.__onFinishChange&&t.__onFinishChange.call(t,t.getValue())},this),s.each(this.__folders,function(t){t.revert(t)}),e||J(this.getRoot(),!1)},listen:function(e){var t=this.__listening.length===0;this.__listening.push(e),t&&we(this.__listening)},updateDisplay:function(){s.each(this.__controllers,function(e){e.updateDisplay()}),s.each(this.__folders,function(e){e.updateDisplay()})}});function oe(n,e,t){var i=document.createElement("li");return e&&i.appendChild(e),t?n.__ul.insertBefore(i,t):n.__ul.appendChild(i),n.onResize(),i}function he(n){a.unbind(window,"resize",n.__resizeHandler),n.saveToLocalStorageIfPossible&&a.unbind(window,"unload",n.saveToLocalStorageIfPossible)}function J(n,e){var t=n.__preset_select[n.__preset_select.selectedIndex];e?t.innerHTML=t.value+"*":t.innerHTML=t.value}function Pe(n,e,t){if(t.__li=e,t.__gui=n,s.extend(t,{options:function(d){if(arguments.length>1){var l=t.__li.nextElementSibling;return t.remove(),I(n,t.object,t.property,{before:l,factoryArgs:[s.toArray(arguments)]})}if(s.isArray(d)||s.isObject(d)){var u=t.__li.nextElementSibling;return t.remove(),I(n,t.object,t.property,{before:u,factoryArgs:[d]})}},name:function(d){return t.__li.firstElementChild.firstElementChild.innerHTML=d,t},listen:function(){return t.__gui.listen(t),t},remove:function(){return t.__gui.remove(t),t}}),t instanceof j){var i=new z(t.object,t.property,{min:t.__min,max:t.__max,step:t.__step});s.each(["updateDisplay","onChange","onFinishChange","step","min","max"],function(r){var d=t[r],l=i[r];t[r]=i[r]=function(){var u=Array.prototype.slice.call(arguments);return l.apply(i,u),d.apply(t,u)}}),a.addClass(e,"has-slider"),t.domElement.insertBefore(i.domElement,t.domElement.firstElementChild)}else if(t instanceof z){var o=function(d){if(s.isNumber(t.__min)&&s.isNumber(t.__max)){var l=t.__li.firstElementChild.firstElementChild.innerHTML,u=t.__gui.__listening.indexOf(t)>-1;t.remove();var f=I(n,t.object,t.property,{before:t.__li.nextElementSibling,factoryArgs:[t.__min,t.__max,t.__step]});return f.name(l),u&&f.listen(),f}return d};t.min=s.compose(o,t.min),t.max=s.compose(o,t.max)}else t instanceof te?(a.bind(e,"click",function(){a.fakeEvent(t.__checkbox,"click")}),a.bind(t.__checkbox,"click",function(r){r.stopPropagation()})):t instanceof ie?(a.bind(e,"click",function(){a.fakeEvent(t.__button,"click")}),a.bind(e,"mouseover",function(){a.addClass(t.__button,"hover")}),a.bind(e,"mouseout",function(){a.removeClass(t.__button,"hover")})):t instanceof Y&&(a.addClass(e,"color"),t.updateDisplay=s.compose(function(r){return e.style.borderLeftColor=t.__color.toString(),r},t.updateDisplay),t.updateDisplay());t.setValue=s.compose(function(r){return n.getRoot().__preset_select&&t.isModified()&&J(n.getRoot(),!0),r},t.setValue)}function ye(n,e){var t=n.getRoot(),i=t.__rememberedObjects.indexOf(e.object);if(i!==-1){var o=t.__rememberedObjectIndecesToControllers[i];if(o===void 0&&(o={},t.__rememberedObjectIndecesToControllers[i]=o),o[e.property]=e,t.load&&t.load.remembered){var r=t.load.remembered,d=void 0;if(r[n.preset])d=r[n.preset];else if(r[U])d=r[U];else return;if(d[i]&&d[i][e.property]!==void 0){var l=d[i][e.property];e.initialValue=l,e.setValue(l)}}}}function I(n,e,t,i){if(e[t]===void 0)throw new Error('Object "'+e+'" has no property "'+t+'"');var o=void 0;if(i.color)o=new Y(e,t);else{var r=[e,t].concat(i.factoryArgs);o=Be.apply(n,r)}i.before instanceof k&&(i.before=i.before.__li),ye(n,o),a.addClass(o.domElement,"c");var d=document.createElement("span");a.addClass(d,"property-name"),d.innerHTML=o.property;var l=document.createElement("div");l.appendChild(d),l.appendChild(o.domElement);var u=oe(n,l,i.before);return a.addClass(u,p.CLASS_CONTROLLER_ROW),o instanceof Y?a.addClass(u,"color"):a.addClass(u,Ee(o.getValue())),Pe(n,u,o),n.__controllers.push(o),o}function L(n,e){return document.location.href+"."+e}function Q(n,e,t){var i=document.createElement("option");i.innerHTML=e,i.value=e,n.__preset_select.appendChild(i),t&&(n.__preset_select.selectedIndex=n.__preset_select.length-1)}function pe(n,e){e.style.display=n.useLocalStorage?"block":"none"}function Ve(n){var e=n.__save_row=document.createElement("li");a.addClass(n.domElement,"has-save"),n.__ul.insertBefore(e,n.__ul.firstChild),a.addClass(e,"save-row");var t=document.createElement("span");t.innerHTML=" ",a.addClass(t,"button gears");var i=document.createElement("span");i.innerHTML="Save",a.addClass(i,"button"),a.addClass(i,"save");var o=document.createElement("span");o.innerHTML="New",a.addClass(o,"button"),a.addClass(o,"save-as");var r=document.createElement("span");r.innerHTML="Revert",a.addClass(r,"button"),a.addClass(r,"revert");var d=n.__preset_select=document.createElement("select");if(n.load&&n.load.remembered?s.each(n.load.remembered,function(c,h){Q(n,h,h===n.preset)}):Q(n,U,!1),a.bind(d,"change",function(){for(var c=0;c0?(Y[0]=(i*s+L*n+c*a-y*r)*2/k,Y[1]=(c*s+L*r+y*n-i*a)*2/k,Y[2]=(y*s+L*a+i*r-c*n)*2/k):(Y[0]=(i*s+L*n+c*a-y*r)*2,Y[1]=(c*s+L*r+y*n-i*a)*2,Y[2]=(y*s+L*a+i*r-c*n)*2),h.fromRotationTranslation(e,t,Y),e}static normalFromMat4(e,t){let n=t[0],r=t[1],a=t[2],s=t[3],i=t[4],c=t[5],y=t[6],L=t[7],k=t[8],l=t[9],b=t[10],M=t[11],d=t[12],m=t[13],o=t[14],x=t[15],z=n*c-r*i,R=n*y-a*i,V=n*L-s*i,w=r*y-a*c,g=r*L-s*c,T=a*L-s*y,E=k*m-l*d,F=k*o-b*d,f=k*x-M*d,N=l*o-b*m,B=l*x-M*m,D=b*x-M*o,Q=z*D-R*B+V*N+w*f-g*F+T*E;return Q?(Q=1/Q,e[0]=(c*D-y*B+L*N)*Q,e[1]=(y*f-i*D-L*F)*Q,e[2]=(i*B-c*f+L*E)*Q,e[3]=0,e[4]=(a*B-r*D-s*N)*Q,e[5]=(n*D-a*f+s*F)*Q,e[6]=(r*f-n*B-s*E)*Q,e[7]=0,e[8]=(m*T-o*g+x*w)*Q,e[9]=(o*V-d*T-x*R)*Q,e[10]=(d*g-m*V+x*z)*Q,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e):null}static normalFromMat4Fast(e,t){let n=t[0],r=t[1],a=t[2],s=t[4],i=t[5],c=t[6],y=t[8],L=t[9],k=t[10];return e[0]=i*k-k*L,e[1]=c*y-y*k,e[2]=s*L-L*y,e[3]=0,e[4]=L*a-k*r,e[5]=k*n-y*a,e[6]=y*r-L*n,e[7]=0,e[8]=r*c-a*i,e[9]=a*s-n*c,e[10]=n*i-r*s,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}static getTranslation(e,t){return e[0]=t[12],e[1]=t[13],e[2]=t[14],e}static getScaling(e,t){let n=t[0],r=t[1],a=t[2],s=t[4],i=t[5],c=t[6],y=t[8],L=t[9],k=t[10];return e[0]=Math.sqrt(n*n+r*r+a*a),e[1]=Math.sqrt(s*s+i*i+c*c),e[2]=Math.sqrt(y*y+L*L+k*k),e}static getRotation(e,t){h.getScaling(Y,t);let n=1/Y[0],r=1/Y[1],a=1/Y[2],s=t[0]*n,i=t[1]*r,c=t[2]*a,y=t[4]*n,L=t[5]*r,k=t[6]*a,l=t[8]*n,b=t[9]*r,M=t[10]*a,d=s+L+M,m=0;return d>0?(m=Math.sqrt(d+1)*2,e[3]=.25*m,e[0]=(k-b)/m,e[1]=(l-c)/m,e[2]=(i-y)/m):s>L&&s>M?(m=Math.sqrt(1+s-L-M)*2,e[3]=(k-b)/m,e[0]=.25*m,e[1]=(i+y)/m,e[2]=(l+c)/m):L>M?(m=Math.sqrt(1+L-s-M)*2,e[3]=(l-c)/m,e[0]=(i+y)/m,e[1]=.25*m,e[2]=(k+b)/m):(m=Math.sqrt(1+M-s-L)*2,e[3]=(i-y)/m,e[0]=(l+c)/m,e[1]=(k+b)/m,e[2]=.25*m),e}static decompose(e,t,n,r){t[0]=r[12],t[1]=r[13],t[2]=r[14];let a=r[0],s=r[1],i=r[2],c=r[4],y=r[5],L=r[6],k=r[8],l=r[9],b=r[10];n[0]=Math.sqrt(a*a+s*s+i*i),n[1]=Math.sqrt(c*c+y*y+L*L),n[2]=Math.sqrt(k*k+l*l+b*b);let M=1/n[0],d=1/n[1],m=1/n[2],o=a*M,x=s*d,z=i*m,R=c*M,V=y*d,w=L*m,g=k*M,T=l*d,E=b*m,F=o+V+E,f=0;return F>0?(f=Math.sqrt(F+1)*2,e[3]=.25*f,e[0]=(w-T)/f,e[1]=(g-z)/f,e[2]=(x-R)/f):o>V&&o>E?(f=Math.sqrt(1+o-V-E)*2,e[3]=(w-T)/f,e[0]=.25*f,e[1]=(x+R)/f,e[2]=(g+z)/f):V>E?(f=Math.sqrt(1+V-o-E)*2,e[3]=(g-z)/f,e[0]=(x+R)/f,e[1]=.25*f,e[2]=(w+T)/f):(f=Math.sqrt(1+E-o-V)*2,e[3]=(x-R)/f,e[0]=(g+z)/f,e[1]=(w+T)/f,e[2]=.25*f),e}static fromRotationTranslationScale(e,t,n,r){let a=t[0],s=t[1],i=t[2],c=t[3],y=a+a,L=s+s,k=i+i,l=a*y,b=a*L,M=a*k,d=s*L,m=s*k,o=i*k,x=c*y,z=c*L,R=c*k,V=r[0],w=r[1],g=r[2];return e[0]=(1-(d+o))*V,e[1]=(b+R)*V,e[2]=(M-z)*V,e[3]=0,e[4]=(b-R)*w,e[5]=(1-(l+o))*w,e[6]=(m+x)*w,e[7]=0,e[8]=(M+z)*g,e[9]=(m-x)*g,e[10]=(1-(l+d))*g,e[11]=0,e[12]=n[0],e[13]=n[1],e[14]=n[2],e[15]=1,e}static fromRotationTranslationScaleOrigin(e,t,n,r,a){let s=t[0],i=t[1],c=t[2],y=t[3],L=s+s,k=i+i,l=c+c,b=s*L,M=s*k,d=s*l,m=i*k,o=i*l,x=c*l,z=y*L,R=y*k,V=y*l,w=r[0],g=r[1],T=r[2],E=a[0],F=a[1],f=a[2],N=(1-(m+x))*w,B=(M+V)*w,D=(d-R)*w,Q=(M-V)*g,Z=(1-(b+x))*g,W=(o+z)*g,U=(d+R)*T,K=(o-z)*T,v=(1-(b+m))*T;return e[0]=N,e[1]=B,e[2]=D,e[3]=0,e[4]=Q,e[5]=Z,e[6]=W,e[7]=0,e[8]=U,e[9]=K,e[10]=v,e[11]=0,e[12]=n[0]+E-(N*E+Q*F+U*f),e[13]=n[1]+F-(B*E+Z*F+K*f),e[14]=n[2]+f-(D*E+W*F+v*f),e[15]=1,e}static fromQuat(e,t){let n=t[0],r=t[1],a=t[2],s=t[3],i=n+n,c=r+r,y=a+a,L=n*i,k=r*i,l=r*c,b=a*i,M=a*c,d=a*y,m=s*i,o=s*c,x=s*y;return e[0]=1-l-d,e[1]=k+x,e[2]=b-o,e[3]=0,e[4]=k-x,e[5]=1-L-d,e[6]=M+m,e[7]=0,e[8]=b+o,e[9]=M-m,e[10]=1-L-l,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}static frustumNO(e,t,n,r,a,s,i=1/0){let c=1/(n-t),y=1/(a-r);if(e[0]=s*2*c,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=s*2*y,e[6]=0,e[7]=0,e[8]=(n+t)*c,e[9]=(a+r)*y,e[11]=-1,e[12]=0,e[13]=0,e[15]=0,i!=null&&i!==1/0){let L=1/(s-i);e[10]=(i+s)*L,e[14]=2*i*s*L}else e[10]=-1,e[14]=-2*s;return e}static frustum(e,t,n,r,a,s,i=1/0){return e}static frustumZO(e,t,n,r,a,s,i=1/0){let c=1/(n-t),y=1/(a-r);if(e[0]=s*2*c,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=s*2*y,e[6]=0,e[7]=0,e[8]=(n+t)*c,e[9]=(a+r)*y,e[11]=-1,e[12]=0,e[13]=0,e[15]=0,i!=null&&i!==1/0){let L=1/(s-i);e[10]=i*L,e[14]=i*s*L}else e[10]=-1,e[14]=-s;return e}static perspectiveNO(e,t,n,r,a=1/0){let s=1/Math.tan(t/2);if(e[0]=s/n,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=s,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[11]=-1,e[12]=0,e[13]=0,e[15]=0,a!=null&&a!==1/0){let i=1/(r-a);e[10]=(a+r)*i,e[14]=2*a*r*i}else e[10]=-1,e[14]=-2*r;return e}static perspective(e,t,n,r,a=1/0){return e}static perspectiveZO(e,t,n,r,a=1/0){let s=1/Math.tan(t/2);if(e[0]=s/n,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=s,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[11]=-1,e[12]=0,e[13]=0,e[15]=0,a!=null&&a!==1/0){let i=1/(r-a);e[10]=a*i,e[14]=a*r*i}else e[10]=-1,e[14]=-r;return e}static perspectiveFromFieldOfView(e,t,n,r){let a=Math.tan(t.upDegrees*Math.PI/180),s=Math.tan(t.downDegrees*Math.PI/180),i=Math.tan(t.leftDegrees*Math.PI/180),c=Math.tan(t.rightDegrees*Math.PI/180),y=2/(i+c),L=2/(a+s);return e[0]=y,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=L,e[6]=0,e[7]=0,e[8]=-((i-c)*y*.5),e[9]=(a-s)*L*.5,e[10]=r/(n-r),e[11]=-1,e[12]=0,e[13]=0,e[14]=r*n/(n-r),e[15]=0,e}static orthoNO(e,t,n,r,a,s,i){let c=1/(t-n),y=1/(r-a),L=1/(s-i);return e[0]=-2*c,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*L,e[11]=0,e[12]=(t+n)*c,e[13]=(a+r)*y,e[14]=(i+s)*L,e[15]=1,e}static ortho(e,t,n,r,a,s,i){return e}static orthoZO(e,t,n,r,a,s,i){let c=1/(t-n),y=1/(r-a),L=1/(s-i);return e[0]=-2*c,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*y,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=L,e[11]=0,e[12]=(t+n)*c,e[13]=(a+r)*y,e[14]=s*L,e[15]=1,e}static lookAt(e,t,n,r){let a=t[0],s=t[1],i=t[2],c=r[0],y=r[1],L=r[2],k=n[0],l=n[1],b=n[2];if(Math.abs(a-k)<1e-6&&Math.abs(s-l)<1e-6&&Math.abs(i-b)<1e-6)return h.identity(e);let M=a-k,d=s-l,m=i-b,o=1/Math.sqrt(M*M+d*d+m*m);M*=o,d*=o,m*=o;let x=y*m-L*d,z=L*M-c*m,R=c*d-y*M;o=Math.sqrt(x*x+z*z+R*R),o?(o=1/o,x*=o,z*=o,R*=o):(x=0,z=0,R=0);let V=d*R-m*z,w=m*x-M*R,g=M*z-d*x;return o=Math.sqrt(V*V+w*w+g*g),o?(o=1/o,V*=o,w*=o,g*=o):(V=0,w=0,g=0),e[0]=x,e[1]=V,e[2]=M,e[3]=0,e[4]=z,e[5]=w,e[6]=d,e[7]=0,e[8]=R,e[9]=g,e[10]=m,e[11]=0,e[12]=-(x*a+z*s+R*i),e[13]=-(V*a+w*s+g*i),e[14]=-(M*a+d*s+m*i),e[15]=1,e}static targetTo(e,t,n,r){let a=t[0],s=t[1],i=t[2],c=r[0],y=r[1],L=r[2],k=a-n[0],l=s-n[1],b=i-n[2],M=k*k+l*l+b*b;M>0&&(M=1/Math.sqrt(M),k*=M,l*=M,b*=M);let d=y*b-L*l,m=L*k-c*b,o=c*l-y*k;return M=d*d+m*m+o*o,M>0&&(M=1/Math.sqrt(M),d*=M,m*=M,o*=M),e[0]=d,e[1]=m,e[2]=o,e[3]=0,e[4]=l*o-b*m,e[5]=b*d-k*o,e[6]=k*m-l*d,e[7]=0,e[8]=k,e[9]=l,e[10]=b,e[11]=0,e[12]=a,e[13]=s,e[14]=i,e[15]=1,e}static frob(e){return Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]+e[3]*e[3]+e[4]*e[4]+e[5]*e[5]+e[6]*e[6]+e[7]*e[7]+e[8]*e[8]+e[9]*e[9]+e[10]*e[10]+e[11]*e[11]+e[12]*e[12]+e[13]*e[13]+e[14]*e[14]+e[15]*e[15])}static add(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e[2]=t[2]+n[2],e[3]=t[3]+n[3],e[4]=t[4]+n[4],e[5]=t[5]+n[5],e[6]=t[6]+n[6],e[7]=t[7]+n[7],e[8]=t[8]+n[8],e[9]=t[9]+n[9],e[10]=t[10]+n[10],e[11]=t[11]+n[11],e[12]=t[12]+n[12],e[13]=t[13]+n[13],e[14]=t[14]+n[14],e[15]=t[15]+n[15],e}static subtract(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e[2]=t[2]-n[2],e[3]=t[3]-n[3],e[4]=t[4]-n[4],e[5]=t[5]-n[5],e[6]=t[6]-n[6],e[7]=t[7]-n[7],e[8]=t[8]-n[8],e[9]=t[9]-n[9],e[10]=t[10]-n[10],e[11]=t[11]-n[11],e[12]=t[12]-n[12],e[13]=t[13]-n[13],e[14]=t[14]-n[14],e[15]=t[15]-n[15],e}static sub(e,t,n){return e}static multiplyScalar(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e[2]=t[2]*n,e[3]=t[3]*n,e[4]=t[4]*n,e[5]=t[5]*n,e[6]=t[6]*n,e[7]=t[7]*n,e[8]=t[8]*n,e[9]=t[9]*n,e[10]=t[10]*n,e[11]=t[11]*n,e[12]=t[12]*n,e[13]=t[13]*n,e[14]=t[14]*n,e[15]=t[15]*n,e}static multiplyScalarAndAdd(e,t,n,r){return e[0]=t[0]+n[0]*r,e[1]=t[1]+n[1]*r,e[2]=t[2]+n[2]*r,e[3]=t[3]+n[3]*r,e[4]=t[4]+n[4]*r,e[5]=t[5]+n[5]*r,e[6]=t[6]+n[6]*r,e[7]=t[7]+n[7]*r,e[8]=t[8]+n[8]*r,e[9]=t[9]+n[9]*r,e[10]=t[10]+n[10]*r,e[11]=t[11]+n[11]*r,e[12]=t[12]+n[12]*r,e[13]=t[13]+n[13]*r,e[14]=t[14]+n[14]*r,e[15]=t[15]+n[15]*r,e}static exactEquals(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[11]===t[11]&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[15]===t[15]}static equals(e,t){let n=e[0],r=e[1],a=e[2],s=e[3],i=e[4],c=e[5],y=e[6],L=e[7],k=e[8],l=e[9],b=e[10],M=e[11],d=e[12],m=e[13],o=e[14],x=e[15],z=t[0],R=t[1],V=t[2],w=t[3],g=t[4],T=t[5],E=t[6],F=t[7],f=t[8],N=t[9],B=t[10],D=t[11],Q=t[12],Z=t[13],W=t[14],U=t[15];return Math.abs(n-z)<=1e-6*Math.max(1,Math.abs(n),Math.abs(z))&&Math.abs(r-R)<=1e-6*Math.max(1,Math.abs(r),Math.abs(R))&&Math.abs(a-V)<=1e-6*Math.max(1,Math.abs(a),Math.abs(V))&&Math.abs(s-w)<=1e-6*Math.max(1,Math.abs(s),Math.abs(w))&&Math.abs(i-g)<=1e-6*Math.max(1,Math.abs(i),Math.abs(g))&&Math.abs(c-T)<=1e-6*Math.max(1,Math.abs(c),Math.abs(T))&&Math.abs(y-E)<=1e-6*Math.max(1,Math.abs(y),Math.abs(E))&&Math.abs(L-F)<=1e-6*Math.max(1,Math.abs(L),Math.abs(F))&&Math.abs(k-f)<=1e-6*Math.max(1,Math.abs(k),Math.abs(f))&&Math.abs(l-N)<=1e-6*Math.max(1,Math.abs(l),Math.abs(N))&&Math.abs(b-B)<=1e-6*Math.max(1,Math.abs(b),Math.abs(B))&&Math.abs(M-D)<=1e-6*Math.max(1,Math.abs(M),Math.abs(D))&&Math.abs(d-Q)<=1e-6*Math.max(1,Math.abs(d),Math.abs(Q))&&Math.abs(m-Z)<=1e-6*Math.max(1,Math.abs(m),Math.abs(Z))&&Math.abs(o-W)<=1e-6*Math.max(1,Math.abs(o),Math.abs(W))&&Math.abs(x-U)<=1e-6*Math.max(1,Math.abs(x),Math.abs(U))}static str(e){return`Mat4(${e.join(", ")})`}},Y=new Float32Array(3);O.prototype.mul=O.prototype.multiply;O.sub=O.subtract;O.mul=O.multiply;O.frustum=O.frustumNO;O.perspective=O.perspectiveNO;O.ortho=O.orthoNO;var le=O;var A=class h extends Float32Array{static BYTE_LENGTH=3*Float32Array.BYTES_PER_ELEMENT;constructor(...e){switch(e.length){case 3:super(e);break;case 2:super(e[0],e[1],3);break;case 1:{let t=e[0];typeof t=="number"?super([t,t,t]):super(t,0,3);break}default:super(3);break}}get x(){return this[0]}set x(e){this[0]=e}get y(){return this[1]}set y(e){this[1]=e}get z(){return this[2]}set z(e){this[2]=e}get r(){return this[0]}set r(e){this[0]=e}get g(){return this[1]}set g(e){this[1]=e}get b(){return this[2]}set b(e){this[2]=e}get magnitude(){let e=this[0],t=this[1],n=this[2];return Math.sqrt(e*e+t*t+n*n)}get mag(){return this.magnitude}get squaredMagnitude(){let e=this[0],t=this[1],n=this[2];return e*e+t*t+n*n}get sqrMag(){return this.squaredMagnitude}get str(){return h.str(this)}copy(e){return this.set(e),this}add(e){return this[0]+=e[0],this[1]+=e[1],this[2]+=e[2],this}subtract(e){return this[0]-=e[0],this[1]-=e[1],this[2]-=e[2],this}sub(e){return this}multiply(e){return this[0]*=e[0],this[1]*=e[1],this[2]*=e[2],this}mul(e){return this}divide(e){return this[0]/=e[0],this[1]/=e[1],this[2]/=e[2],this}div(e){return this}scale(e){return this[0]*=e,this[1]*=e,this[2]*=e,this}scaleAndAdd(e,t){return this[0]+=e[0]*t,this[1]+=e[1]*t,this[2]+=e[2]*t,this}distance(e){return h.distance(this,e)}dist(e){return 0}squaredDistance(e){return h.squaredDistance(this,e)}sqrDist(e){return 0}negate(){return this[0]*=-1,this[1]*=-1,this[2]*=-1,this}invert(){return this[0]=1/this[0],this[1]=1/this[1],this[2]=1/this[2],this}abs(){return this[0]=Math.abs(this[0]),this[1]=Math.abs(this[1]),this[2]=Math.abs(this[2]),this}dot(e){return this[0]*e[0]+this[1]*e[1]+this[2]*e[2]}normalize(){return h.normalize(this,this)}static create(){return new h}static clone(e){return new h(e)}static magnitude(e){let t=e[0],n=e[1],r=e[2];return Math.sqrt(t*t+n*n+r*r)}static mag(e){return 0}static length(e){return 0}static len(e){return 0}static fromValues(e,t,n){return new h(e,t,n)}static copy(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e}static set(e,t,n,r){return e[0]=t,e[1]=n,e[2]=r,e}static add(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e[2]=t[2]+n[2],e}static subtract(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e[2]=t[2]-n[2],e}static sub(e,t,n){return[0,0,0]}static multiply(e,t,n){return e[0]=t[0]*n[0],e[1]=t[1]*n[1],e[2]=t[2]*n[2],e}static mul(e,t,n){return[0,0,0]}static divide(e,t,n){return e[0]=t[0]/n[0],e[1]=t[1]/n[1],e[2]=t[2]/n[2],e}static div(e,t,n){return[0,0,0]}static ceil(e,t){return e[0]=Math.ceil(t[0]),e[1]=Math.ceil(t[1]),e[2]=Math.ceil(t[2]),e}static floor(e,t){return e[0]=Math.floor(t[0]),e[1]=Math.floor(t[1]),e[2]=Math.floor(t[2]),e}static min(e,t,n){return e[0]=Math.min(t[0],n[0]),e[1]=Math.min(t[1],n[1]),e[2]=Math.min(t[2],n[2]),e}static max(e,t,n){return e[0]=Math.max(t[0],n[0]),e[1]=Math.max(t[1],n[1]),e[2]=Math.max(t[2],n[2]),e}static round(e,t){return e[0]=Math.round(t[0]),e[1]=Math.round(t[1]),e[2]=Math.round(t[2]),e}static scale(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e[2]=t[2]*n,e}static scaleAndAdd(e,t,n,r){return e[0]=t[0]+n[0]*r,e[1]=t[1]+n[1]*r,e[2]=t[2]+n[2]*r,e}static distance(e,t){let n=t[0]-e[0],r=t[1]-e[1],a=t[2]-e[2];return Math.sqrt(n*n+r*r+a*a)}static dist(e,t){return 0}static squaredDistance(e,t){let n=t[0]-e[0],r=t[1]-e[1],a=t[2]-e[2];return n*n+r*r+a*a}static sqrDist(e,t){return 0}static squaredLength(e){let t=e[0],n=e[1],r=e[2];return t*t+n*n+r*r}static sqrLen(e,t){return 0}static negate(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e}static inverse(e,t){return e[0]=1/t[0],e[1]=1/t[1],e[2]=1/t[2],e}static abs(e,t){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e}static normalize(e,t){let n=t[0],r=t[1],a=t[2],s=n*n+r*r+a*a;return s>0&&(s=1/Math.sqrt(s)),e[0]=t[0]*s,e[1]=t[1]*s,e[2]=t[2]*s,e}static dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}static cross(e,t,n){let r=t[0],a=t[1],s=t[2],i=n[0],c=n[1],y=n[2];return e[0]=a*y-s*c,e[1]=s*i-r*y,e[2]=r*c-a*i,e}static lerp(e,t,n,r){let a=t[0],s=t[1],i=t[2];return e[0]=a+r*(n[0]-a),e[1]=s+r*(n[1]-s),e[2]=i+r*(n[2]-i),e}static slerp(e,t,n,r){let a=Math.acos(Math.min(Math.max(h.dot(t,n),-1),1)),s=Math.sin(a),i=Math.sin((1-r)*a)/s,c=Math.sin(r*a)/s;return e[0]=i*t[0]+c*n[0],e[1]=i*t[1]+c*n[1],e[2]=i*t[2]+c*n[2],e}static hermite(e,t,n,r,a,s){let i=s*s,c=i*(2*s-3)+1,y=i*(s-2)+s,L=i*(s-1),k=i*(3-2*s);return e[0]=t[0]*c+n[0]*y+r[0]*L+a[0]*k,e[1]=t[1]*c+n[1]*y+r[1]*L+a[1]*k,e[2]=t[2]*c+n[2]*y+r[2]*L+a[2]*k,e}static bezier(e,t,n,r,a,s){let i=1-s,c=i*i,y=s*s,L=c*i,k=3*s*c,l=3*y*i,b=y*s;return e[0]=t[0]*L+n[0]*k+r[0]*l+a[0]*b,e[1]=t[1]*L+n[1]*k+r[1]*l+a[1]*b,e[2]=t[2]*L+n[2]*k+r[2]*l+a[2]*b,e}static random(e,t){t=t===void 0?1:t;let n=Math.random()*2*Math.PI,r=Math.random()*2-1,a=Math.sqrt(1-r*r)*t;return e[0]=Math.cos(n)*a,e[1]=Math.sin(n)*a,e[2]=r*t,e}static transformMat4(e,t,n){let r=t[0],a=t[1],s=t[2],i=n[3]*r+n[7]*a+n[11]*s+n[15]||1;return e[0]=(n[0]*r+n[4]*a+n[8]*s+n[12])/i,e[1]=(n[1]*r+n[5]*a+n[9]*s+n[13])/i,e[2]=(n[2]*r+n[6]*a+n[10]*s+n[14])/i,e}static transformMat3(e,t,n){let r=t[0],a=t[1],s=t[2];return e[0]=r*n[0]+a*n[3]+s*n[6],e[1]=r*n[1]+a*n[4]+s*n[7],e[2]=r*n[2]+a*n[5]+s*n[8],e}static transformQuat(e,t,n){let r=n[0],a=n[1],s=n[2],i=n[3]*2,c=t[0],y=t[1],L=t[2],k=a*L-s*y,l=s*c-r*L,b=r*y-a*c,M=(a*b-s*l)*2,d=(s*k-r*b)*2,m=(r*l-a*k)*2;return e[0]=c+k*i+M,e[1]=y+l*i+d,e[2]=L+b*i+m,e}static rotateX(e,t,n,r){let a=n[1],s=n[2],i=t[1]-a,c=t[2]-s;return e[0]=t[0],e[1]=i*Math.cos(r)-c*Math.sin(r)+a,e[2]=i*Math.sin(r)+c*Math.cos(r)+s,e}static rotateY(e,t,n,r){let a=n[0],s=n[2],i=t[0]-a,c=t[2]-s;return e[0]=c*Math.sin(r)+i*Math.cos(r)+a,e[1]=t[1],e[2]=c*Math.cos(r)-i*Math.sin(r)+s,e}static rotateZ(e,t,n,r){let a=n[0],s=n[1],i=t[0]-a,c=t[1]-s;return e[0]=i*Math.cos(r)-c*Math.sin(r)+a,e[1]=i*Math.sin(r)+c*Math.cos(r)+s,e[2]=n[2],e}static angle(e,t){let n=e[0],r=e[1],a=e[2],s=t[0],i=t[1],c=t[2],y=Math.sqrt((n*n+r*r+a*a)*(s*s+i*i+c*c)),L=y&&h.dot(e,t)/y;return Math.acos(Math.min(Math.max(L,-1),1))}static zero(e){return e[0]=0,e[1]=0,e[2]=0,e}static str(e){return`Vec3(${e.join(", ")})`}static exactEquals(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]}static equals(e,t){let n=e[0],r=e[1],a=e[2],s=t[0],i=t[1],c=t[2];return Math.abs(n-s)<=1e-6*Math.max(1,Math.abs(n),Math.abs(s))&&Math.abs(r-i)<=1e-6*Math.max(1,Math.abs(r),Math.abs(i))&&Math.abs(a-c)<=1e-6*Math.max(1,Math.abs(a),Math.abs(c))}};A.prototype.sub=A.prototype.subtract;A.prototype.mul=A.prototype.multiply;A.prototype.div=A.prototype.divide;A.prototype.dist=A.prototype.distance;A.prototype.sqrDist=A.prototype.squaredDistance;A.sub=A.subtract;A.mul=A.multiply;A.div=A.divide;A.dist=A.distance;A.sqrDist=A.squaredDistance;A.sqrLen=A.squaredLength;A.mag=A.magnitude;A.length=A.magnitude;A.len=A.magnitude;var Me=A;var q=class h extends Float32Array{static BYTE_LENGTH=4*Float32Array.BYTES_PER_ELEMENT;constructor(...e){switch(e.length){case 4:super(e);break;case 2:super(e[0],e[1],4);break;case 1:{let t=e[0];typeof t=="number"?super([t,t,t,t]):super(t,0,4);break}default:super(4);break}}get x(){return this[0]}set x(e){this[0]=e}get y(){return this[1]}set y(e){this[1]=e}get z(){return this[2]}set z(e){this[2]=e}get w(){return this[3]}set w(e){this[3]=e}get r(){return this[0]}set r(e){this[0]=e}get g(){return this[1]}set g(e){this[1]=e}get b(){return this[2]}set b(e){this[2]=e}get a(){return this[3]}set a(e){this[3]=e}get magnitude(){let e=this[0],t=this[1],n=this[2],r=this[3];return Math.sqrt(e*e+t*t+n*n+r*r)}get mag(){return this.magnitude}get str(){return h.str(this)}copy(e){return super.set(e),this}add(e){return this[0]+=e[0],this[1]+=e[1],this[2]+=e[2],this[3]+=e[3],this}subtract(e){return this[0]-=e[0],this[1]-=e[1],this[2]-=e[2],this[3]-=e[3],this}sub(e){return this}multiply(e){return this[0]*=e[0],this[1]*=e[1],this[2]*=e[2],this[3]*=e[3],this}mul(e){return this}divide(e){return this[0]/=e[0],this[1]/=e[1],this[2]/=e[2],this[3]/=e[3],this}div(e){return this}scale(e){return this[0]*=e,this[1]*=e,this[2]*=e,this[3]*=e,this}scaleAndAdd(e,t){return this[0]+=e[0]*t,this[1]+=e[1]*t,this[2]+=e[2]*t,this[3]+=e[3]*t,this}distance(e){return h.distance(this,e)}dist(e){return 0}squaredDistance(e){return h.squaredDistance(this,e)}sqrDist(e){return 0}negate(){return this[0]*=-1,this[1]*=-1,this[2]*=-1,this[3]*=-1,this}invert(){return this[0]=1/this[0],this[1]=1/this[1],this[2]=1/this[2],this[3]=1/this[3],this}abs(){return this[0]=Math.abs(this[0]),this[1]=Math.abs(this[1]),this[2]=Math.abs(this[2]),this[3]=Math.abs(this[3]),this}dot(e){return this[0]*e[0]+this[1]*e[1]+this[2]*e[2]+this[3]*e[3]}normalize(){return h.normalize(this,this)}static create(){return new h}static clone(e){return new h(e)}static fromValues(e,t,n,r){return new h(e,t,n,r)}static copy(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}static set(e,t,n,r,a){return e[0]=t,e[1]=n,e[2]=r,e[3]=a,e}static add(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e[2]=t[2]+n[2],e[3]=t[3]+n[3],e}static subtract(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e[2]=t[2]-n[2],e[3]=t[3]-n[3],e}static sub(e,t,n){return e}static multiply(e,t,n){return e[0]=t[0]*n[0],e[1]=t[1]*n[1],e[2]=t[2]*n[2],e[3]=t[3]*n[3],e}static mul(e,t,n){return e}static divide(e,t,n){return e[0]=t[0]/n[0],e[1]=t[1]/n[1],e[2]=t[2]/n[2],e[3]=t[3]/n[3],e}static div(e,t,n){return e}static ceil(e,t){return e[0]=Math.ceil(t[0]),e[1]=Math.ceil(t[1]),e[2]=Math.ceil(t[2]),e[3]=Math.ceil(t[3]),e}static floor(e,t){return e[0]=Math.floor(t[0]),e[1]=Math.floor(t[1]),e[2]=Math.floor(t[2]),e[3]=Math.floor(t[3]),e}static min(e,t,n){return e[0]=Math.min(t[0],n[0]),e[1]=Math.min(t[1],n[1]),e[2]=Math.min(t[2],n[2]),e[3]=Math.min(t[3],n[3]),e}static max(e,t,n){return e[0]=Math.max(t[0],n[0]),e[1]=Math.max(t[1],n[1]),e[2]=Math.max(t[2],n[2]),e[3]=Math.max(t[3],n[3]),e}static round(e,t){return e[0]=Math.round(t[0]),e[1]=Math.round(t[1]),e[2]=Math.round(t[2]),e[3]=Math.round(t[3]),e}static scale(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e[2]=t[2]*n,e[3]=t[3]*n,e}static scaleAndAdd(e,t,n,r){return e[0]=t[0]+n[0]*r,e[1]=t[1]+n[1]*r,e[2]=t[2]+n[2]*r,e[3]=t[3]+n[3]*r,e}static distance(e,t){let n=t[0]-e[0],r=t[1]-e[1],a=t[2]-e[2],s=t[3]-e[3];return Math.hypot(n,r,a,s)}static dist(e,t){return 0}static squaredDistance(e,t){let n=t[0]-e[0],r=t[1]-e[1],a=t[2]-e[2],s=t[3]-e[3];return n*n+r*r+a*a+s*s}static sqrDist(e,t){return 0}static magnitude(e){let t=e[0],n=e[1],r=e[2],a=e[3];return Math.sqrt(t*t+n*n+r*r+a*a)}static mag(e){return 0}static length(e){return 0}static len(e){return 0}static squaredLength(e){let t=e[0],n=e[1],r=e[2],a=e[3];return t*t+n*n+r*r+a*a}static sqrLen(e){return 0}static negate(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e}static inverse(e,t){return e[0]=1/t[0],e[1]=1/t[1],e[2]=1/t[2],e[3]=1/t[3],e}static abs(e,t){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e[2]=Math.abs(t[2]),e[3]=Math.abs(t[3]),e}static normalize(e,t){let n=t[0],r=t[1],a=t[2],s=t[3],i=n*n+r*r+a*a+s*s;return i>0&&(i=1/Math.sqrt(i)),e[0]=n*i,e[1]=r*i,e[2]=a*i,e[3]=s*i,e}static dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3]}static cross(e,t,n,r){let a=n[0]*r[1]-n[1]*r[0],s=n[0]*r[2]-n[2]*r[0],i=n[0]*r[3]-n[3]*r[0],c=n[1]*r[2]-n[2]*r[1],y=n[1]*r[3]-n[3]*r[1],L=n[2]*r[3]-n[3]*r[2],k=t[0],l=t[1],b=t[2],M=t[3];return e[0]=l*L-b*y+M*c,e[1]=-(k*L)+b*i-M*s,e[2]=k*y-l*i+M*a,e[3]=-(k*c)+l*s-b*a,e}static lerp(e,t,n,r){let a=t[0],s=t[1],i=t[2],c=t[3];return e[0]=a+r*(n[0]-a),e[1]=s+r*(n[1]-s),e[2]=i+r*(n[2]-i),e[3]=c+r*(n[3]-c),e}static random(e,t){t=t||1;var n,r,a,s,i,c;do n=Math.random()*2-1,r=Math.random()*2-1,i=n*n+r*r;while(i>=1);do a=Math.random()*2-1,s=Math.random()*2-1,c=a*a+s*s;while(c>=1);var y=Math.sqrt((1-i)/c);return e[0]=t*n,e[1]=t*r,e[2]=t*a*y,e[3]=t*s*y,e}static transformMat4(e,t,n){let r=t[0],a=t[1],s=t[2],i=t[3];return e[0]=n[0]*r+n[4]*a+n[8]*s+n[12]*i,e[1]=n[1]*r+n[5]*a+n[9]*s+n[13]*i,e[2]=n[2]*r+n[6]*a+n[10]*s+n[14]*i,e[3]=n[3]*r+n[7]*a+n[11]*s+n[15]*i,e}static transformQuat(e,t,n){let r=t[0],a=t[1],s=t[2],i=n[0],c=n[1],y=n[2],L=n[3],k=L*r+c*s-y*a,l=L*a+y*r-i*s,b=L*s+i*a-c*r,M=-i*r-c*a-y*s;return e[0]=k*L+M*-i+l*-y-b*-c,e[1]=l*L+M*-c+b*-i-k*-y,e[2]=b*L+M*-y+k*-c-l*-i,e[3]=t[3],e}static zero(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=0,e}static str(e){return`Vec4(${e.join(", ")})`}static exactEquals(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]}static equals(e,t){let n=e[0],r=e[1],a=e[2],s=e[3],i=t[0],c=t[1],y=t[2],L=t[3];return Math.abs(n-i)<=1e-6*Math.max(1,Math.abs(n),Math.abs(i))&&Math.abs(r-c)<=1e-6*Math.max(1,Math.abs(r),Math.abs(c))&&Math.abs(a-y)<=1e-6*Math.max(1,Math.abs(a),Math.abs(y))&&Math.abs(s-L)<=1e-6*Math.max(1,Math.abs(s),Math.abs(L))}};q.prototype.sub=q.prototype.subtract;q.prototype.mul=q.prototype.multiply;q.prototype.div=q.prototype.divide;q.prototype.dist=q.prototype.distance;q.prototype.sqrDist=q.prototype.squaredDistance;q.sub=q.subtract;q.mul=q.multiply;q.div=q.divide;q.dist=q.distance;q.sqrDist=q.squaredDistance;q.sqrLen=q.squaredLength;q.mag=q.magnitude;q.length=q.magnitude;q.len=q.magnitude;var be=q;var I=class h extends Float32Array{static BYTE_LENGTH=4*Float32Array.BYTES_PER_ELEMENT;constructor(...e){switch(e.length){case 4:super(e);break;case 2:super(e[0],e[1],4);break;case 1:{let t=e[0];typeof t=="number"?super([t,t,t,t]):super(t,0,4);break}default:super(4),this[3]=1;break}}get x(){return this[0]}set x(e){this[0]=e}get y(){return this[1]}set y(e){this[1]=e}get z(){return this[2]}set z(e){this[2]=e}get w(){return this[3]}set w(e){this[3]=e}get magnitude(){let e=this[0],t=this[1],n=this[2],r=this[3];return Math.sqrt(e*e+t*t+n*n+r*r)}get mag(){return this.magnitude}get str(){return h.str(this)}copy(e){return super.set(e),this}identity(){return this[0]=0,this[1]=0,this[2]=0,this[3]=1,this}multiply(e){return h.multiply(this,this,e)}mul(e){return this}rotateX(e){return h.rotateX(this,this,e)}rotateY(e){return h.rotateY(this,this,e)}rotateZ(e){return h.rotateZ(this,this,e)}invert(){return h.invert(this,this)}scale(e){return this[0]*=e,this[1]*=e,this[2]*=e,this[3]*=e,this}dot(e){return h.dot(this,e)}static create(){return new h}static identity(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e}static setAxisAngle(e,t,n){n=n*.5;let r=Math.sin(n);return e[0]=r*t[0],e[1]=r*t[1],e[2]=r*t[2],e[3]=Math.cos(n),e}static getAxisAngle(e,t){let n=Math.acos(t[3])*2,r=Math.sin(n/2);return r>1e-6?(e[0]=t[0]/r,e[1]=t[1]/r,e[2]=t[2]/r):(e[0]=1,e[1]=0,e[2]=0),n}static getAngle(e,t){let n=h.dot(e,t);return Math.acos(2*n*n-1)}static multiply(e,t,n){let r=t[0],a=t[1],s=t[2],i=t[3],c=n[0],y=n[1],L=n[2],k=n[3];return e[0]=r*k+i*c+a*L-s*y,e[1]=a*k+i*y+s*c-r*L,e[2]=s*k+i*L+r*y-a*c,e[3]=i*k-r*c-a*y-s*L,e}static rotateX(e,t,n){n*=.5;let r=t[0],a=t[1],s=t[2],i=t[3],c=Math.sin(n),y=Math.cos(n);return e[0]=r*y+i*c,e[1]=a*y+s*c,e[2]=s*y-a*c,e[3]=i*y-r*c,e}static rotateY(e,t,n){n*=.5;let r=t[0],a=t[1],s=t[2],i=t[3],c=Math.sin(n),y=Math.cos(n);return e[0]=r*y-s*c,e[1]=a*y+i*c,e[2]=s*y+r*c,e[3]=i*y-a*c,e}static rotateZ(e,t,n){n*=.5;let r=t[0],a=t[1],s=t[2],i=t[3],c=Math.sin(n),y=Math.cos(n);return e[0]=r*y+a*c,e[1]=a*y-r*c,e[2]=s*y+i*c,e[3]=i*y-s*c,e}static calculateW(e,t){let n=t[0],r=t[1],a=t[2];return e[0]=n,e[1]=r,e[2]=a,e[3]=Math.sqrt(Math.abs(1-n*n-r*r-a*a)),e}static exp(e,t){let n=t[0],r=t[1],a=t[2],s=t[3],i=Math.sqrt(n*n+r*r+a*a),c=Math.exp(s),y=i>0?c*Math.sin(i)/i:0;return e[0]=n*y,e[1]=r*y,e[2]=a*y,e[3]=c*Math.cos(i),e}static ln(e,t){let n=t[0],r=t[1],a=t[2],s=t[3],i=Math.sqrt(n*n+r*r+a*a),c=i>0?Math.atan2(i,s)/i:0;return e[0]=n*c,e[1]=r*c,e[2]=a*c,e[3]=.5*Math.log(n*n+r*r+a*a+s*s),e}static pow(e,t,n){return h.ln(e,t),h.scale(e,e,n),h.exp(e,e),e}static slerp(e,t,n,r){let a=t[0],s=t[1],i=t[2],c=t[3],y=n[0],L=n[1],k=n[2],l=n[3],b,M,d=a*y+s*L+i*k+c*l;if(d<0&&(d=-d,y=-y,L=-L,k=-k,l=-l),1-d>1e-6){let m=Math.acos(d),o=Math.sin(m);b=Math.sin((1-r)*m)/o,M=Math.sin(r*m)/o}else b=1-r,M=r;return e[0]=b*a+M*y,e[1]=b*s+M*L,e[2]=b*i+M*k,e[3]=b*c+M*l,e}static random(e){let t=Math.random(),n=Math.random(),r=Math.random(),a=Math.sqrt(1-t),s=Math.sqrt(t);return e[0]=a*Math.sin(2*Math.PI*n),e[1]=a*Math.cos(2*Math.PI*n),e[2]=s*Math.sin(2*Math.PI*r),e[3]=s*Math.cos(2*Math.PI*r),e}static invert(e,t){let n=t[0],r=t[1],a=t[2],s=t[3],i=n*n+r*r+a*a+s*s,c=i?1/i:0;return e[0]=-n*c,e[1]=-r*c,e[2]=-a*c,e[3]=s*c,e}static conjugate(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=t[3],e}static fromMat3(e,t){let n=t[0]+t[4]+t[8],r;if(n>0)r=Math.sqrt(n+1),e[3]=.5*r,r=.5/r,e[0]=(t[5]-t[7])*r,e[1]=(t[6]-t[2])*r,e[2]=(t[1]-t[3])*r;else{let a=0;t[4]>t[0]&&(a=1),t[8]>t[a*3+a]&&(a=2);let s=(a+1)%3,i=(a+2)%3;r=Math.sqrt(t[a*3+a]-t[s*3+s]-t[i*3+i]+1),e[a]=.5*r,r=.5/r,e[3]=(t[s*3+i]-t[i*3+s])*r,e[s]=(t[s*3+a]+t[a*3+s])*r,e[i]=(t[i*3+a]+t[a*3+i])*r}return e}static fromEuler(e,t,n,r,a=u){let s=.5*Math.PI/180;t*=s,n*=s,r*=s;let i=Math.sin(t),c=Math.cos(t),y=Math.sin(n),L=Math.cos(n),k=Math.sin(r),l=Math.cos(r);switch(a){case"xyz":e[0]=i*L*l+c*y*k,e[1]=c*y*l-i*L*k,e[2]=c*L*k+i*y*l,e[3]=c*L*l-i*y*k;break;case"xzy":e[0]=i*L*l-c*y*k,e[1]=c*y*l-i*L*k,e[2]=c*L*k+i*y*l,e[3]=c*L*l+i*y*k;break;case"yxz":e[0]=i*L*l+c*y*k,e[1]=c*y*l-i*L*k,e[2]=c*L*k-i*y*l,e[3]=c*L*l+i*y*k;break;case"yzx":e[0]=i*L*l+c*y*k,e[1]=c*y*l+i*L*k,e[2]=c*L*k-i*y*l,e[3]=c*L*l-i*y*k;break;case"zxy":e[0]=i*L*l-c*y*k,e[1]=c*y*l+i*L*k,e[2]=c*L*k+i*y*l,e[3]=c*L*l-i*y*k;break;case"zyx":e[0]=i*L*l-c*y*k,e[1]=c*y*l+i*L*k,e[2]=c*L*k-i*y*l,e[3]=c*L*l+i*y*k;break;default:throw new Error("Unknown angle order "+a)}return e}static str(e){return`Quat(${e.join(", ")})`}static clone(e){return new h(e)}static fromValues(e,t,n,r){return new h(e,t,n,r)}static copy(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}static set(e,t,n,r,a){return e}static add(e,t,n){return e}static mul(e,t,n){return e}static scale(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e[2]=t[2]*n,e[3]=t[3]*n,e}static dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3]}static lerp(e,t,n,r){return e}static magnitude(e){return 0}static mag(e){return 0}static length(e){return 0}static len(e){return 0}static squaredLength(e){return 0}static sqrLen(e){return 0}static normalize(e,t){return e}static exactEquals(e,t){return!1}static equals(e,t){return!1}static rotationTo(e,t,n){let r=A.dot(t,n);return r<-.999999?(A.cross(H,de,t),A.mag(H)<1e-6&&A.cross(H,he,t),A.normalize(H,H),h.setAxisAngle(e,H,Math.PI),e):r>.999999?(e[0]=0,e[1]=0,e[2]=0,e[3]=1,e):(A.cross(H,t,n),e[0]=H[0],e[1]=H[1],e[2]=H[2],e[3]=1+r,h.normalize(e,e))}static sqlerp(e,t,n,r,a,s){return h.slerp(re,t,a,s),h.slerp(ae,n,r,s),h.slerp(e,re,ae,2*s*(1-s)),e}static setAxes(e,t,n,r){return G[0]=n[0],G[3]=n[1],G[6]=n[2],G[1]=r[0],G[4]=r[1],G[7]=r[2],G[2]=-t[0],G[5]=-t[1],G[8]=-t[2],h.normalize(e,h.fromMat3(e,G))}},re=new Float32Array(4),ae=new Float32Array(4),G=new Float32Array(9),H=new Float32Array(3),de=new Float32Array([1,0,0]),he=new Float32Array([0,1,0]);I.set=q.set;I.add=q.add;I.lerp=q.lerp;I.normalize=q.normalize;I.squaredLength=q.squaredLength;I.sqrLen=q.squaredLength;I.exactEquals=q.exactEquals;I.equals=q.equals;I.magnitude=q.magnitude;I.prototype.mul=I.prototype.multiply;I.mul=I.multiply;I.mag=I.magnitude;I.length=I.magnitude;I.len=I.magnitude;var me=I;var P=class h extends Float32Array{static BYTE_LENGTH=8*Float32Array.BYTES_PER_ELEMENT;constructor(...e){switch(e.length){case 8:super(e);break;case 2:super(e[0],e[1],8);break;case 1:{let t=e[0];typeof t=="number"?super([t,t,t,t,t,t,t,t]):super(t,0,8);break}default:super(8),this[3]=1;break}}get str(){return h.str(this)}copy(e){return super.set(e),this}static create(){return new h}static clone(e){return new h(e)}static fromValues(e,t,n,r,a,s,i,c){return new h(e,t,n,r,a,s,i,c)}static fromRotationTranslationValues(e,t,n,r,a,s,i){let c=a*.5,y=s*.5,L=i*.5;return new h(e,t,n,r,c*r+y*n-L*t,y*r+L*e-c*n,L*r+c*t-y*e,-c*e-y*t-L*n)}static fromRotationTranslation(e,t,n){let r=n[0]*.5,a=n[1]*.5,s=n[2]*.5,i=t[0],c=t[1],y=t[2],L=t[3];return e[0]=i,e[1]=c,e[2]=y,e[3]=L,e[4]=r*L+a*y-s*c,e[5]=a*L+s*i-r*y,e[6]=s*L+r*c-a*i,e[7]=-r*i-a*c-s*y,e}static fromTranslation(e,t){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e[4]=t[0]*.5,e[5]=t[1]*.5,e[6]=t[2]*.5,e[7]=0,e}static fromRotation(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=0,e[5]=0,e[6]=0,e[7]=0,e}static fromMat4(e,t){return O.getRotation(se,t),O.getTranslation(ie,t),h.fromRotationTranslation(e,se,ie)}static copy(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e}static identity(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e[4]=0,e[5]=0,e[6]=0,e[7]=0,e}static set(e,t,n,r,a,s,i,c,y){return e[0]=t,e[1]=n,e[2]=r,e[3]=a,e[4]=s,e[5]=i,e[6]=c,e[7]=y,e}static getReal(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}static getDual(e,t){return e[0]=t[4],e[1]=t[5],e[2]=t[6],e[3]=t[7],e}static setReal(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}static setDual(e,t){return e[4]=t[0],e[5]=t[1],e[6]=t[2],e[7]=t[3],e}static getTranslation(e,t){let n=t[4],r=t[5],a=t[6],s=t[7],i=-t[0],c=-t[1],y=-t[2],L=t[3];return e[0]=(n*L+s*i+r*y-a*c)*2,e[1]=(r*L+s*c+a*i-n*y)*2,e[2]=(a*L+s*y+n*c-r*i)*2,e}static translate(e,t,n){let r=t[0],a=t[1],s=t[2],i=t[3],c=n[0]*.5,y=n[1]*.5,L=n[2]*.5,k=t[4],l=t[5],b=t[6],M=t[7];return e[0]=r,e[1]=a,e[2]=s,e[3]=i,e[4]=i*c+a*L-s*y+k,e[5]=i*y+s*c-r*L+l,e[6]=i*L+r*y-a*c+b,e[7]=-r*c-a*y-s*L+M,e}static rotateX(e,t,n){let r=-t[0],a=-t[1],s=-t[2],i=t[3],c=t[4],y=t[5],L=t[6],k=t[7],l=c*i+k*r+y*s-L*a,b=y*i+k*a+L*r-c*s,M=L*i+k*s+c*a-y*r,d=k*i-c*r-y*a-L*s;return I.rotateX(e,t,n),r=e[0],a=e[1],s=e[2],i=e[3],e[4]=l*i+d*r+b*s-M*a,e[5]=b*i+d*a+M*r-l*s,e[6]=M*i+d*s+l*a-b*r,e[7]=d*i-l*r-b*a-M*s,e}static rotateY(e,t,n){let r=-t[0],a=-t[1],s=-t[2],i=t[3],c=t[4],y=t[5],L=t[6],k=t[7],l=c*i+k*r+y*s-L*a,b=y*i+k*a+L*r-c*s,M=L*i+k*s+c*a-y*r,d=k*i-c*r-y*a-L*s;return I.rotateY(e,t,n),r=e[0],a=e[1],s=e[2],i=e[3],e[4]=l*i+d*r+b*s-M*a,e[5]=b*i+d*a+M*r-l*s,e[6]=M*i+d*s+l*a-b*r,e[7]=d*i-l*r-b*a-M*s,e}static rotateZ(e,t,n){let r=-t[0],a=-t[1],s=-t[2],i=t[3],c=t[4],y=t[5],L=t[6],k=t[7],l=c*i+k*r+y*s-L*a,b=y*i+k*a+L*r-c*s,M=L*i+k*s+c*a-y*r,d=k*i-c*r-y*a-L*s;return I.rotateZ(e,t,n),r=e[0],a=e[1],s=e[2],i=e[3],e[4]=l*i+d*r+b*s-M*a,e[5]=b*i+d*a+M*r-l*s,e[6]=M*i+d*s+l*a-b*r,e[7]=d*i-l*r-b*a-M*s,e}static rotateByQuatAppend(e,t,n){let r=n[0],a=n[1],s=n[2],i=n[3],c=t[0],y=t[1],L=t[2],k=t[3];return e[0]=c*i+k*r+y*s-L*a,e[1]=y*i+k*a+L*r-c*s,e[2]=L*i+k*s+c*a-y*r,e[3]=k*i-c*r-y*a-L*s,c=t[4],y=t[5],L=t[6],k=t[7],e[4]=c*i+k*r+y*s-L*a,e[5]=y*i+k*a+L*r-c*s,e[6]=L*i+k*s+c*a-y*r,e[7]=k*i-c*r-y*a-L*s,e}static rotateByQuatPrepend(e,t,n){let r=t[0],a=t[1],s=t[2],i=t[3],c=n[0],y=n[1],L=n[2],k=n[3];return e[0]=r*k+i*c+a*L-s*y,e[1]=a*k+i*y+s*c-r*L,e[2]=s*k+i*L+r*y-a*c,e[3]=i*k-r*c-a*y-s*L,c=n[4],y=n[5],L=n[6],k=n[7],e[4]=r*k+i*c+a*L-s*y,e[5]=a*k+i*y+s*c-r*L,e[6]=s*k+i*L+r*y-a*c,e[7]=i*k-r*c-a*y-s*L,e}static rotateAroundAxis(e,t,n,r){if(Math.abs(r)<1e-6)return h.copy(e,t);let a=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);r=r*.5;let s=Math.sin(r),i=s*n[0]/a,c=s*n[1]/a,y=s*n[2]/a,L=Math.cos(r),k=t[0],l=t[1],b=t[2],M=t[3];e[0]=k*L+M*i+l*y-b*c,e[1]=l*L+M*c+b*i-k*y,e[2]=b*L+M*y+k*c-l*i,e[3]=M*L-k*i-l*c-b*y;let d=t[4],m=t[5],o=t[6],x=t[7];return e[4]=d*L+x*i+m*y-o*c,e[5]=m*L+x*c+o*i-d*y,e[6]=o*L+x*y+d*c-m*i,e[7]=x*L-d*i-m*c-o*y,e}static add(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e[2]=t[2]+n[2],e[3]=t[3]+n[3],e[4]=t[4]+n[4],e[5]=t[5]+n[5],e[6]=t[6]+n[6],e[7]=t[7]+n[7],e}static multiply(e,t,n){let r=t[0],a=t[1],s=t[2],i=t[3],c=n[4],y=n[5],L=n[6],k=n[7],l=t[4],b=t[5],M=t[6],d=t[7],m=n[0],o=n[1],x=n[2],z=n[3];return e[0]=r*z+i*m+a*x-s*o,e[1]=a*z+i*o+s*m-r*x,e[2]=s*z+i*x+r*o-a*m,e[3]=i*z-r*m-a*o-s*x,e[4]=r*k+i*c+a*L-s*y+l*z+d*m+b*x-M*o,e[5]=a*k+i*y+s*c-r*L+b*z+d*o+M*m-l*x,e[6]=s*k+i*L+r*y-a*c+M*z+d*x+l*o-b*m,e[7]=i*k-r*c-a*y-s*L+d*z-l*m-b*o-M*x,e}static mul(e,t,n){return e}static scale(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e[2]=t[2]*n,e[3]=t[3]*n,e[4]=t[4]*n,e[5]=t[5]*n,e[6]=t[6]*n,e[7]=t[7]*n,e}static dot(e,t){return 0}static lerp(e,t,n,r){let a=1-r;return h.dot(t,n)<0&&(r=-r),e[0]=t[0]*a+n[0]*r,e[1]=t[1]*a+n[1]*r,e[2]=t[2]*a+n[2]*r,e[3]=t[3]*a+n[3]*r,e[4]=t[4]*a+n[4]*r,e[5]=t[5]*a+n[5]*r,e[6]=t[6]*a+n[6]*r,e[7]=t[7]*a+n[7]*r,e}static invert(e,t){let n=h.squaredLength(t);return e[0]=-t[0]/n,e[1]=-t[1]/n,e[2]=-t[2]/n,e[3]=t[3]/n,e[4]=-t[4]/n,e[5]=-t[5]/n,e[6]=-t[6]/n,e[7]=t[7]/n,e}static conjugate(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=t[3],e[4]=-t[4],e[5]=-t[5],e[6]=-t[6],e[7]=t[7],e}static magnitude(e){return 0}static mag(e){return 0}static length(e){return 0}static len(e){return 0}static squaredLength(e){return 0}static sqrLen(e){return 0}static normalize(e,t){let n=h.squaredLength(t);if(n>0){n=Math.sqrt(n);let r=t[0]/n,a=t[1]/n,s=t[2]/n,i=t[3]/n,c=t[4],y=t[5],L=t[6],k=t[7],l=r*c+a*y+s*L+i*k;e[0]=r,e[1]=a,e[2]=s,e[3]=i,e[4]=(c-r*l)/n,e[5]=(y-a*l)/n,e[6]=(L-s*l)/n,e[7]=(k-i*l)/n}return e}static str(e){return`Quat2(${e.join(", ")})`}static exactEquals(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]}static equals(e,t){let n=e[0],r=e[1],a=e[2],s=e[3],i=e[4],c=e[5],y=e[6],L=e[7],k=t[0],l=t[1],b=t[2],M=t[3],d=t[4],m=t[5],o=t[6],x=t[7];return Math.abs(n-k)<=1e-6*Math.max(1,Math.abs(n),Math.abs(k))&&Math.abs(r-l)<=1e-6*Math.max(1,Math.abs(r),Math.abs(l))&&Math.abs(a-b)<=1e-6*Math.max(1,Math.abs(a),Math.abs(b))&&Math.abs(s-M)<=1e-6*Math.max(1,Math.abs(s),Math.abs(M))&&Math.abs(i-d)<=1e-6*Math.max(1,Math.abs(i),Math.abs(d))&&Math.abs(c-m)<=1e-6*Math.max(1,Math.abs(c),Math.abs(m))&&Math.abs(y-o)<=1e-6*Math.max(1,Math.abs(y),Math.abs(o))&&Math.abs(L-x)<=1e-6*Math.max(1,Math.abs(L),Math.abs(x))}},se=new Float32Array(4),ie=new Float32Array(3);P.dot=I.dot;P.squaredLength=I.squaredLength;P.sqrLen=I.squaredLength;P.mag=I.magnitude;P.length=I.magnitude;P.len=I.magnitude;P.mul=P.multiply;var oe=P;var S=class h extends Float32Array{static BYTE_LENGTH=2*Float32Array.BYTES_PER_ELEMENT;constructor(...e){switch(e.length){case 2:{let t=e[0];typeof t=="number"?super([t,e[1]]):super(t,e[1],2);break}case 1:{let t=e[0];typeof t=="number"?super([t,t]):super(t,0,2);break}default:super(2);break}}get x(){return this[0]}set x(e){this[0]=e}get y(){return this[1]}set y(e){this[1]=e}get r(){return this[0]}set r(e){this[0]=e}get g(){return this[1]}set g(e){this[1]=e}get magnitude(){return Math.hypot(this[0],this[1])}get mag(){return this.magnitude}get squaredMagnitude(){let e=this[0],t=this[1];return e*e+t*t}get sqrMag(){return this.squaredMagnitude}get str(){return h.str(this)}copy(e){return this.set(e),this}add(e){return this[0]+=e[0],this[1]+=e[1],this}subtract(e){return this[0]-=e[0],this[1]-=e[1],this}sub(e){return this}multiply(e){return this[0]*=e[0],this[1]*=e[1],this}mul(e){return this}divide(e){return this[0]/=e[0],this[1]/=e[1],this}div(e){return this}scale(e){return this[0]*=e,this[1]*=e,this}scaleAndAdd(e,t){return this[0]+=e[0]*t,this[1]+=e[1]*t,this}distance(e){return h.distance(this,e)}dist(e){return 0}squaredDistance(e){return h.squaredDistance(this,e)}sqrDist(e){return 0}negate(){return this[0]*=-1,this[1]*=-1,this}invert(){return this[0]=1/this[0],this[1]=1/this[1],this}abs(){return this[0]=Math.abs(this[0]),this[1]=Math.abs(this[1]),this}dot(e){return this[0]*e[0]+this[1]*e[1]}normalize(){return h.normalize(this,this)}static create(){return new h}static clone(e){return new h(e)}static fromValues(e,t){return new h(e,t)}static copy(e,t){return e[0]=t[0],e[1]=t[1],e}static set(e,t,n){return e[0]=t,e[1]=n,e}static add(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e}static subtract(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e}static sub(e,t,n){return[0,0]}static multiply(e,t,n){return e[0]=t[0]*n[0],e[1]=t[1]*n[1],e}static mul(e,t,n){return[0,0]}static divide(e,t,n){return e[0]=t[0]/n[0],e[1]=t[1]/n[1],e}static div(e,t,n){return[0,0]}static ceil(e,t){return e[0]=Math.ceil(t[0]),e[1]=Math.ceil(t[1]),e}static floor(e,t){return e[0]=Math.floor(t[0]),e[1]=Math.floor(t[1]),e}static min(e,t,n){return e[0]=Math.min(t[0],n[0]),e[1]=Math.min(t[1],n[1]),e}static max(e,t,n){return e[0]=Math.max(t[0],n[0]),e[1]=Math.max(t[1],n[1]),e}static round(e,t){return e[0]=Math.round(t[0]),e[1]=Math.round(t[1]),e}static scale(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e}static scaleAndAdd(e,t,n,r){return e[0]=t[0]+n[0]*r,e[1]=t[1]+n[1]*r,e}static distance(e,t){return Math.hypot(t[0]-e[0],t[1]-e[1])}static dist(e,t){return 0}static squaredDistance(e,t){let n=t[0]-e[0],r=t[1]-e[1];return n*n+r*r}static sqrDist(e,t){return 0}static magnitude(e){let t=e[0],n=e[1];return Math.sqrt(t*t+n*n)}static mag(e){return 0}static length(e){return 0}static len(e){return 0}static squaredLength(e){let t=e[0],n=e[1];return t*t+n*n}static sqrLen(e,t){return 0}static negate(e,t){return e[0]=-t[0],e[1]=-t[1],e}static inverse(e,t){return e[0]=1/t[0],e[1]=1/t[1],e}static abs(e,t){return e[0]=Math.abs(t[0]),e[1]=Math.abs(t[1]),e}static normalize(e,t){let n=t[0],r=t[1],a=n*n+r*r;return a>0&&(a=1/Math.sqrt(a)),e[0]=t[0]*a,e[1]=t[1]*a,e}static dot(e,t){return e[0]*t[0]+e[1]*t[1]}static cross(e,t,n){let r=t[0]*n[1]-t[1]*n[0];return e[0]=e[1]=0,e[2]=r,e}static lerp(e,t,n,r){let a=t[0],s=t[1];return e[0]=a+r*(n[0]-a),e[1]=s+r*(n[1]-s),e}static transformMat2(e,t,n){let r=t[0],a=t[1];return e[0]=n[0]*r+n[2]*a,e[1]=n[1]*r+n[3]*a,e}static transformMat2d(e,t,n){let r=t[0],a=t[1];return e[0]=n[0]*r+n[2]*a+n[4],e[1]=n[1]*r+n[3]*a+n[5],e}static transformMat3(e,t,n){let r=t[0],a=t[1];return e[0]=n[0]*r+n[3]*a+n[6],e[1]=n[1]*r+n[4]*a+n[7],e}static transformMat4(e,t,n){let r=t[0],a=t[1];return e[0]=n[0]*r+n[4]*a+n[12],e[1]=n[1]*r+n[5]*a+n[13],e}static rotate(e,t,n,r){let a=t[0]-n[0],s=t[1]-n[1],i=Math.sin(r),c=Math.cos(r);return e[0]=a*c-s*i+n[0],e[1]=a*i+s*c+n[1],e}static angle(e,t){let n=e[0],r=e[1],a=t[0],s=t[1],i=Math.sqrt(n*n+r*r)*Math.sqrt(a*a+s*s),c=i&&(n*a+r*s)/i;return Math.acos(Math.min(Math.max(c,-1),1))}static zero(e){return e[0]=0,e[1]=0,e}static exactEquals(e,t){return e[0]===t[0]&&e[1]===t[1]}static equals(e,t){let n=e[0],r=e[1],a=t[0],s=t[1];return Math.abs(n-a)<=1e-6*Math.max(1,Math.abs(n),Math.abs(a))&&Math.abs(r-s)<=1e-6*Math.max(1,Math.abs(r),Math.abs(s))}static str(e){return`Vec2(${e.join(", ")})`}};S.prototype.sub=S.prototype.subtract;S.prototype.mul=S.prototype.multiply;S.prototype.div=S.prototype.divide;S.prototype.dist=S.prototype.distance;S.prototype.sqrDist=S.prototype.squaredDistance;S.sub=S.subtract;S.mul=S.multiply;S.div=S.divide;S.dist=S.distance;S.sqrDist=S.squaredDistance;S.sqrLen=S.squaredLength;S.mag=S.magnitude;S.length=S.magnitude;S.len=S.magnitude;var xe=S;var Re=["xx","xy","yx","yy","xxx","xxy","xyx","xyy","yxx","yxy","yyx","yyy","xxxx","xxxy","xxyx","xxyy","xyxx","xyxy","xyyx","xyyy","yxxx","yxxy","yxyx","yxyy","yyxx","yyxy","yyyx","yyyy","rr","rg","gr","gg","rrr","rrg","rgr","rgg","grr","grg","ggr","ggg","rrrr","rrrg","rrgr","rrgg","rgrr","rgrg","rggr","rggg","grrr","grrg","grgr","grgg","ggrr","ggrg","gggr","gggg"],Ve=["xz","yz","zx","zy","zz","xxz","xyz","xzx","xzy","xzz","yxz","yyz","yzx","yzy","yzz","zxx","zxy","zxz","zyx","zyy","zyz","zzx","zzy","zzz","xxxz","xxyz","xxzx","xxzy","xxzz","xyxz","xyyz","xyzx","xyzy","xyzz","xzxx","xzxy","xzxz","xzyx","xzyy","xzyz","xzzx","xzzy","xzzz","yxxz","yxyz","yxzx","yxzy","yxzz","yyxz","yyyz","yyzx","yyzy","yyzz","yzxx","yzxy","yzxz","yzyx","yzyy","yzyz","yzzx","yzzy","yzzz","zxxx","zxxy","zxxz","zxyx","zxyy","zxyz","zxzx","zxzy","zxzz","zyxx","zyxy","zyxz","zyyx","zyyy","zyyz","zyzx","zyzy","zyzz","zzxx","zzxy","zzxz","zzyx","zzyy","zzyz","zzzx","zzzy","zzzz","rb","gb","br","bg","bb","rrb","rgb","rbr","rbg","rbb","grb","ggb","gbr","gbg","gbb","brr","brg","brb","bgr","bgg","bgb","bbr","bbg","bbb","rrrb","rrgb","rrbr","rrbg","rrbb","rgrb","rggb","rgbr","rgbg","rgbb","rbrr","rbrg","rbrb","rbgr","rbgg","rbgb","rbbr","rbbg","rbbb","grrb","grgb","grbr","grbg","grbb","ggrb","gggb","ggbr","ggbg","ggbb","gbrr","gbrg","gbrb","gbgr","gbgg","gbgb","gbbr","gbbg","gbbb","brrr","brrg","brrb","brgr","brgg","brgb","brbr","brbg","brbb","bgrr","bgrg","bgrb","bggr","bggg","bggb","bgbr","bgbg","bgbb","bbrr","bbrg","bbrb","bbgr","bbgg","bbgb","bbbr","bbbg","bbbb"],ge=["xw","yw","zw","wx","wy","wz","ww","xxw","xyw","xzw","xwx","xwy","xwz","xww","yxw","yyw","yzw","ywx","ywy","ywz","yww","zxw","zyw","zzw","zwx","zwy","zwz","zww","wxx","wxy","wxz","wxw","wyx","wyy","wyz","wyw","wzx","wzy","wzz","wzw","wwx","wwy","wwz","www","xxxw","xxyw","xxzw","xxwx","xxwy","xxwz","xxww","xyxw","xyyw","xyzw","xywx","xywy","xywz","xyww","xzxw","xzyw","xzzw","xzwx","xzwy","xzwz","xzww","xwxx","xwxy","xwxz","xwxw","xwyx","xwyy","xwyz","xwyw","xwzx","xwzy","xwzz","xwzw","xwwx","xwwy","xwwz","xwww","yxxw","yxyw","yxzw","yxwx","yxwy","yxwz","yxww","yyxw","yyyw","yyzw","yywx","yywy","yywz","yyww","yzxw","yzyw","yzzw","yzwx","yzwy","yzwz","yzww","ywxx","ywxy","ywxz","ywxw","ywyx","ywyy","ywyz","ywyw","ywzx","ywzy","ywzz","ywzw","ywwx","ywwy","ywwz","ywww","zxxw","zxyw","zxzw","zxwx","zxwy","zxwz","zxww","zyxw","zyyw","zyzw","zywx","zywy","zywz","zyww","zzxw","zzyw","zzzw","zzwx","zzwy","zzwz","zzww","zwxx","zwxy","zwxz","zwxw","zwyx","zwyy","zwyz","zwyw","zwzx","zwzy","zwzz","zwzw","zwwx","zwwy","zwwz","zwww","wxxx","wxxy","wxxz","wxxw","wxyx","wxyy","wxyz","wxyw","wxzx","wxzy","wxzz","wxzw","wxwx","wxwy","wxwz","wxww","wyxx","wyxy","wyxz","wyxw","wyyx","wyyy","wyyz","wyyw","wyzx","wyzy","wyzz","wyzw","wywx","wywy","wywz","wyww","wzxx","wzxy","wzxz","wzxw","wzyx","wzyy","wzyz","wzyw","wzzx","wzzy","wzzz","wzzw","wzwx","wzwy","wzwz","wzww","wwxx","wwxy","wwxz","wwxw","wwyx","wwyy","wwyz","wwyw","wwzx","wwzy","wwzz","wwzw","wwwx","wwwy","wwwz","wwww","ra","ga","ba","ar","ag","ab","aa","rra","rga","rba","rar","rag","rab","raa","gra","gga","gba","gar","gag","gab","gaa","bra","bga","bba","bar","bag","bab","baa","arr","arg","arb","ara","agr","agg","agb","aga","abr","abg","abb","aba","aar","aag","aab","aaa","rrra","rrga","rrba","rrar","rrag","rrab","rraa","rgra","rgga","rgba","rgar","rgag","rgab","rgaa","rbra","rbga","rbba","rbar","rbag","rbab","rbaa","rarr","rarg","rarb","rara","ragr","ragg","ragb","raga","rabr","rabg","rabb","raba","raar","raag","raab","raaa","grra","grga","grba","grar","grag","grab","graa","ggra","ggga","ggba","ggar","ggag","ggab","ggaa","gbra","gbga","gbba","gbar","gbag","gbab","gbaa","garr","garg","garb","gara","gagr","gagg","gagb","gaga","gabr","gabg","gabb","gaba","gaar","gaag","gaab","gaaa","brra","brga","brba","brar","brag","brab","braa","bgra","bgga","bgba","bgar","bgag","bgab","bgaa","bbra","bbga","bbba","bbar","bbag","bbab","bbaa","barr","barg","barb","bara","bagr","bagg","bagb","baga","babr","babg","babb","baba","baar","baag","baab","baaa","arrr","arrg","arrb","arra","argr","argg","argb","arga","arbr","arbg","arbb","arba","arar","arag","arab","araa","agrr","agrg","agrb","agra","aggr","aggg","aggb","agga","agbr","agbg","agbb","agba","agar","agag","agab","agaa","abrr","abrg","abrb","abra","abgr","abgg","abgb","abga","abbr","abbg","abbb","abba","abar","abag","abab","abaa","aarr","aarg","aarb","aara","aagr","aagg","aagb","aaga","aabr","aabg","aabb","aaba","aaar","aaag","aaab","aaaa"],$={x:0,r:0,y:1,g:1,z:2,b:2,w:3,a:3};function J(h){switch(h.length){case 2:return function(){return new S(this[$[h[0]]],this[$[h[1]]])};case 3:return function(){return new A(this[$[h[0]]],this[$[h[1]]],this[$[h[2]]])};case 4:return function(){return new q(this[$[h[0]]],this[$[h[1]]],this[$[h[2]]],this[$[h[3]]])}}}var ce=!1;function ze(){if(!ce){for(let h of Re){let e=J(h);Object.defineProperty(S.prototype,h,{get:e}),Object.defineProperty(A.prototype,h,{get:e}),Object.defineProperty(q.prototype,h,{get:e})}for(let h of Ve){let e=J(h);Object.defineProperty(A.prototype,h,{get:e}),Object.defineProperty(q.prototype,h,{get:e})}for(let h of ge){let e=J(h);Object.defineProperty(q.prototype,h,{get:e})}ce=!0}}export{ze as EnableSwizzles,j as Mat2,C as Mat2d,X as Mat3,O as Mat4,I as Quat,P as Quat2,S as Vec2,A as Vec3,q as Vec4,ye as mat2,Le as mat2d,ke as mat3,le as mat4,me as quat,oe as quat2,xe as vec2,Me as vec3,be as vec4}; diff --git a/naloga_3/main.js b/naloga_3/main.js new file mode 100644 index 0000000..0084520 --- /dev/null +++ b/naloga_3/main.js @@ -0,0 +1,98 @@ +import { ResizeSystem } from 'engine/systems/ResizeSystem.js'; +import { UpdateSystem } from 'engine/systems/UpdateSystem.js'; +import { GLTFLoader } from 'engine/loaders/GLTFLoader.js'; +import { OrbitController } from 'engine/controllers/OrbitController.js'; +import { RotateAnimator } from 'engine/animators/RotateAnimator.js'; +import { LinearAnimator } from 'engine/animators/LinearAnimator.js'; +import { quat } from './lib/glm.js'; + +import { Camera, Model, Node, Transform } from 'engine/core.js'; + +import { Renderer } from './Renderer.js'; +import { Light } from './Light.js'; + +const canvas = document.querySelector('canvas'); +const renderer = new Renderer(canvas); +await renderer.initialize(); + +const gltfLoader = new GLTFLoader(); +await gltfLoader.load('./models/monkey/monkey.gltf'); + +const gltfLoader2 = new GLTFLoader(); +await gltfLoader2.load('./models/cone/cone.gltf'); + +const scene = gltfLoader.loadScene(gltfLoader.defaultScene); + +const camera = scene.find((node) => node.getComponentOfType(Camera)); +const cameraTransform = camera.getComponentOfType(Transform); +cameraTransform.rotation = [0, 0, 0, 1]; +cameraTransform.translation = [0, 0, 10]; + +camera.addComponent( + new OrbitController(camera, document.body, { + distance: 8, + }), +); + +const model = scene.find((node) => node.getComponentOfType(Model)); +// model.addComponent( +// new LinearAnimator(model, { +// startPosition: [1, 0, 0], +// endPosition: [-1, 0, 0], +// duration: 5, +// loop: true, +// }), +// ); + +const light = gltfLoader2.loadScene(gltfLoader.defaultScene); + +light.addComponent( + new Transform({ + translation: [0, 0, 0], + }), +); +light.addComponent( + new Light({ + ambient: 0, + intensity: 0.5, + cutoffAngle: 45 * (Math.PI / 180), + }), +); +light.addComponent({ + update(t, dt) { + const transform = light.getComponentOfType(Transform); + + const rotation = quat.create(); + quat.rotateX(rotation, rotation, (Math.PI / 180) * t * 100); + + transform.rotation = rotation; + }, +}); +// light.addComponent( +// new LinearAnimator(light, { +// startPosition: [0, 0, 0], +// endPosition: [0, 0, 0], +// duration: 5, +// loop: true, +// }), +// ); +scene.addChild(light); + +function update(time, dt) { + scene.traverse((node) => { + for (const component of node.components) { + component.update?.(time, dt); + } + }); +} + +function render() { + renderer.render(scene, camera); +} + +function resize({ displaySize: { width, height } }) { + camera.getComponentOfType(Camera).aspect = width / height; +} + +new ResizeSystem({ canvas, resize }).start(); +new UpdateSystem({ update, render }).start(); diff --git a/naloga_3/models/cone/base.png b/naloga_3/models/cone/base.png new file mode 100644 index 0000000000000000000000000000000000000000..92c90d35737ef8d26ab0725d562bed7616d3c7a7 GIT binary patch literal 61635 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 z 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 literal 0 HcmV?d00001 diff --git a/naloga_3/models/cone/cone.bin b/naloga_3/models/cone/cone.bin new file mode 100644 index 0000000000000000000000000000000000000000..beb3d17b8bb27602af994ca62cc73b6816e0150d GIT binary patch literal 4468 zcmeHIPjKB+7(J3|m9}Xsc~KE0MN6tgTN>WG_o@EVP;HfXRx}js?JNLcYo}YPlYeVk5`Oe&T?)Sd$eCOT({2R@x zpZfUI&(}D9UuoW-rEuZ*iNF~+vMWpBZ+d2V=IQ=+bC$xVrYs8_i&+ZW`M|Lp%vBd# z9bw;Usid&=6FAmWC55ftz@bPfEN5K`OARiCr5B&VqKQvo(blK1%*dy(%-W|g9mAPc zwW*J(FFDjEg*hj3s7(rU-sDi56sB*;p*AUO=L3h@q_EWyIMgPEt)IZ5HYv(NAhcRakOAYjM;7}*U(o2@Yq6sw$c^DOow!Ei-!+eTmM!fHFb~!Aw=DQI+ki)?~ z;f_%s{_(#3kN;&IY{o#_mmijn7AD=%!nVxtc*Oj!=HVP?=iHaw$$68mVbhjyK5}$_ zqUme*OY5Y2w{u;NqxN^6`6-V0$Nz&9eZ@SLntyT}-RCT8{>gE4pPs1sC&$r!(gE4-{zjx{F9rz?hDR&O!8Dx9I2>UhPO4od*X-iF2}b{yu`OF`qR8u_FG?Tusbp8 zG#>t|*S|5|=o|lh(`jry(&yhUPV)-jV-G9;bgVQ)LvCscBve1A0%1NhjXvK&>*tpamf9VgWacs{4tG(>ket+8T z{>(@vQ&#+&O%*o%NJ{qYfYoeYSS#!0AQK#{c z^-A99nHvH>Mry*mW2ZVo{urqt>nQyCTS+4|XWfItV}P*9zsO!6KY{MdSVG!40F&;uUZonQa#WFmFo3I>D<7V7~ zXHkN~K9q4QUchZwi4m;E8XUy!ScgNn6L;VMHsCJo$KBY3=W#FY!E?AD_u(0AMZf)H zX|y#J({0T_ldZXEv2_vJY+Z^DTUTI#t!r?tt?RMG){W?~RfM;-0;_DTMX#;(*l24r z`fNR5+50UwGdG2tZ6Vu&kY`EA;KSM8aH=oxrw3+7;PixVH-`O|u(QhW7VO1?7{D+Z F@Hc3Qm}~$5 literal 0 HcmV?d00001 diff --git a/naloga_3/models/cone/cone.gltf b/naloga_3/models/cone/cone.gltf new file mode 100644 index 0000000..372f020 --- /dev/null +++ b/naloga_3/models/cone/cone.gltf @@ -0,0 +1,149 @@ +{ + "asset":{ + "generator":"Khronos glTF Blender I/O v4.2.60", + "version":"2.0" + }, + "extensionsUsed":[ + "KHR_materials_unlit" + ], + "scene":0, + "scenes":[ + { + "name":"Scene", + "nodes":[ + 0 + ] + } + ], + "nodes":[ + { + "mesh":0, + "name":"Cone", + "rotation":[ + 0, + 0, + -0.7071068286895752, + 0.7071068286895752 + ] + } + ], + "materials":[ + { + "doubleSided":true, + "extensions":{ + "KHR_materials_unlit":{} + }, + "name":"Material", + "pbrMetallicRoughness":{ + "baseColorTexture":{ + "index":0 + }, + "metallicFactor":0, + "roughnessFactor":0.9 + } + } + ], + "meshes":[ + { + "name":"Cone", + "primitives":[ + { + "attributes":{ + "POSITION":0, + "NORMAL":1, + "TEXCOORD_0":2 + }, + "indices":3, + "material":0 + } + ] + } + ], + "textures":[ + { + "sampler":0, + "source":0 + } + ], + "images":[ + { + "mimeType":"image/png", + "name":"base", + "uri":"base.png" + } + ], + "accessors":[ + { + "bufferView":0, + "componentType":5126, + "count":128, + "max":[ + 1, + 1, + 1 + ], + "min":[ + -1, + -1, + -1 + ], + "type":"VEC3" + }, + { + "bufferView":1, + "componentType":5126, + "count":128, + "type":"VEC3" + }, + { + "bufferView":2, + "componentType":5126, + "count":128, + "type":"VEC2" + }, + { + "bufferView":3, + "componentType":5123, + "count":186, + "type":"SCALAR" + } + ], + "bufferViews":[ + { + "buffer":0, + "byteLength":1536, + "byteOffset":0, + "target":34962 + }, + { + "buffer":0, + "byteLength":1536, + "byteOffset":1536, + "target":34962 + }, + { + "buffer":0, + "byteLength":1024, + "byteOffset":3072, + "target":34962 + }, + { + "buffer":0, + "byteLength":372, + "byteOffset":4096, + "target":34963 + } + ], + "samplers":[ + { + "magFilter":9729, + "minFilter":9987 + } + ], + "buffers":[ + { + "byteLength":4468, + "uri":"cone.bin" + } + ] +} diff --git a/naloga_3/models/cube.obj b/naloga_3/models/cube.obj new file mode 100644 index 0000000..6c8bfe1 --- /dev/null +++ b/naloga_3/models/cube.obj @@ -0,0 +1,40 @@ +# Blender 4.2.1 LTS +# www.blender.org +mtllib cube.mtl +o Cube +v 1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 1.000000 +v -1.000000 1.000000 -1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 1.000000 +vn -0.0000 1.0000 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -1.0000 -0.0000 -0.0000 +vn -0.0000 -1.0000 -0.0000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vt 0.625000 0.500000 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.625000 0.750000 +vt 0.375000 0.750000 +vt 0.625000 1.000000 +vt 0.375000 1.000000 +vt 0.375000 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.250000 +vt 0.375000 0.250000 +vt 0.125000 0.500000 +vt 0.375000 0.500000 +vt 0.125000 0.750000 +s 0 +usemtl Material +f 1/1/1 5/2/1 7/3/1 3/4/1 +f 4/5/2 3/4/2 7/6/2 8/7/2 +f 8/8/3 7/9/3 5/10/3 6/11/3 +f 6/12/4 2/13/4 4/5/4 8/14/4 +f 2/13/5 1/1/5 3/4/5 4/5/5 +f 6/11/6 5/10/6 1/1/6 2/13/6 diff --git a/naloga_3/models/monkey/base.png b/naloga_3/models/monkey/base.png new file mode 100644 index 0000000000000000000000000000000000000000..92c90d35737ef8d26ab0725d562bed7616d3c7a7 GIT binary patch literal 61635 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 z zmoYVCvRy$hptO_}6cl1h-c-}~TIbyI9xriYiIN7pJSWo0H4hIj*??efSAf$!K9|*> zdRtmPiVg=3mATJ}D(2At>FTv~&(ii-fdvgLES~ zbTiZC(2YbTztbs4{ePkpz44S`iKNC27D0(UkO^VlX`F74Qnb_ODYysW*p;YhCenHn2*botp@_5O2YN(g zWTeP(y(t`ayJ--O?5SlSubfsSmeo|qHPWq#ABy`yT9Hl8@K~R`}rzeJdPcvu_Hs-$KbD;>h1g8}3ZB&JssSew| z!v5jiPpB<;RkKdtL2cUh)zkA%?S@0dK-mKsJShHxy%p%-2Fg&`A|7}YGO==*Vs`ac znw1ZcK`r^iZyfvdfxpLG5SuNAveR8~L#}q*@ONqucX4!bruY**bM$cQ&7Ik$ZAUD~ z!WjGL-t_ysTgfAd(&2&$5CZ0MNcyOrP;b6}R7VOsMcs-cAiRfiaG-RN_+X+W3SQ!g zOZin+($@#jy^3parGucSy;$y82ZwC(Q&Qgaru4e!s%t7^|K{i@JsHI{S4=~dT@7VgV!m4zmt56+-;cu-1Ufn zpo3Q+mDe$fcunO4?P^w2b*wE+)j1>YH7!t<7FI0(DkepAhyY~biqdFLd~|E9FAKvE zkRaTG>Pnup@E~=11qQyvR(a+->a=RKzyGHUX!lC(&rMPC7&||50N<0ZrKD%a-F&ml zFBw`&BC`_7xiVF~0DkWsDZ0oztCiW@lw_%{uq`33@x+>1LPT_M0&(4TEr|{q6*bd2 zz}f*;>ocEE;vzn{*tpmZyvO`gUyU zJ?uhF?G=1y1cy12o15DK^1wgo=ZJ~e&5s*jhP1Tg7d6zh=3;3%i~94m>pHZANE(Gj z;qMrDAMw#`h8uHJfHxkLd-~8KAq2%TE4#@C3smemjcDjwDm2#BG zib~6M+cw|50F|I8rkgBjHd%`6LGXcUM@Yhp-Yb<+lNqy7qxMWzMn*>3FPOfSE&g%i zBOxdzX-M#@EHKs4%G~nu(wqQTv6b#~Ic;Ubox?b^<2#;r#E*={<~XFi|BW%r?iyqc)3$ znJHj^oXks6@;%%b^r+tXeV6CGQG|&uHKb(>jp%L3Y6Y#%t{H3j?F}J0PEj_#Ek!Q^+<3kUz0^xcITLhr zaD35|Cy+^*nW2;6DCSjg`KJT~YXpl4_2f4WKeYWFXB#Kq#mL>8osU3oXaL2o{r%T{p0$<7bEzPZs+Ta+n^UX3 zqWZMa=YMc)4jS3L$u4Vae$Cvb_mCPO_S@ReL5m&@N`);zgBao>8!?)SgT)t8yuUDL)rqXpFX%H%FxJtSO`?QC2yy;D?6Nh6$u_I9e-|U zPXLH?HeA?$M?>2@#eaHHl)5Kyd5&{(HMug<-GwbJdOd3@8%M=>1gjk6=uBu@L~6V4 ze18M_WpRV;uee}coh!OW&hd?AcVi&s{zBvg8Wy%Qlo57}Bmyng#FrOoX!r;ZmRxgy z9CPXw25@{O@og-v%J)Sa$6UEhL9f2v)Y%+y%)d8bBsj}G?;HChG$*<}KIc7G-Qcr% zu9nqab5OaSttzA zdP(iDa;_TgG5S@@AYusHEGI6gnVD+%_>zO(N6J(CcCKl2*OrQ(J#|G-cuU@f`CCqn z(JkcSVq^^tzc@eNJoRu1wEsAB-*h9fckJ82(rPpEQSautM+{3cPrv*v_+lgFa zj7~4SCnnoov>%gA%emsCGV^japQ1=FaMAWA{T!T{(et9tMjjogaxQ;Wk%QBF0o_ih^maZ^7_@pd z79fmi@*5|kF$j>~?P^8|sI~P_-}&p|!<_28@B(D{jy`RpuXki5&i9Q9QHPeSw=6$o ze!>i(Rum-rIhTbTAr_8g zPCZ=Rxm250XUo@8W9aHkagpyu5<~kHe44oniDkab!y+!T1XNT#8~*5h4>CdX5QB!R zPdjQOLy7YX63oP!zQEP&N#CZz}w*R}5S&an{R(EKQ(c%S{E!kplD&!~i5S@51~SL06n zbH!FgRIEy2!M@5`TFx~>OZAlgW(`WEr4#lo&ym`#@t6|WRFUs4)}{-X4slEi)AaiN zxEsjE=N51$LV;Gt*)+d)JV_@Q?!jLbhBFU$=Wl%1I-7}|ke?;}>F$Zola!=r4uoFE zmX+naLB^t`r=H=-5rVat3v~+>c>=*|Hh;RIz;TShm<=saEPbP_p4m-2Xd zo=er5DjEs4!K40%Bqr% zbDOqBFT&7IpJ2Z=N{jSl{E9g+0Z?|mGnJ7pqsDdqU_^72rpg;*mMVw%-XKmrA}V@8 z!Gumo!Een<0mo~1a_B>}9%LVnYM8sP|_ZOqi6>uJKO_D6N8+o&IW z$rCU3XBFSL)BujMj$El6TBZMlB{-Y^dUen7{L33xS637JysC*?FZ4Ta42=5_NzP$G zc(1a@p8c5Wu3CIj*tn&cB2a(9Kmcy+@n10>X=&7-dFKpU7RcbSmTEnMrFfp)zAXVD zBUj}{{If#r0ov?&L`kXSsExXyZ@9t*g8cGFVqu~yOt?05ed`gP^3DcBsH%#P0GWwN zxNBh$S9!8?X>O{!f1-10Wd?OgI05+|ka_@h>oZ_cTm=bsPTJ(W1twE?{kO;B@7K(d z{I@zTM`AoilCP`5-@iNLq=L&m9P6pambn8FXPt#2Kks7XJ^ngh5U9%;e@3q3{UP|s zR4d8RA3mwo%_*R}dTW~VCW^~=56Fh4#?m$RA{7VCzOkBTaxEHgA3Gh6gTTG|pK50V zy)l2M=M2{x;xi*Cmn%AX+SPAk%8_UtG30*{13;r?FK?OCl4bALdX9I)yv)r-DI$N2Wg}%iKf!U|$FleE4D! zv7KQ@M`Ewu)4@pf#4SwxW|%T)U5XoXB4hVJO|?Cf`+yCm$eYeYBZcJLjNNNd>=d$9eFqGqdi zZwJIYE_ThbiEsQxUW)ZiZM({gAZ11aGJpobC^`(6&w!KXDmKanv%W-vtqKAGxN$`C z25LTMGZd$NmAyKi4+AzeTZ0v`4tIh13t7>V$rjBJ&;g>2VRKNCtkKOq3WX3m7iDgAAy4^<;hkU=XzbVWi}Bk0TNiO$Rh6M<9` z;NJOf&%)NLxgRC%h`|{0k(sGEjDc2&F>T-z93`5fdt~{Sm<0A%fK?edzDCQ~h<;RS2_NfrFvA3G}bPf#Xo!g8N|X>x;r|-JL5eWJOdhkW54&@37{c-`B`W0A2)d5{+IDioBd^pfQ=Rle79FR zzWM(0JP_9|)&4jH+9nYcV=2N$cUypy0fO8wovd<(5BP7$egV@Nf){UrE5hLp_$0mr zG5EVe=v8)FIK?YK8v#N=hg6$k;b8^e4fLH@1!DNveu$$KA>mFiij_qJ#6vyT=emEI zTQ=QMdcwa{qS@JG;gG9oaoCr9btP1r={bVbujfmH2!}VZc>^~(Dmk9lCg$*=Eyxrb zV*POJ_n6YqqSgQ8ZgCVg*guAHD}Vkv66wROZbZ;1=UzTXm5)UA$lze-^AU2wiLp@1 zk0k(uO%Lm@l&kFMi8wks8b$7Id`=axi{uYIzi@!G_?#F_Z1tLGmeTa`JFQFUc+|G4 z`-Plx>-(KY|Mlfi_mlT%clIxLm4`{9&;c>lcyDiA*kwKrQZ;hb$q^Pp3hk7n))OyB zZ)a`~#v+ms`s7hC(2ylc@EYUtS8OaEk7e|P;9b&n0WZ8|29CbMmE!Yb0W8(Vhr`LqE_3*S(hl?zNA}<{h@)9t zqArH`Nq%H$m7z!zQATVmB|Ee%*c<=TM~>qt;$G_5)V1V8x14nOD>r9HuvBqMqMwQZ%{{BV@j;PsbZbHjsDw-1Xx@RRMG zB?`TE663ds%RiMJg2fp@PFicr-Ps%%+wV8B z%~y1f5E0xe<-8~%3E5B2Je+~2*Y43&s@H;+J4*8-o4S?_VVF;*1oZ+G>;`ZL^}Zyw z&EzS1r#4?9*uA zX9I>cE}Y7KSt}ZHbdhhP*iO9`i10ef?(jv2u#E0C?iFNcKZ4wTmt(S<5k8G@)_DK| z{pXCWFuB~PWpjGt<^gfo{u@V1s+ufyv@@CzDFNm@6kh>k^L_}j*>SIRn%n`Zd7W!q zCZ;Myjw(+DO22Gm`Q3evM)p_|HJzA7#fWpgeMX4{U1)vqZqj#JfT}5YAR*%GPsebW z2)NeHsKs8$_xALlDF1M}ZaQx{*-OeRS73U&;);G&_$K1Lxn;U7mCN3xLI3Z(embM@ zP37Qldz5r*Oe6_D5+lCI{8hya{`RZe(dK5;=YcCyI@pTj1D}5o!_4~H1-s)x{SN;d z+ZbmuHP^FAGFtAE%W-5CazATQeV4gk3PaNpBQ`Rx$H)e!;N`{rM8{#}kU|bmftXn1#Nv z1xBKt6OCgn8@A6wjatr6q;gqA>l;o-r^Ui*k3o$aR<{8zQ-$-F3A$cwhJS`4{vM9W z+;Cn{laqXptmJx-g53mR;Ey{yVcr6}e;i9T1xOeEcZc()Z>U%&qb){A)_g?W?t6ho z%7@~mCJ(Xcru!QQp!lw)=-#_kyE){c@!T}|yxILP94g3y^{uLZ*<13gdR3sv?fJ|Xf;H8a>*>aSUc;pcFC zTWXZN1pExOJ=c@HTe2cYOW9uUn-%3A0pWWWCzqzp%E5wV_l&5fdq6cWhqKQs2C-L| zEjJt47XPL4y!&gk^Cq@9T_XYVX_B#@kofDL3d8=GOtbDj8xzdkP?4tXpUN40+rp%l z0`ySXd#P|olC_J&8t{v+X)%H2X`R+_Q+FQD&VesqFB8FZGz=dWQ_D1`vQN&0BB6g6 zK><4F^J8Q&a6|FJd7I?vUYr&C_?Ad)=Vl^jbH|upS_*$o)U7Csjn9z zZ(m^+rlI-ZNE(1|@pG~WiwS;tIK$j^(r>Q6Z^uwb5c3oXKFL{DT~nQ_C93N+ztoM} zL>Vtz!jYXwYHb3@54SoVwN-=TaShfbq$lvG15@PXG3S)Z?L(HQ<$Zm zrm&`u+KH7BzvqpxgmgoSjBmFY0Z(vkNi|BE#LktGsfE+Ij{^@?$C;Vju{6;yvcpk7 zjMwL_y(PeG@{|+c6@VZ8nYpIsJg%9RV?3-O{M^k*6nZ`>zz=u0+HYF+`Xh7lTMZ9^ z1Ty_dv}t|QT}NKpbYV^?_4G_6_sPI}X}c;QleZ=KD|T3Ol*=w0Y$`c%&X{57dDs~$ zOgm6a0WbAC?%Dw1F##m|rVaV-|MUU~0p8w6NGU$u2G0O;AkHG`gV9q*S9e!uH#~*N zuJ+2jgAzCuKGMS5K@R9^TD(;jGqW;9jBeJ6I~A{dvyO7~r(BU{C9gi>b(%6qw(7T} znI(0t7^qMrWl1jb-`+LM@$|LqnpoALU@wOQ>Zv1-YL?@pitu{@2YZfrj$TWnQ7k-X ztp;Hek=^g+gMIpmP!XdP+8~INuusdnA#UP!T#poOFgm&$lzKE_|&HeitK zVN(@(L@OKyisuUJWi>O6Uoa!>%+1Z&769o~z3~Z*eXT=w!2rvXN0wdMidAUN_8kV% zUR`Q2D=yGit0Yve!S`Xp-J%bC#GL)ta}~Mm8DLGij9G=`BdzuB&wL*0L=?!+=w*Nzv+&*rNJ`mW zR&}?(het4HA^mL0e~6)8(Y;=H-|1Ymsm`B5_n2_{@3U;b<_eeMfmPp5QjHCD8V|;_ z0Z=)l!x}`4CJ-5N=!1uv&j6M8&_*x)@8y&9)Q4s7mWD@WCYD=SHR-;N#^aaJpO?cF zbE`aO|C1;qwPt$Ao*s@L87QmMce^M4-lB;I#s?`&765GfT3I5oZEO22?gLh@shsJO zgn7PO1(Ic_7lFM_S9UP@JD?|&xgR*m=x|2_KXH1iACtULfL}l#d8$;m@FCeSPcPK$ z;_lt+q|;&tD~A&aUL!qun1M4RG5Pqn#`g>a0<&@r+QI8oLNMG7?!VMLH?{IJ1U95n zo&Hp$x(u0O&*Dr4y`d++l_5*#L=iVOeT7=PSB{cVR&Dj~jHI40X}znU{Vpw$+(YxZ zd6DEHpqve^3g1<{B!&3y(9%Vlb#Zel3lQDXh;yBpIN1AjA@?x&>y6FP;&C<1XL5At zT~2*zFhl)B1>V5;o0s<&HXk9M82I2)x0Sjn*cmINSr9X`@MSLzzTut;ulQh;E89v2 zNrewA+oaW2x>qOr4fcMa=i>nBi6e0non?#rte+IFk^W{Kf&%NL^HQ*(4xY9$))zk*Tx2oKZ>XbZ=4&DD0&j~jjGEcj zo8J=Bas3ful^Rvw&v(@mZAj0rO=Rx}@{bM_G&(7?h)Ji7LrU}=1AXtZMN}Q{-GNl(>jQQ?m^_M`vvf3|t-K(oNY z9(`a2%KK~^X5kM5PR$3O>8PT40Eg!ZiLFAy_vg6~vH=HCaM@X1^Fv%@oow1uPZ+sP zNW`nZiK`c3IhO0so#>2{WqD990K3l7vM&Fes{ACAK@;=G{{8mm`==5B`p5)KuzoaM zfpnP$@!Z_1tJjEnh3XP_+C;&3Z_+m73@Y{BAM#PqlqjC^rpBT3(Dd!?y!6@n!GZYu z2I{dex>XqCWqT|(92+S8RM^Y*K~gS~i+hd9F!e<5sv~jc9u33AsY=5yGRO?&XE}TP zj{xOgaU%~^mPxt{XT7G~Ew}mOe}-q!?(Q|SfWF1+Hn*GB{NzH4VP$b=yASGIX`T4k zB1%E;c#o}ZIMdMw&OV|qbzD;)dT!YzMX$zX8?A+~G6_KAGnotu6*GG9ker;HxV{hq ztxnU+8!pw@2!n}>=NgB3W#30Vk7!JZzxHynu(;e^_T!K?9w@fun1^5@AL@5`VV)Wl zzIc)FVA3pv>y@2@k{ty+dWC)_+|vq-lldzf3)yn@rJxd(4)n*w&>f2z@n<-_!R@0G zUK=0N>fAzI1u}^>`8J}1FNN15Jn`#=aNOg7qBJi5UC~=n7D0<(HIwyT@6Ldd5#O`l zCHp@~#6uNhRYwJ0u2XOB2#E2xtZnv--#t5WhISfYVQxNEZr*Av+F~9K3A;4qHg=@4DKf)GApw3;vM&Sj!iYs z!Bq=je~0Vf+*AXx`A%J{ac8JUbuG}5^lH9&rgLV3r)_~M%8(f_{cwW5a=#=%8{11I zzOyAHeSyq7BakPrPE37saov3zNo7fzS%&$bE6G!Ow_}3Zm}7>PA?f(zx|#uZ(e7O# zjPbQsKyc@HVgG31SX&6K{aaf(Sxd`N`IPnbbwDtF^WAkR!mNF2T#qx+rM&|rEY#G) zX#UozyK_Oybf&v&`R%N1BFw6$5pi$Ct=*!Di3@2 z4Qi-_`SbJYJ*afjsg##@$4jJC3!V*zE8U*;D`Q!<%L*)GI(H+6hkrL-*ijxe#U0sv zw(;FMkXHBWJ{{9V!4dSh*O1YP1JSMPC=|A)H|?`t;r9-McEx&-uySt?T*Gnq4tM30 z#+tHC>aN#bVY#;*3*@GMVQV_=8mpXrl%O%>POU98Q&R9T|j zAk*t=Jp@i8>uBF=Ha4>@lrVpPB$e0{%~_GK-K)_GWr+<`oX^PAEe^)4d!&FM%W!r{ z4hwrV0{`U58gWP3Hr9^}7K~*QidkKmpRM#BihUq=&ySNyjrlWb!C|mPKA!z>g)3Az z+6ODdx=|4i_x)pwkW>ghML_T$aH*mZw$X9HoKd&u{BJF_}#X#^g12lu8Zm62n1JFXR`{sDa}xj8k3d z4g&Fr-^3SN2XAIR6Tp6R?}^zeyoycme(Q8gwgFI0Y)4t`@cT}=%<1v)I>6!?qp05E z+X$@4K)2Zgg%#s574%`}k&o(%V>8bT4GBVgjtCHW^zSw|S80%aX6N3vSdagZ56=W- z*|q%Fx3@(t%wEG8zM00$oNz{BMQ7GiYDt9zgX$MQB5&RfOewIt%A>K2f#kHe$^5*! z5Q_v~f=T8fp9Ei!bg9nrj}&~hLOg3y@Tz6_aYgSlW7V_GovL(VZX-A0h$q>+^%0wp zg;J3S)LwXM^jYF&r5C%T|CSk1pM0tQ3N8>3{Xk3~_{D(H=;e#^B zai5efpOieFvddm*CRX=9$31X=x=tJd9u%0>TG(V16^uXL<>UplOt3|iUxX@qc?sWs zHCWT|=ucz>TCs#;NaVrqeA37rnh6X&j>Np~Y@dJ4t^;EeEFjdWYP*yID-%ET84r(d z&1W>Y8c)YbW4zQQo-W}-GdM*lo*KgSf` z*i2IqHt@e$_Kx%W8F6~*_!KEtX}Bd6KdW^AlvBjb>|l)Y@WOn_2jv6o66iisQ&;=| z7%a!V@TRpIq5u@>SWOgK zWn^Um>8=F^TypMM2<>||xVfwn<&qBDKA20DaPd@T@aj*f?Wf3J)aCvVy@t?BxCutv z^oktW!yCNfXQs%Wj^qq1X~ADrXI*|}*>EIn(7{CJTVYqI zk)eMnQ<5qWuhZSeD<|dZC@{B`ND#Hx*I+jN_gq45GL4eVb$Lx;bD}8ik|)nfwYR(w zzkad&LIv6a)=KR}BEj0NiZOzN{kDJ@_Vn2n21I9?>6`59gzD%*bC1tX9TLNzzqayo zhi(&oJ&p*T#;SQ&y$alDD$lWd@YVU?DdmzEEfW`0G(!nU^)TZ5XNaUoe>~*?g05s-K|o^yIss}I?0QuQwN6w z=w^xeDW%;vn4()uauv(i{G`cC<-y~Q@-g2hM#u1kPq&KH0knkf0qqnAnrT`z)`aWe zp>)0|It|}D-fg%@3MXmIwG>tQ5L1LfCx#n0jb$q#SF0V6oU37Wz=A~ad%lH?Bnp^Gl zAAC)F-HGQl>R+($3?^ND(1rwV<7m&f&jsiqRuC)?vST8G$gh{@s2GGUE>7aqL3c|u_&UC1R}OkdImccA^9{oJ24 z*8y7B!g8#KkyYHvdash;CsZPch)8}vTM}F8!YXDc@HOw2gT3#)E*y1ht05vna~-@7 zyPazC;JmwDXxz4_eGuT~CxZP$>>9-wah?izUha-nR=&yP7uW-Z10KpNgM&B;NY2jA zId7y|kOEK-pBQ*u3~rbQS|q$*XjpUs`9aN`HKV@*;CRtoLxoj825UOnk#6ovU9oQp z=~pH*W(91Q{oRP=Lu!?fC1KM6t25=MeF(J)Ny6k(MUMr-<)D0CH)S#uu&q8$7+y zAEGD;QRwlIog_b8*{PF-C?5lAvD44rl%nZid(zwkNbK z#L2CX&`FN>EHKxca`_1FGUGP9RE@q65JO0}fL?k&)%920JrO%a8pNPy{yI)3%*wvz zGNRb9YRd}e5=cs(DA!AQH*VW9Yj__F-?mh)+M36v)+v)$9@0n#WuXjar~DzgLp^Ef z9dK}g;ZqgO*6fVhIQZh4IfvpaD!hCnN-zF~j;n2Dup4VQ*i}2beVAZ^3ymg7LtoLZ zvwuRP>6&8hd;wkpd2Wi!%{AYk=l$hkZ-ltpuvAa}?jFD8RbJImfZc*^`qvfB%jGJx zg2JI+LgO#mZB5o>*kd#X3_TUJT4K1TJ+XDk{-l6`Dy>I$5%x%jdrHr>uw>LCJLCw^ zPnlg;)>_qsvSR_TMQhb3&?9=l9jWn;!7506Hn| z+DXIhes4Le{Xtqo3E9LOOD?nHo-zPslR(J$7q?A%9kryjJ>0)Ca3#qrIE#y; z{)cjFQ+?zm%d5AWQ~$-Nf+&#d+h@q)dZP^Q*$nI*x>@=8{K^Q=t*U!A&epXudNFE^ zVa9~A0RSLLe#cT;#<%tQ1%~#XU?&Q=q-Xt0^EQw9m<7?`oB4GFxVbh51p$vISZ5!U{{l8>h z*4F!>xa7$j+1Z&8&!osLYHqXA-)C|C*+tg3YO1BGHLzR1+utc5)4aw7M9u9>fL2v4 z1*e68_gq!RX2>^SBaC^AFV>x`JuVfCKF47y&uw@qgQR zBRf+PwDu!vCILWX;-&m;ke%3R{$XjkPXtdL+OZ8822w@<1%^NWkcV>F`W)BXKe0Fc@( zPQWrfVT_T(f*8G2`G-w3a@LcN=zy~J88=!(enSNOb-1$0FUaqE>Q)W8jsUv*-hcl$f81S#8#s$dy267wl;|F|0fW}J5J^=j-Xi*W(8t8L> zxzDH;W#W=;BSW)&zL0WJ@f7+08>$L~5@|+q$7?r82VZ~7T@?0kv~ZJp68JA04Zz=0 z{tL)YRUZr&yolEpAAxW_x}4j?G1;QU@MyUSfN|rs!=)7eY1bjEL zF0GsM{nYuw9OG{tKS&h-ikeCSDp?aS3XLVdLy@CHeuuet`~IlNjd+1z7l1a+%Fc!u zcRtyI-p}6x)K(Ln2mq0jfgzK68iOEr+m4i>jITD?ksBwwP3BRNTb!i_>TdT=A7V6X zU`t}+l)YAvGCb@!tiPrhk4Um_sDGo_tF!+fY&HaF-ae3=ZnW@pNVCS{$Hepq5eqxc z2dLR21-MuMH%e(o@btQEB?^GxFEO$wgLIyJZ}k263zUKs2jGECv%=or&BdSI4e4K( z*xBtLwFCEQrT<_45I{N~r?jvCuMabW!Alie<&bmj?D53$ z?QIKfTVu$0e}7R`6_M8AVt|R5e!QVPyd-P*ch5>YvmCH0Lw-Ke|4P&VL;ncL#$7tG zv$I#UKFZ=;J`@JRZm|Ib_FqIF2$PQ!!UrX&D*r8YQp*T|Rn1J%Ek%7vjYEDO{`t6u zFG@5#tPJVNUZ2CU0qw{Lz*s&NMJu-(zFKLZ^!IN=n(^2^%3NqVttYsv^KahMKe=xs zpZF5<&-(+TAV#aFY@?Y%Y*A7E^DTeP7Jgg(#6OFPnuX4{Q@(-ozt4$`t_I8e6pX&= zz8RrHa!2}!y@1Tp4^iB5M~Yp19tN&e$N?K$XH8)B7hRCOBZHsD5z^Wd# z#Jn`;ML&3O{7(So%lVf-1b}N_{_~53pnn$TFLLB1wweXxu3v!bcpWMi73A$_vAgne zb&Uh3`&mGqz(vHr)ef;=hgPfQ@j>Yd;LjUCJNyUhgn#BpdD#MvrdlvcfRD)S1_XO5 zvBX**P?Fzc(+iA`CGv5-{~xv-{sqZ;CV$6ozaiV}xNvz?xy5=J=j(zoOJnP*j^=;1 zg;56rfM33cJ`L-A49Dun1nIzk)X*lWh_tIVN5BR7MC&Ny)qno50{rLA#YGhswU8$- zH`!y%L&|pU_HqfiHgZ+Ym-4bdA$W?gWb^=Si(c4Ej zcFZqZ?LRZg2#Fq8a`lw|WnF)*5NdC6yG=P@6+0{FP^LmS2~;4A<&CB&e^&4$`0hG% zGEGtK^_*G*UEKc9`V`;AfX0IUiO0a?Py*s*8_m)^dE1Uo(1qeQK=5n(Bh8?Y{ScR6 zvtsoDI6y$#-~~#fkf$f(&!2$W02ywFuJw079r3=fN1W0*J!_@67kG}!?a%!ug!Lk2 zj}w}oX(dBEtdjF!0gyb{hDlgzN^;tA7P}P!=reP}WoOsW_G7#aYw!jhKLmz+AVl>}y~aR69hBM5uxe@dPb|6Yb{p8Yu>nTzD()Zp0RTM+{uB36^Df#>v(hO?s5YhG>ox!=wbDh!UZgiD5pSA#+4R)V3C`pBKNEk#a&_0 z0x@qZzeuFP7{z?>$bcM0`ipPG)JHo9d+Y0Hp-)a1kP*|`jr1v*jQN=m;NsK4JglEcID=o zX3P+e!kF?H0N!(qrw3gIO_ov0`-`{Nt*3~v(E3~TEa5PvlfKr@oe}j?gr8g7&lhW) zo@IJ|X2(>h+F+3unUTLE*}exQp}5Ja1NhX-4ffv~&ZVTfyL$@p6)6d*UhZrig&naE z#4`m-(kCd9^Y8byi)BndNG-@_ulkSQ|5)S}O0sXbql%0$UU!rqyDMQ;YzMtzFgdRO zM8x@${5j$0*}dx8+LYAPruuq7^eUIw%+cL7HZHt-CGgdSJMq!ojR&<>${5bV338R)YQUV3d@U z9i1p=9($7?Wn-1}&zF8bhu9ymQr!Jsq8{@Z-5BXZZH3gsf=7&3T*4;tJD`F4cgylqY%> zAxUa=b@d=e6Ps&aynlH)&(_utcs*Hyi#j}dO^7Hjl%b)%v7%Ux00O_WF*c@stpEnP z`x*fomqoD_?~>M@t=^<#b6D@T65VRw8i?VIIGbQ4%&f=>M%}R1I@mkn%ZOLxaVfPux6(_7Jccf#=LhxO6b)t!saSfmp(;?YKbzw zw(m|7z~iTDzhH@s3Rynq@+5da#w56rjLx%!>=y?{#FLU`yFeV=^sl6i0cxR*RnQ2oOS2)SgMb}3ogj(tok^!{bX_IG ztK5&~1(v^{qPEe;iM|2&^+V#JY#-@x@aY35hzT0rGf%AL++!La3QGheycUQQi~1U-;`GOltkaq3!M`xut@m%=p?Y$3q1E18T_I5$!T<7%5EByvg4I&I z-}97nfBxJmhNE&?Ji?sImH&k~KN{FKLb7kD5$Brb8Z|1Kb%o|mI&HGhDIMVov?tlq zwVHrjSdO;xzhks9v&IJ`?oA6f{jRfrCZ6|Qk$b_{{oK|yCXy;uRVe<4^So1uf5B&+ z%!LH?>OV8vON5Qtd{a0v74e4}cj}1+hu%*pgDSM+d3AVRGE^usG%$_Vfqa#njJt`S zF%)E)vL;-G>Hnt}KvamAm)HiA_qaQX6xFG7IXi{r@(rori*t&$WaC$JRL5Cu z?SgRAO6IF@Wo`fRic{!DoT)Wp(PhN=C*$0`+FyATPp+qbzl)H@VR=i@Y+G)N`7TgD z;o4?P>|Eav(+lBCa)MPTb}ci0!@ImervBHM*Rb@4xx8xT|4^S#C^O{1Uv@*=1HtZ* zVTB^rb`%Kiq)J9^0UX8?q-@sX-FX|Y)c_2s7LYI9i=V}ugRXeK#pqJkU=`0x6k?Qg zD+dPzU{P|$_eOkqaE74;U0HdJuT66VV0HqFSj^2u19GQ|Ek6slK8RZS#g-$2;+$X` zrlEItQ1Y^}{5%7Wk@-RS z$iMZ2+uGXXlbG}YN8GgSjUcoS=bZYDu7L3b4a#j(S!0X9g0W!@;&9V!at00N zMz5wCz2Wd>A8(lE2?oZ_=H}mQ5TbU$-W#xM4nP3p9e!k06_mpHV7df{gpCG&YoLJ$ z0~IcmANDO6(!wDCQhNfoP2qO}@zGsI zNFt#(TU{^Aw*dt+GV*+emB9zF(Pbl%QV3QVW$7f}1@3Kag-k2~mfZy8 zPTClzWe8ve0YHI=({LO!QvBQYwNt?BcW-r7;^ZAl+@2v&4I}(W&>nI2u}4AuzAS;; zxZOD5SF!vN*g3ZQ>gx17&Etm8EVyTT-#K)Ps_i$mAVmAn4ifYHGUHhsojJrlM68_2`nbMBu`n9RDXNIPyk))B z6x5>p@~M-ZHhO5)DVDBjJ-Pbt9!+L>Lz61L<;SF2$#2reZOY&_|bsBSXVLeQ#M=7X=$hNi`Q293iUk*jT@V zk~&9BHZs&lh|^g?#`-XX$l~jQFjmvPpfZUe^T?s~H{iX+Md#vCSqd%zD;_sR39Dx+ z-J#cjEP~={cm7Ku)lmo+EUjZg)AP<5J-#3tY5j-CN~@M&iX-=djbXoChq+_1rtxQ9~c|hMw6Itk!Pe}`udA9F)siP z&-HjUB{@0R9=((O@+D^9S3ZsGGU$G-B{`3c;gH{I$E-E2r;OxcKq&=U)XyP!W-xpM~TJ4bAJk^*?|7Sa#~ARJuF*o{}=H z?~T`baZ+~Twfpm>mZ;-xP25P!b;UO=G1nn>Wj~0m7~X6=wYU9@z6T}YWl$;s84;9B zgrV8Parcj^Oblg!b$TQuWAN7*ee^1)R#aEzUfg(GDpAc~rWox)~n{03S1dNb^4;!^Yl@U=TA|tf#tRWF5guf9kSh z;12Y4zn!D_%vC02*x+zei{~3vXe%Aj+L2o}aCLzj9z#MRS+D`JpCqP-rhYF)s+(Ey zp(MwN8H$mk7WIR2p1|#TTC_xOmRGq8zX)pa=cKW|pRAa6e;ScS?HF@{+%%?9-7; zB9L6}0aYFtmLZbVdW$}dp*tEj9T zX6Gm!!sVBQ|1sOe#Vv7@W}SW@pA2RhJ-zq03+!4z0HBBU`=vJYM0o+Pixb45tEfOD zZiC^MHT1-k=5*D_M^)1k9ua@u2RNzwXQQ9eAH!o}q+PmZ&Nh10=mmqQ#3?sOL}T*enyCrH$@dkf4Y9Ba|w%1eS_pTM9Fc8NDG0K)q&qd z+frYygApea<_cM01mh!z_-RpRVL=?ehtua@WdZ_$)?VsC+umczGh@i|Bajs0CQlG) zVUScU6SE(3IM&!vTWw9SH^jLYPnL41b7e(@ma)h6LmpAs zhX$`uq+j1DFUyR;vg4!C;c;=ypZjebOr`|511ip=ryxk$hz^eAym;?5?WY&MNQ!%x z$re!P+4=;2k|_$gRguc|yLU$wog@aQHw8zrkPn{z5fL@8VO+N zn_60;#L6UHC}$JOjBvB(G!!`!o_K?fYFo8{nEW_t(jfbdbP=3X^=Gs^+iU+-W+Z`a z7#^kd?zulqs!Yt8Uq6(}(4_!EOR$=k2>iv{V`9T6LOZhdH3 zk&qC{iGr%VDwd+danq|7$p5SAtfSg$x;-3Ri)#x6ioduOS|BOX0;NEa;w}Y>yAxbW z@fMd-pwuYt5-2Xk-3d?}54XvzC`5Bhj}Sns6Ph21ZP&+MCe= z(XZWI&M|}J@uNBq?&pyRW9kOvADhKsS-S6k8n~utPA+;3+R6B(68_ydR>YlUC~4-` zLY7z=k$l9OeD?7J5zdRPuY!ER;%w!Y1JY@10GfB|8U<{W#A?q`ghaWWATFnMhiVB@$&!y^=fLO@2WSZ>&EN(E}Lt@LTXio&SaSG zZY2X*#QNtq(SF%wUBGL_h zLfQC05q7$N=r?=X>brQ_b_#m?fO_ja?ykl5tnRHCLr~scI`m%6LB3Q3LkFHX>f-zN ze@xwO;&_7P{ZJ>?!yg1M_<20vMG3`CtY|3SmZz(x?Yv2wTcFV&n!07g9*rt+a>hfn zDyxZvqoMwKnDR&8Mpnq`Y=3{&oruR}zzf}N(9$bzY*h@Sz&Ox#PGLqAY8Yl^6mR7K zpMN?0M}`(V`o4?|+2hgXd}7gLffy}52}CTeLoXqzVd(C<_3*1<^ay`9v-FF|EzTVL zS8$CMd!h(^hmp7Q*wf)LdSZYHdVHRa&DgjV1+08CRjzo;+ji2Ozqto&QsK?xI1333 z?2@Kdy}%ehuO5BoOkZ53<#`g#*fsG}IN+{i8kecqHOFSjg%? z{`uRKai5a@Cms(iPpJK`XeXkyk6BwgT=m+l=;b+&J4Wd6X0fbo!KH{;*E}}BX!Us! z(d+AnR#H+@5{yrS$2Y?=#wSrzw^=H46D5`?Eq~l)^M}_-4v6tVaa~MHUH{$YX6(GV z%;nU#pvT;Ldhz{TyFL+6>c%ZRvH#RhMf5)~`L}-REpC^SVzs=qOySQ+{Sxgn)!wf7 zO3fL)yflw(#hC#E{~~dTSkVYtq$i@N!uh&wXA`7B|C`fy)g)tfJ4p_>pDBt%;hC;a z0FsovU#C!2fe2~S3HT&W<#qLH14fwayR;V*Xrs!Bk)K3t8>24LN>t>f?^A3`{~{_g z4@=(CP@uZZSm){(C`&hq!cc=UZn8hHFV?ECMC`zUd1=4)XKFFo!tnfyUXfJdTe8M< zal+`GY|cNi)aG+(+hX~KB@8==$>!E(Cz;<3c(fEt%Q&p-hfh5}sK0%Z#_(&qPA+#3 z!NB$j#PsU_RJ3DRfgOhuAI_i@K)FccdZ$Tx9R)mIU)A4Ft;Vk~IUZaDk3*I%tFaTC zcKvtD7kiHVhM2dmBaYj~Ho=jp(ipYj#-Geb8}~o;m0%v)by>Cjd zt(t-yG+m_5)M2OAr`9{76KFxBmxD~iT*iS3(htS&`2B5eQyJKW6@Sv;^NoFC{3p!! zOEs1=3A@&DNKT&6L&=Ih)>z`Pxe1pO_6+#On#7-{(`rbmWuWC7N4 z)je~TmQYRDhB6Oby*>LMw;;IZF$4%7Y#Fd9v^|TR~UB+^Nz2TB3Y&%4-X$+2sSK{ECr9u ze&&q%%f*%Pl!Io7g0!2ICq^Bxi5buRW51y2mdrEVPk393B_f*wP?y+nD&6Y|S$*1XQ5b0yTk32(p zZ&`t*QCQ5`s6>f=Gxr|{iK5)LOfH{QY|p_x?ZO`q6cvAjQ4 z%ZQCw1e&DReLGJ_8~Nz09~)kP4GiL<7C-Pr7$uV_@%9=#>oRD8S>KoUFjo1^7G2P8 zanOODu7HHq9@7syeyyI`>eTpVsQJGBavKJHunV@l=a>BUW?Uac^deWmtJ{caGd|&x zdi{Cu1k`?rj*t(~QHk8PYDCi>E1T?WX>4=7*Rfpx_Jrrl^&7@Ir}Vz@N~Tj+2~JfL~s_;WAV?xK}&8X{#y>{fY17 z#1*%=JPx}vLhI!f#H4xKmn1&93j?#-)SzItm!8E|q@%xo828iCqzHbpP>F2+ zoPxNt2z5y>c4l*~Dny?QV5P=Wuzgaq@YDTdaXVC^D>z6rj2wtX7lfm85!ju0Xv#U+ z2IUTUVZ(-jk}vcVFc{mlf^O-eA<2KYiudq0XRS~A$qn~{WYlq5cprmCFuT!$)pV_p zud5y6uQqbM)|>Z!V*4|m4Q3_00k=W2SZ@_v60l;3=lU1@iduU|>!X)~AHGI(;qVNh zcXw5}FG*g!cqJvpr(cS;y8SCd7aFzlp+lKJS{A?WYH3L4u$iJ*LPPid4nND25G#44 zk!T3%z1>YK3nL9UcsBTp(;VH5LGSwdxcwQK;A1%6M8dGN^9S&6Hq70C6}hB__H#J+ zU!vNAXx9TkkoHFF+1_8E(TrgRuJKcUbkFZvnc-6o^bTW65=15X9u~*pUewoPg;-fl zH@NVUPyv!hX-;mSr-!k4e9o1xk)L#d!@z|fu1ob~HjinPc_G@tuP@VOF(}cS!(_;t zuZ{y)l_`auK4|S&95#3EGw+l}x+I1Vte>DWL_&wL$xXCJ|1_?Xd}z32cC_4-8Z*OJ zZI_?VI$jCdd;M9NgxoyI zYOv>J9;!&spvQ@=D|1ucN>^$FwuAVDo>Ifuu$TYL0|un`Y;ahDK5ARKHxQ z$TZ(;DlG@yWV5g6$f+=fcItbN!8XBmFF3w^)77Wj17AVsLF~-DvEXPWX4}}>1GNQq z_w~*~-(ion(1y=nrlNIgI}|rgU!bl3bayA7$>EkE{6_rS;?$hK<=EyJ?gfP>-=k9H zgI%!b%7QOl8tj5KD`A^JUL!quzjC@o z>LU$WasToy6@|vjbkjdQP*<$dL!EO3{qDH`XFg`Ef@+1Du+yNJgMQN&-ZigvBeIMH z#g`pzw99XL;_iL2I%v5#@PU@-QmSjM&ARzeWbPLZOqV_ZxSDr3&`W>KU+AYV7IT_Q zy*Os9MzJgUlKRomMd#K&2hUW^K-Tw)a_-&r|1LUT`1dZ&RqW()Dr^l-GYpXG1g5 z8N}Ppy-yN$e@bGiETERb+oW#uC8cV!@bS?ynIPjZe+}}935GsJbA zqc^zCc4*AcG|n)*ICTMN(D@rQD+`O~ypj8k*CPSNDpHT+HK)R}8>oMWYn9tNnE(}g zn(fT_-(nM_ti3blYKa6NpWqd6#O+zE$ZtArkLphk*F^SC+Y!*@OQ8PBQ(YwGLfwbd zLz(X3#(99)Rj5AolMhW!kEjZ(_wAP<%Wh2?kl>)o_1f5}8v7E;>H4Fiql^r?7x8!m zu8hh(J(bSRT9=ngJ7sJP6idiz8I4886?}yRum+&32N<7f_DCbH5pJMlWj*&iJsxt? zJeWAd>UU4gSUONn;STtq!co03pjl=NmBKF1xB3k8lq_*5;VUp-y8#W~S5pwD3i3YC z8vjVZeue-xINYH?*3W5O!bCA8xJ*-*u<3i9rv7Kp_DdZ|_<6@5>A9TG*T>Rw!on1(Irl9`U<#kh@rI~~P zb9BdZH{>)Q8AKAZ!+l>AlfK3GhG(AL836KO`n$WWNqneY`@E6`&TnmAV@pI{VYX}; zf(a1L;QSuCkmqW`te~+%b~clKF6ccQT_jK(YlH1`$I_BzuoT;L_b%3Qi>eFui2~%x zxcz9@QGsqEHT2or+2_~zRYjH>AzVWq84peMQGRN3l(8dfW0a$3xKv&Ri<`TN>`MN^K zdC=`%MWLf&MD&{6`Hka6A>^zdszH_JFi&KTmXds%3N-4*UgY}lYll5lq@_Z&i-`)} z%*nb_-y@3(dt!ii<^0<-c7^$G$*X?OlI4Y(FV6b>-{Ab`>5(WQZh1yGg9q3b|ImwK zd@AM)fU(0o|BNYr>X~~-EYqC?p1n&+&4rsHsYbyW0TJlP>!((e80^Hoc3tGPP)BwR zOR=j$q)c1cw$&NhH3}TFlHbvY6zST2!u}H#0C3H{5Y^;zaKzyrVBk#EXFNU3ZnAIi z+6q)Jg!DMOBLxw-a>_ZX@G;Wt4R*68Jxo`Wi2Sg|WW~<~{97{-2Q|#L(b!bbwRaYE z6=(H`=Cz8yJlYlDyHOFA4<#lEL7g(GjlR~&MI+q>X! zxh1+p`ye=71YHh@YDQN6G1p(11N9&3cU$qF)u20@qow*(K7X~&Wi@U&0yc}yuKSbjMemu;yG$23$V$|_Nc*6!usQSkx%fYLt%?4YnnSi z^YyR?`KM2#mKJ67nB1_Eq7rGx^rw8}-vRdf?UMD|;>3OUxQFSWV3kGqC40n+5Wl_( ztL4R}fOG-lkGVpNX4MROb1$;PcHZnRv>&X*LPC9Q4eaZA$Pj%#Y1k4Eh33#2EvY!c zIBlUl69uYN#jAyXnQ3P`LfNtk*zHb&Tjw9g%YB>UmFw|Eia>{8D{X6y@cq>nQ)KIb zejh~#YKvC0i{>qE2DEY_3eMgaF?pbB(RvuO(WN`1XTi(+DGk`mqef<++AGelkVPUu zw@Eq!WrYeoKi>y-*OTeRCj&r9fitSUlsKbs~Y8u283yTS>yMn4BNBen3F1 zkpYIQEg9|CoSYA-P>Y>$*$Vh{5%_l1$z~Ab+^xsC=Q#_=|I|bwsGwXQSyA3oyZ+~9 z*U=F&6(hJ8*HLxlwXhI+a9jusMQT!P#H8*Mhd-)MO=DuA=xUyz`3JgcQP3A@v~Gv4 z7|(_Iqj$%O{Tj*@rES^zl9?7twO<&BZNQWNq!3-Q9E2nrrsxm#Oq;aEpW&(U@(||! zaZ0rS@cF3*uG{)%Tt0F^HDO{LvW^!oOf#yO{z8KU~} zRqyedyrDupObK=z<;p@THyV{{P0a&idE_J3ff+u;UOT=weFl=fr^xlsurPT1qz~e* zos!hd<)W~khpP_Pn5rHZhx17=BTGr*d(Ja*?mKcY!!QWQh;S4&MPbND;B)CQkLVs& z3QsIm*W#>7NZ7Uye={c`2?Y%ubRk*c%B<1c%1WowCEfg99-F;Ml8)xNP`Wf%8RNlO z^$OcaQFpiQSPe%v5V@j}xtau~jC_f?x`FIxm4jPPZ+q8hpVQ)i$UMXnL~Q=F7xkM> zkY&u&p_$1xJHiI~`qZlNujiKj0`uHN$4y1wKtB3b>Y56_SUkv7_0;-dX;=)t*EFJU zzeugWV(spApo^$;VF)6gYvPsgt+-*`rBB~0R2FWQXoNd)-23UES0P7NVu%DTsq5h8>f9q;rw#j+Fs*pS5 zzbq_2KYg#$X2uA!`>u9QRrDvy0Dw)gWAL(GwgrArRLjy?dQQlO;R+y6^*2(_sfDK+X}- zV&_a7Omge|wo~~D#TcuAuf-mM5|k3)#pGxi_5kC^@Oz?H13Cnjzn zR7^J7#--kVFeLu#infD2jTnf(5=^42>KL0U=Pfz_BZ!qo+{@xWJ4{YGRahKlFDw{K z-qv{}Fi@Ft?hbltI5GoR;(ljQfou_p`-6HE?>#?mp9=MCC1#NoN*V~u&G9Q-ej$+? z+`qbg9`o#(8t&l}yir`3q0#W=+$X8X_*~$Mu$h@JnC;GPP_N$W%gZfpOxQS>BkaU$ zKl$TZbB#Hxc8}p)P7l6ddnc!Qh2n!qNU*6wb)J;aEgJa?4)-c7wBX|EZl0TAuV6Xz z#B^VGvd%NNW>{2AI`oQFwcXklLu)MWl+n)R5|G!!fOkTIZRs4ej7;qOEv&f4UidGO zoF3u%w6APLM_o~)ix-GEA3t71#LzrvVxU)qryuY5HL8r8)hE1!`QvT88A{}eobQ)$ z$vZq8Ld9hYzX#~?{a9>ewoK5`iq+(3KN4szEG(RGT*Ki!vKH)}Lr45|%Rns|^b%QX z5K5&MaiRf~0w}H&7bXA94{cP{)`YRkr~b~35pxTbkr6D6$ClklM?o+bE6LPgS_aNo zR1nTf={2E~dh|3h&kF~2B}K)Yot$;JK#&6A$T{^ct$n0xRkh0EyT7-G%De(QV5ufQ`kqztaEH9Tn| z$Ft*A+T%H;B;oyjbA4Km`E@IP@ zAUf2AcZ>+N2u@*u0$Pg?dNkym^;O;DbW%o*s-aLa(=NtDsuq44ziwp`R#wtnR(tl! zP5)dFKAxK=AscY;nW$xJG((R8Xl(!b_3L!WmM8);+R2qACK?9k8-y5t#5Qc*FMSO2 z?k4-Vsu#bjXB`X(iU|&HeM1nQWWmt)j-5K?0?M(J7};&BJ(2^-(lU98=Ig|kT zr4nuLY|&?DME&I=XEaq_PTXfn`Um6sla=#)y&Kd~W04nlpT&J?^g*rfUq<17OmE6_ z7J9$#HP_fhiV?tb?-*b<;5m?x%&leSR;R2(BijvrGE5tALJ{lJoOt>JS2Hb?ulaH}Q_Y)&9L?p!g zy~g^m%oEel-E8JH&}hx;f#lG`t(}h#<1Mye>kD7U96hZ1r8zJ}$m#x(tOR&nPwqc@ ztJjcH!;iv0u*RyV5p|#89DaB>0&^LEyRib=#U?%6@?=kWm$HIEX4R0CAjjF<_ z93}h~%q)R@=StfMQ+!-Jwg4G42D2tx2!0Ka5^RL&HUV-kg|UfmJor zF6m}Hc{ubIzHMf=V`_PtWJakwj%j>|Hzwrq7 zD7vHk@lo}1bJNPwqB4BFKa-!9Ra#mgAs+nYW^HYR@Fgd)j!`Hd&Y8>pNP7*gWQiyL zb!243D~eqINlZ-L?c25XAayokTdmar_TnNt2fP2LZbxk`JTvL|c!&u?>GGBXJm-xu zcl`P|CLUYgB4t8VHkuhfaV*|+JDr}-{j3mrg#z(N@gOeyw%(z;SX7#$s6>BFb5|Nl zQ-i2jd|c&+yvZNT55sITjP!Rp2flyzCMU0cpnUTW+dX}dN5>_TLDD9z?%!&%ie=LT zbf!F+O3iWEr4Gj{T?Hd%q#eN)g|PDZn*LH zI%}_6ywXrG!Pm0}45KDpJ>Vx(bnNaF@xSAcyz{$cC44hg$G!`zo`NBUYjKfiw!G#1BAvi-#kd=J6@z)aU_3;nIAaKas= zit(A>wOI>YtMcl*Q5jhcXD{YFhFW8~Imn}x>tC{0=-?v3sRP%0yf0n_Qf~01yw~E{8yrkXh*2%!N@K=Baix@B2CTx9ja&1!LlL3$e^fLvltWh_y_)+3cMn*=7 zfTT?&#&+iqMx8#jUOj=}T`|Pqb(2ezNNVP<8_ETL=2LgAbS8i(rebM%d5ltkUG#b_X_8O?=N`1fHqrF!=mi@(rk{NSg?PQ42=O>4RclpL{9{eARWrQg1aeHim%P#2RIa%) zC3LKOC?(v}e{lh?x2&8CQE!(YB5EFy$Y0NDdep5e#V1H66kj^eA^^-fDhUMNUCstouwiLs@tU-4^_G!!+a9~auPEjYTKR#(% zOND*6liz4kEY{F1y69K)z%1aE_4NvDtxprs>r~zVK?Mx-Jw4D9V>`p=yHKbo50sWdv z(&6R9jO{P2q_3m;N;88?G)1!3cHf!EHR_)XfLpk2gb^B{l$&I9IJHt z$7GRGsPhAhlDeXPR}adMOUxqDv*Z>kCd>KO@2KW3w`Q zgZ$067nZU?hZYUNJ?-fII!Eos{%733rQQxPJw;N@GLniv{70lJ`26^qYSHzf8zMJX z-_?m^pS8!dKLZ&6mq0d+OGk3E5tr)Z{yMlgc?;vWpMH>@<(H`^k^Mi`LRXl7wS z)ZJezmtqn){WC*O*mmYlkI=}?AT3Q!ASNfhpghDaWSf?7knfhW_AE`(kY#^AWBj#w z2{$P27ur!QzfuU&u|qxnLZTi`@5p@L6eAXD^RZ;7n7v9I<5N35&CjPb_9Cf9H7;4| z7MU8^n8w2!*~sF7$`NdB6DvY)ucR-0Oz9XKH>7*`w2l%S97f+5;(kbj>(AYg&^MKc$9DuD zFERpmxwrx?9Cc}zsykHBz&xi1%zf&+b1G8;epAL2WGrtYa(S7B4IDSIKunrpM8zN~ zBS4NKXD4LGQnDfj>>+h^BO7vgKNx+}bpWlOVWOqneeYWlea>g)=`PaA& zzUNQ(03Wz*5?;UhkM%1TqzUX1aDsowL5R=IfEVMLeP)~?Gz8K76?MYOrVg_7ZrCBo zsw1R$qND<0Yfr<=vERXc(;0|Z+AXGkhqvbqGRv546oZ^TvtQ(8P?~>0QaYY#OCqjp zgvk&02%#@te%DD)+Dw7BbqH`OqG<>eGb$XLJ&|w^%N1UoEsaXWP1%MLp;Hl?O1~|g zJfPrfi%v!uy|9mO?qtk`ozze41~W1g}0=w*0mc7iBV}V_-Kv1$QL>vd$mW0zE@Sm=&V;*v% z0jeOt|4LGsR=ktHx?9mX8HO0ioE}J6t5g1K6CEMZ0qLkR@9_3fcMk;vY~n?aCe-TL zTf6T9d(Y+T$E)~d#$cBJ9ZM(;&65b);4A*K^8ftH@N9^rl^d`m!4{?@LGUBf# zot@>GnX(i^!sSr2lg3fg<4-@!!2 zME_lx&B%xvZox$ME>c_%2cxn}@8ppl=j$eSVJ^Xq`-yl1R zT|$I}kZ=O$yHz#vrvMfy*nG2TJ)1YfP}n_Z#ig!R3#g0~=RFyiIEzn~yt<)ocRfOQ f+@p}ZxIsd=+FYlnc6e_AxR1s&ZPj1O)=~ch)kP#- literal 0 HcmV?d00001 diff --git a/naloga_3/models/monkey/monkey.bin b/naloga_3/models/monkey/monkey.bin new file mode 100644 index 0000000000000000000000000000000000000000..b81d93e54f9da1be47d8cb707e56fb36e0d9dd6e GIT binary patch literal 32496 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%0AbgWvTqGXr9vkt6$)D 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 C-YCZa literal 0 HcmV?d00001 diff --git a/naloga_3/shader.wgsl b/naloga_3/shader.wgsl new file mode 100644 index 0000000..74868a7 --- /dev/null +++ b/naloga_3/shader.wgsl @@ -0,0 +1,98 @@ +struct VertexInput { + @location(0) position: vec3f, + @location(1) texcoords: vec2f, + @location(2) normal: vec3f, +} + +struct VertexOutput { + @builtin(position) clipPosition: vec4f, + @location(0) position: vec3f, + @location(1) texcoords: vec2f, + @location(2) normal: vec3f, +} + +struct FragmentInput { + @location(0) position: vec3f, + @location(1) texcoords: vec2f, + @location(2) normal: vec3f, +} + +struct FragmentOutput { + @location(0) color: vec4f, +} + +struct CameraUniforms { + viewMatrix: mat4x4f, + projectionMatrix: mat4x4f, + cameraPosition: vec3f, +} + +struct ModelUniforms { + modelMatrix: mat4x4f, + normalMatrix: mat3x3f, +} + +struct MaterialUniforms { + baseFactor: vec4f, + specularFactor: f32, + shininess: f32, +} + +struct SpotLightUniforms { + position: vec3f, + direction: vec3f, + cutoffAngle: f32, + ambient: f32, + intensity: f32, +} + +@group(0) @binding(0) var camera: CameraUniforms; +@group(1) @binding(0) var model: ModelUniforms; +@group(2) @binding(0) var material: MaterialUniforms; +@group(2) @binding(1) var baseTexture: texture_2d; +@group(2) @binding(2) var baseSampler: sampler; +@group(3) @binding(0) var spotLight: SpotLightUniforms; + +@vertex +fn vertex(input: VertexInput) -> VertexOutput { + var output: VertexOutput; + + output.clipPosition = camera.projectionMatrix * camera.viewMatrix * model.modelMatrix * vec4(input.position, 1); + + output.position = (model.modelMatrix * vec4(input.position, 1)).xyz; + output.texcoords = input.texcoords; + output.normal = model.normalMatrix * input.normal; + + return output; +} + +@fragment +fn fragment(input: FragmentInput) -> FragmentOutput { + var output: FragmentOutput; + + let N = normalize(input.normal); + let L = normalize(spotLight.position - input.position); + let V = normalize(camera.cameraPosition - input.position); + let H = normalize(L + V); + + // Spotlight factor based on cutoff angle + let lightDir = normalize(spotLight.direction); + let theta = dot(L, -lightDir); + let spotlightFactor = select(0.0, 1.0, theta > spotLight.cutoffAngle); + + // Diffuse and Specular components + let lambert = max(dot(N, L), 0) * spotlightFactor; + let specular = pow(max(dot(N, H), 0), material.shininess) * spotlightFactor; + + let materialColor = textureSample(baseTexture, baseSampler, input.texcoords) * material.baseFactor; + let lambertFactor = vec4(vec3(lambert), 1); + let specularFactor = vec4(vec3(specular * material.specularFactor), 1); + let ambientFactor = vec4(vec3(spotLight.ambient), 1); + + // Final color +// output.color = materialColor * ((lambertFactor + specularFactor) + specularFactor * spotLight.intensity); +// output.color = spotLight.intensity * (lambertFactor + specularFactor) + ambientFactor; + output.color = spotlightFactor * materialColor; + + return output; +} diff --git a/vaja_1/base.png b/vaja_1/base.png new file mode 100644 index 0000000000000000000000000000000000000000..92c90d35737ef8d26ab0725d562bed7616d3c7a7 GIT binary patch literal 61635 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 z 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 literal 0 HcmV?d00001 diff --git a/vaja_1/main.js b/vaja_1/main.js index ba206fe..02c907d 100644 --- a/vaja_1/main.js +++ b/vaja_1/main.js @@ -15,6 +15,35 @@ const depthTexture = device.createTexture({ format: 'depth24plus', }); +// Prepare color texture +// 1. fetch the texture from the server +const imageBitmap = await fetch('base.png') + .then((response) => response.blob()) + .then((blob) => createImageBitmap(blob)); + +// 2. create a texture +const colorTexture = device.createTexture({ + size: [imageBitmap.width, imageBitmap.height], + usage: + GPUTextureUsage.TEXTURE_BINDING | + GPUTextureUsage.RENDER_ATTACHMENT | + GPUTextureUsage.COPY_DST, + format: 'rgba8unorm', + mipLevelCount: 2, +}); + +// 3. transfer data +device.queue.copyExternalImageToTexture( + { source: imageBitmap }, + { texture: colorTexture }, + [imageBitmap.width, imageBitmap.height], +); + +// 4. create sampler +const colorSampler = device.createSampler({ + mipmapFilter: 'linear', +}); + // Create vertex buffer // prettier-ignore const vertices = new Float32Array([ @@ -24,7 +53,7 @@ const vertices = new Float32Array([ -1, 1, -1, 1, 0, 0, 1, 1, 1, 1, -1, 1, 1, 1, 0, 1, - -1, 1, 1, 1, 1, 0, 0, 1, + -1, -1, 1, 1, 1, 0, 0, 1, 1, -1, 1, 1, 0, 1, 0, 1, -1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, @@ -62,12 +91,12 @@ const module = device.createShaderModule({ code }); // Create the pipeline /** @type {GPUVertexBufferLayout} */ const vertexBufferLayout = { - arrayStride: 24, + arrayStride: 32, attributes: [ { shaderLocation: 0, offset: 0, - format: 'float32x2', + format: 'float32x4', }, { shaderLocation: 1, @@ -103,7 +132,11 @@ const uniformBuffer = device.createBuffer({ // Create the bind group const bindGroup = device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), - entries: [{ binding: 0, resource: { buffer: uniformBuffer } }], + entries: [ + { binding: 0, resource: { buffer: uniformBuffer } }, + { binding: 1, resource: colorTexture.createView() }, + { binding: 2, resource: colorSampler }, + ], }); function update() { diff --git a/vaja_1/shader.wgsl b/vaja_1/shader.wgsl index aba83d8..9f3d5e8 100644 --- a/vaja_1/shader.wgsl +++ b/vaja_1/shader.wgsl @@ -1,38 +1,21 @@ -struct VertexInput { - @location(0) position: vec4f, - @location(1) color: vec4f, -} - struct VertexOutput { @builtin(position) position: vec4f, @location(0) color: vec4f, } -struct FragmentInput { - @location(0) color: vec4f, -} - -struct FragmentOutput { - @location(0) color: vec4f, -} - @group(0) @binding(0) var mtrx: mat4x4f; +@group(0) @binding(1) var colorTexture: texture_2d; +@group(0) @binding(2) var colorSampler: sampler; @vertex -fn vertex(input: VertexInput) -> VertexOutput { +fn vertex(@location(0) position: vec4f, @location(1) color: vec4f) -> VertexOutput { var output: VertexOutput; - - output.position = mtrx * input.position; - output.color = input.color; - + output.position = mtrx * position; + output.color = color; return output; } @fragment -fn fragment(input: FragmentInput) -> FragmentOutput { - var output: FragmentOutput; - - output.color = input.color; - - return output; +fn fragment(@location(0) color: vec4f) -> @location(0) vec4f { + return textureSample(colorTexture, colorSampler, color.xy); }