Fakultas Ilmu Komputer UI

Commit 6b229364 authored by Rachmat Ridwan's avatar Rachmat Ridwan
Browse files

Implement focusing camera with 'F' button

parent 91d1d10a
......@@ -3,8 +3,10 @@
let scrollDetector;
let scrollInitial;
let MAX_FOCUS_PROGRESS_FRAME_DURATION = 15;
function initNavigableCamera() {
scrollDetector = document.querySelector('#scroll-detector > *')
scrollDetector.scrollTop = scrollDetector.clientHeight / 2;
scrollInitial = scrollDetector.scrollTop;
......@@ -17,8 +19,9 @@ function initNavigableCamera() {
scrollDetector.parentElement.addEventListener('touchstart', startTrackballOnDevice)
document.addEventListener('touchmove', trackMouseForTrackballOnDevice)
document.addEventListener('touchend', stopTrackballOnDevice)
canvas.parentElement.addEventListener('keydown', processCanvasArrowKeydown)
canvas.parentElement.addEventListener('keydown', processCanvasFocusKeydown)
}
/**
......@@ -94,7 +97,7 @@ function processCanvasArrowKeydown(event) {
* values.
*/
function zoomCameraFromScrollDetector () {
function zoomCameraFromScrollDetector() {
let deltaScroll = scrollDetector.scrollTop - scrollInitial;
scrollDetector.scrollTop = scrollInitial;
let newRadius = Math.pow(Math.E, Math.log(camera.radius) + deltaScroll / 10);
......@@ -131,7 +134,7 @@ function startTrackball(event) {
posXInit = event.touches[0].screenX;
posYInit = event.touches[1].screenY;
}
initPhi = phi;
initTheta = theta;
......@@ -224,4 +227,61 @@ function trackMouseForTrackballOnDevice(event) {
function stopTrackballOnDevice(event) {
stopTrackball(event)
}
function getPressedAlphabet(event) {
let key = undefined
if (event.code) {
key = (event.code.match(/Key([A-Z])/) || {})[1]
} else if (event.key) {
key = (event.key.match(/^([a-zA-Z])/) || {})[1]
}
if (key) {
return key.toUpperCase()
}
}
let cancelFocusAnimation = function () { }
function processCanvasFocusKeydown(event) {
let key = getPressedAlphabet(event)
if (key === 'F') {
let node = sceneGraph.nodes[sceneGraph.selectedNodeName]
if (node) {
let model = node.model;
let oldAt = at;
let newAt = vec3(mat4(model.fullTransformMatrix)[3].slice(0, 3));
let oldRadius = camera.radius;
let newRadius = 4;
cancelFocusAnimation()
let progress = 0;
let cancelAnimation = false
cancelFocusAnimation = function () {
cancelAnimation = true
}
let animateFocus = function () {
if (progress > MAX_FOCUS_PROGRESS_FRAME_DURATION || cancelAnimation) {
return
}
let x = progress / MAX_FOCUS_PROGRESS_FRAME_DURATION;
let y = 1 - Math.pow(x - 1, 2)
at = mix(oldAt, newAt, y)
camera.radius = oldRadius * (1 - y) + newRadius * y
updateViewMatrix()
progress += 1
window.requestAnimationFrame(animateFocus)
}
window.requestAnimationFrame(animateFocus)
}
}
}
\ No newline at end of file
......@@ -390,7 +390,7 @@ li:not(.selected) > input[type="checkbox"]:hover + .obj-name {
border-left: 1px solid #a2a2a2;
}
.obj-name::before {
#tree .obj-name::before {
content: "";
position: absolute;
bottom: 10px;
......@@ -401,7 +401,7 @@ li:not(.selected) > input[type="checkbox"]:hover + .obj-name {
}
.collapsed-sign::before {
#tree .collapsed-sign::before {
content: "\25B2";
color: #b9b9b9;
position: absolute;
......@@ -441,7 +441,8 @@ li:not(.selected) > input[type="checkbox"]:hover + .obj-name {
cursor: pointer;
}
li.selected > .obj-name, li.selected > input[type="checkbox"]:hover + .obj-name {
#tree li.selected > .obj-name,
#tree li.selected > input[type="checkbox"]:hover + .obj-name {
background-color: #f2a518;
border-color: #f2a518;
margin-bottom: 0px;
......@@ -449,11 +450,11 @@ li.selected > .obj-name, li.selected > input[type="checkbox"]:hover + .obj-name
color: black;
}
li.selected > input[type="checkbox"]:focus {
#tree li.selected > input[type="checkbox"]:focus {
outline: none;
}
li.selected > input[type="checkbox"]:focus + .obj-name {
#tree li.selected > input[type="checkbox"]:focus + .obj-name {
border-color: white;
border-width: 2px;
margin-left: -1px;
......@@ -462,11 +463,11 @@ li.selected > input[type="checkbox"]:focus + .obj-name {
margin-bottom: -1px;
}
li.selected > ul > .collapsed-sign::before {
#tree li.selected > ul > .collapsed-sign::before {
color: black;
}
ul > li:last-child::before {
#tree ul > li:last-child::before {
content: "";
display: block;
position: absolute;
......
......@@ -30,7 +30,7 @@ void main()
gl_Position = projectionMatrix * vertPos4;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
......@@ -129,11 +129,13 @@ void main()
<div class="submenu">
<h3 class="submenu-title">Bantuan</h3>
<div id="help-content">
<p>Tekan kanvas terlebih dahulu untuk melakukan perintah di bawah.
<br />Tekan <strong>panah keyboard</strong> untuk memindahkan posisi kamera.
<br />Tekan <strong>spasi</strong> untuk memulai/menghentikan animasi.
<br />Tekan dan <strong>tahan kanvas</strong> untuk memutar kamera.
</p>
Tekan kanvas terlebih dahulu untuk melakukan perintah berikut.
<ul>
<li>Tekan <strong>panah keyboard</strong> untuk memindahkan posisi kamera.</li>
<li>Tekan <strong>spasi</strong> untuk memulai/menghentikan animasi.</li>
<li>Tekan dan <strong>tahan kanvas</strong> untuk memutar kamera.</li>
<li>Tekan <strong>F</strong> untuk fokus pada model yang <strong>dipilih</strong>.</li>
</ul>
</div>
</div>
<div class="submenu">
......
......@@ -20,7 +20,6 @@ let phi = 0
let cameraPosIndex = 17
let coordinateDirectionOrder = ['UP', 'LEFT', 'DOWN', 'RIGHT']
let eye
let at = vec3(0.0, 0.0, 0.0)
let up = vec3(0.0, 0.0, 1.0)
......@@ -235,7 +234,7 @@ function updateViewMatrix() {
let y = r * sin_t * sin_p;
let z = r * cos_t;
eye = vec3(x, y, z);
let eye = add(at, vec3(x, y, z));
camera.viewMatrix = flatten(lookAt(eye, at, up));
gl.uniformMatrix4fv(sceneGraph.glLocations.viewMatrix, false, flatten(camera.viewMatrix));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment