feat: basic click functionality

This commit is contained in:
TrèsAbhi committed 2024-02-02 10:31:40 -06:00
1 parent 0251bfc842
commit b01a03c6ce
6 files changed
+505 -415

No files matched your search

@@ -6,7 +6,10 @@ import { canSplash } from '../../../../core/blitz/canSplash';
import { isExplosive } from '../../../../core/blitz/isExplosive';
import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration';
import { useDuel } from '../../../../stores/duel';
import { useTankopediaPersistent } from '../../../../stores/tankopedia';
import {
useTankopediaPersistent,
useTankopediaTemporary,
} from '../../../../stores/tankopedia';
import { externalModuleMaskRenderTarget } from '../ExternalModuleMask';
import { spacedArmorDepthRenderTarget } from '../SpacedArmorDepth';
import fragmentShader from './shaders/fragment.glsl';
@@ -17,6 +20,11 @@ interface ArmorMeshProps extends MeshProps {
maxThickness: number;
}
export type ArmorMeshUserData = {
type: 'coreArmor' | 'spacedArmor' | 'externalModule';
thickness: number;
};
export function ArmorMesh({
thickness,
maxThickness,
@@ -109,7 +117,26 @@ export function ArmorMesh({
<meshBasicMaterial colorWrite={false} />
</mesh>
<mesh {...props} renderOrder={1}>
<mesh
{...props}
renderOrder={1}
userData={
{
type: 'coreArmor',
thickness,
} satisfies ArmorMeshUserData
}
onClick={(event) => {
if (useTankopediaTemporary.getState().mode !== 'armor') return;
event.intersections
.filter(({ object }) => Boolean(object.userData.type))
.map(({ object }) => {
const data = object.userData as ArmorMeshUserData;
console.log(data.type, data.thickness);
});
}}
>
<shaderMaterial
ref={material}
fragmentShader={fragmentShader}
@@ -1,10 +1,12 @@
import { MeshProps } from '@react-three/fiber';
import { Color, WebGLRenderTarget } from 'three';
import { ArmorMeshUserData } from './Armor';
export const externalModuleMaskRenderTarget = new WebGLRenderTarget();
type ArmorMeshExternalModuleMaskProps = MeshProps &
(
type ArmorMeshExternalModuleMaskProps = MeshProps & {
ornamental?: boolean;
} & (
| {
exclude?: false;
maxThickness: number;
@@ -15,22 +17,34 @@ type ArmorMeshExternalModuleMaskProps = MeshProps &
}
);
export function ArmorMeshExternalModuleMask(
props: ArmorMeshExternalModuleMaskProps,
) {
export function ArmorMeshExternalModuleMask({
ornamental = false,
...props
}: ArmorMeshExternalModuleMaskProps) {
return (
<>
{props.exclude && (
{(props.exclude || ornamental) && (
<mesh {...props} renderOrder={0}>
<meshBasicMaterial colorWrite={false} />
</mesh>
)}
{!props.exclude && (
<mesh {...props} renderOrder={1}>
<mesh
{...props}
renderOrder={1}
onClick={ornamental ? () => {} : undefined}
userData={
{
type: 'externalModule',
thickness: props.thickness,
} satisfies ArmorMeshUserData
}
>
<meshBasicMaterial
color={new Color(1, props.thickness / props.maxThickness, 0)}
depthWrite={false}
colorWrite={!ornamental}
/>
</mesh>
)}
@@ -1,12 +1,14 @@
import { MeshProps } from '@react-three/fiber';
import { WebGLRenderTarget } from 'three';
import { ArmorMeshUserData } from '../Armor';
import fragmentShader from './shaders/fragment.glsl';
import vertexShader from './shaders/vertex.glsl';
export const spacedArmorDepthRenderTarget = new WebGLRenderTarget();
type ArmorMeshSpacedArmorDepthProps = MeshProps &
(
type ArmorMeshSpacedArmorDepthProps = MeshProps & {
ornamental?: boolean;
} & (
| {
include?: false;
isExternalModule: boolean;
@@ -18,27 +20,44 @@ type ArmorMeshSpacedArmorDepthProps = MeshProps &
}
);
export function ArmorMeshSpacedArmorDepth(
props: ArmorMeshSpacedArmorDepthProps,
) {
export function ArmorMeshSpacedArmorDepth({
ornamental = false,
...props
}: ArmorMeshSpacedArmorDepthProps) {
return (
<>
{!props.include && (
{!props.include && !ornamental && (
<mesh {...props} renderOrder={props.isExternalModule ? 2 : 0}>
<meshBasicMaterial colorWrite={false} />
</mesh>
)}
{props.include && (
<mesh {...props} renderOrder={1}>
<shaderMaterial
fragmentShader={fragmentShader}
vertexShader={vertexShader}
uniforms={{
thickness: { value: props.thickness },
maxThickness: { value: props.maxThickness },
}}
/>
<mesh
{...props}
renderOrder={1}
onClick={ornamental ? () => {} : undefined}
userData={
{
type: 'spacedArmor',
thickness: props.thickness,
} satisfies ArmorMeshUserData
}
>
{!ornamental && (
<shaderMaterial
fragmentShader={fragmentShader}
vertexShader={vertexShader}
uniforms={{
thickness: { value: props.thickness },
maxThickness: { value: props.maxThickness },
}}
/>
)}
{ornamental && (
<meshBasicMaterial colorWrite={false} depthWrite={false} />
)}
</mesh>
)}
</>