mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 03:59:50 +02:00
feat: wireframe armor viewer
This commit is contained in:
1 parent
544eb92a6b
commit
70f7b862e3
5 files changed
+72
-40
No files matched your search
Vendored
+1
@@ -130,6 +130,7 @@
|
|||||||
"wargaming",
|
"wargaming",
|
||||||
"webp",
|
"webp",
|
||||||
"winrate",
|
"winrate",
|
||||||
|
"wireframe",
|
||||||
"wotblitz",
|
"wotblitz",
|
||||||
"xffn",
|
"xffn",
|
||||||
"xkdkw",
|
"xkdkw",
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ export function Options({ isFullScreen, canvas }: OptionsProps) {
|
|||||||
const greenPenetration = useTankopediaPersistent(
|
const greenPenetration = useTankopediaPersistent(
|
||||||
(state) => state.model.visual.greenPenetration,
|
(state) => state.model.visual.greenPenetration,
|
||||||
);
|
);
|
||||||
|
const wireframe = useTankopediaPersistent(
|
||||||
|
(state) => state.model.visual.wireframe,
|
||||||
|
);
|
||||||
const fullScreenAvailable =
|
const fullScreenAvailable =
|
||||||
typeof document !== 'undefined' && document.fullscreenEnabled;
|
typeof document !== 'undefined' && document.fullscreenEnabled;
|
||||||
const environment = useTankopediaPersistent(
|
const environment = useTankopediaPersistent(
|
||||||
@@ -126,6 +129,17 @@ export function Options({ isFullScreen, canvas }: OptionsProps) {
|
|||||||
</DropdownMenu.RadioGroup>
|
</DropdownMenu.RadioGroup>
|
||||||
</DropdownMenu.SubContent>
|
</DropdownMenu.SubContent>
|
||||||
</DropdownMenu.Sub>
|
</DropdownMenu.Sub>
|
||||||
|
|
||||||
|
<DropdownMenu.CheckboxItem
|
||||||
|
checked={wireframe}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
mutateTankopediaPersistent((draft) => {
|
||||||
|
draft.model.visual.wireframe = checked;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Wireframe
|
||||||
|
</DropdownMenu.CheckboxItem>
|
||||||
</DropdownMenu.Content>
|
</DropdownMenu.Content>
|
||||||
</DropdownMenu.Root>
|
</DropdownMenu.Root>
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ export function ArmorMesh({
|
|||||||
const scene = useThree((state) => state.scene);
|
const scene = useThree((state) => state.scene);
|
||||||
const hasCalibratedShells = useAwait(hasEquipment(103));
|
const hasCalibratedShells = useAwait(hasEquipment(103));
|
||||||
const hasEnhancedArmor = useAwait(hasEquipment(110));
|
const hasEnhancedArmor = useAwait(hasEquipment(110));
|
||||||
|
const wireframe = initialTankopedia.model.visual.wireframe;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function updateQuickEquipments() {
|
async function updateQuickEquipments() {
|
||||||
@@ -109,6 +110,15 @@ export function ArmorMesh({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
useTankopediaPersistent.subscribe(
|
||||||
|
(state) => state.model.visual.wireframe,
|
||||||
|
(wireframe) => {
|
||||||
|
if (material.current) {
|
||||||
|
material.current.wireframe = wireframe;
|
||||||
|
material.current.uniforms.wireframe.value = wireframe;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
@@ -386,44 +396,48 @@ export function ArmorMesh({
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<shaderMaterial
|
{true && (
|
||||||
ref={material}
|
<shaderMaterial
|
||||||
fragmentShader={fragmentShader}
|
wireframe={wireframe}
|
||||||
vertexShader={vertexShader}
|
ref={material}
|
||||||
transparent
|
fragmentShader={fragmentShader}
|
||||||
depthWrite={false}
|
vertexShader={vertexShader}
|
||||||
uniforms={{
|
transparent
|
||||||
resolution: { value: new Vector2() },
|
depthWrite={false}
|
||||||
externalModuleMask: { value: null },
|
uniforms={{
|
||||||
spacedArmorDepth: { value: null },
|
resolution: { value: new Vector2() },
|
||||||
spacedArmorMask: { value: null },
|
externalModuleMask: { value: null },
|
||||||
projectionMatrixInverse: { value: null },
|
spacedArmorDepth: { value: null },
|
||||||
zNear: { value: camera.near },
|
spacedArmorMask: { value: null },
|
||||||
zFar: { value: camera.far },
|
projectionMatrixInverse: { value: null },
|
||||||
greenPenetration: {
|
zNear: { value: camera.near },
|
||||||
value: initialTankopedia.model.visual.greenPenetration,
|
zFar: { value: camera.far },
|
||||||
},
|
greenPenetration: {
|
||||||
maxThickness: { value: maxThickness },
|
value: initialTankopedia.model.visual.greenPenetration,
|
||||||
isExplosive: { value: explosionCapable },
|
},
|
||||||
canRicochet: { value: ricochetCapable },
|
maxThickness: { value: maxThickness },
|
||||||
canSplash: { value: canSplash(initialShell.type) },
|
isExplosive: { value: explosionCapable },
|
||||||
thickness: {
|
canRicochet: { value: ricochetCapable },
|
||||||
value: thickness * (hasEnhancedArmor ? 1.04 : 1),
|
canSplash: { value: canSplash(initialShell.type) },
|
||||||
},
|
thickness: {
|
||||||
penetration: {
|
value: thickness * (hasEnhancedArmor ? 1.04 : 1),
|
||||||
value:
|
},
|
||||||
resolveNearPenetration(initialShell.penetration) *
|
penetration: {
|
||||||
(hasCalibratedShells ? (explosionCapable ? 1.1 : 1.05) : 1),
|
value:
|
||||||
},
|
resolveNearPenetration(initialShell.penetration) *
|
||||||
caliber: { value: initialShell.caliber },
|
(hasCalibratedShells ? (explosionCapable ? 1.1 : 1.05) : 1),
|
||||||
ricochetAngle: { value: degToRad(initialShell.ricochet ?? 90) },
|
},
|
||||||
normalization: {
|
caliber: { value: initialShell.caliber },
|
||||||
value: degToRad(initialShell.normalization ?? 0),
|
ricochetAngle: { value: degToRad(initialShell.ricochet ?? 90) },
|
||||||
},
|
normalization: {
|
||||||
damage: { value: initialShell.damage.armor },
|
value: degToRad(initialShell.normalization ?? 0),
|
||||||
explosionRadius: { value: initialShell.explosionRadius ?? 0 },
|
},
|
||||||
}}
|
damage: { value: initialShell.damage.armor },
|
||||||
/>
|
explosionRadius: { value: initialShell.explosionRadius ?? 0 },
|
||||||
|
wireframe: { value: wireframe },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</mesh>
|
</mesh>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ uniform float maxThickness;
|
|||||||
uniform bool greenPenetration;
|
uniform bool greenPenetration;
|
||||||
uniform float damage;
|
uniform float damage;
|
||||||
uniform float explosionRadius;
|
uniform float explosionRadius;
|
||||||
|
uniform bool wireframe;
|
||||||
|
|
||||||
float depthToDistance(float depth) {
|
float depthToDistance(float depth) {
|
||||||
mat4 projectionMatrixInverse = inverse(vProjectionMatrix);
|
mat4 projectionMatrixInverse = inverse(vProjectionMatrix);
|
||||||
@@ -107,8 +108,8 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec3 color = vec3(1.0, splashChance * 0.392, 0.0);
|
vec3 color = vec3(1.0, splashChance * 0.392, 0.0);
|
||||||
if (greenPenetration) {
|
if (greenPenetration || wireframe) {
|
||||||
gl_FragColor = vec4(mix(color, vec3(0.0, 1.0, 0.0), penetrationChance), 0.5);
|
gl_FragColor = vec4(mix(color, vec3(0.0, 1.0, 0.0), penetrationChance), wireframe ? 1.0 : 0.5);
|
||||||
} else {
|
} else {
|
||||||
gl_FragColor = vec4(color, (1.0 - penetrationChance) * 0.5);
|
gl_FragColor = vec4(color, (1.0 - penetrationChance) * 0.5);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export interface DuelMember {
|
|||||||
interface TankopediaPersistent {
|
interface TankopediaPersistent {
|
||||||
model: {
|
model: {
|
||||||
visual: {
|
visual: {
|
||||||
|
wireframe: boolean;
|
||||||
environment: (typeof ENVIRONMENTS)[number];
|
environment: (typeof ENVIRONMENTS)[number];
|
||||||
controlsEnabled: boolean;
|
controlsEnabled: boolean;
|
||||||
showGrid: boolean;
|
showGrid: boolean;
|
||||||
@@ -131,6 +132,7 @@ export const useTankopediaPersistent = create<TankopediaPersistent>()(
|
|||||||
subscribeWithSelector<TankopediaPersistent>(() => ({
|
subscribeWithSelector<TankopediaPersistent>(() => ({
|
||||||
model: {
|
model: {
|
||||||
visual: {
|
visual: {
|
||||||
|
wireframe: false,
|
||||||
environment: ENVIRONMENTS[0],
|
environment: ENVIRONMENTS[0],
|
||||||
controlsEnabled: true,
|
controlsEnabled: true,
|
||||||
showGrid: true,
|
showGrid: true,
|
||||||
|
|||||||
Reference in new issue
Block a user