feat: spaced armor

This commit is contained in:
TrèsAbhi committed 2024-01-10 19:04:04 -06:00
1 parent cae4836e17
commit 9218eb09d6
4 files changed
+34 -9

No files matched your search

@@ -142,7 +142,11 @@ export function TankDisplay() {
}
>
<TankModel />
{mode === 'armor' && <TankArmor visible={controlsEnabled} />}
{mode === 'armor' && (
<group visible={controlsEnabled}>
<TankArmor />
</group>
)}
</Suspense>
</Canvas>
</div>
@@ -16,7 +16,7 @@ import { Lighting } from '../../Lighting';
interface TankArmorProps extends GroupProps {}
export function TankArmor(props: TankArmorProps) {
export function TankArmor({ ...props }: TankArmorProps) {
const [awaitedModelDefinitions, setAwaitedModelDefinitions] = useState<
ModelDefinitions | undefined
>(undefined);
@@ -91,10 +91,12 @@ export function TankArmor(props: TankArmorProps) {
const armorId = parseInt(node.name.match(/.+_armor_(\d+)/)![1]);
const isVisible = isHull;
const thickness = tankModelDefinition.armor.thickness[armorId];
const isSpaced = tankModelDefinition.armor.spaced?.includes(armorId);
if (!isVisible || thickness === undefined) return null;
return (
<ArmorMesh
spaced={isSpaced}
key={node.uuid}
geometry={(node as Mesh).geometry}
thickness={thickness}
@@ -116,10 +118,13 @@ export function TankArmor(props: TankArmorProps) {
const isVisible = isCurrentTurret;
const armorId = parseInt(node.name.match(/.+_armor_(\d+)/)![1]);
const thickness = turretModelDefinition.armor.thickness[armorId];
const isSpaced =
turretModelDefinition.armor.spaced?.includes(armorId);
if (!isVisible || thickness === undefined) return null;
return (
<ArmorMesh
spaced={isSpaced}
key={node.uuid}
position={turretOrigin}
geometry={(node as Mesh).geometry}
@@ -148,10 +153,13 @@ export function TankArmor(props: TankArmorProps) {
const isVisible = isCurrentGun;
const armorId = parseInt(node.name.match(/.+_armor_(\d+)/)![1]);
const thickness = gunModelDefinition.armor.thickness[armorId];
const isSpaced =
gunModelDefinition.armor.spaced?.includes(armorId);
if (!isVisible || thickness === undefined) return null;
return (
<ArmorMesh
spaced={isSpaced}
key={node.uuid}
position={turretOrigin.clone().add(gunOrigin)}
geometry={(node as Mesh).geometry}
+12 -6
View File
@@ -12,25 +12,31 @@ interface ArmorMeshProps extends MeshProps {
ricochet: number;
caliber: number;
normalization: number;
spaced?: boolean;
}
// shader split: https://github.com/FarazzShaikh/THREE-CustomShaderMaterial/issues/48
export function ArmorMesh({
thickness,
penetration,
caliber,
ricochet,
normalization,
spaced = false,
...props
}: ArmorMeshProps) {
const opaqueArmor = useTankopedia((state) => state.model.opaqueArmor);
return (
<>
<mesh {...props}>
<meshBasicMaterial colorWrite={false} />
</mesh>
{!spaced && (
<mesh {...props}>
<meshBasicMaterial colorWrite={false} />
</mesh>
)}
<mesh {...props} renderOrder={1}>
<mesh {...props} renderOrder={spaced ? 3 : 1}>
<CustomShaderMaterial
baseMaterial={MeshStandardMaterial}
transparent
@@ -42,10 +48,10 @@ export function ArmorMesh({
ricochet: { value: ricochet * (Math.PI / 180) },
caliber: { value: caliber },
normalization: { value: normalization * (Math.PI / 180) },
spaced: { value: spaced },
}}
vertexShader={vertex}
// split shaders due to https://github.com/FarazzShaikh/THREE-CustomShaderMaterial/issues/48
fragmentShader={opaqueArmor ? fragmentOpaque : fragment}
fragmentShader={opaqueArmor && !spaced ? fragmentOpaque : fragment}
/>
</mesh>
</>
@@ -6,6 +6,7 @@ uniform float penetration;
uniform float ricochet;
uniform float caliber;
uniform float normalization;
uniform bool spaced;
void main() {
vec3 normalizedNormal = normalize(vNormal);
@@ -41,5 +42,11 @@ void main() {
}
}
csm_FragColor = vec4(1.0, 0.0, 0.0, (1.0 - penetrationChance) * 0.5);
float alpha = (1.0 - penetrationChance) * 0.5;
if (spaced) {
csm_FragColor = vec4(0.0, 0.0, 1.0, alpha);
} else {
csm_FragColor = vec4(1.0, 0.0, 0.0, alpha);
}
}