From 409bfe48c1a3e4df15b688ff0e2412e3ae400445 Mon Sep 17 00:00:00 2001 From: Greg Fodor <gfodor@gmail.com> Date: Wed, 26 Sep 2018 01:20:55 +0000 Subject: [PATCH] Add preview camera --- src/assets/stylesheets/scene.scss | 5 +++ src/components/scene-preview-camera.js | 51 ++++++++++++++++++++++++++ src/scene.html | 2 + src/scene.js | 12 +++++- 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/components/scene-preview-camera.js diff --git a/src/assets/stylesheets/scene.scss b/src/assets/stylesheets/scene.scss index 44e6591aa..39c9092e8 100644 --- a/src/assets/stylesheets/scene.scss +++ b/src/assets/stylesheets/scene.scss @@ -1,2 +1,7 @@ @import 'shared'; @import 'loader'; + +.brightened { + filter: saturate(1.1) brightness(1.1) contrast(1.1); +} + diff --git a/src/components/scene-preview-camera.js b/src/components/scene-preview-camera.js new file mode 100644 index 000000000..17024305c --- /dev/null +++ b/src/components/scene-preview-camera.js @@ -0,0 +1,51 @@ +/** + * Nicely pans the camera for previewing a scene. There's some weirdness with this right now + * since it ends up panning in a direction dependent upon the start camera orientation, + * but it's good enough for now. + */ +function lerp(start, end, t) { + return (1 - t) * start + t * end; +} + +const DURATION = 90.0; + +AFRAME.registerComponent("scene-preview-camera", { + init: function() { + this.startPoint = this.el.object3D.position.clone(); + this.startRotation = new THREE.Quaternion(); + this.startRotation.setFromEuler(this.el.object3D.rotation); + + this.targetPoint = new THREE.Vector3(1, 0.5, -0.5); + this.targetPoint.applyMatrix4(this.el.object3D.matrix); + this.targetPoint.add(new THREE.Vector3(0, 0, -2)); + + const targetRotDelta = new THREE.Euler(-0.15, 0.0, 0.15); + this.targetRotation = new THREE.Quaternion(); + this.targetRotation.setFromEuler(targetRotDelta); + this.targetRotation.premultiply(this.startRotation); + + this.startTime = new Date().getTime(); + this.backwards = false; + }, + + tick: function() { + let t = (new Date().getTime() - this.startTime) / (1000.0 * DURATION); + t = (Math.sin(t * Math.PI * 2) + 1.0) / 2.0; + + const from = this.backwards ? this.targetPoint : this.startPoint; + const to = this.backwards ? this.startPoint : this.targetPoint; + const fromRot = this.backwards ? this.targetRotation : this.startRotation; + const toRot = this.backwards ? this.startRotation : this.targetRotation; + const newRot = new THREE.Quaternion(); + + THREE.Quaternion.slerp(fromRot, toRot, newRot, t); + + this.el.object3D.position.set(lerp(from.x, to.x, t), lerp(from.y, to.y, t), lerp(from.z, to.z, t)); + this.el.object3D.rotation.setFromQuaternion(newRot); + + if (t >= 1.0) { + this.backwards = !this.backwards; + this.startTime = new Date().getTime(); + } + } +}); diff --git a/src/scene.html b/src/scene.html index 6a4ebaa0f..a492ba13d 100644 --- a/src/scene.html +++ b/src/scene.html @@ -22,6 +22,8 @@ id="scene-root" static-body="shape: none;" ></a-entity> + + <a-camera id="camera" fov="80" look-controls="enabled: false" wasd-controls="enabled: false"></a-camera> </a-scene> <div id="ui-root"></div> diff --git a/src/scene.js b/src/scene.js index 3211cad81..8c77d2364 100644 --- a/src/scene.js +++ b/src/scene.js @@ -26,6 +26,7 @@ import "./components/media-loader"; import "./components/point-light"; import "./components/quack"; import "./components/scene-shadow"; +import "./components/scene-preview-camera"; import "./components/skybox"; import "./components/spawn-controller"; import "./components/spot-light"; @@ -86,6 +87,7 @@ function mountUI(scene, props = {}) { const onReady = async () => { const scene = document.querySelector("a-scene"); window.APP.scene = scene; + document.querySelector("canvas").classList.add("brightened"); const sceneId = qs.get("scene_id") || document.location.pathname.substring(1).split("/")[0]; console.log(`Scene ID: ${sceneId}`); @@ -101,9 +103,18 @@ const onReady = async () => { const sceneRoot = document.querySelector("#scene-root"); const sceneModelEntity = document.createElement("a-entity"); + const gltfEl = document.createElement("a-entity"); + const camera = document.getElementById("camera"); sceneModelEntity.addEventListener("scene-loaded", () => { remountUI({ sceneLoaded: true }); + const previewCamera = gltfEl.object3D.getObjectByName("scene-preview-camera"); + + if (previewCamera) { + camera.object3D.applyMatrix(previewCamera.matrixWorld); + } + + camera.setAttribute("scene-preview-camera", ""); }); sceneRoot.appendChild(sceneModelEntity); @@ -114,7 +125,6 @@ const onReady = async () => { const modelUrl = sceneInfo.model_url; console.log(`Scene Model URL: ${modelUrl}`); - const gltfEl = document.createElement("a-entity"); gltfEl.setAttribute("gltf-model-plus", { src: modelUrl, useCache: false, inflate: true }); gltfEl.addEventListener("model-loaded", () => sceneModelEntity.emit("scene-loaded")); sceneModelEntity.appendChild(gltfEl); -- GitLab