webgl/src/client/uiscene.ts

340 lines
20 KiB
TypeScript

import $ from 'jquery';
import _ from 'lodash';
import {loadTexture} from './texture';
import {fetchObj, loadObj, loadObjBuffers} from './objutils';
import {changeFragmentShader} from './shaders';
import {initBuffers} from './buffers';
import vsSource from './shaders/shader.vert';
import blackandwhite from './shaders/blackandwhite.frag';
import colored from './shaders/colored.frag';
import grey from './shaders/grey.frag';
import texture from './shaders/texture.frag';
import sobel from './shaders/sobel.frag';
import fractal from './shaders/fractal.frag';
/**
* UI block to update scene
* @param {any} context the program context
*/
export function uiUpdateScene(context: any) {
$('#pushtoscene').on('click', () => {
context.scene.push({
buffers: initBuffers(context.gl,
context.obj.positions,
context.obj.indices,
context.obj.normals,
context.obj.uvs),
texture: context.texture,
params: _.cloneDeep(context.params),
programInfo: _.cloneDeep(context.programInfo),
shaderProgram: _.cloneDeep(context.shaderProgram),
shaders: _.cloneDeep(context.shaders),
});
/* eslint-disable */
let instanceRadioString;
if ($('input[name=instance]:checked', '#instanceoptions').val() ==
'normal') {
instanceRadioString = `
<div class='custom-control custom-radio'>
<input class="custom-control-input" type="radio" id="` + context.scene.length + `normal" name="` + context.scene.length + `instance" value="normal" checked>
<label class="custom-control-label" for="` + context.scene.length + `normal">Use instance slider</label>
</div>
<div class='custom-control custom-radio'>
<input class="custom-control-input" type="radio" id="` + context.scene.length + `one" name="` + context.scene.length + `instance" value="one">
<label class="custom-control-label" for="` + context.scene.length + `one">Lock to one working instance</label>
</div>
<div class='custom-control custom-radio'>
<input class="custom-control-input" type="radio" id="` + context.scene.length + `zero" name="` + context.scene.length + `instance" value="zero">
<label class="custom-control-label" for="` + context.scene.length + `zero">Do not show working instance</label>
</div>`;
} else if (
($('input[name=instance]:checked', '#instanceoptions').val() ==
'one')) {
instanceRadioString = `
<div class='custom-control custom-radio'>
<input class="custom-control-input" type="radio" id="` + context.scene.length + `normal" name="` + context.scene.length + `instance" value="normal">
<label class="custom-control-label" for="` + context.scene.length + `normal">Use instance slider</label>
</div>
<div class='custom-control custom-radio'>
<input class="custom-control-input" type="radio" id="` + context.scene.length + `one" name="` + context.scene.length + `instance" value="one" checked>
<label class="custom-control-label" for="` + context.scene.length + `one">Lock to one working instance</label>
</div>
<div class='custom-control custom-radio'>
<input class="custom-control-input" type="radio" id="` + context.scene.length + `zero" name="` + context.scene.length + `instance" value="zero">
<label class="custom-control-label" for="` + context.scene.length + `zero">Do not show working instance</label>
</div>`;
} else {
instanceRadioString = `
<div class='custom-control custom-radio'>
<input class="custom-control-input" type="radio" id="` + context.scene.length + `normal" name="` + context.scene.length + `instance" value="normal">
<label class="custom-control-label" for="` + context.scene.length + `normal">Use instance slider</label>
</div>
<div class='custom-control custom-radio'>
<input class="custom-control-input" type="radio" id="` + context.scene.length + `one" name="` + context.scene.length + `instance" value="one">
<label class="custom-control-label" for="` + context.scene.length + `one">Lock to one working instance</label>
</div>
<div class='custom-control custom-radio'>
<input class="custom-control-input" type="radio" id="` + context.scene.length + `zero" name="` + context.scene.length + `instance" value="zero" checked>
<label class="custom-control-label" for="` + context.scene.length + `zero">Do not show working instance</label>
</div>`;
}
$('#scene-block').append(`
<button class="btn btn-scene my-1" type="button" data-toggle="collapse" data-target="#collapse` + context.scene.length + `" aria-expanded="false" aria-controls="collapse` + context.scene.length + `">
Object ` + context.scene.length + `
</button>
<div class="collapse" id="collapse` + context.scene.length + `">
<div class='ui-block my-2'>
<div class='text-left' style='display: inline-block; width:30%;'>Change shader: </div>
<div style='display: inline-block; width: 65%'>
<button class="my-1 btn btn-shader" id='` + context.scene.length + `s_blackandwhite'>Black & White</button>
<button class="my-1 btn btn-shader" id='` + context.scene.length + `s_color'>Colored</button>
<button class="my-1 btn btn-shader" id='` + context.scene.length + `s_grey'>No texture</button>
<button class="my-1 btn btn-shader" id='` + context.scene.length + `s_texture'>Texture</button>
<button class="my-1 btn btn-shader" id='` + context.scene.length + `s_sobel'>Sobel Edge Detection</button>
<button class="my-1 btn btn-shader" id='` + context.scene.length + `s_fractal'>Fractal</button>
</div>
</div>
<div class='ui-block my-2'>
<div style='display: inline-block; width:30%;'>Change object: </div>
<div style='display: inline-block; width: 65%'>
<button class="my-1 btn btn-object" style='min-width: 8%' id='` + context.scene.length + `o_sphere'>Sphere</button>
<button class="my-1 btn btn-object" style='min-width: 8%' id='` + context.scene.length + `o_teapot'>Teapot</button>
<button class="my-1 btn btn-object" style='min-width: 8%' id='` + context.scene.length + `o_fox'>Fox</button>
<button class="my-1 btn btn-object" style='min-width: 8%' id='` + context.scene.length + `o_mecha'>Mecha</button>
<button class="my-1 btn btn-object" style='min-width: 8%' id='` + context.scene.length + `o_racer'>Racer</button>
</div>
</div>
<div class='ui-block my-2'>
<div style='display: inline-block; width:30%;'>Change texture: </div>
<div style='display: inline-block; width: 65%'>
<button class="my-1 btn btn-texture" style='min-width: 8%' id='` + context.scene.length + `t_wall'>Wall</button>
<button class="my-1 btn btn-texture" style='min-width: 8%' id='` + context.scene.length + `t_ice'>Ice</button>
<button class="my-1 btn btn-texture" style='min-width: 8%' id='` + context.scene.length + `t_noise'>Noise</button>
<button class="my-1 btn btn-texture" style='min-width: 8%' id='` + context.scene.length + `t_fox'>Fox</button>
<button class="my-1 btn btn-texture" style='min-width: 8%' id='` + context.scene.length + `t_racer'>Racer</button>
<button class="my-1 btn btn-texture" style='min-width: 8%' id='` + context.scene.length + `t_racer_wireframe'>Racer Wireframe</button>
</div>
</div>
<div class='ui-block'>
<div style='display: inline-block; width:30%;'>Instances Number: </div>
<input class='custom-range' style='width:65%' type="range" min="1" max="180" value="9" step='1' class="slider" id="` + context.scene.length + `instance">
</div>
<div class='ui-block'>
<form id="` + context.scene.length + `instanceoptions">` + instanceRadioString + `</form>
</div>
<div class='ui-block my-2'>
<div style='display: inline-block; width:30%;'>Rotate: </div>
<div class='m-0 p-0' style='display: inline-block; width:2%;'>X: </div>
<input class='custom-range m-0 p-0' style='width:19%' type="range" min="0" max="6.2830" value="0" step='0.0001' class="slider" id="` + context.scene.length + `rotx">
<div class='m-0 p-0' style='display: inline-block; width:2%;'>Y: </div>
<input class='custom-range m-0 p-0' style='width:19%' type="range" min="0" max="6.2830" value="0" step='0.0001' class="slider" id="` + context.scene.length + `roty">
<div class='m-0 p-0' style='display: inline-block; width:2%;'>Z: </div>
<input class='custom-range m-0 p-0' style='width:19%' type="range" min="0" max="6.2830" value="0" step='0.0001' class="slider" id="` + context.scene.length + `rotz">
</div>
<div class='ui-block my-2'>
<div style='display: inline-block; width:30%;'>Scale: </div>
<div style='display: inline-block; width:2%;'>X: </div>
<input class='form-control m-0 p-0' style='display: inline-block; width:19%' type="number" value="1" min="0" step='0.00001' id="` + context.scene.length + `scalex">
<div style='display: inline-block; width:2%;'>Y: </div>
<input class='form-control m-0 p-0' style='display: inline-block; width:19%' type="number" value="1" min="0" step='0.00001' id="` + context.scene.length + `scaley">
<div style='display: inline-block; width:2%;'>Z: </div>
<input class='form-control m-0 p-0' style='display: inline-block; width:19%' type="number" value="1" min="0" step='0.00001' id="` + context.scene.length + `scalez">
</div>
<div class='ui-block my-2'>
<div style='display: inline-block; width:30%;'>Translate: </div>
<div style='display: inline-block; width:2%;'>X: </div>
<input class='form-control m-0 p-0' style='display: inline-block; width:19%' type="number" value="0" step='0.00001' id="` + context.scene.length + `posx">
<div style='display: inline-block; width:2%;'>Y: </div>
<input class='form-control m-0 p-0' style='display: inline-block; width:19%' type="number" value="0" step='0.00001' id="` + context.scene.length + `posy">
<div style='display: inline-block; width:2%;'>Z: </div>
<input class='form-control m-0 p-0' style='display: inline-block; width:19%' type="number" value="0" step='0.00001' id="` + context.scene.length + `posz">
</div>
</div>`);
$('#' + context.scene.length + 't_wall').on('click', (event) => {
const n = parseInt(event.target.id.split('t')[0]);
if (context.cache.textures.wall == null) {
context.cache.textures.wall = loadTexture(context.gl,
'/static/textures/wall.png');
}
context.scene[n - 1].texture = context.cache.textures.wall;
});
$('#' + context.scene.length + 't_ice').on('click', (event) => {
const n = parseInt(event.target.id.split('t')[0]);
if (context.cache.textures.ice == null) {
context.cache.textures.ice = loadTexture(context.gl,
'/static/textures/ice.png');
}
context.scene[n - 1].texture = context.cache.textures.ice;
});
$('#' + context.scene.length + 't_noise').on('click', (event) => {
const n = parseInt(event.target.id.split('t')[0]);
if (context.cache.textures.noise == null) {
context.cache.textures.noise = loadTexture(context.gl,
'/static/textures/noise.png');
}
context.scene[n - 1].texture = context.cache.textures.noise;
});
$('#' + context.scene.length + 't_fox').on('click', (event) => {
const n = parseInt(event.target.id.split('t')[0]);
if (context.cache.textures.fox == null) {
context.cache.textures.fox = loadTexture(context.gl,
'/static/textures/fox.png');
}
context.scene[n - 1].texture = context.cache.textures.fox;
});
$('#' + context.scene.length + 't_racer').on('click', (event) => {
const n = parseInt(event.target.id.split('t')[0]);
if (context.cache.textures.racer == null) {
context.cache.textures.racer = loadTexture(context.gl,
'/static/textures/racer.png');
}
context.scene[n - 1].texture = context.cache.textures.racer;
});
$('#' + context.scene.length + 't_racer_wireframe').on('click',
(event) => {
const n = parseInt(event.target.id.split('t')[0]);
if (context.cache.textures.racerWireframe == null) {
context.cache.textures.racerWireframe = loadTexture(
context.gl,
'/static/textures/racer_wireframe.png');
}
context.scene[n - 1].texture = context.cache.textures.racerWireframe;
});
$('#' + context.scene.length + 'instanceoptions input').on('change', (event) => {
const n = parseInt(event.target.attributes[2].nodeValue!.split('instance')[0]);
if ($('input[name=' + n + 'instance]:checked', '#' + n + 'instanceoptions').val() ==
'normal') {
context.scene[n - 1].params.instanceNumber = parseFloat(<string>$('#' + n + 'instance').val());
} else if (
($('input[name=' + n + 'instance]:checked', '#' + n + 'instanceoptions').val() ==
'one')) {
context.scene[n - 1].params.instanceNumber = 1;
} else {
context.scene[n - 1].params.instanceNumber = 0;
}
});
$('#' + context.scene.length + 'instance').on('input', (event) => {
const n = parseInt(event.target.id.split('instance')[0]);
if ($('input[name=' + n + 'instance]:checked', '#' + n + 'instanceoptions').val() ==
'normal') {
context.scene[n - 1].params.instanceNumber = parseFloat(<string>$('#' + n + 'instance').val());
}
});
$('#' + context.scene.length + 'rotx').on('input', (event) => {
const n = parseInt(event.target.id.split('rot')[0]);
console.log(n);
context.scene[n - 1].params.rot.x = parseFloat(<string>$('#' + n + 'rotx').val());
});
$('#' + context.scene.length + 'roty').on('input', (event) => {
const n = parseInt(event.target.id.split('rot')[0]);
context.scene[n - 1].params.rot.y = parseFloat(<string>$('#' + n + 'roty').val());
});
$('#' + context.scene.length + 'rotz').on('input', (event) => {
const n = parseInt(event.target.id.split('rot')[0]);
context.scene[n - 1].params.rot.z = parseFloat(<string>$('#' + n + 'rotz').val());
});
$('#' + context.scene.length + 'posx').on('input', (event) => {
const n = parseInt(event.target.id.split('pos')[0]);
context.scene[n - 1].params.pos.x = parseFloat(<string>$('#' + n + 'posx').val());
});
$('#' + context.scene.length + 'posy').on('input', (event) => {
const n = parseInt(event.target.id.split('pos')[0]);
context.scene[n - 1].params.pos.y = parseFloat(<string>$('#' + n + 'posy').val());
});
$('#' + context.scene.length + 'posz').on('input', (event) => {
const n = parseInt(event.target.id.split('pos')[0]);
context.scene[n - 1].params.pos.z = parseFloat(<string>$('#' + n + 'posz').val());
});
$('#' + context.scene.length + 'scalex').on('input', (event) => {
const n = parseInt(event.target.id.split('scale')[0]);
console.log(n);
console.log(parseFloat(<string>$('#' + n + 'scalex').val()));
context.scene[n - 1].params.scale.x = parseFloat(<string>$('#' + n + 'scalex').val());
});
$('#' + context.scene.length + 'scaley').on('input', (event) => {
const n = parseInt(event.target.id.split('scale')[0]);
context.scene[n - 1].params.scale.y = parseFloat(<string>$('#' + n + 'scaley').val());
});
$('#' + context.scene.length + 'scalez').on('input', (event) => {
const n = parseInt(event.target.id.split('scale')[0]);
context.scene[n - 1].params.scale.z = parseFloat(<string>$('#' + n + 'scalez').val());
});
$('#' + context.scene.length + 's_blackandwhite').on('click', function(event) {
const n = parseInt(event.target.id.split('s')[0]);
[context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders, blackandwhite, vsSource);
});
$('#' + context.scene.length + 's_color').on('click', function(event) {
const n = parseInt(event.target.id.split('s')[0]);
[context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders, colored, vsSource);
});
$('#' + context.scene.length + 's_grey').on('click', function(event) {
const n = parseInt(event.target.id.split('s')[0]);
[context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders, grey, vsSource);
});
$('#' + context.scene.length + 's_texture').on('click', function(event) {
const n = parseInt(event.target.id.split('s')[0]);
[context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders, texture, vsSource);
});
$('#' + context.scene.length + 's_sobel').on('click', function(event) {
const n = parseInt(event.target.id.split('s')[0]);
[context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders, sobel, vsSource);
});
$('#' + context.scene.length + 's_fractal').on('click', function(event) {
const n = parseInt(event.target.id.split('s')[0]);
[context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram] = changeFragmentShader(context, context.scene[n - 1].programInfo, context.scene[n - 1].shaderProgram, context.scene[n - 1].shaders, fractal, vsSource);
});
$('#' + context.scene.length + 'o_sphere').on('click', async function(event) {
const n = parseInt(event.target.id.split('o')[0]);
if (context.cache.objs.sphere == null) {
const data = await fetchObj('/static/objs/sphere.obj');
context.cache.objs.sphere = loadObj(data);
}
context.scene[n - 1].buffers = loadObjBuffers(context, context.scene[n - 1].buffers, context.cache.objs.sphere);
context.scene[n - 1].params.len = context.cache.objs.sphere.indices.length;
context.scene[n - 1].params.range = context.cache.objs.sphere.range;
});
$('#' + context.scene.length + 'o_teapot').on('click', async function(event) {
const n = parseInt(event.target.id.split('o')[0]);
if (context.cache.objs.teapot == null) {
const data = await fetchObj('/static/objs/teapot.obj');
context.cache.objs.teapot = loadObj(data);
}
context.scene[n - 1].buffers = loadObjBuffers(context, context.scene[n - 1].buffers, context.cache.objs.teapot);
context.scene[n - 1].params.len = context.cache.objs.teapot.indices.length;
context.scene[n - 1].params.range = context.cache.objs.teapot.range;
});
$('#' + context.scene.length + 'o_fox').on('click', async function(event) {
const n = parseInt(event.target.id.split('o')[0]);
if (context.cache.objs.fox == null) {
const data = await fetchObj('/static/objs/fox.obj');
context.cache.objs.fox = loadObj(data);
}
context.scene[n - 1].buffers = loadObjBuffers(context, context.scene[n - 1].buffers, context.cache.objs.fox);
context.scene[n - 1].params.len = context.cache.objs.fox.indices.length;
context.scene[n - 1].params.range = context.cache.objs.fox.range;
});
$('#' + context.scene.length + 'o_mecha').on('click', async function(event) {
const n = parseInt(event.target.id.split('o')[0]);
if (context.cache.objs.mecha == null) {
const data = await fetchObj('/static/objs/mecha.obj');
context.cache.objs.mecha = loadObj(data);
}
context.scene[n - 1].buffers = loadObjBuffers(context, context.scene[n - 1].buffers, context.cache.objs.mecha);
context.scene[n - 1].params.len = context.cache.objs.mecha.indices.length;
context.scene[n - 1].params.range = context.cache.objs.mecha.range;
});
$('#' + context.scene.length + 'o_racer').on('click', async function(event) {
const n = parseInt(event.target.id.split('o')[0]);
if (context.cache.objs.racer == null) {
const data = await fetchObj('/static/objs/racer.obj');
context.cache.objs.racer = loadObj(data);
}
context.scene[n - 1].buffers = loadObjBuffers(context, context.scene[n - 1].buffers, context.cache.objs.racer);
context.scene[n - 1].params.len = context.cache.objs.racer.indices.length;
context.scene[n - 1].params.range = context.cache.objs.racer.range;
});
/* eslint-enable */
});
}