mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
feat: use armor model
This commit is contained in:
1 parent
3846cbab4a
commit
69f3a95379
4 files changed
+93
-36
No files matched your search
Vendored
+1
@@ -167,6 +167,7 @@
|
||||
"searchtanks",
|
||||
"SHAREDEXP",
|
||||
"SKLLD",
|
||||
"smoothstep",
|
||||
"Smri",
|
||||
"Specularity",
|
||||
"SSAO",
|
||||
|
||||
@@ -77,7 +77,9 @@ export class Varuna<Type, Arguments = void> {
|
||||
}
|
||||
|
||||
private assertInitialized() {
|
||||
if (!this.initialized) throw new Error("State used before initialization");
|
||||
if (!this.initialized) {
|
||||
throw new Error("Varuna store used before initialization");
|
||||
}
|
||||
}
|
||||
|
||||
get state() {
|
||||
|
||||
+88
-34
@@ -1,11 +1,12 @@
|
||||
import { useRef } from "react";
|
||||
import { Group, ShaderMaterial, UniformsLib, UniformsUtils } from "three";
|
||||
import { correctZYTuple } from "../../../../../../../core/blitz/correctZYTuple";
|
||||
import { jsxTree } from "../../../../../../../core/blitzkit/jsxTree";
|
||||
import { useArmor } from "../../../../../../../hooks/useArmor";
|
||||
import { useModel } from "../../../../../../../hooks/useModel";
|
||||
import { useTankModelDefinition } from "../../../../../../../hooks/useTankModelDefinition";
|
||||
import { useTankTransform } from "../../../../../../../hooks/useTankTransform";
|
||||
import { Duel } from "../../../../../../../stores/duel";
|
||||
import { Tankopedia } from "../../../../../../../stores/tankopedia";
|
||||
import { ModelTankWrapper } from "../../../../../../Armor/components/ModelTankWrapper";
|
||||
import fragmentShader from "./shaders/fragment.glsl?raw";
|
||||
import vertexShader from "./shaders/vertex.glsl?raw";
|
||||
@@ -21,29 +22,48 @@ const skeletonMaterial = new ShaderMaterial({
|
||||
});
|
||||
|
||||
export function TransitionSkeleton() {
|
||||
const protagonist = Duel.use((draft) => draft.protagonist);
|
||||
const tank = Duel.use((state) => state.protagonist.tank);
|
||||
const gun = Duel.use((state) => state.protagonist.gun);
|
||||
const track = Duel.use((state) => state.protagonist.track);
|
||||
const turret = Duel.use((state) => state.protagonist.turret);
|
||||
const hullContainer = useRef<Group>(null);
|
||||
const turretContainer = useRef<Group>(null);
|
||||
const gunContainer = useRef<Group>(null);
|
||||
const { gltf: armorGltf } = useArmor(tank.id);
|
||||
const { gltf: modelGltf } = useModel(tank.id);
|
||||
const modelNodes = Object.values(modelGltf.nodes);
|
||||
const armorNodes = Object.values(armorGltf.nodes);
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const turretModelDefinition =
|
||||
tankModelDefinition.turrets[protagonist.turret.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id];
|
||||
const { gltf } = useModel(protagonist.tank.id);
|
||||
const nodes = Object.values(gltf.nodes);
|
||||
const revealed = Tankopedia.use((state) => state.revealed);
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
||||
const wrapper = useRef<Group>(null);
|
||||
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
|
||||
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
|
||||
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
|
||||
|
||||
useTankTransform(track, turret, turretContainer, gunContainer);
|
||||
|
||||
return (
|
||||
<ModelTankWrapper ref={hullContainer} visible={revealed}>
|
||||
{nodes.map((node) => {
|
||||
const isHull = node.name === "hull";
|
||||
<ModelTankWrapper ref={wrapper}>
|
||||
<group position={hullOrigin}>
|
||||
{armorNodes.map((node) => {
|
||||
const isHull = node.name.startsWith("hull_");
|
||||
const isVisible = isHull;
|
||||
|
||||
if (!isVisible) return null;
|
||||
|
||||
return jsxTree(node, {
|
||||
mesh(_, props, key) {
|
||||
return <mesh {...props} key={key} material={skeletonMaterial} />;
|
||||
},
|
||||
});
|
||||
})}
|
||||
</group>
|
||||
|
||||
{modelNodes.map((node) => {
|
||||
const isWheel = node.name.startsWith("chassis_wheel_");
|
||||
const isTrack = node.name.startsWith("chassis_track_");
|
||||
const isVisible = isHull || isWheel || isTrack;
|
||||
const isVisible = isWheel || isTrack;
|
||||
|
||||
if (!isVisible) return null;
|
||||
|
||||
@@ -55,32 +75,66 @@ export function TransitionSkeleton() {
|
||||
})}
|
||||
|
||||
<group ref={turretContainer}>
|
||||
{nodes.map((node) => {
|
||||
const isCurrentTurret =
|
||||
node.name ===
|
||||
`turret_${turretModelDefinition.model_id.toString().padStart(2, "0")}`;
|
||||
{armorNodes.map((node) => {
|
||||
const isCurrentTurret = node.name.startsWith(
|
||||
`turret_${turretModelDefinition.model_id.toString().padStart(2, "0")}`
|
||||
);
|
||||
const isVisible = isCurrentTurret;
|
||||
if (!isVisible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isVisible) return null;
|
||||
|
||||
return jsxTree(node, {
|
||||
mesh(_, props, key) {
|
||||
return <mesh {...props} key={key} material={skeletonMaterial} />;
|
||||
},
|
||||
});
|
||||
return (
|
||||
<group key={node.uuid} position={hullOrigin}>
|
||||
<group position={turretOrigin}>
|
||||
{jsxTree(node, {
|
||||
mesh(_, props, key) {
|
||||
return (
|
||||
<mesh {...props} key={key} material={skeletonMaterial} />
|
||||
);
|
||||
},
|
||||
})}
|
||||
</group>
|
||||
</group>
|
||||
);
|
||||
})}
|
||||
|
||||
<group ref={gunContainer}>
|
||||
{nodes.map((node) => {
|
||||
const isCurrentMantlet =
|
||||
node.name ===
|
||||
`gun_${gunModelDefinition.model_id
|
||||
.toString()
|
||||
.padStart(2, "0")}_mask`;
|
||||
const isCurrentGun =
|
||||
node.name ===
|
||||
`gun_${gunModelDefinition.model_id.toString().padStart(2, "0")}`;
|
||||
const isVisible = isCurrentGun || isCurrentMantlet;
|
||||
{armorNodes.map((node) => {
|
||||
const isCurrentGun = node.name.startsWith(
|
||||
`gun_${gunModelDefinition.model_id.toString().padStart(2, "0")}`
|
||||
);
|
||||
const isVisible = isCurrentGun;
|
||||
|
||||
if (!isVisible) return null;
|
||||
|
||||
return (
|
||||
<group key={node.uuid} position={hullOrigin}>
|
||||
<group position={turretOrigin.clone().add(gunOrigin)}>
|
||||
{jsxTree(node, {
|
||||
mesh(_, props, key) {
|
||||
return (
|
||||
<mesh
|
||||
{...props}
|
||||
key={key}
|
||||
material={skeletonMaterial}
|
||||
/>
|
||||
);
|
||||
},
|
||||
})}
|
||||
</group>
|
||||
</group>
|
||||
);
|
||||
})}
|
||||
|
||||
{modelNodes.map((node) => {
|
||||
const gunString = `gun_${gunModelDefinition.model_id
|
||||
.toString()
|
||||
.padStart(2, "0")}`;
|
||||
const isCurrentGun = gunModelDefinition.mask
|
||||
? node.name.startsWith(gunString)
|
||||
: node.name === gunString;
|
||||
const isVisible = isCurrentGun;
|
||||
|
||||
if (!isVisible) return null;
|
||||
|
||||
|
||||
+1
-1
@@ -7,5 +7,5 @@ precision mediump float;
|
||||
void main() {
|
||||
float fogFactor = smoothstep(fogNear, fogFar, vFogDepth);
|
||||
gl_FragColor = vec4(0.5, 0.5, 0.5, fogFactor);
|
||||
gl_FragColor.rgb = mix(gl_FragColor.rgb, fogColor, 1.0 - fogFactor);
|
||||
gl_FragColor.rgb = mix(fogColor, gl_FragColor.rgb, fogFactor);
|
||||
}
|
||||
Reference in new issue
Block a user