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