feat: he splash visual

This commit is contained in:
TrèsAbhi committed 2024-07-23 21:01:32 -05:00
1 parent 16500793a5
commit 8b5638f82d
4 files changed
+91 -11

No files matched your search

+1
View File
@@ -2,6 +2,7 @@
"cSpell.words": [
"AABBOX",
"Abhi",
"absarc",
"accountinfo",
"adsense",
"aeson",
+88 -11
View File
@@ -1,9 +1,21 @@
import { Box, Flex, Text } from '@radix-ui/themes';
import { Html } from '@react-three/drei';
import { useFrame } from '@react-three/fiber';
import { ComponentProps, useRef } from 'react';
import { Euler, Mesh, Quaternion } from 'three';
import { J_HAT } from '../../../constants/axis';
import { clamp } from 'lodash';
import { ComponentProps, useEffect, useRef } from 'react';
import {
BufferGeometry,
DoubleSide,
Euler,
Group,
Line,
LineDashedMaterial,
Mesh,
MeshBasicMaterial,
Path,
Quaternion,
} from 'three';
import { J_HAT, K_HAT } from '../../../constants/axis';
import * as TankopediaEphemeral from '../../../stores/tankopediaEphemeral';
import { ShotDisplayCard } from './ShotDisplayCard';
@@ -26,20 +38,65 @@ export function ShotDisplay() {
const shot = TankopediaEphemeral.use((state) => state.shot);
const inTracer = useRef<Mesh>(null);
const outTracer = useRef<Mesh>(null);
const splashRadiusWrapper = useRef<Group>(null);
const splashRadiusMaterial = useRef<MeshBasicMaterial>(null);
let animationStartTime: number | null = null;
useEffect(() => {
if (shot && shot.splashRadius !== undefined) {
const outlineGeometry = new BufferGeometry().setFromPoints(
new Path().absarc(0, 0, 1, 0, Math.PI * 2).getSpacedPoints(50),
);
const outlineMaterial = new LineDashedMaterial({
color: 'orange',
dashSize: 0.05,
gapSize: 0.025,
});
const outline = new Line(
outlineGeometry,
outlineMaterial,
).computeLineDistances();
splashRadiusWrapper.current?.add(outline);
return () => {
splashRadiusWrapper.current?.remove(outline);
};
}
});
useFrame(({ clock }) => {
if (!shot || !inTracer.current) return;
if (!shot) return;
const t1 = clock.elapsedTime % 1;
const t2 = (clock.elapsedTime + 0.5) % 1;
const t = clock.elapsedTime;
inTracer.current.scale.set(1, 1 - 2 * Math.abs(t1 - 0.5), 1);
inTracer.current.position.set(0, (1 - t1) * inLength, 0);
if (inTracer.current) {
const tracerT1 = t % 1;
const tracerT2 = (t + 0.5) % 1;
if (!outTracer.current) return;
inTracer.current.scale.set(1, 1 - 2 * Math.abs(tracerT1 - 0.5), 1);
inTracer.current.position.set(0, (1 - tracerT1) * inLength, 0);
outTracer.current.scale.set(1, 1 - 2 * Math.abs(t2 - 0.5), 1);
outTracer.current.position.set(0, t2 * outLength, 0);
if (outTracer.current) {
outTracer.current.scale.set(1, 1 - 2 * Math.abs(tracerT2 - 0.5), 1);
outTracer.current.position.set(0, tracerT2 * outLength, 0);
}
}
if (
shot.splashRadius !== undefined &&
splashRadiusWrapper.current &&
splashRadiusMaterial.current
) {
if (animationStartTime === null) animationStartTime = t;
const scale =
clamp(4 * (t - animationStartTime), 0, 1) * shot.splashRadius;
const opacity = 1 - clamp(2 * (t - animationStartTime), 0, 1);
splashRadiusWrapper.current.scale.set(scale, scale, scale);
splashRadiusMaterial.current.opacity = opacity;
}
});
if (!shot) return null;
@@ -68,6 +125,26 @@ export function ShotDisplay() {
return (
<group>
{shot.splashRadius && (
<group
position={inLast.point}
ref={splashRadiusWrapper}
rotation={new Euler().setFromQuaternion(
new Quaternion().setFromUnitVectors(K_HAT, shot.in.surfaceNormal),
)}
>
<mesh>
<circleGeometry />
<meshBasicMaterial
side={DoubleSide}
color="orange"
transparent
ref={splashRadiusMaterial}
/>
</mesh>
</group>
)}
<Html
position={inLast.point}
style={{
@@ -85,6 +85,7 @@ export function SpacedArmorSceneComponent({
const shell = antagonist.shell;
const cameraNormal = camera.position.clone().sub(point).normalize();
const shot: TankopediaEphemeral.Shot = {
splashRadius: shell.explosionRadius,
damage: -1,
containsGaps: shell.type === ShellType.HEAT,
in: {
+1
View File
@@ -43,6 +43,7 @@ export type ShotLayer = ShotLayerExternal | ShotLayerNonExternal | ShotLayerGap;
export type Shot = {
containsGaps: boolean;
damage: number;
splashRadius?: number;
in: {
surfaceNormal: Vector3;