Trent Larson
2 years ago
2 changed files with 130 additions and 129 deletions
@ -0,0 +1,127 @@ |
|||
import axios from "axios"; |
|||
import * as THREE from "three"; |
|||
import { GLTFLoader } from "three/addons/loaders/GLTFLoader"; |
|||
import * as SkeletonUtils from "three/addons/utils/SkeletonUtils"; |
|||
import * as TWEEN from "@tweenjs/tween.js"; |
|||
import { AppString } from "@/constants/app"; |
|||
|
|||
const ANIMATION_DURATION_SECS = 10; |
|||
const BASE32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; |
|||
|
|||
export async function loadLandmarks(vue, world, scene, loop) { |
|||
const endorserApiServer = AppString.DEFAULT_ENDORSER_API_SERVER; |
|||
try { |
|||
const url = |
|||
endorserApiServer + "/api/v2/report/claims?claimType=GiveAction"; |
|||
const headers = { "Content-Type": "application/json" }; |
|||
const resp = await axios.get(url, { headers: headers }); |
|||
if (resp.status === 200) { |
|||
const minDate = resp.data.data[resp.data.data.length - 1].issuedAt; |
|||
const maxDate = resp.data.data[0].issuedAt; |
|||
const minTimeMillis = new Date(minDate).getTime(); |
|||
const fullTimeMillis = new Date(maxDate).getTime() - minTimeMillis; |
|||
// ratio of animation time to real time
|
|||
const fakeRealRatio = (ANIMATION_DURATION_SECS * 1000) / fullTimeMillis; |
|||
|
|||
// load plant model first because it takes a second
|
|||
const loader = new GLTFLoader(); |
|||
// choose the right plant
|
|||
const modelLoc = "/models/lupine_plant/scene.gltf", // push with pokies
|
|||
modScale = 0.1; |
|||
//const modelLoc = "/models/round_bush/scene.gltf", // green & pink
|
|||
// modScale = 1;
|
|||
//const modelLoc = "/models/coreopsis-flower.glb", // 3 flowers
|
|||
// modScale = 2;
|
|||
//const modelLoc = "/models/a_bush/scene.gltf", // purple leaves
|
|||
// modScale = 15,
|
|||
|
|||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|||
const parentWorld = world; |
|||
loader.load( |
|||
modelLoc, |
|||
function (gltf) { |
|||
gltf.scene.scale.set(0, 0, 0); |
|||
for (const claim of resp.data.data) { |
|||
const newPlant = SkeletonUtils.clone(gltf.scene); |
|||
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; |
|||
newPlant.position.set(x, 0, z); |
|||
|
|||
parentWorld.scene.add(newPlant); |
|||
const timeDelayMillis = |
|||
fakeRealRatio * |
|||
(new Date(claim.issuedAt).getTime() - minTimeMillis); |
|||
new TWEEN.Tween(newPlant.scale) |
|||
.delay(timeDelayMillis) |
|||
.to({ x: modScale, y: modScale, z: modScale }, 5000) |
|||
.start(); |
|||
parentWorld.bushes = [...parentWorld.bushes, newPlant]; |
|||
} |
|||
}, |
|||
undefined, |
|||
function (error) { |
|||
console.error(error); |
|||
} |
|||
); |
|||
|
|||
// calculate when lights shine on appearing claim area
|
|||
for (const claim of resp.data.data) { |
|||
// claim is a GiveServerRecord (see endorserServer.ts)
|
|||
|
|||
// compute location for this 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; |
|||
const light = createLight(); |
|||
light.position.set(x, 20, z); |
|||
light.target.position.set(x, 0, z); |
|||
loop.updatables.push(light); |
|||
scene.add(light); |
|||
scene.add(light.target); |
|||
|
|||
// now figure out the timing and shine a light
|
|||
const timeDelayMillis = |
|||
fakeRealRatio * (new Date(claim.issuedAt).getTime() - minTimeMillis); |
|||
new TWEEN.Tween(light) |
|||
.delay(timeDelayMillis) |
|||
.to({ intensity: 100 }, 10) |
|||
.chain( |
|||
new TWEEN.Tween(light.position) |
|||
.to({ y: 5 }, 5000) |
|||
.onComplete(() => { |
|||
scene.remove(light); |
|||
light.dispose(); |
|||
}) |
|||
) |
|||
.start(); |
|||
world.lights = [...world.lights, light]; |
|||
} |
|||
} else { |
|||
console.log( |
|||
"Got bad server response status & data of", |
|||
resp.status, |
|||
resp.data |
|||
); |
|||
vue.setAlert( |
|||
"Error With Server", |
|||
"There was an error retrieving your claims from the server." |
|||
); |
|||
} |
|||
} catch (error) { |
|||
console.log("Got exception contacting server:", error); |
|||
vue.setAlert( |
|||
"Error With Server", |
|||
"There was a problem retrieving your claims from the server." |
|||
); |
|||
} |
|||
} |
|||
|
|||
function createLight() { |
|||
const light = new THREE.SpotLight(0xffffff, 0, 0, Math.PI / 8, 0.5, 0); |
|||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|||
light.tick = () => {}; |
|||
return light; |
|||
} |
Loading…
Reference in new issue