duplication asset snapping movement and slow movement added
This commit is contained in:
@@ -9,6 +9,7 @@ import { useParams } from "react-router-dom";
|
||||
import { getUserData } from "../../../../../functions/getUserData";
|
||||
import { useSceneContext } from "../../../sceneContext";
|
||||
import { useVersionContext } from "../../../../builder/version/versionContext";
|
||||
import { handleAssetPositionSnap } from "./functions/handleAssetPositionSnap";
|
||||
|
||||
// import { setAssetsApi } from "../../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi";
|
||||
|
||||
@@ -35,11 +36,15 @@ const DuplicationControls3D = ({
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { userId, organization } = getUserData();
|
||||
|
||||
const [keyEvent, setKeyEvent] = useState<"Ctrl" | "Shift" | "Ctrl+Shift" | "">("");
|
||||
const [axisConstraint, setAxisConstraint] = useState<"x" | "z" | null>(null);
|
||||
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
|
||||
const [initialPositions, setInitialPositions] = useState<Record<string, THREE.Vector3>>({});
|
||||
const [isDuplicating, setIsDuplicating] = useState(false);
|
||||
const mouseButtonsDown = useRef<{ left: boolean; right: boolean }>({ left: false, right: false, });
|
||||
const fineMoveBaseRef = useRef<THREE.Vector3 | null>(null);
|
||||
const lastPointerPositionRef = useRef<THREE.Vector3 | null>(null);
|
||||
const wasShiftHeldRef = useRef(false);
|
||||
|
||||
const calculateDragOffset = useCallback((point: THREE.Object3D, hitPoint: THREE.Vector3) => {
|
||||
const pointPosition = new THREE.Vector3().copy(point.position);
|
||||
@@ -78,6 +83,7 @@ const DuplicationControls3D = ({
|
||||
removeAsset(obj.userData.modelUuid);
|
||||
});
|
||||
}
|
||||
setKeyEvent("");
|
||||
};
|
||||
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
@@ -96,6 +102,14 @@ const DuplicationControls3D = ({
|
||||
}
|
||||
}
|
||||
|
||||
if (keyCombination !== keyEvent) {
|
||||
if (keyCombination === "Ctrl" || keyCombination === "Ctrl+Shift" || keyCombination === "Shift") {
|
||||
setKeyEvent(keyCombination);
|
||||
} else {
|
||||
setKeyEvent("");
|
||||
}
|
||||
}
|
||||
|
||||
if (keyCombination === "Ctrl+D" && movedObjects.length === 0 && rotatedObjects.length === 0) {
|
||||
duplicateSelection();
|
||||
}
|
||||
@@ -108,11 +122,34 @@ const DuplicationControls3D = ({
|
||||
}
|
||||
};
|
||||
|
||||
const onKeyUp = (event: KeyboardEvent) => {
|
||||
const keyCombination = detectModifierKeys(event);
|
||||
|
||||
if (keyCombination === "") {
|
||||
setKeyEvent("");
|
||||
} else if (keyCombination === "Ctrl" || keyCombination === "Ctrl+Shift" || keyCombination === "Shift") {
|
||||
setKeyEvent(keyCombination);
|
||||
}
|
||||
if (duplicatedObjects[0] && keyEvent !== "" && keyCombination === '') {
|
||||
const intersectionPoint = new THREE.Vector3();
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
if (hit) {
|
||||
const model = scene.getObjectByProperty("uuid", duplicatedObjects[0].userData.modelUuid);
|
||||
if (model) {
|
||||
const newOffset = calculateDragOffset(model, intersectionPoint);
|
||||
setDragOffset(newOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!toggleView) {
|
||||
canvasElement.addEventListener("pointerdown", onPointerDown);
|
||||
canvasElement.addEventListener("pointermove", onPointerMove);
|
||||
canvasElement.addEventListener("pointerup", onPointerUp);
|
||||
canvasElement.addEventListener("keydown", onKeyDown);
|
||||
canvasElement.addEventListener("keyup", onKeyUp);
|
||||
}
|
||||
|
||||
return () => {
|
||||
@@ -120,8 +157,9 @@ const DuplicationControls3D = ({
|
||||
canvasElement.removeEventListener("pointermove", onPointerMove);
|
||||
canvasElement.removeEventListener("pointerup", onPointerUp);
|
||||
canvasElement.removeEventListener("keydown", onKeyDown);
|
||||
canvasElement.addEventListener("keyup", onKeyUp);
|
||||
};
|
||||
}, [assets, camera, controls, scene, toggleView, selectedAssets, duplicatedObjects, movedObjects, socket, rotatedObjects]);
|
||||
}, [assets, camera, controls, scene, toggleView, selectedAssets, duplicatedObjects, movedObjects, socket, rotatedObjects, keyEvent]);
|
||||
|
||||
useFrame(() => {
|
||||
if (!isDuplicating || duplicatedObjects.length === 0) return;
|
||||
@@ -141,28 +179,9 @@ const DuplicationControls3D = ({
|
||||
}
|
||||
|
||||
if (dragOffset) {
|
||||
let adjustedHit = new THREE.Vector3().addVectors(intersectionPoint, dragOffset);
|
||||
|
||||
if (axisConstraint) {
|
||||
const model = scene.getObjectByProperty("uuid", duplicatedObjects[0].userData.modelUuid);
|
||||
if (model) {
|
||||
|
||||
const currentBasePosition = model.position.clone();
|
||||
if (axisConstraint === 'x') {
|
||||
adjustedHit = new THREE.Vector3(
|
||||
adjustedHit.x,
|
||||
currentBasePosition.y,
|
||||
currentBasePosition.z
|
||||
);
|
||||
} else if (axisConstraint === 'z') {
|
||||
adjustedHit = new THREE.Vector3(
|
||||
currentBasePosition.x,
|
||||
currentBasePosition.y,
|
||||
adjustedHit.z
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
const rawBasePosition = new THREE.Vector3().addVectors(intersectionPoint, dragOffset);
|
||||
const model = scene.getObjectByProperty("uuid", duplicatedObjects[0].userData.modelUuid);
|
||||
const baseNewPosition = handleAssetPositionSnap({ rawBasePosition, intersectionPoint, model, axisConstraint, keyEvent, fineMoveBaseRef, lastPointerPositionRef, wasShiftHeldRef });
|
||||
|
||||
duplicatedObjects.forEach((duplicatedObject: THREE.Object3D) => {
|
||||
if (duplicatedObject.userData.modelUuid) {
|
||||
@@ -176,7 +195,7 @@ const DuplicationControls3D = ({
|
||||
);
|
||||
const model = scene.getObjectByProperty("uuid", duplicatedObject.userData.modelUuid);
|
||||
|
||||
const newPosition = new THREE.Vector3().addVectors(adjustedHit, relativeOffset);
|
||||
const newPosition = new THREE.Vector3().addVectors(baseNewPosition, relativeOffset);
|
||||
const positionArray: [number, number, number] = [newPosition.x, newPosition.y, newPosition.z];
|
||||
|
||||
if (model) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as THREE from "three";
|
||||
|
||||
export function getSnappedBasePosition({
|
||||
export function handleAssetPositionSnap({
|
||||
rawBasePosition,
|
||||
intersectionPoint,
|
||||
movedObjects,
|
||||
model,
|
||||
axisConstraint,
|
||||
keyEvent,
|
||||
fineMoveBaseRef,
|
||||
@@ -12,7 +12,7 @@ export function getSnappedBasePosition({
|
||||
}: {
|
||||
rawBasePosition: THREE.Vector3;
|
||||
intersectionPoint: THREE.Vector3;
|
||||
movedObjects: THREE.Object3D[];
|
||||
model: THREE.Object3D | undefined;
|
||||
axisConstraint: "x" | "z" | null;
|
||||
keyEvent: string;
|
||||
fineMoveBaseRef: React.MutableRefObject<THREE.Vector3 | null>;
|
||||
@@ -26,9 +26,9 @@ export function getSnappedBasePosition({
|
||||
const isShiftHeld = keyEvent.includes("Shift");
|
||||
|
||||
// Handle Shift toggle state
|
||||
if (isShiftHeld !== wasShiftHeldRef.current) {
|
||||
if (isShiftHeld !== wasShiftHeldRef.current && model) {
|
||||
if (isShiftHeld) {
|
||||
fineMoveBaseRef.current = movedObjects[0].position.clone();
|
||||
fineMoveBaseRef.current = model.position.clone();
|
||||
lastPointerPositionRef.current = intersectionPoint.clone();
|
||||
} else {
|
||||
fineMoveBaseRef.current = null;
|
||||
@@ -62,8 +62,8 @@ export function getSnappedBasePosition({
|
||||
}
|
||||
|
||||
// Apply axis constraint last
|
||||
if (axisConstraint) {
|
||||
const currentBasePosition = movedObjects[0].position.clone();
|
||||
if (axisConstraint && model) {
|
||||
const currentBasePosition = model.position.clone();
|
||||
if (axisConstraint === 'x') {
|
||||
baseNewPosition.set(baseNewPosition.x, currentBasePosition.y, currentBasePosition.z);
|
||||
} else if (axisConstraint === 'z') {
|
||||
@@ -72,4 +72,4 @@ export function getSnappedBasePosition({
|
||||
}
|
||||
|
||||
return baseNewPosition;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import { useSelectedAssets, useSocketStore, useToggleView, } from "../../../../.
|
||||
import * as Types from "../../../../../types/world/worldTypes";
|
||||
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
|
||||
import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { getSnappedBasePosition } from "../../../../../utils/handleSnap";
|
||||
import { handleAssetPositionSnap } from "./functions/handleAssetPositionSnap";
|
||||
import DistanceFindingControls from "./distanceFindingControls";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useProductContext } from "../../../../simulation/products/productContext";
|
||||
@@ -34,7 +34,6 @@ function MoveControls3D({
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { socket } = useSocketStore();
|
||||
const [keyEvent, setKeyEvent] = useState<"Ctrl" | "Shift" | "Ctrl+Shift" | "">("");
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
const { assetStore, eventStore, productStore, undoRedo3DStore } = useSceneContext();
|
||||
@@ -43,13 +42,13 @@ function MoveControls3D({
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
|
||||
const [keyEvent, setKeyEvent] = useState<"Ctrl" | "Shift" | "Ctrl+Shift" | "">("");
|
||||
const [axisConstraint, setAxisConstraint] = useState<"x" | "z" | null>(null);
|
||||
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
|
||||
const [initialPositions, setInitialPositions] = useState<Record<string, THREE.Vector3>>({});
|
||||
const [initialStates, setInitialStates] = useState<Record<string, { position: THREE.Vector3; rotation?: THREE.Euler; }>>({});
|
||||
const [isMoving, setIsMoving] = useState(false);
|
||||
const mouseButtonsDown = useRef<{ left: boolean; right: boolean }>({ left: false, right: false, });
|
||||
// Add a ref to track fine-move base
|
||||
const fineMoveBaseRef = useRef<THREE.Vector3 | null>(null);
|
||||
const lastPointerPositionRef = useRef<THREE.Vector3 | null>(null);
|
||||
const wasShiftHeldRef = useRef(false);
|
||||
@@ -121,7 +120,6 @@ function MoveControls3D({
|
||||
clearSelection();
|
||||
setMovedObjects([]);
|
||||
}
|
||||
setKeyEvent("");
|
||||
};
|
||||
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
@@ -247,8 +245,8 @@ function MoveControls3D({
|
||||
|
||||
if (dragOffset) {
|
||||
const rawBasePosition = new THREE.Vector3().addVectors(intersectionPoint, dragOffset);
|
||||
|
||||
const baseNewPosition = getSnappedBasePosition({ rawBasePosition, intersectionPoint, movedObjects, axisConstraint, keyEvent, fineMoveBaseRef, lastPointerPositionRef, wasShiftHeldRef });
|
||||
const model = movedObjects[0];
|
||||
const baseNewPosition = handleAssetPositionSnap({ rawBasePosition, intersectionPoint, model, axisConstraint, keyEvent, fineMoveBaseRef, lastPointerPositionRef, wasShiftHeldRef });
|
||||
|
||||
movedObjects.forEach((movedAsset: THREE.Object3D) => {
|
||||
if (movedAsset.userData.modelUuid) {
|
||||
|
||||
Reference in New Issue
Block a user