mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +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,
|
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}>
|
||||||
|
|||||||
Reference in new issue
Block a user