feat: better opacity

This commit is contained in:
TrèsAbhi committed 2024-07-27 12:46:12 -05:00
1 parent 1a91214dd0
commit f13622836e
2 files changed
+60 -23

No files matched your search

@@ -5,7 +5,6 @@ import {
Intersection, Intersection,
MeshBasicMaterial, MeshBasicMaterial,
MeshStandardMaterial, MeshStandardMaterial,
NormalBlending,
Object3D, Object3D,
Plane, Plane,
Quaternion, Quaternion,
@@ -377,26 +376,35 @@ export function SpacedArmorSceneComponent({
if (staticMode) { if (staticMode) {
const x = clamp(thickness / thicknessRange.max, 0, 1); const x = clamp(thickness / thicknessRange.max, 0, 1);
const r = -((1 - x) ** 2) + 1; const y = Math.sqrt(x);
const g = -(x ** 2) + 1; 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, { return jsxTree(node, {
material: new MeshStandardMaterial({ material: new MeshStandardMaterial({
color: color,
props.type === ArmorType.Core opacity,
? `rgb(${to255(r)}, ${to255(g)}, 0)` transparent: opacity !== 1,
: 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,
}), }),
userData: { userData: {
@@ -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 { Group, Plane, Scene, Vector3 } from 'three';
import { correctZYTuple } from '../../../core/blitz/correctZYTuple'; import { correctZYTuple } from '../../../core/blitz/correctZYTuple';
import { nameToArmorId } from '../../../core/blitzkit/nameToArmorId'; import { nameToArmorId } from '../../../core/blitzkit/nameToArmorId';
@@ -9,6 +9,7 @@ import { useModel } from '../../../hooks/useModel';
import { useModelDefinitions } from '../../../hooks/useModelDefinitions'; import { useModelDefinitions } from '../../../hooks/useModelDefinitions';
import { useTankTransform } from '../../../hooks/useTankTransform'; import { useTankTransform } from '../../../hooks/useTankTransform';
import * as Duel from '../../../stores/duel'; import * as Duel from '../../../stores/duel';
import * as TankopediaPersistent from '../../../stores/tankopediaPersistent';
import { ModelTankWrapper } from '../../Armor/components/ModelTankWrapper'; import { ModelTankWrapper } from '../../Armor/components/ModelTankWrapper';
import { ArmorType } from '../../Armor/components/SpacedArmorScene'; import { ArmorType } from '../../Armor/components/SpacedArmorScene';
import { SpacedArmorSceneComponent } from '../../Armor/components/SpacedArmorSceneComponent'; import { SpacedArmorSceneComponent } from '../../Armor/components/SpacedArmorSceneComponent';
@@ -25,6 +26,7 @@ export interface ThicknessRange {
export const StaticArmorScene = memo<StaticArmorSceneProps>( export const StaticArmorScene = memo<StaticArmorSceneProps>(
({ scene, awaitedTankDefinitions }) => { ({ scene, awaitedTankDefinitions }) => {
const wrapper = useRef<Group>(null); const wrapper = useRef<Group>(null);
const tankopediaPersistentStore = TankopediaPersistent.useStore();
const awaitedTankModelDefinitions = useModelDefinitions(); const awaitedTankModelDefinitions = useModelDefinitions();
const turretContainer = useRef<Group>(null); const turretContainer = useRef<Group>(null);
const gunContainer = useRef<Group>(null); const gunContainer = useRef<Group>(null);
@@ -48,12 +50,16 @@ export const StaticArmorScene = memo<StaticArmorSceneProps>(
gunModelDefinition.mask === undefined gunModelDefinition.mask === undefined
? undefined ? undefined
: gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y; : gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y;
let thisTankThicknesses: number[] = [];
const thicknessRange = useMemo(() => { const thicknessRange = useMemo(() => {
const thicknesses = Object.values(awaitedTankDefinitions) const thicknesses = Object.values(awaitedTankDefinitions)
.filter((thisTank) => thisTank.tier === tank.tier) .filter((thisTank) => thisTank.tier === tank.tier)
.map((tank) => awaitedTankModelDefinitions[tank.id]) .map((tank) => ({
model: awaitedTankModelDefinitions[tank.id],
id: tank.id,
}))
.filter(Boolean) .filter(Boolean)
.map((model) => { .map(({ model, id }) => {
const tankThicknesses = Object.values(model.armor.thickness); const tankThicknesses = Object.values(model.armor.thickness);
const trackThicknesses = Object.values(model.tracks) const trackThicknesses = Object.values(model.tracks)
.map((track) => track.thickness) .map((track) => track.thickness)
@@ -71,21 +77,44 @@ export const StaticArmorScene = memo<StaticArmorSceneProps>(
}) })
.flat(); .flat();
return [ const totalThicknesses = [
...tankThicknesses, ...tankThicknesses,
...trackThicknesses, ...trackThicknesses,
...turretThicknesses, ...turretThicknesses,
]; ];
if (id === tank.id) thisTankThicknesses = totalThicknesses;
return totalThicknesses;
}) })
.flat(); .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; return { max } satisfies ThicknessRange;
}, [tank.tier]); }, [tank.tier]);
useTankTransform(protagonist, turretContainer, gunContainer); 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 ( return (
<ModelTankWrapper ref={wrapper}> <ModelTankWrapper ref={wrapper}>
<group position={hullOrigin}> <group position={hullOrigin}>