mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
feat: gun limits
This commit is contained in:
1 parent
9bd26ef3bf
commit
d543e42268
5 files changed
+103
-34
No files matched your search
Binary file not shown.
@@ -533,7 +533,7 @@ if (allTargets || targets?.includes('tankModels')) {
|
|||||||
// if (id !== 1) continue; // t-34
|
// if (id !== 1) continue; // t-34
|
||||||
// if (id !== 6753) continue; // type 71
|
// if (id !== 6753) continue; // type 71
|
||||||
// if (id !== 5137) continue; // tiger ii
|
// if (id !== 5137) continue; // tiger ii
|
||||||
if (id !== 11633) continue; // tiger ii
|
if (id !== 11633) continue; // forest witch
|
||||||
// if (id !== 6225) continue; // fv215b
|
// if (id !== 6225) continue; // fv215b
|
||||||
|
|
||||||
console.log(`Building model ${id} @ ${nation}/${tankIndex}`);
|
console.log(`Building model ${id} @ ${nation}/${tankIndex}`);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
} from '@radix-ui/themes';
|
} from '@radix-ui/themes';
|
||||||
import { Canvas, ThreeEvent, useLoader } from '@react-three/fiber';
|
import { Canvas, ThreeEvent, useLoader } from '@react-three/fiber';
|
||||||
import { go } from 'fuzzysort';
|
import { go } from 'fuzzysort';
|
||||||
import { debounce } from 'lodash';
|
import { clamp, debounce } from 'lodash';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { use, useEffect, useRef, useState } from 'react';
|
import { use, useEffect, useRef, useState } from 'react';
|
||||||
import { Color, Group, Mesh, Vector3 } from 'three';
|
import { Color, Group, Mesh, Vector3 } from 'three';
|
||||||
@@ -67,9 +67,14 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
tank.turretOrigin[1],
|
tank.turretOrigin[1],
|
||||||
-tank.turretOrigin[2],
|
-tank.turretOrigin[2],
|
||||||
).applyAxisAngle(new Vector3(1, 0, 0), Math.PI / 2);
|
).applyAxisAngle(new Vector3(1, 0, 0), Math.PI / 2);
|
||||||
const gunOrigin = new Vector3(...turret.gunOrigin);
|
const gunOrigin = new Vector3(
|
||||||
const [turretRotation, setTurretRotation] = useState(0);
|
turret.gunOrigin[0],
|
||||||
const [hullRotation, setHullRotation] = useState(0);
|
turret.gunOrigin[1],
|
||||||
|
-turret.gunOrigin[2],
|
||||||
|
).applyAxisAngle(new Vector3(1, 0, 0), Math.PI / 2);
|
||||||
|
const [turretYaw, setTurretYaw] = useState(0);
|
||||||
|
const [hullYaw, setHullYaw] = useState(0);
|
||||||
|
const [mantletPitch, setMantletPitch] = useState(0);
|
||||||
const [orbitControlsEnabled, setOrbitControlsEnabled] = useState(true);
|
const [orbitControlsEnabled, setOrbitControlsEnabled] = useState(true);
|
||||||
const turretRotationInput = useRef<HTMLInputElement>(null);
|
const turretRotationInput = useRef<HTMLInputElement>(null);
|
||||||
const hullRotationInput = useRef<HTMLInputElement>(null);
|
const hullRotationInput = useRef<HTMLInputElement>(null);
|
||||||
@@ -93,14 +98,19 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
}, [versusTurret]);
|
}, [versusTurret]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
turretRotationInput.current!.value = `${Math.round(
|
turretRotationInput.current!.value = `${Math.round(
|
||||||
turretRotation * (180 / Math.PI),
|
turretYaw * (180 / Math.PI),
|
||||||
)}`;
|
)}`;
|
||||||
}, [turretRotation]);
|
}, [turretYaw]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
hullRotationInput.current!.value = `${Math.round(
|
hullRotationInput.current!.value = `${Math.round(
|
||||||
hullRotation * (180 / Math.PI),
|
hullYaw * (180 / Math.PI),
|
||||||
)}`;
|
)}`;
|
||||||
});
|
}, [hullYaw]);
|
||||||
|
useEffect(() => {
|
||||||
|
gunRotationInput.current!.value = `${Math.round(
|
||||||
|
mantletPitch * (180 / Math.PI),
|
||||||
|
)}`;
|
||||||
|
}, [mantletPitch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageWrapper color="purple">
|
<PageWrapper color="purple">
|
||||||
@@ -173,7 +183,7 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
|
|
||||||
<group
|
<group
|
||||||
ref={hullContainer}
|
ref={hullContainer}
|
||||||
rotation={[-Math.PI / 2, 0, hullRotation]}
|
rotation={[-Math.PI / 2, 0, hullYaw]}
|
||||||
>
|
>
|
||||||
{gltf.scene.children[0].children.map((child) => {
|
{gltf.scene.children[0].children.map((child) => {
|
||||||
const isHull = child.name === 'hull';
|
const isHull = child.name === 'hull';
|
||||||
@@ -188,7 +198,7 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
if (isHull) {
|
if (isHull) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
draftTurretRotation = hullRotation;
|
draftTurretRotation = hullYaw;
|
||||||
|
|
||||||
setOrbitControlsEnabled(false);
|
setOrbitControlsEnabled(false);
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
@@ -214,7 +224,7 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
}
|
}
|
||||||
function handlePointerUp(event: PointerEvent) {
|
function handlePointerUp(event: PointerEvent) {
|
||||||
setOrbitControlsEnabled(true);
|
setOrbitControlsEnabled(true);
|
||||||
setHullRotation(normalizeAngle180(draftTurretRotation));
|
setHullYaw(normalizeAngle180(draftTurretRotation));
|
||||||
|
|
||||||
window.removeEventListener(
|
window.removeEventListener(
|
||||||
'pointermove',
|
'pointermove',
|
||||||
@@ -246,9 +256,9 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
<group
|
<group
|
||||||
position={new Vector3()
|
position={new Vector3()
|
||||||
.sub(turretOrigin)
|
.sub(turretOrigin)
|
||||||
.applyAxisAngle(new Vector3(0, 0, 1), turretRotation)
|
.applyAxisAngle(new Vector3(0, 0, 1), turretYaw)
|
||||||
.add(turretOrigin)}
|
.add(turretOrigin)}
|
||||||
rotation={[0, 0, turretRotation]}
|
rotation={[0, 0, turretYaw]}
|
||||||
ref={turretContainer}
|
ref={turretContainer}
|
||||||
>
|
>
|
||||||
{gltf.scene.children[0].children.map((child) => {
|
{gltf.scene.children[0].children.map((child) => {
|
||||||
@@ -270,7 +280,7 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
if (isTurret) {
|
if (isTurret) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
draftTurretRotation = turretRotation;
|
draftTurretRotation = turretYaw;
|
||||||
|
|
||||||
setOrbitControlsEnabled(false);
|
setOrbitControlsEnabled(false);
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
@@ -303,9 +313,7 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
}
|
}
|
||||||
function handlePointerUp(event: PointerEvent) {
|
function handlePointerUp(event: PointerEvent) {
|
||||||
setOrbitControlsEnabled(true);
|
setOrbitControlsEnabled(true);
|
||||||
setTurretRotation(
|
setTurretYaw(normalizeAngle180(draftTurretRotation));
|
||||||
normalizeAngle180(draftTurretRotation),
|
|
||||||
);
|
|
||||||
|
|
||||||
window.removeEventListener(
|
window.removeEventListener(
|
||||||
'pointermove',
|
'pointermove',
|
||||||
@@ -335,11 +343,13 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
})}
|
})}
|
||||||
|
|
||||||
<group
|
<group
|
||||||
// position={new Vector3()
|
position={new Vector3()
|
||||||
// .sub(turretOrigin)
|
.sub(turretOrigin)
|
||||||
// .applyAxisAngle(new Vector3(0, 0, 1), turretRotation)
|
.sub(gunOrigin)
|
||||||
// .add(turretOrigin)}
|
.applyAxisAngle(new Vector3(1, 0, 0), mantletPitch)
|
||||||
// rotation={[0, 0, turretRotation]}
|
.add(turretOrigin)
|
||||||
|
.add(gunOrigin)}
|
||||||
|
rotation={[mantletPitch, 0, 0]}
|
||||||
ref={mantletContainer}
|
ref={mantletContainer}
|
||||||
>
|
>
|
||||||
{gltf.scene.children[0].children.map((child) => {
|
{gltf.scene.children[0].children.map((child) => {
|
||||||
@@ -365,7 +375,7 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
) {
|
) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
draftMantletPitch = turretRotation;
|
draftMantletPitch = mantletPitch;
|
||||||
|
|
||||||
setOrbitControlsEnabled(false);
|
setOrbitControlsEnabled(false);
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
@@ -385,11 +395,22 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
(2 * Math.PI) / canvas.current!.width;
|
(2 * Math.PI) / canvas.current!.width;
|
||||||
const delta = -event.movementY * rotationSpeed;
|
const delta = -event.movementY * rotationSpeed;
|
||||||
draftMantletPitch += delta;
|
draftMantletPitch += delta;
|
||||||
|
draftMantletPitch = clamp(
|
||||||
|
draftMantletPitch,
|
||||||
|
-gun.pitch[1] * (Math.PI / 180),
|
||||||
|
-gun.pitch[0] * (Math.PI / 180),
|
||||||
|
);
|
||||||
|
|
||||||
if (mantletContainer.current) {
|
if (mantletContainer.current) {
|
||||||
mantletContainer.current.position
|
mantletContainer.current.position
|
||||||
|
.set(0, 0, 0)
|
||||||
|
.sub(turretOrigin)
|
||||||
.sub(gunOrigin)
|
.sub(gunOrigin)
|
||||||
.applyAxisAngle(new Vector3(1, 0, 0), delta)
|
.applyAxisAngle(
|
||||||
|
new Vector3(1, 0, 0),
|
||||||
|
draftMantletPitch,
|
||||||
|
)
|
||||||
|
.add(turretOrigin)
|
||||||
.add(gunOrigin);
|
.add(gunOrigin);
|
||||||
mantletContainer.current.rotation.x =
|
mantletContainer.current.rotation.x =
|
||||||
draftMantletPitch;
|
draftMantletPitch;
|
||||||
@@ -397,7 +418,7 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
}
|
}
|
||||||
function handlePointerUp(event: PointerEvent) {
|
function handlePointerUp(event: PointerEvent) {
|
||||||
setOrbitControlsEnabled(true);
|
setOrbitControlsEnabled(true);
|
||||||
setTurretRotation(
|
setMantletPitch(
|
||||||
normalizeAngle180(draftMantletPitch),
|
normalizeAngle180(draftMantletPitch),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -458,7 +479,7 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
<TextField.Slot>Hull</TextField.Slot>
|
<TextField.Slot>Hull</TextField.Slot>
|
||||||
<TextField.Input
|
<TextField.Input
|
||||||
onBlur={() => {
|
onBlur={() => {
|
||||||
setHullRotation(
|
setHullYaw(
|
||||||
normalizeAngle180(
|
normalizeAngle180(
|
||||||
Number(hullRotationInput.current?.value) *
|
Number(hullRotationInput.current?.value) *
|
||||||
(Math.PI / 180),
|
(Math.PI / 180),
|
||||||
@@ -485,7 +506,7 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
<TextField.Slot>Turret</TextField.Slot>
|
<TextField.Slot>Turret</TextField.Slot>
|
||||||
<TextField.Input
|
<TextField.Input
|
||||||
onBlur={() => {
|
onBlur={() => {
|
||||||
setTurretRotation(
|
setTurretYaw(
|
||||||
normalizeAngle180(
|
normalizeAngle180(
|
||||||
Number(turretRotationInput.current?.value) *
|
Number(turretRotationInput.current?.value) *
|
||||||
(Math.PI / 180),
|
(Math.PI / 180),
|
||||||
@@ -511,8 +532,24 @@ export default function Page({ params }: { params: { id: string } }) {
|
|||||||
>
|
>
|
||||||
<TextField.Slot>Gun</TextField.Slot>
|
<TextField.Slot>Gun</TextField.Slot>
|
||||||
<TextField.Input
|
<TextField.Input
|
||||||
|
onBlur={() => {
|
||||||
|
setMantletPitch(
|
||||||
|
clamp(
|
||||||
|
normalizeAngle180(
|
||||||
|
Number(gunRotationInput.current?.value) *
|
||||||
|
(Math.PI / 180),
|
||||||
|
),
|
||||||
|
-gun.pitch[1] * (Math.PI / 180),
|
||||||
|
-gun.pitch[0] * (Math.PI / 180),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
gunRotationInput.current?.blur();
|
||||||
|
}
|
||||||
|
}}
|
||||||
ref={gunRotationInput}
|
ref={gunRotationInput}
|
||||||
value={0}
|
|
||||||
style={{ textAlign: 'right' }}
|
style={{ textAlign: 'right' }}
|
||||||
/>
|
/>
|
||||||
<TextField.Slot>°</TextField.Slot>
|
<TextField.Slot>°</TextField.Slot>
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ import { ScgStream, vertexAttributeVectorSizes } from '../streams/scg';
|
|||||||
import { VertexAttribute } from '../streams/scpg';
|
import { VertexAttribute } from '../streams/scpg';
|
||||||
import { readDVPLFile } from './readDVPLFile';
|
import { readDVPLFile } from './readDVPLFile';
|
||||||
|
|
||||||
BigInt.prototype.toJSON = function () {
|
// BigInt.prototype.toJSON = function () {
|
||||||
return this.toString();
|
// return this.toString();
|
||||||
};
|
// };
|
||||||
|
|
||||||
const MAX_FLOAT32 = 2 ** 127 * (2 - 2 ** -23);
|
const MAX_FLOAT32 = 2 ** 127 * (2 - 2 ** -23);
|
||||||
|
|
||||||
@@ -175,11 +175,11 @@ export async function extractModel(
|
|||||||
case 'ActionComponent':
|
case 'ActionComponent':
|
||||||
case 'ParticleEffectComponent':
|
case 'ParticleEffectComponent':
|
||||||
case 'SlotComponent':
|
case 'SlotComponent':
|
||||||
|
case 'MotionComponent':
|
||||||
case 'TankElementComponent':
|
case 'TankElementComponent':
|
||||||
|
case 'SkeletonComponent':
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// console.log(JSON.stringify(component, null, 2));
|
|
||||||
|
|
||||||
case 'TransformComponent': {
|
case 'TransformComponent': {
|
||||||
const translation = new Vector3();
|
const translation = new Vector3();
|
||||||
const rotation = new Quaternion();
|
const rotation = new Quaternion();
|
||||||
|
|||||||
@@ -232,6 +232,38 @@ export type Component =
|
|||||||
isDestructible: boolean;
|
isDestructible: boolean;
|
||||||
shouldCastShadow: boolean;
|
shouldCastShadow: boolean;
|
||||||
shouldGenerateSilhouette: boolean;
|
shouldGenerateSilhouette: boolean;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
'comp.typename': 'MotionComponent';
|
||||||
|
'motion.filepath': string;
|
||||||
|
'motion.playbackRate': number;
|
||||||
|
'simpleMotion.repeatsCount': number;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
'comp.typename': 'SkeletonComponent';
|
||||||
|
joints: Record<
|
||||||
|
string, // 0000, 0001, ...
|
||||||
|
{
|
||||||
|
'joint.bbox.max': Vector3Tuple;
|
||||||
|
'joint.bbox.min': Vector3Tuple;
|
||||||
|
'joint.bindPose': [
|
||||||
|
Vector4Tuple,
|
||||||
|
Vector4Tuple,
|
||||||
|
Vector4Tuple,
|
||||||
|
Vector4Tuple,
|
||||||
|
];
|
||||||
|
'joint.invBindPose': [
|
||||||
|
Vector4Tuple,
|
||||||
|
Vector4Tuple,
|
||||||
|
Vector4Tuple,
|
||||||
|
Vector4Tuple,
|
||||||
|
];
|
||||||
|
'joint.name': string;
|
||||||
|
'joint.parentIndex': number;
|
||||||
|
'joint.uid': string;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
jointsCount: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface SceneComponents {
|
interface SceneComponents {
|
||||||
|
|||||||
Reference in new issue
Block a user