mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
feat: better opacity
This commit is contained in:
1 parent
1a91214dd0
commit
f13622836e
2 files changed
+60
-23
No files matched your search
@@ -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: {
|
||||
|
||||
@@ -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<StaticArmorSceneProps>(
|
||||
({ scene, awaitedTankDefinitions }) => {
|
||||
const wrapper = useRef<Group>(null);
|
||||
const tankopediaPersistentStore = TankopediaPersistent.useStore();
|
||||
const awaitedTankModelDefinitions = useModelDefinitions();
|
||||
const turretContainer = useRef<Group>(null);
|
||||
const gunContainer = useRef<Group>(null);
|
||||
@@ -48,12 +50,16 @@ export const StaticArmorScene = memo<StaticArmorSceneProps>(
|
||||
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<StaticArmorSceneProps>(
|
||||
})
|
||||
.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 (
|
||||
<ModelTankWrapper ref={wrapper}>
|
||||
<group position={hullOrigin}>
|
||||
|
||||
Reference in new issue
Block a user