mirror of
https://iceshrimp.dev/Crimekillz/jointrashposs.git
synced 2024-11-25 10:19:07 +01:00
96 lines
2.7 KiB
TypeScript
96 lines
2.7 KiB
TypeScript
import * as THREE from 'three';
|
|
import { MeshLineGeometry as MeshLine, MeshLineMaterial } from 'meshline';
|
|
import * as Calc from './utils/calc';
|
|
import * as Ease from './utils/ease';
|
|
import { Loader } from './loader';
|
|
import { System } from './system';
|
|
|
|
export class Ripple {
|
|
private loader: Loader;
|
|
private system: System;
|
|
|
|
private array: Ripple[];
|
|
private group: THREE.Object3D;
|
|
private sphere: THREE.Sphere;
|
|
private strength: number; // 波の高さ
|
|
private threshold: number;
|
|
private growth: number;
|
|
private life: number;
|
|
private decay: number;
|
|
private influence: THREE.Vector3;
|
|
private geometry: MeshLine;
|
|
private material: THREE.LineBasicMaterial;
|
|
private mesh: THREE.Mesh;
|
|
|
|
constructor(config, system) {
|
|
this.system = system;
|
|
this.loader = this.system.loader;
|
|
|
|
this.array = config.array;
|
|
this.group = config.group;
|
|
this.sphere = new THREE.Sphere(new THREE.Vector3(config.x, config.y, config.z), 0);
|
|
this.strength = config.strength ? config.strength : Calc.rand(7, 15);
|
|
this.threshold = Calc.rand(5, 20);
|
|
this.growth = Calc.rand(0.2, 0.5);
|
|
this.life = 1;
|
|
this.decay = Calc.rand(0.01, 0.02);
|
|
this.influence = new THREE.Vector3();
|
|
const points = [];
|
|
const resolution = 64;
|
|
for (let j = 0; j < (Math.PI * 2) + ((Math.PI) / resolution); j += (2 * Math.PI) / resolution) {
|
|
points.push(Math.cos(j), Math.sin(j), 0);
|
|
}
|
|
this.geometry = new MeshLine();
|
|
this.geometry.setPoints(points);
|
|
|
|
this.material = new MeshLineMaterial({
|
|
lineWidth: 0.25,
|
|
color: config.color,
|
|
opacity: 1,
|
|
transparent: true,
|
|
depthTest: false,
|
|
});
|
|
this.material.onBeforeRender = () => {};
|
|
this.mesh = new THREE.Mesh(this.geometry, this.material);
|
|
this.mesh.rotation.x = Math.PI / 2;
|
|
this.mesh.position.x = this.sphere.center.x;
|
|
this.mesh.position.y = 0;
|
|
this.mesh.position.z = this.sphere.center.z;
|
|
this.group.add(this.mesh);
|
|
}
|
|
|
|
getInfluenceVector(vec) {
|
|
this.influence.set(0, 0, 0);
|
|
let distance = this.sphere.distanceToPoint(vec);
|
|
|
|
if(distance <= this.threshold ) {
|
|
let ease = Ease.inOutSine(this.threshold - distance, 0, 1, this.threshold);
|
|
let power = (this.strength * ease * this.life);
|
|
this.influence.addVectors(vec, this.sphere.center).multiplyScalar(power);
|
|
}
|
|
|
|
return this.influence;
|
|
}
|
|
|
|
update(i) {
|
|
this.sphere.radius += (this.growth * this.life) * this.loader.deltaTimeNormal;
|
|
this.life -= this.decay * this.loader.deltaTimeNormal;
|
|
|
|
this.mesh.position.y = (1 - this.life) * -2;
|
|
let newScale = 0.001 + this.sphere.radius;
|
|
this.mesh.scale.set(newScale, newScale, newScale);
|
|
this.mesh.material.opacity = this.life / 3;
|
|
|
|
if(this.life <= 0) {
|
|
this.destroy(i);
|
|
}
|
|
}
|
|
|
|
destroy(i) {
|
|
this.geometry.dispose();
|
|
this.material.dispose();
|
|
this.group.remove(this.mesh);
|
|
this.array.splice(i, 1);
|
|
}
|
|
}
|