diff --git a/package-lock.json b/package-lock.json index 0ccd820bf..22903247e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@fortawesome/free-solid-svg-icons": "^6.4.0", "@fortawesome/vue-fontawesome": "^3.0.3", "@pvermeer/dexie-encrypted-addon": "^2.0.5", + "@tweenjs/tween.js": "^20.0.3", "@veramo/core": "^5.1.2", "@veramo/credential-w3c": "^5.1.4", "@veramo/data-store": "^5.1.2", @@ -7744,10 +7745,9 @@ } }, "node_modules/@tweenjs/tween.js": { - "version": "18.6.4", - "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", - "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==", - "dev": true + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-20.0.3.tgz", + "integrity": "sha512-SYUe1UgY5HM05EB4+0B4arq2IPjvyzKXoklXKxSYrc2IFxGm1cBrqg5XbiB5uwbs0xY5j+rj986NAJMM0KZaUw==" }, "node_modules/@types/bn.js": { "version": "5.1.1", @@ -8033,6 +8033,12 @@ "lil-gui": "~0.17.0" } }, + "node_modules/@types/three/node_modules/@tweenjs/tween.js": { + "version": "18.6.4", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", + "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==", + "dev": true + }, "node_modules/@types/trusted-types": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.2.tgz", diff --git a/package.json b/package.json index 361f90845..395188301 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@fortawesome/free-solid-svg-icons": "^6.4.0", "@fortawesome/vue-fontawesome": "^3.0.3", "@pvermeer/dexie-encrypted-addon": "^2.0.5", + "@tweenjs/tween.js": "^20.0.3", "@veramo/core": "^5.1.2", "@veramo/credential-w3c": "^5.1.4", "@veramo/data-store": "^5.1.2", diff --git a/src/components/World/World.js b/src/components/World/World.js index 17bbba329..ad5ee8681 100644 --- a/src/components/World/World.js +++ b/src/components/World/World.js @@ -1,5 +1,9 @@ // from https://medium.com/nicasource/building-an-interactive-web-portfolio-with-vue-three-js-part-three-implementing-three-js-452cb375ef80 +import axios from "axios"; +import { SpotLight, SpotLightHelper } from "three"; +import * as TWEEN from "@tweenjs/tween.js"; + import { createCamera } from "./components/camera.js"; import { createLights } from "./components/lights.js"; import { createScene } from "./components/scene.js"; @@ -8,68 +12,173 @@ import { Loop } from "./systems/Loop.js"; import { Resizer } from "./systems/Resizer.js"; import { createControls } from "./systems/controls.js"; import { createRenderer } from "./systems/renderer.js"; +import { AppString } from "@/constants/app"; // These variables are module-scoped: we cannot access them // from outside the module const color = "#42b883"; const color2 = "#0055aa"; - -let camera; -let renderer; -let scene; -let loop; +const PLATFORM_SIZE = 100; +const PLATFORM_BORDER = 10; +const PLATFORM_EDGE_FOR_UNKNOWNS = 10; +const BASE32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; class World { constructor(container) { + this.update = this.update.bind(this); + this.renderLight = this.renderLight.bind(this); + // Instances of camera, scene, and renderer - camera = createCamera(); - scene = createScene(color2); - renderer = createRenderer(); + this.camera = createCamera(); + this.scene = createScene(color2); + this.renderer = createRenderer(); + + this.light = null; + this.helper = null; // Initializate Loop - loop = new Loop(camera, scene, renderer); + this.loop = new Loop(this.camera, this.scene, this.renderer); - container.append(renderer.domElement); + container.append(this.renderer.domElement); // Orbit Controls - const controls = createControls(camera, renderer.domElement); + const controls = createControls(this.camera, this.renderer.domElement); // Light Instance, with optional light helper const { light } = createLights(color); // Terrain Instance - const terrain = createTerrain({ color: color }); + const terrain = createTerrain({ + color: color, + height: PLATFORM_SIZE + PLATFORM_BORDER, + width: PLATFORM_SIZE + PLATFORM_BORDER + PLATFORM_EDGE_FOR_UNKNOWNS, + }); + + this.loop.updatables.push(controls); + this.loop.updatables.push(light); + this.loop.updatables.push(terrain); + + this.scene.add(light, terrain); - loop.updatables.push(controls); - loop.updatables.push(light); - loop.updatables.push(terrain); + const cube = createCube(-10, 5, 0, 1, 1, 1); + this.loop.updatables.push(cube); + this.scene.add(cube); - scene.add(light, terrain); + new TWEEN.Tween(cube.position).to({ x: 10 }, 5000).start(); + this.loadClaims(); - const cube = createCube(); - loop.updatables.push(cube); - scene.add(cube); + requestAnimationFrame(this.update); + requestAnimationFrame(this.renderLight); // Responsive handler - const resizer = new Resizer(container, camera, renderer); + const resizer = new Resizer(container, this.camera, this.renderer); resizer.onResize = () => { this.render(); }; } + update(time) { + TWEEN.update(time); + requestAnimationFrame(this.update); + } + + async loadClaims() { + const endorserApiServer = AppString.DEFAULT_ENDORSER_API_SERVER; + try { + const url = endorserApiServer + "/api/v2/report/claims"; + const headers = { "Content-Type": "application/json" }; + const resp = await axios.get(url, { headers: headers }); + if (resp.status === 200) { + resp.data.data.map((claim) => { + const randomness = claim.id.substring(10); + const x = + (100 * BASE32.indexOf(randomness.substring(0, 1))) / 32 - 50; + const z = + (100 * BASE32.indexOf(randomness.substring(8, 9))) / 32 - 50; + console.log( + "randomness", + randomness, + randomness.substring(0, 1), + BASE32.indexOf(randomness.substring(0, 1)), + x, + randomness.substring(8, 9), + BASE32.indexOf(randomness.substring(8, 9)), + z + ); + + this.light = new SpotLight(0xffffff, 100, 0, Math.PI / 32, 0.5, 0); + this.light.position.set(x, 20, z); + this.light.target.position.set(x, 0, z); + this.scene.add(this.light); + + this.helper = new SpotLightHelper(this.light); + this.scene.add(this.helper); + }); + console.log("done adding cube"); + } else { + console.log( + "Got bad response status & data of", + resp.status, + resp.data + ); + // this.alertTitle = "Error With Server"; + // this.alertMessage = + // "Got an error retrieving your given time from the server."; + // this.isAlertVisible = true; + } + } catch (error) { + console.log("Got error of", error); + // this.alertTitle = "Error With Server"; + // this.alertMessage = + // "Got an error retrieving your given time from the server."; + // this.isAlertVisible = true; + } + } + + renderLight(time) { + time *= 0.001; // convert time to seconds + + if (!this.light && Math.round(time) % 2 === 0) { + //const xPos = Math.random() * 100; + //const yPos = Math.random() * 100; + this.light = new SpotLight(0xffffff, 100, 0, Math.PI / 32, 0.5, 0); + this.light.position.set(0, 20, 0); + this.light.target.position.set(-5, 0, 0); + this.scene.add(this.light); + //this.scene.add(this.light.target); + + this.helper = new SpotLightHelper(this.light); + this.scene.add(this.helper); + + console.log("added light"); + } else if (Math.round(time) % 2 != 0 && this.light) { + this.scene.remove(this.light); + this.light.dispose(); + this.light = null; + this.scene.remove(this.helper); + this.helper.dispose(); + this.helper = null; + console.log("disposed light"); + } + + this.renderer.render(this.scene, this.camera); + + requestAnimationFrame(this.renderLight); + } + render() { // draw a single frame - renderer.render(scene, camera); + this.renderer.render(this.scene, this.camera); } // Animation handlers start() { - loop.start(); + this.loop.start(); } stop() { - loop.stop(); + this.loop.stop(); } } diff --git a/src/components/World/components/objects/terrain.js b/src/components/World/components/objects/terrain.js index a5d1b7e59..6537f9072 100644 --- a/src/components/World/components/objects/terrain.js +++ b/src/components/World/components/objects/terrain.js @@ -9,8 +9,8 @@ import { export function createTerrain(props) { const loader = new TextureLoader(); const height = loader.load("img/textures/forest-floor.png"); - // w h - const geometry = new PlaneGeometry(100, 100, 64, 64); + // w h + const geometry = new PlaneGeometry(props.width, props.height, 64, 64); const material = new MeshLambertMaterial({ color: props.color, @@ -34,11 +34,11 @@ export function createTerrain(props) { return plane; } -export function createCube() { - const geometry = new BoxGeometry(1, 1, 1); +export function createCube(xPos, yPos, zPos, x, y, z) { + const geometry = new BoxGeometry(x, y, z); const material = new MeshLambertMaterial({ color: 0xff0000 }); const cube = new Mesh(geometry, material); - cube.position.set(0, 5, 0); + cube.position.set(xPos, yPos, zPos); // eslint-disable-next-line @typescript-eslint/no-empty-function cube.tick = () => {}; return cube; diff --git a/src/components/World/components/scene.js b/src/components/World/components/scene.js index 06a2b8365..2bb3a1eba 100644 --- a/src/components/World/components/scene.js +++ b/src/components/World/components/scene.js @@ -1,4 +1,4 @@ -import { Color, Scene, Fog } from "three"; +import { Color, Scene } from "three"; function createScene(color) { const scene = new Scene();