1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-05 10:49:36 +02:00
Oinktube/node_modules/cardboard-vr-display/src/cardboard-ui.js
2023-12-11 11:59:56 -03:00

285 lines
8.6 KiB
JavaScript

/*
* Copyright 2016 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as Util from './util.js';
import WGLUPreserveGLState from 'gl-preserve-state';
var uiVS = [
'attribute vec2 position;',
'uniform mat4 projectionMat;',
'void main() {',
' gl_Position = projectionMat * vec4( position, -1.0, 1.0 );',
'}',
].join('\n');
var uiFS = [
'precision mediump float;',
'uniform vec4 color;',
'void main() {',
' gl_FragColor = color;',
'}',
].join('\n');
var DEG2RAD = Math.PI/180.0;
// The gear has 6 identical sections, each spanning 60 degrees.
var kAnglePerGearSection = 60;
// Half-angle of the span of the outer rim.
var kOuterRimEndAngle = 12;
// Angle between the middle of the outer rim and the start of the inner rim.
var kInnerRimBeginAngle = 20;
// Distance from center to outer rim, normalized so that the entire model
// fits in a [-1, 1] x [-1, 1] square.
var kOuterRadius = 1;
// Distance from center to depressed rim, in model units.
var kMiddleRadius = 0.75;
// Radius of the inner hollow circle, in model units.
var kInnerRadius = 0.3125;
// Center line thickness in DP.
var kCenterLineThicknessDp = 4;
// Button width in DP.
var kButtonWidthDp = 28;
// Factor to scale the touch area that responds to the touch.
var kTouchSlopFactor = 1.5;
var Angles = [
0, kOuterRimEndAngle, kInnerRimBeginAngle,
kAnglePerGearSection - kInnerRimBeginAngle,
kAnglePerGearSection - kOuterRimEndAngle
];
/**
* Renders the alignment line and "options" gear. It is assumed that the canvas
* this is rendered into covers the entire screen (or close to it.)
*/
function CardboardUI(gl) {
this.gl = gl;
this.attribs = {
position: 0
};
this.program = Util.linkProgram(gl, uiVS, uiFS, this.attribs);
this.uniforms = Util.getProgramUniforms(gl, this.program);
this.vertexBuffer = gl.createBuffer();
this.gearOffset = 0;
this.gearVertexCount = 0;
this.arrowOffset = 0;
this.arrowVertexCount = 0;
this.projMat = new Float32Array(16);
this.listener = null;
this.onResize();
};
/**
* Tears down all the resources created by the UI renderer.
*/
CardboardUI.prototype.destroy = function() {
var gl = this.gl;
if (this.listener) {
gl.canvas.removeEventListener('click', this.listener, false);
}
gl.deleteProgram(this.program);
gl.deleteBuffer(this.vertexBuffer);
};
/**
* Adds a listener to clicks on the gear and back icons
*/
CardboardUI.prototype.listen = function(optionsCallback, backCallback) {
var canvas = this.gl.canvas;
this.listener = function(event) {
var midline = canvas.clientWidth / 2;
var buttonSize = kButtonWidthDp * kTouchSlopFactor;
// Check to see if the user clicked on (or around) the gear icon
if (event.clientX > midline - buttonSize &&
event.clientX < midline + buttonSize &&
event.clientY > canvas.clientHeight - buttonSize) {
optionsCallback(event);
}
// Check to see if the user clicked on (or around) the back icon
else if (event.clientX < buttonSize && event.clientY < buttonSize) {
backCallback(event);
}
};
canvas.addEventListener('click', this.listener, false);
};
/**
* Builds the UI mesh.
*/
CardboardUI.prototype.onResize = function() {
var gl = this.gl;
var self = this;
var glState = [
gl.ARRAY_BUFFER_BINDING
];
WGLUPreserveGLState(gl, glState, function(gl) {
var vertices = [];
var midline = gl.drawingBufferWidth / 2;
// The gl buffer size will likely be smaller than the physical pixel count.
// So we need to scale the dps down based on the actual buffer size vs physical pixel count.
// This will properly size the ui elements no matter what the gl buffer resolution is
var physicalPixels = Math.max(screen.width, screen.height) * window.devicePixelRatio;
var scalingRatio = gl.drawingBufferWidth / physicalPixels;
var dps = scalingRatio * window.devicePixelRatio;
var lineWidth = kCenterLineThicknessDp * dps / 2;
var buttonSize = kButtonWidthDp * kTouchSlopFactor * dps;
var buttonScale = kButtonWidthDp * dps / 2;
var buttonBorder = ((kButtonWidthDp * kTouchSlopFactor) - kButtonWidthDp) * dps;
// Build centerline
vertices.push(midline - lineWidth, buttonSize);
vertices.push(midline - lineWidth, gl.drawingBufferHeight);
vertices.push(midline + lineWidth, buttonSize);
vertices.push(midline + lineWidth, gl.drawingBufferHeight);
// Build gear
self.gearOffset = (vertices.length / 2);
function addGearSegment(theta, r) {
var angle = (90 - theta) * DEG2RAD;
var x = Math.cos(angle);
var y = Math.sin(angle);
vertices.push(kInnerRadius * x * buttonScale + midline, kInnerRadius * y * buttonScale + buttonScale);
vertices.push(r * x * buttonScale + midline, r * y * buttonScale + buttonScale);
}
for (var i = 0; i <= 6; i++) {
var segmentTheta = i * kAnglePerGearSection;
addGearSegment(segmentTheta, kOuterRadius);
addGearSegment(segmentTheta + kOuterRimEndAngle, kOuterRadius);
addGearSegment(segmentTheta + kInnerRimBeginAngle, kMiddleRadius);
addGearSegment(segmentTheta + (kAnglePerGearSection - kInnerRimBeginAngle), kMiddleRadius);
addGearSegment(segmentTheta + (kAnglePerGearSection - kOuterRimEndAngle), kOuterRadius);
}
self.gearVertexCount = (vertices.length / 2) - self.gearOffset;
// Build back arrow
self.arrowOffset = (vertices.length / 2);
function addArrowVertex(x, y) {
vertices.push(buttonBorder + x, gl.drawingBufferHeight - buttonBorder - y);
}
var angledLineWidth = lineWidth / Math.sin(45 * DEG2RAD);
addArrowVertex(0, buttonScale);
addArrowVertex(buttonScale, 0);
addArrowVertex(buttonScale + angledLineWidth, angledLineWidth);
addArrowVertex(angledLineWidth, buttonScale + angledLineWidth);
addArrowVertex(angledLineWidth, buttonScale - angledLineWidth);
addArrowVertex(0, buttonScale);
addArrowVertex(buttonScale, buttonScale * 2);
addArrowVertex(buttonScale + angledLineWidth, (buttonScale * 2) - angledLineWidth);
addArrowVertex(angledLineWidth, buttonScale - angledLineWidth);
addArrowVertex(0, buttonScale);
addArrowVertex(angledLineWidth, buttonScale - lineWidth);
addArrowVertex(kButtonWidthDp * dps, buttonScale - lineWidth);
addArrowVertex(angledLineWidth, buttonScale + lineWidth);
addArrowVertex(kButtonWidthDp * dps, buttonScale + lineWidth);
self.arrowVertexCount = (vertices.length / 2) - self.arrowOffset;
// Buffer data
gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
});
};
/**
* Performs distortion pass on the injected backbuffer, rendering it to the real
* backbuffer.
*/
CardboardUI.prototype.render = function() {
var gl = this.gl;
var self = this;
var glState = [
gl.CULL_FACE,
gl.DEPTH_TEST,
gl.BLEND,
gl.SCISSOR_TEST,
gl.STENCIL_TEST,
gl.COLOR_WRITEMASK,
gl.VIEWPORT,
gl.CURRENT_PROGRAM,
gl.ARRAY_BUFFER_BINDING
];
WGLUPreserveGLState(gl, glState, function(gl) {
// Make sure the GL state is in a good place
gl.disable(gl.CULL_FACE);
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.BLEND);
gl.disable(gl.SCISSOR_TEST);
gl.disable(gl.STENCIL_TEST);
gl.colorMask(true, true, true, true);
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
self.renderNoState();
});
};
CardboardUI.prototype.renderNoState = function() {
var gl = this.gl;
// Bind distortion program and mesh
gl.useProgram(this.program);
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.enableVertexAttribArray(this.attribs.position);
gl.vertexAttribPointer(this.attribs.position, 2, gl.FLOAT, false, 8, 0);
gl.uniform4f(this.uniforms.color, 1.0, 1.0, 1.0, 1.0);
Util.orthoMatrix(this.projMat, 0, gl.drawingBufferWidth, 0, gl.drawingBufferHeight, 0.1, 1024.0);
gl.uniformMatrix4fv(this.uniforms.projectionMat, false, this.projMat);
// Draws UI element
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
gl.drawArrays(gl.TRIANGLE_STRIP, this.gearOffset, this.gearVertexCount);
gl.drawArrays(gl.TRIANGLE_STRIP, this.arrowOffset, this.arrowVertexCount);
};
export default CardboardUI;