feat: Enhance arrow and trigger connection handling with backend updates and improved event management
This commit is contained in:
@@ -2,6 +2,11 @@ import * as THREE from "three";
|
||||
import { useMemo, useRef, useState } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { useToolMode } from "../../../../store/builder/store";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
import { useVersionContext } from "../../../builder/version/versionContext";
|
||||
import { useProductContext } from "../../products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
|
||||
interface ConnectionLine {
|
||||
id: string;
|
||||
@@ -15,6 +20,28 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[]
|
||||
const groupRef = useRef<THREE.Group>(null);
|
||||
const { scene } = useThree();
|
||||
const { toolMode } = useToolMode();
|
||||
const { eventStore, productStore } = useSceneContext();
|
||||
const { removeTrigger } = productStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
upsertProductOrEventApi({
|
||||
productName: productName,
|
||||
productUuid: productUuid,
|
||||
projectId: projectId,
|
||||
eventDatas: eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
})
|
||||
}
|
||||
|
||||
const getWorldPositionFromScene = (uuid: string): THREE.Vector3 | null => {
|
||||
const obj = scene.getObjectByProperty("uuid", uuid);
|
||||
@@ -24,14 +51,20 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[]
|
||||
return pos;
|
||||
};
|
||||
|
||||
const processedArrows = new Set<string>();
|
||||
|
||||
const createArrow = (
|
||||
key: string,
|
||||
fullCurve: THREE.QuadraticBezierCurve3,
|
||||
centerT: number,
|
||||
segmentSize: number,
|
||||
scale: number,
|
||||
reverse = false
|
||||
reverse: boolean,
|
||||
trigger: TriggerSchema
|
||||
) => {
|
||||
if (processedArrows.has(trigger.triggerUuid)) return [];
|
||||
processedArrows.add(trigger.triggerUuid);
|
||||
|
||||
const t1 = Math.max(0, centerT - segmentSize / 2);
|
||||
const t2 = Math.min(1, centerT + segmentSize / 2);
|
||||
const subCurve = getSubCurve(fullCurve, t1, t2, reverse);
|
||||
@@ -53,26 +86,41 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[]
|
||||
tangent
|
||||
);
|
||||
|
||||
const removeConnection = (trigger: TriggerSchema) => {
|
||||
if (trigger.triggerUuid) {
|
||||
const event = removeTrigger(selectedProduct.productUuid, trigger.triggerUuid);
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
event
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<group key={key}>
|
||||
<group
|
||||
key={key}
|
||||
onPointerOver={() => setHoveredLineKey(trigger.triggerUuid)}
|
||||
onPointerOut={() => setHoveredLineKey(null)}
|
||||
onClick={() => { removeConnection(trigger) }}
|
||||
>
|
||||
<mesh
|
||||
geometry={shaftGeometry}
|
||||
onPointerOver={() => setHoveredLineKey(key)}
|
||||
onPointerOut={() => setHoveredLineKey(null)}
|
||||
>
|
||||
<meshStandardMaterial
|
||||
color={toolMode === '2D-Delete' && hoveredLineKey === key ? "red" : "#42a5f5"}
|
||||
color={toolMode === '3D-Delete' && hoveredLineKey === trigger.triggerUuid ? "red" : "#42a5f5"}
|
||||
/>
|
||||
</mesh>
|
||||
<mesh
|
||||
position={end}
|
||||
quaternion={rotation}
|
||||
geometry={headGeometry}
|
||||
onPointerOver={() => setHoveredLineKey(key)}
|
||||
onPointerOut={() => setHoveredLineKey(null)}
|
||||
>
|
||||
<meshStandardMaterial
|
||||
color={toolMode === '2D-Delete' && hoveredLineKey === key ? "red" : "#42a5f5"}
|
||||
color={toolMode === '3D-Delete' && hoveredLineKey === trigger.triggerUuid ? "red" : "#42a5f5"}
|
||||
/>
|
||||
</mesh>
|
||||
</group>
|
||||
@@ -97,50 +145,29 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[]
|
||||
};
|
||||
|
||||
const arrowGroups = connections.flatMap((connection) => {
|
||||
const start = getWorldPositionFromScene(connection.startPointUuid);
|
||||
const end = getWorldPositionFromScene(connection.endPointUuid);
|
||||
const { startPointUuid, endPointUuid } = connection;
|
||||
const start = getWorldPositionFromScene(startPointUuid);
|
||||
const end = getWorldPositionFromScene(endPointUuid);
|
||||
if (!start || !end) return [];
|
||||
|
||||
const isBidirectional = connections.some(
|
||||
(other) =>
|
||||
other.startPointUuid === connection.endPointUuid &&
|
||||
other.endPointUuid === connection.startPointUuid
|
||||
);
|
||||
const isBidirectional = connections.some((other) => other.startPointUuid === endPointUuid && other.endPointUuid === startPointUuid);
|
||||
|
||||
if (isBidirectional && connection.startPointUuid < connection.endPointUuid) {
|
||||
const distance = start.distanceTo(end);
|
||||
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||
const control = new THREE.Vector3(
|
||||
(start.x + end.x) / 2,
|
||||
Math.max(start.y, end.y) + heightFactor,
|
||||
(start.z + end.z) / 2
|
||||
);
|
||||
const curve = new THREE.QuadraticBezierCurve3(start, control, end);
|
||||
const scale = THREE.MathUtils.clamp(distance * 0.75, 0.5, 3);
|
||||
const distance = start.distanceTo(end);
|
||||
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||
const control = new THREE.Vector3((start.x + end.x) / 2, Math.max(start.y, end.y) + heightFactor, (start.z + end.z) / 2);
|
||||
const curve = new THREE.QuadraticBezierCurve3(start, control, end);
|
||||
const scale = THREE.MathUtils.clamp(distance * 0.75, 0.5, 5);
|
||||
|
||||
if (isBidirectional) {
|
||||
return [
|
||||
createArrow(connection.id + "-fwd", curve, 0.33, 0.25, scale, true),
|
||||
createArrow(connection.id + "-bwd", curve, 0.66, 0.25, scale, false),
|
||||
createArrow(connection.id + "-fwd", curve, 0.33, 0.25, scale, true, connection.trigger),
|
||||
createArrow(connection.id + "-bwd", curve, 0.66, 0.25, scale, false, connection.trigger),
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
createArrow(connection.id, curve, 0.5, 0.3, scale, false, connection.trigger)
|
||||
];
|
||||
}
|
||||
|
||||
if (!isBidirectional) {
|
||||
const distance = start.distanceTo(end);
|
||||
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||
const control = new THREE.Vector3(
|
||||
(start.x + end.x) / 2,
|
||||
Math.max(start.y, end.y) + heightFactor,
|
||||
(start.z + end.z) / 2
|
||||
);
|
||||
const curve = new THREE.QuadraticBezierCurve3(start, control, end);
|
||||
const scale = THREE.MathUtils.clamp(distance * 0.75, 0.5, 5);
|
||||
|
||||
return [
|
||||
createArrow(connection.id, curve, 0.5, 0.3, scale)
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
});
|
||||
|
||||
return <group ref={groupRef} name="connectionArrows">{arrowGroups}</group>;
|
||||
|
||||
@@ -503,15 +503,15 @@ function TriggerConnector() {
|
||||
dashed={toolMode === '3D-Delete' && hoveredLineKey === connection.id ? false : true}
|
||||
dashSize={0.75}
|
||||
dashScale={20}
|
||||
onPointerOver={() => setHoveredLineKey(connection.id)}
|
||||
onPointerOut={() => setHoveredLineKey(null)}
|
||||
onClick={() => {
|
||||
if (toolMode === '3D-Delete') {
|
||||
setHoveredLineKey(null);
|
||||
setCurrentLine(null);
|
||||
removeConnection(connection);
|
||||
}
|
||||
}}
|
||||
// onPointerOver={() => setHoveredLineKey(connection.id)}
|
||||
// onPointerOut={() => setHoveredLineKey(null)}
|
||||
// onClick={() => {
|
||||
// if (toolMode === '3D-Delete') {
|
||||
// setHoveredLineKey(null);
|
||||
// setCurrentLine(null);
|
||||
// removeConnection(connection);
|
||||
// }
|
||||
// }}
|
||||
userData={connection.trigger}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user