feat: more progress

This commit is contained in:
TrèsAbhi committed 2024-02-28 23:06:37 -06:00
1 parent f55313e0cd
commit 7f49245f15
4 files changed
+95 -67

No files matched your search

@@ -1,6 +1,6 @@
import { Text } from '@radix-ui/themes';
import { Html } from '@react-three/drei';
import { DoubleSide, Euler, Quaternion, Vector3 } from 'three';
import { Euler, Quaternion, Vector3 } from 'three';
import { J_HAT } from '../../../constants/axis';
import {
ShotLayerGap,
@@ -22,7 +22,7 @@ import {
// const THICKNESS = 0.05;
// const LENGTH = 4;
export function ShotScene() {
export function ShotDisplay() {
const shot = useTankopediaTemporary((state) => state.shot);
return (
@@ -39,28 +39,39 @@ export function ShotScene() {
return (
<>
<mesh renderOrder={1} key={`${index}-point`} position={layer.point}>
<icosahedronGeometry args={[1 / 16, 1]} />
<meshBasicMaterial
side={DoubleSide}
color={
layer.status === 'penetration'
? 0x00ff00
: layer.status === 'blocked'
? 0xff0000
: 0xffff00
}
/>
</mesh>
<group
key={`${index}-line`}
position={layer.point}
rotation={shellRotation}
>
{shot.length > 1 && (
<Html>
<Text>{layer.index + 1}</Text>
<Html center>
<div
style={{
width: 12,
height: 12,
borderRadius: '100%',
position: 'relative',
backgroundColor:
layer.status === 'penetration'
? '#00ff00'
: layer.status === 'blocked'
? '#ff0000'
: '#ffff00',
}}
>
<Text
style={{
position: 'absolute',
left: '100%',
top: '50%',
transform: 'translateY(-50%)',
marginLeft: 8,
}}
>
{layer.index + 1}
</Text>
</div>
</Html>
)}
@@ -73,9 +84,9 @@ export function ShotScene() {
}
return (
<mesh position={[0, length / 2, 0]} renderOrder={0}>
<mesh position={[0, length / 2, 0]}>
<cylinderGeometry args={[1 / 64, 1 / 64, length]} />
<meshBasicMaterial color={0xffffff} />
<meshBasicMaterial color={0xffffff} depthTest={false} />
</mesh>
);
})()}
@@ -8,13 +8,17 @@ import {
Scene,
Vector3,
} from 'three';
import { degToRad, radToDeg } from 'three/src/math/MathUtils';
import { degToRad } from 'three/src/math/MathUtils';
import { isExplosive } from '../../../../core/blitz/isExplosive';
import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration';
import { hasEquipment } from '../../../../core/blitzkrieg/hasEquipment';
import { jsxTree } from '../../../../core/blitzkrieg/jsxTree';
import { useDuel } from '../../../../stores/duel';
import { Shot, useTankopediaTemporary } from '../../../../stores/tankopedia';
import {
Shot,
ShotLayerBase,
useTankopediaTemporary,
} from '../../../../stores/tankopedia';
import { ArmorType } from '../SpacedArmorScene';
import { SpacedArmorSubExternal } from './components/SpacedArmorSubExternal';
import { SpacedArmorSubSpaced } from './components/SpacedArmorSubSpaced';
@@ -68,7 +72,7 @@ export function SpacedArmorSceneComponent({
...props
}: SpacedArmorSceneComponentProps) {
const camera = useThree((state) => state.camera);
const cameraNormal = new Vector3();
// const cameraNormal = new Vector3();
return (
<>
@@ -104,26 +108,26 @@ export function SpacedArmorSceneComponent({
.clone()
.sub(event.point)
.normalize();
shellNormal
.copy(camera.getWorldDirection(cameraNormal))
.multiplyScalar(-1);
const cameraNormal = shellNormal.clone().multiplyScalar(-1);
pushLogs(
shellNormal,
cameraNormal,
filterIntersections(event.intersections),
true,
0,
);
console.clear();
console.log(
JSON.stringify(
shot.map((i) => ({
...i,
...(i.angle ? { angle: radToDeg(i.angle) } : {}),
})),
null,
2,
),
);
// console.clear();
// console.log(
// JSON.stringify(
// shot.map((i) => ({
// ...i,
// ...(i.angle ? { angle: radToDeg(i.angle) } : {}),
// })),
// null,
// 2,
// ),
// );
function filterIntersections(intersectionsRaw: Intersection[]) {
const intersectionsAll = intersectionsRaw.filter(
@@ -166,15 +170,35 @@ export function SpacedArmorSceneComponent({
});
}
console.log(
JSON.stringify(
intersections.map((i) => i.object.userData),
null,
2,
),
);
return intersections;
}
function pushLogs(
shellNormal: Vector3,
cameraNormal: Vector3,
intersections: ArmorMeshIntersection[],
allowRicochets: boolean,
startingIndex: number,
) {
let index = 0;
let layerIndex = startingIndex;
let loopIndex = 0;
if (layerIndex !== 0) {
shot.push({
type: null,
distance: (shot.at(-1) as ShotLayerBase).point.distanceTo(
intersections[0].point,
),
});
}
for (const intersection of intersections) {
const surfaceNormal = intersection
.normal!.clone()
@@ -184,8 +208,8 @@ export function SpacedArmorSceneComponent({
const thickness =
thicknessCoefficient * intersection.object.userData.thickness;
if (index !== 0) {
const previousIntersection = intersections[index - 1];
if (layerIndex !== 0 && startingIndex === 0) {
const previousIntersection = intersections[layerIndex - 1];
shot.push({
type: null,
distance:
@@ -199,7 +223,7 @@ export function SpacedArmorSceneComponent({
shot.push({
type: ArmorType.External,
index,
index: layerIndex,
shellNormal,
surfaceNormal,
point: intersection.point,
@@ -210,19 +234,11 @@ export function SpacedArmorSceneComponent({
if (blocked) break;
} else {
const type = intersection.object.userData.type;
shellNormal.copy(
cameraNormal
.copy(camera.position)
.sub(event.point)
.normalize(),
);
const angle = surfaceNormal.angleTo(shellNormal);
const ricochet = degToRad(shell.ricochet ?? 90);
const normalization = degToRad(shell.normalization ?? 0);
const threeCalibersRule =
shell.caliber > thickness * 3 ||
index > 0 ||
!allowRicochets;
shell.caliber > thickness * 3 || layerIndex > 0;
const twoCalibersRule = shell.caliber > thickness * 2;
const finalNormalization = twoCalibersRule
? (1.4 * normalization * shell.caliber) / (2.0 * thickness)
@@ -234,7 +250,7 @@ export function SpacedArmorSceneComponent({
if (!threeCalibersRule && angle >= ricochet) {
shot.push({
type,
index,
index: layerIndex,
shellNormal,
surfaceNormal,
point: intersection.point,
@@ -245,15 +261,21 @@ export function SpacedArmorSceneComponent({
});
const raycaster = new Raycaster();
const newShellNormal = cameraNormal
const newShellNormal = shellNormal
.clone()
.reflect(surfaceNormal);
const newCameraNormal = newShellNormal
.clone()
.multiplyScalar(-1);
raycaster.set(intersection.point, newShellNormal);
raycaster.set(intersection.point, newCameraNormal);
pushLogs(
newShellNormal,
raycaster.intersectObjects(scene.children, true),
false,
newCameraNormal,
filterIntersections(
raycaster.intersectObjects(scene.children, true),
),
layerIndex + 1,
);
break;
@@ -261,7 +283,7 @@ export function SpacedArmorSceneComponent({
const blocked = remainingPenetration < 0;
shot.push({
type,
index,
index: layerIndex,
shellNormal,
surfaceNormal,
point: intersection.point,
@@ -273,7 +295,8 @@ export function SpacedArmorSceneComponent({
}
}
index++;
layerIndex++;
loopIndex++;
}
}
-7
View File
@@ -3,19 +3,16 @@ import { memo, useState } from 'react';
import { DepthTexture, Scene, Vector2 } from 'three';
import { CoreArmorScene } from './components/CoreArmorScene';
import { spacedArmorRenderTarget } from './components/CoreArmorSceneComponent';
import { ShotScene } from './components/ShotScene';
import { SpacedArmorScene } from './components/SpacedArmorScene';
export const Armor = memo(() => {
const [spacedArmorScene] = useState(() => new Scene());
const [coreArmorScene] = useState(() => new Scene());
const [shotScene] = useState(() => new Scene());
const spacedArmorPortal = createPortal(
<SpacedArmorScene scene={spacedArmorScene} />,
spacedArmorScene,
);
const coreArmorPortal = createPortal(<CoreArmorScene />, coreArmorScene);
const shotPortal = createPortal(<ShotScene />, shotScene);
const renderSize = new Vector2();
const newRenderSize = new Vector2();
@@ -44,16 +41,12 @@ export const Armor = memo(() => {
gl.clearDepth();
gl.render(coreArmorScene, camera);
gl.clearDepth();
gl.render(shotScene, camera);
}, 1);
return (
<>
{spacedArmorPortal}
{coreArmorPortal}
{shotPortal}
</>
);
});