221 lines
7.3 KiB
JavaScript
221 lines
7.3 KiB
JavaScript
var parade;
|
|
var interview_sorter;
|
|
|
|
// polyfill
|
|
window.performance = window.performance || {};
|
|
performance.now = (function() {
|
|
return performance.now ||
|
|
performance.mozNow ||
|
|
performance.msNow ||
|
|
performance.oNow ||
|
|
performance.webkitNow ||
|
|
Date.now /*none found - fallback to browser default */
|
|
})();
|
|
|
|
|
|
const request = new Request('dataset/images_prop.json');
|
|
fetch(request)
|
|
.then(response => {
|
|
if (response.status === 200) {
|
|
return response.json();
|
|
} else {
|
|
throw new Error('Something went wrong on api server!');
|
|
}
|
|
})
|
|
.then(data => {
|
|
console.debug(data);
|
|
// loaded data from json, initialise interface
|
|
const canvas = document.getElementById("renderCanvas");
|
|
parade = new Parade(canvas, data['image']);
|
|
parade.createScene();
|
|
// parade.scene.debugLayer.show();
|
|
}).catch(error => {
|
|
console.error(error);
|
|
});
|
|
|
|
|
|
class Parade {
|
|
constructor(canvasEl, images) {
|
|
this.speedFactor = -.05;
|
|
this.distanceFactor = 20;
|
|
this.startOffset = 800;
|
|
this.maxStepSize = 1;
|
|
|
|
this.prevRenderTime = null;
|
|
this.canvasEl = canvasEl;
|
|
this.engine = new BABYLON.Engine(canvasEl, true);
|
|
|
|
this.audioEl = document.getElementById('interview'); // audio player
|
|
this.subtitleEl = document.getElementById('subtitles'); // the subtitle div
|
|
this.trackEl = this.audioEl.querySelector('track'); // the subtitle track
|
|
|
|
|
|
// set up subtitles:
|
|
this.trackEl.addEventListener("cuechange", (event) => {
|
|
console.log(event);
|
|
let cues = event.target.track.activeCues;
|
|
let content = "";
|
|
for(let cue of cues) {
|
|
content += "<p>"+cue.text+"</p>";
|
|
}
|
|
this.subtitleEl.innerHTML = content;
|
|
});
|
|
|
|
|
|
// initialise image objects:
|
|
this.images = [];
|
|
for(let i in images) {
|
|
this.images.push(new ParadeImage(images[i], i));
|
|
// for testing:
|
|
// if(this.images.length > 5)
|
|
// break;
|
|
}
|
|
|
|
// Watch for browser/canvas resize events
|
|
window.addEventListener("resize", function () {
|
|
this.engine.resize();
|
|
}.bind(this));
|
|
|
|
//Register a render loop to repeatedly render the scene
|
|
this.engine.runRenderLoop(this.renderLoop.bind(this));
|
|
}
|
|
|
|
renderLoop() {
|
|
// limit camera movement:
|
|
// let camera = this.scene.cameras[0];
|
|
// if(camera.rotation['x'] < 0.1) {
|
|
// camera.rotation['x'] = 0.1
|
|
// }
|
|
// if(camera.rotation['x'] > .3) {
|
|
// camera.rotation['x'] = .3
|
|
// }
|
|
this.animate();
|
|
this.scene.render();
|
|
}
|
|
|
|
animate() {
|
|
let t = window.performance.now() - this.startTime;
|
|
// let maxStepSize = Math.inf;
|
|
|
|
// if (this.prevRenderTime === null) {
|
|
|
|
// } else {
|
|
// let tdiff = t - this.prevRenderTime;
|
|
// if(tdiff < 1) {
|
|
// // sometimes multiple render calls within very short moment??
|
|
// // skip some work.
|
|
// return;
|
|
// }
|
|
|
|
// maxStepSize = Math.abs(this.maxStepSize * tdiff * this.speedFactor);
|
|
// }
|
|
|
|
|
|
// this.prevRenderTime = t;
|
|
// console.log(tdiff);
|
|
t -= 800/this.speedFactor; // start offset ( milliseconds)
|
|
// console.log(maxStepSize);
|
|
for(let i of this.images){
|
|
i.updateMeshPosition(t*this.speedFactor/1000);
|
|
t-= this.distanceFactor/this.speedFactor;
|
|
}
|
|
}
|
|
|
|
createScene() {
|
|
// This creates a basic Babylon Scene object (non-mesh)
|
|
this.scene = new BABYLON.Scene(this.engine);
|
|
// return this.scene;
|
|
// this.scene.clearColor = new BABYLON.Color3(0.6, 0.6, 0.); // color RGB
|
|
// this.scene.clearColor = new BABYLON.Color4(0.6, 0.6, 0.,0); // transparent - RGBA
|
|
this.scene.fogMode = BABYLON.Scene.FOGMODE_EXP;
|
|
this.scene.fogColor = this.scene.clearColor;
|
|
this.scene.fogDensity = 0.002;
|
|
|
|
// let camera = new BABYLON.UniversalCamera("camera1", new BABYLON.Vector3( 0.0, 0.0, 120.86337575312979), this.scene);
|
|
// camera.rotation = new BABYLON.Vector3(0, Math.PI, 0);
|
|
// camera.fov = 1.1; // default: 0.8
|
|
let camera = new BABYLON.UniversalCamera("camera2", new BABYLON.Vector3( -14.40894348196419, 0.9954991699417852, 17.582966906902247), this.scene);
|
|
camera.rotation = new BABYLON.Vector3(0.023121520223909536, 2.5494248799675163, 0);
|
|
camera.fov = 1.5;
|
|
// camera.rotation = new BABYLON.Vector3(0.1, 0,0);
|
|
// camera.lowerRadiusLimit = 6;
|
|
// camera.upperRadiusLimit = 20;
|
|
// This attaches the camera to the canvas
|
|
camera.attachControl(this.canvasEl, true);
|
|
|
|
let radius = 60;
|
|
for(let i in this.images) {
|
|
// console.log(i, this.images, this);
|
|
this.images[i].makeMesh(this.scene);
|
|
}
|
|
|
|
|
|
this.startTime = window.performance.now();
|
|
// this.scene.registerBeforeRender(this.animate.bind(this));
|
|
return this.scene;
|
|
}
|
|
}
|
|
|
|
class ParadeImage {
|
|
constructor(info, position) {
|
|
this.info = info;
|
|
this.weight = info['weight'];
|
|
this.position = position; // index in list
|
|
}
|
|
|
|
makeMesh(scene) {
|
|
// let videoSrc = this.images[i]['image'];
|
|
// random fluctuation in radius
|
|
let i = 1;
|
|
let radius = 60
|
|
let localRadius = (Math.random() * .2 + 1) * radius;
|
|
let x = Math.sin(2*Math.PI * i / 1) * localRadius;
|
|
let y = Math.cos(2*Math.PI * i / 1) * localRadius;
|
|
var planeOpts = {
|
|
height: 5.4762,
|
|
width: 7.3967,
|
|
sideOrientation: BABYLON.Mesh.DOUBLESIDE
|
|
};
|
|
this.mesh = BABYLON.MeshBuilder.CreatePlane("plane", planeOpts, scene);
|
|
|
|
var ANote0VideoMat = new BABYLON.StandardMaterial("m", scene);
|
|
|
|
let imgUrl = 'dataset/small/'+ this.info['image'];
|
|
// console.log(imgUrl);
|
|
ANote0VideoMat.diffuseTexture = new BABYLON.Texture(imgUrl, scene);
|
|
ANote0VideoMat.roughness = 1;
|
|
ANote0VideoMat.emissiveColor = new BABYLON.Color3.White();
|
|
this.mesh.material = ANote0VideoMat;
|
|
|
|
// this.updateMeshPosition(1, Math.inf); //TODO: remove when animating
|
|
}
|
|
|
|
updateMeshPosition(t){
|
|
// factors determine scale of animation
|
|
let target_x = Math.sin(2*t)*100;
|
|
let target_z = Math.sin(t)*1300;
|
|
|
|
// let diff_x = target_x - this.mesh.position.x;
|
|
// let diff_z = target_z - this.mesh.position.z;
|
|
|
|
// let stepSize = Math.sqrt( Math.pow(diff_x, 2) + Math.pow(diff_z, 2) );
|
|
|
|
// if(stepSize > maxStepSize) {
|
|
// // console.log('throttle', maxStepSize, stepSize);
|
|
// // throttle the step, so switching items looks like movement
|
|
// diff_x *= maxStepSize/stepSize;
|
|
// diff_z *= maxStepSize/stepSize;
|
|
// }
|
|
|
|
// // console.log(diff_x, diff_z, stepSize);
|
|
// this.mesh.position.x += diff_x;
|
|
// this.mesh.position.z += diff_z;
|
|
this.mesh.position.x = target_x;
|
|
this.mesh.position.z = target_z;
|
|
|
|
// this.mesh.position = new BABYLON.Vector3(x,0,y);
|
|
}
|
|
|
|
|
|
}
|