From f13622836e1c6b59df7c65707f89851ccdbf06ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Sat, 27 Jul 2024 12:46:12 -0500 Subject: [PATCH] feat: better opacity --- .../SpacedArmorSceneComponent/index.tsx | 44 +++++++++++-------- .../components/StaticArmorScene.tsx | 39 +++++++++++++--- 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx b/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx index ac77cab8b..2f47f304e 100644 --- a/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx +++ b/src/components/Armor/components/SpacedArmorSceneComponent/index.tsx @@ -5,7 +5,6 @@ import { Intersection, MeshBasicMaterial, MeshStandardMaterial, - NormalBlending, Object3D, Plane, Quaternion, @@ -377,26 +376,35 @@ export function SpacedArmorSceneComponent({ if (staticMode) { const x = clamp(thickness / thicknessRange.max, 0, 1); - const r = -((1 - x) ** 2) + 1; - const g = -(x ** 2) + 1; + const y = Math.sqrt(x); + const r = -((1 - y) ** 2) + 1; + const g = -(y ** 2) + 1; + + let color: string; + let opacity: number; + + switch (props.type) { + case ArmorType.Core: + color = `rgb(${to255(r)}, ${to255(g)}, 0)`; + opacity = 1; + break; + + case ArmorType.Spaced: + color = `rgb(${to255(1 - y)}, 0, ${to255(0.75 * (1 - y))})`; + opacity = x + 0.5; + break; + + case ArmorType.External: + color = `rgb(0, 255, 255)`; + opacity = 1 / 8; + break; + } return jsxTree(node, { material: new MeshStandardMaterial({ - color: - props.type === ArmorType.Core - ? `rgb(${to255(r)}, ${to255(g)}, 0)` - : props.type === ArmorType.Spaced - ? `rgb(${to255(1 - x)}, 0, ${to255(1 - 0.75 * x)})` - : `rgb(0, 255, 255)`, - opacity: - props.type === ArmorType.External - ? 1 / 8 - : props.type === ArmorType.Spaced - ? 7 / 8 - : 1, - transparent: props.type !== ArmorType.Core, - blending: - props.type === ArmorType.Core ? NormalBlending : NormalBlending, + color, + opacity, + transparent: opacity !== 1, }), userData: { diff --git a/src/components/StaticArmor/components/StaticArmorScene.tsx b/src/components/StaticArmor/components/StaticArmorScene.tsx index a55125337..3a0618f07 100644 --- a/src/components/StaticArmor/components/StaticArmorScene.tsx +++ b/src/components/StaticArmor/components/StaticArmorScene.tsx @@ -1,4 +1,4 @@ -import { memo, useMemo, useRef } from 'react'; +import { memo, useEffect, useMemo, useRef } from 'react'; import { Group, Plane, Scene, Vector3 } from 'three'; import { correctZYTuple } from '../../../core/blitz/correctZYTuple'; import { nameToArmorId } from '../../../core/blitzkit/nameToArmorId'; @@ -9,6 +9,7 @@ import { useModel } from '../../../hooks/useModel'; import { useModelDefinitions } from '../../../hooks/useModelDefinitions'; import { useTankTransform } from '../../../hooks/useTankTransform'; import * as Duel from '../../../stores/duel'; +import * as TankopediaPersistent from '../../../stores/tankopediaPersistent'; import { ModelTankWrapper } from '../../Armor/components/ModelTankWrapper'; import { ArmorType } from '../../Armor/components/SpacedArmorScene'; import { SpacedArmorSceneComponent } from '../../Armor/components/SpacedArmorSceneComponent'; @@ -25,6 +26,7 @@ export interface ThicknessRange { export const StaticArmorScene = memo( ({ scene, awaitedTankDefinitions }) => { const wrapper = useRef(null); + const tankopediaPersistentStore = TankopediaPersistent.useStore(); const awaitedTankModelDefinitions = useModelDefinitions(); const turretContainer = useRef(null); const gunContainer = useRef(null); @@ -48,12 +50,16 @@ export const StaticArmorScene = memo( gunModelDefinition.mask === undefined ? undefined : gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y; + let thisTankThicknesses: number[] = []; const thicknessRange = useMemo(() => { const thicknesses = Object.values(awaitedTankDefinitions) .filter((thisTank) => thisTank.tier === tank.tier) - .map((tank) => awaitedTankModelDefinitions[tank.id]) + .map((tank) => ({ + model: awaitedTankModelDefinitions[tank.id], + id: tank.id, + })) .filter(Boolean) - .map((model) => { + .map(({ model, id }) => { const tankThicknesses = Object.values(model.armor.thickness); const trackThicknesses = Object.values(model.tracks) .map((track) => track.thickness) @@ -71,21 +77,44 @@ export const StaticArmorScene = memo( }) .flat(); - return [ + const totalThicknesses = [ ...tankThicknesses, ...trackThicknesses, ...turretThicknesses, ]; + + if (id === tank.id) thisTankThicknesses = totalThicknesses; + + return totalThicknesses; }) .flat(); - const max = Math.max(...thicknesses) * 0.75; + // const maxOfAll = Math.max(...thicknesses) * 0.75; + // const max = Math.max(...thisTankThicknesses, maxOfAll); + + const max = Math.max(...thicknesses); return { max } satisfies ThicknessRange; }, [tank.tier]); useTankTransform(protagonist, turretContainer, gunContainer); + useEffect(() => { + function handleMode(mode: TankopediaPersistent.TankopediaMode) { + if (!wrapper.current) return; + wrapper.current.visible = mode === 'armor'; + } + + const unsubscribe = tankopediaPersistentStore.subscribe( + (state) => state.mode, + handleMode, + ); + + handleMode(tankopediaPersistentStore.getState().mode); + + return unsubscribe; + }, []); + return (