mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: spaced armor
This commit is contained in:
1 parent
cae4836e17
commit
9218eb09d6
4 files changed
+31
-6
No files matched your search
@@ -142,7 +142,11 @@ export function TankDisplay() {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<TankModel />
|
<TankModel />
|
||||||
{mode === 'armor' && <TankArmor visible={controlsEnabled} />}
|
{mode === 'armor' && (
|
||||||
|
<group visible={controlsEnabled}>
|
||||||
|
<TankArmor />
|
||||||
|
</group>
|
||||||
|
)}
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { Lighting } from '../../Lighting';
|
|||||||
|
|
||||||
interface TankArmorProps extends GroupProps {}
|
interface TankArmorProps extends GroupProps {}
|
||||||
|
|
||||||
export function TankArmor(props: TankArmorProps) {
|
export function TankArmor({ ...props }: TankArmorProps) {
|
||||||
const [awaitedModelDefinitions, setAwaitedModelDefinitions] = useState<
|
const [awaitedModelDefinitions, setAwaitedModelDefinitions] = useState<
|
||||||
ModelDefinitions | undefined
|
ModelDefinitions | undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
@@ -91,10 +91,12 @@ export function TankArmor(props: TankArmorProps) {
|
|||||||
const armorId = parseInt(node.name.match(/.+_armor_(\d+)/)![1]);
|
const armorId = parseInt(node.name.match(/.+_armor_(\d+)/)![1]);
|
||||||
const isVisible = isHull;
|
const isVisible = isHull;
|
||||||
const thickness = tankModelDefinition.armor.thickness[armorId];
|
const thickness = tankModelDefinition.armor.thickness[armorId];
|
||||||
|
const isSpaced = tankModelDefinition.armor.spaced?.includes(armorId);
|
||||||
|
|
||||||
if (!isVisible || thickness === undefined) return null;
|
if (!isVisible || thickness === undefined) return null;
|
||||||
return (
|
return (
|
||||||
<ArmorMesh
|
<ArmorMesh
|
||||||
|
spaced={isSpaced}
|
||||||
key={node.uuid}
|
key={node.uuid}
|
||||||
geometry={(node as Mesh).geometry}
|
geometry={(node as Mesh).geometry}
|
||||||
thickness={thickness}
|
thickness={thickness}
|
||||||
@@ -116,10 +118,13 @@ export function TankArmor(props: TankArmorProps) {
|
|||||||
const isVisible = isCurrentTurret;
|
const isVisible = isCurrentTurret;
|
||||||
const armorId = parseInt(node.name.match(/.+_armor_(\d+)/)![1]);
|
const armorId = parseInt(node.name.match(/.+_armor_(\d+)/)![1]);
|
||||||
const thickness = turretModelDefinition.armor.thickness[armorId];
|
const thickness = turretModelDefinition.armor.thickness[armorId];
|
||||||
|
const isSpaced =
|
||||||
|
turretModelDefinition.armor.spaced?.includes(armorId);
|
||||||
|
|
||||||
if (!isVisible || thickness === undefined) return null;
|
if (!isVisible || thickness === undefined) return null;
|
||||||
return (
|
return (
|
||||||
<ArmorMesh
|
<ArmorMesh
|
||||||
|
spaced={isSpaced}
|
||||||
key={node.uuid}
|
key={node.uuid}
|
||||||
position={turretOrigin}
|
position={turretOrigin}
|
||||||
geometry={(node as Mesh).geometry}
|
geometry={(node as Mesh).geometry}
|
||||||
@@ -148,10 +153,13 @@ export function TankArmor(props: TankArmorProps) {
|
|||||||
const isVisible = isCurrentGun;
|
const isVisible = isCurrentGun;
|
||||||
const armorId = parseInt(node.name.match(/.+_armor_(\d+)/)![1]);
|
const armorId = parseInt(node.name.match(/.+_armor_(\d+)/)![1]);
|
||||||
const thickness = gunModelDefinition.armor.thickness[armorId];
|
const thickness = gunModelDefinition.armor.thickness[armorId];
|
||||||
|
const isSpaced =
|
||||||
|
gunModelDefinition.armor.spaced?.includes(armorId);
|
||||||
|
|
||||||
if (!isVisible || thickness === undefined) return null;
|
if (!isVisible || thickness === undefined) return null;
|
||||||
return (
|
return (
|
||||||
<ArmorMesh
|
<ArmorMesh
|
||||||
|
spaced={isSpaced}
|
||||||
key={node.uuid}
|
key={node.uuid}
|
||||||
position={turretOrigin.clone().add(gunOrigin)}
|
position={turretOrigin.clone().add(gunOrigin)}
|
||||||
geometry={(node as Mesh).geometry}
|
geometry={(node as Mesh).geometry}
|
||||||
|
|||||||
@@ -12,25 +12,31 @@ interface ArmorMeshProps extends MeshProps {
|
|||||||
ricochet: number;
|
ricochet: number;
|
||||||
caliber: number;
|
caliber: number;
|
||||||
normalization: number;
|
normalization: number;
|
||||||
|
spaced?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shader split: https://github.com/FarazzShaikh/THREE-CustomShaderMaterial/issues/48
|
||||||
|
|
||||||
export function ArmorMesh({
|
export function ArmorMesh({
|
||||||
thickness,
|
thickness,
|
||||||
penetration,
|
penetration,
|
||||||
caliber,
|
caliber,
|
||||||
ricochet,
|
ricochet,
|
||||||
normalization,
|
normalization,
|
||||||
|
spaced = false,
|
||||||
...props
|
...props
|
||||||
}: ArmorMeshProps) {
|
}: ArmorMeshProps) {
|
||||||
const opaqueArmor = useTankopedia((state) => state.model.opaqueArmor);
|
const opaqueArmor = useTankopedia((state) => state.model.opaqueArmor);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{!spaced && (
|
||||||
<mesh {...props}>
|
<mesh {...props}>
|
||||||
<meshBasicMaterial colorWrite={false} />
|
<meshBasicMaterial colorWrite={false} />
|
||||||
</mesh>
|
</mesh>
|
||||||
|
)}
|
||||||
|
|
||||||
<mesh {...props} renderOrder={1}>
|
<mesh {...props} renderOrder={spaced ? 3 : 1}>
|
||||||
<CustomShaderMaterial
|
<CustomShaderMaterial
|
||||||
baseMaterial={MeshStandardMaterial}
|
baseMaterial={MeshStandardMaterial}
|
||||||
transparent
|
transparent
|
||||||
@@ -42,10 +48,10 @@ export function ArmorMesh({
|
|||||||
ricochet: { value: ricochet * (Math.PI / 180) },
|
ricochet: { value: ricochet * (Math.PI / 180) },
|
||||||
caliber: { value: caliber },
|
caliber: { value: caliber },
|
||||||
normalization: { value: normalization * (Math.PI / 180) },
|
normalization: { value: normalization * (Math.PI / 180) },
|
||||||
|
spaced: { value: spaced },
|
||||||
}}
|
}}
|
||||||
vertexShader={vertex}
|
vertexShader={vertex}
|
||||||
// split shaders due to https://github.com/FarazzShaikh/THREE-CustomShaderMaterial/issues/48
|
fragmentShader={opaqueArmor && !spaced ? fragmentOpaque : fragment}
|
||||||
fragmentShader={opaqueArmor ? fragmentOpaque : fragment}
|
|
||||||
/>
|
/>
|
||||||
</mesh>
|
</mesh>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ uniform float penetration;
|
|||||||
uniform float ricochet;
|
uniform float ricochet;
|
||||||
uniform float caliber;
|
uniform float caliber;
|
||||||
uniform float normalization;
|
uniform float normalization;
|
||||||
|
uniform bool spaced;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec3 normalizedNormal = normalize(vNormal);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user