diff --git a/src/app/tools/tankopedia/[id]/components/Lighting.tsx b/src/app/tools/tankopedia/[id]/components/Lighting.tsx
new file mode 100644
index 000000000..9b6a178f2
--- /dev/null
+++ b/src/app/tools/tankopedia/[id]/components/Lighting.tsx
@@ -0,0 +1,19 @@
+export function Lighting() {
+ return (
+ <>
+
+
+
+ >
+ );
+}
diff --git a/src/app/tools/tankopedia/[id]/components/Model/TankDisplay.tsx b/src/app/tools/tankopedia/[id]/components/Model/TankDisplay.tsx
index abd477c6e..6396db4e6 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/TankDisplay.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/TankDisplay.tsx
@@ -17,9 +17,9 @@ import mutateTankopedia, {
} from '../../../../../../stores/tankopedia';
import { Loader } from '../../../../components/Loader';
import { Controls } from '../Control';
+import { Lighting } from '../Lighting';
import { RotationInputs } from '../RotationInputs';
import { SceneProps } from '../SceneProps';
-import { TankArmor } from './components/TankArmor';
import { TankModel } from './components/TankModel';
export function TankDisplay() {
@@ -117,9 +117,11 @@ export function TankDisplay() {
ref={canvas}
camera={{ fov: 20 }}
onPointerDown={handlePointerDown}
+ gl={{ logarithmicDepthBuffer: true }}
>
+
- {mode === 'armor' && }
diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor.tsx
index a0e1e29fa..d237b93e6 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankArmor.tsx
@@ -68,6 +68,7 @@ export const TankArmor = forwardRef((_props, ref) => {
return (
(
pitch,
initialTurretRotation,
yaw,
- objects,
+ modelObjects,
yawLimits,
onPitchStart,
turretContainer,
+ armorObjects,
pitchLimits,
model,
onPitchEnd,
@@ -59,7 +62,7 @@ export const GunContainer = forwardRef(
rotation={[pitch, 0, 0]}
ref={gunContainer}
>
- {objects.map((object) => {
+ {modelObjects.map((object) => {
const isCurrentMantlet =
object.name === `gun_${model.toString().padStart(2, '0')}_mask`;
const isCurrentGun =
@@ -143,6 +146,25 @@ export const GunContainer = forwardRef(
/>
);
})}
+
+ {armorObjects.map((object) => {
+ const isCurrentGun = object.name.startsWith(
+ `gun_${model.toString().padStart(2, '0')}`,
+ );
+ const isVisible = isCurrentGun;
+
+ if (!isVisible) return null;
+
+ return (
+
+
+
+ );
+ })}
);
},
diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/components/HullContainer.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/components/HullContainer.tsx
index a681ad0ed..e3ab0f071 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/components/HullContainer.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/components/HullContainer.tsx
@@ -1,13 +1,22 @@
import { ThreeEvent, useThree } from '@react-three/fiber';
import { ReactNode, forwardRef, useImperativeHandle, useRef } from 'react';
-import { Group, Mesh, MeshStandardMaterial, Object3D, Vector2 } from 'three';
+import {
+ Euler,
+ Group,
+ Mesh,
+ MeshStandardMaterial,
+ Object3D,
+ Vector2,
+} from 'three';
+import { ArmorHighlightMaterial } from '../../../../../../../../../components/ArmorHighlightMaterial';
import { resolveJsxTree } from '../../../../../../../../../core/blitzkrieg/resolveJsxTree';
import { normalizeAnglePI } from '../../../../../../../../../core/math/normalizeAngle180';
interface HullContainerProps {
children: ReactNode;
yaw: number;
- objects: Object3D[];
+ modelObjects: Object3D[];
+ armorObjects: Object3D[];
onYawStart: () => void;
onYawEnd: (yaw: number) => void;
onTrackStart: () => void;
@@ -16,17 +25,27 @@ interface HullContainerProps {
export const HullContainer = forwardRef(
(
- { children, yaw, objects, onYawStart, onYawEnd, onTrackEnd, onTrackStart },
+ {
+ children,
+ yaw,
+ armorObjects,
+ modelObjects,
+ onYawStart,
+ onYawEnd,
+ onTrackEnd,
+ onTrackStart,
+ },
ref,
) => {
const canvas = useThree((state) => state.gl.domElement);
const hullContainer = useRef(null);
+ const rotation = [-Math.PI / 2, 0, yaw] as unknown as Euler;
useImperativeHandle(ref, () => hullContainer.current!);
return (
-
- {objects.map((object) => {
+
+ {modelObjects.map((object) => {
const isHull = object.name === 'hull';
const isWheel = object.name.startsWith('chassis_wheel_');
const isTrack = object.name.startsWith('chassis_track_');
@@ -96,6 +115,19 @@ export const HullContainer = forwardRef(
);
})}
+ {armorObjects.map((object) => {
+ const isHull = object.name.startsWith('hull_');
+ const isVisible = isHull;
+
+ if (!isVisible) return null;
+
+ return (
+
+
+
+ );
+ })}
+
{children}
);
diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/components/TurretContainer.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/components/TurretContainer.tsx
index 1c55c4e78..41e43ba57 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/components/TurretContainer.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/components/TurretContainer.tsx
@@ -7,6 +7,7 @@ import {
useRef,
} from 'react';
import { Euler, Group, Mesh, Object3D, Vector3 } from 'three';
+import { ArmorHighlightMaterial } from '../../../../../../../../../components/ArmorHighlightMaterial';
import { applyPitchYawLimits } from '../../../../../../../../../core/blitz/applyPitchYawLimits';
import {
InitialTurretRotation,
@@ -19,7 +20,8 @@ import { normalizeAnglePI } from '../../../../../../../../../core/math/normalize
interface TurretContainerProps {
turretOrigin: Vector3;
gunOrigin: Vector3;
- objects: Object3D[];
+ modelObjects: Object3D[];
+ armorObjects: Object3D[];
children: ReactNode;
yaw: number;
pitch: number;
@@ -39,12 +41,13 @@ export const TurretContainer = forwardRef(
turretOrigin,
yaw,
children,
- objects,
+ modelObjects,
yawLimits,
model,
onYawEnd,
pitch,
gunOrigin,
+ armorObjects,
pitchLimits,
onYawStart,
initialTurretRotation,
@@ -78,7 +81,7 @@ export const TurretContainer = forwardRef(
return (
- {objects.map((object) => {
+ {modelObjects.map((object) => {
const isTurret = object.name.startsWith('turret_');
const isCurrentTurret =
object.name === `turret_${model.toString().padStart(2, '0')}`;
@@ -162,6 +165,25 @@ export const TurretContainer = forwardRef(
);
})}
+ {armorObjects.map((object) => {
+ const isCurrentTurret = object.name.startsWith(
+ `turret_${model.toString().padStart(2, '0')}`,
+ );
+ const isVisible = isCurrentTurret;
+
+ if (!isVisible) return null;
+
+ return (
+
+
+
+ );
+ })}
+
{children}
);
diff --git a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/index.tsx b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/index.tsx
index 427bf1ebf..e5cb06b57 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/index.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/components/TankModel/index.tsx
@@ -34,10 +34,14 @@ export const TankModel = forwardRef((_props, ref) => {
if (!protagonist) return null;
- const gltf = useLoader(
+ const modelGltf = useLoader(
GLTFLoader,
asset(`3d/tanks/models/${protagonist.tank.id}.glb`),
);
+ const armorGltf = useLoader(
+ GLTFLoader,
+ asset(`3d/tanks/armor/${protagonist.tank.id}.glb`),
+ );
const model = useTankopedia((state) => state.model);
const hullContainer = useRef(null);
const turretContainer = useRef(null);
@@ -69,7 +73,8 @@ export const TankModel = forwardRef((_props, ref) => {
return (
@@ -95,10 +100,11 @@ export const TankModel = forwardRef((_props, ref) => {
}}
>
mutateTankopedia((state) => {
@@ -121,6 +127,7 @@ export const TankModel = forwardRef((_props, ref) => {
>
{
mutateTankopedia((state) => {
@@ -141,7 +148,7 @@ export const TankModel = forwardRef((_props, ref) => {
gunOrigin={gunOrigin}
pitch={model.gunPitch}
model={gunModelDefinition.model}
- objects={Object.values(gltf.nodes)}
+ modelObjects={Object.values(modelGltf.nodes)}
turretOrigin={turretOrigin}
/>
diff --git a/src/app/tools/tankopedia/[id]/components/SceneProps.tsx b/src/app/tools/tankopedia/[id]/components/SceneProps.tsx
index b5d183ae8..f27f34c4c 100644
--- a/src/app/tools/tankopedia/[id]/components/SceneProps.tsx
+++ b/src/app/tools/tankopedia/[id]/components/SceneProps.tsx
@@ -5,39 +5,23 @@ import { useTankopedia } from '../../../../../stores/tankopedia';
export function SceneProps() {
const showGrid = useTankopedia((state) => state.model.showGrid);
+ if (!showGrid) return null;
+
return (
<>
- {showGrid && (
- <>
-
-
- >
- )}
-
-
-
-
>
);
}
diff --git a/src/components/ArmorHighlightMaterial.tsx b/src/components/ArmorHighlightMaterial.tsx
new file mode 100644
index 000000000..c7772ee37
--- /dev/null
+++ b/src/components/ArmorHighlightMaterial.tsx
@@ -0,0 +1,42 @@
+import { GreaterEqualDepth } from 'three';
+
+const INFLATE = '0.0';
+
+export function ArmorHighlightMaterial() {
+ return (
+
+ );
+}