mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
feat: advanced jsxTree
This commit is contained in:
1 parent
2bef96475c
commit
0e6aa734cb
10 files changed
+305
-226
No files matched your search
+19
-10
@@ -211,16 +211,25 @@ export function PrimaryArmorSceneComponent({
|
||||
|
||||
return (
|
||||
<>
|
||||
{jsxTree(
|
||||
node,
|
||||
{ mesh: { renderOrder: 0, material: excludeMaterial } },
|
||||
`${node.uuid}-exclude`,
|
||||
)}
|
||||
{jsxTree(
|
||||
node,
|
||||
{ mesh: { renderOrder: 1, material } },
|
||||
`${node.uuid}-include`,
|
||||
)}
|
||||
{jsxTree(node, {
|
||||
mesh(_, props, key) {
|
||||
return (
|
||||
<mesh
|
||||
{...props}
|
||||
key={key}
|
||||
renderOrder={0}
|
||||
material={excludeMaterial}
|
||||
/>
|
||||
);
|
||||
},
|
||||
})}
|
||||
{jsxTree(node, {
|
||||
mesh(_, props, key) {
|
||||
return (
|
||||
<mesh {...props} key={key} renderOrder={1} material={material} />
|
||||
);
|
||||
},
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
+32
-25
@@ -114,33 +114,40 @@ export function SpacedArmorSubExternal({
|
||||
|
||||
return (
|
||||
<>
|
||||
{jsxTree(
|
||||
node,
|
||||
{
|
||||
mesh: {
|
||||
renderOrder: 3,
|
||||
material: new MeshBasicMaterial({
|
||||
colorWrite: false,
|
||||
depthTest: true,
|
||||
depthWrite: true,
|
||||
...(clip ? { clippingPlanes: [clip] } : {}),
|
||||
}),
|
||||
onClick() {},
|
||||
userData: {
|
||||
type: ArmorType.External,
|
||||
thickness,
|
||||
variant,
|
||||
} satisfies ArmorUserData,
|
||||
},
|
||||
{jsxTree(node, {
|
||||
mesh(_, props, key) {
|
||||
return (
|
||||
<mesh
|
||||
{...props}
|
||||
key={key}
|
||||
renderOrder={3}
|
||||
material={
|
||||
new MeshBasicMaterial({
|
||||
colorWrite: false,
|
||||
depthTest: true,
|
||||
depthWrite: true,
|
||||
...(clip ? { clippingPlanes: [clip] } : {}),
|
||||
})
|
||||
}
|
||||
userData={
|
||||
{
|
||||
type: ArmorType.External,
|
||||
thickness,
|
||||
variant,
|
||||
} satisfies ArmorUserData
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
`${node.uuid}-exclude`,
|
||||
)}
|
||||
})}
|
||||
|
||||
{jsxTree(
|
||||
node,
|
||||
{ mesh: { renderOrder: 4, material } },
|
||||
`${node.uuid}-include`,
|
||||
)}
|
||||
{jsxTree(node, {
|
||||
mesh(_, props, key) {
|
||||
return (
|
||||
<mesh {...props} key={key} renderOrder={4} material={material} />
|
||||
);
|
||||
},
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
+29
-23
@@ -124,32 +124,38 @@ export function SpacedArmorSubSpaced({
|
||||
|
||||
return (
|
||||
<>
|
||||
{jsxTree(
|
||||
node,
|
||||
{
|
||||
mesh: {
|
||||
renderOrder: 2,
|
||||
material,
|
||||
onClick() {},
|
||||
userData: {
|
||||
type: ArmorType.Spaced,
|
||||
thickness,
|
||||
} satisfies ArmorUserData,
|
||||
},
|
||||
{jsxTree(node, {
|
||||
mesh(_, props, key) {
|
||||
return (
|
||||
<mesh
|
||||
{...props}
|
||||
key={key}
|
||||
renderOrder={2}
|
||||
material={material}
|
||||
onClick={() => {}}
|
||||
userData={
|
||||
{
|
||||
type: ArmorType.Spaced,
|
||||
thickness,
|
||||
} satisfies ArmorUserData
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
`${node.uuid}-exclude`,
|
||||
)}
|
||||
})}
|
||||
|
||||
{jsxTree(
|
||||
node,
|
||||
{
|
||||
mesh: {
|
||||
renderOrder: 5,
|
||||
material: depthWriteMaterial,
|
||||
},
|
||||
{jsxTree(node, {
|
||||
mesh(_, props, key) {
|
||||
return (
|
||||
<mesh
|
||||
{...props}
|
||||
key={key}
|
||||
renderOrder={5}
|
||||
material={depthWriteMaterial}
|
||||
/>
|
||||
);
|
||||
},
|
||||
`${node.uuid}-include`,
|
||||
)}
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
+26
-22
@@ -372,29 +372,33 @@ export function SpacedArmorSceneComponent({
|
||||
return (
|
||||
<>
|
||||
{props.type === ArmorType.Primary &&
|
||||
jsxTree(
|
||||
node,
|
||||
{
|
||||
mesh: {
|
||||
renderOrder: 0,
|
||||
material: omitMaterial,
|
||||
userData: {
|
||||
type: ArmorType.Primary,
|
||||
thickness,
|
||||
} satisfies ArmorUserData,
|
||||
async onClick(event) {
|
||||
event.stopPropagation();
|
||||
const shot = (await shoot(
|
||||
event.point,
|
||||
event.intersections,
|
||||
true,
|
||||
))!;
|
||||
tankopediaEphemeralStore.setState({ shot });
|
||||
},
|
||||
},
|
||||
jsxTree(node, {
|
||||
mesh(mesh, props, key) {
|
||||
return (
|
||||
<mesh
|
||||
{...props}
|
||||
key={key}
|
||||
renderOrder={0}
|
||||
material={omitMaterial}
|
||||
userData={
|
||||
{
|
||||
type: ArmorType.Primary,
|
||||
thickness,
|
||||
} satisfies ArmorUserData
|
||||
}
|
||||
onClick={async (event) => {
|
||||
event.stopPropagation();
|
||||
const shot = (await shoot(
|
||||
event.point,
|
||||
event.intersections,
|
||||
true,
|
||||
))!;
|
||||
tankopediaEphemeralStore.setState({ shot });
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
node.uuid,
|
||||
)}
|
||||
})}
|
||||
|
||||
{props.type === ArmorType.Spaced && (
|
||||
<SpacedArmorSubSpaced node={node} thickness={thickness} />
|
||||
|
||||
@@ -215,50 +215,61 @@ export function StaticArmorSceneComponent({
|
||||
return (
|
||||
<>
|
||||
{jsxTree(node, {
|
||||
mesh: {
|
||||
material: surfaceMaterial,
|
||||
onPointerDown,
|
||||
userData: {
|
||||
type: props.type,
|
||||
variant: props.type === ArmorType.External ? props.variant : 'gun',
|
||||
thickness,
|
||||
} satisfies ArmorUserData,
|
||||
mesh(_, meshProps, key) {
|
||||
return (
|
||||
<mesh
|
||||
{...meshProps}
|
||||
key={key}
|
||||
material={surfaceMaterial}
|
||||
userData={
|
||||
{
|
||||
type: props.type,
|
||||
variant:
|
||||
props.type === ArmorType.External ? props.variant : 'gun',
|
||||
thickness,
|
||||
} satisfies ArmorUserData
|
||||
}
|
||||
onClick={(event) => {
|
||||
if (discardClippingPlane(event.object, event.point)) return;
|
||||
|
||||
onClick(event) {
|
||||
if (discardClippingPlane(event.object, event.point)) return;
|
||||
event.stopPropagation();
|
||||
|
||||
event.stopPropagation();
|
||||
const { editStatic } = tankopediaEphemeralStore.getState();
|
||||
|
||||
const { editStatic } = tankopediaEphemeralStore.getState();
|
||||
const bounds = new Box3().setFromObject(event.object);
|
||||
const point = bounds.min
|
||||
.clone()
|
||||
.add(bounds.max)
|
||||
.divideScalar(2)
|
||||
.setY(bounds.max.y);
|
||||
const cameraNormal = camera.position
|
||||
.clone()
|
||||
.sub(point)
|
||||
.normalize();
|
||||
const surfaceNormal = event
|
||||
.normal!.clone()
|
||||
.applyQuaternion(
|
||||
event.object.getWorldQuaternion(new Quaternion()),
|
||||
);
|
||||
const angle = surfaceNormal.angleTo(cameraNormal);
|
||||
const thicknessAngled =
|
||||
thickness / Math.sin(Math.PI / 2 - angle);
|
||||
|
||||
const bounds = new Box3().setFromObject(event.object);
|
||||
const point = bounds.min
|
||||
.clone()
|
||||
.add(bounds.max)
|
||||
.divideScalar(2)
|
||||
.setY(bounds.max.y);
|
||||
const cameraNormal = camera.position.clone().sub(point).normalize();
|
||||
const surfaceNormal = event
|
||||
.normal!.clone()
|
||||
.applyQuaternion(
|
||||
event.object.getWorldQuaternion(new Quaternion()),
|
||||
);
|
||||
const angle = surfaceNormal.angleTo(cameraNormal);
|
||||
const thicknessAngled = thickness / Math.sin(Math.PI / 2 - angle);
|
||||
|
||||
mutateTankopediaEphemeralStore((draft) => {
|
||||
draft.highlightArmor = {
|
||||
type: props.type,
|
||||
name,
|
||||
point,
|
||||
thickness,
|
||||
thicknessAngled,
|
||||
angle,
|
||||
color: `#${color.getHexString()}`,
|
||||
editingPlate: editStatic,
|
||||
};
|
||||
});
|
||||
},
|
||||
mutateTankopediaEphemeralStore((draft) => {
|
||||
draft.highlightArmor = {
|
||||
type: props.type,
|
||||
name,
|
||||
point,
|
||||
thickness,
|
||||
thicknessAngled,
|
||||
angle,
|
||||
color: `#${color.getHexString()}`,
|
||||
editingPlate: editStatic,
|
||||
};
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
})}
|
||||
|
||||
|
||||
Reference in new issue
Block a user