moveControls and other controls altered

This commit is contained in:
2025-07-18 14:14:34 +05:30
parent 0b9f23ba4f
commit c309af135d
9 changed files with 634 additions and 485 deletions

View File

@@ -1,5 +1,5 @@
import * as THREE from "three";
import { useEffect, useMemo } from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useFrame, useThree } from "@react-three/fiber";
import { SkeletonUtils } from "three-stdlib";
import { useSelectedAssets, useSocketStore, useToggleView } from "../../../../../store/builder/store";
@@ -10,18 +10,14 @@ import { getUserData } from "../../../../../functions/getUserData";
import { useSceneContext } from "../../../sceneContext";
import { useVersionContext } from "../../../../builder/version/versionContext";
// import { setAssetsApi } from '../../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi';
const DuplicationControls3D = ({
duplicatedObjects,
setDuplicatedObjects,
setpastedObjects,
selectionGroup,
movedObjects,
setMovedObjects,
rotatedObjects,
setRotatedObjects,
boundingBoxRef
}: any) => {
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
const { toggleView } = useToggleView();
@@ -31,39 +27,71 @@ const DuplicationControls3D = ({
const { assetStore, eventStore } = useSceneContext();
const { addEvent } = eventStore();
const { projectId } = useParams();
const { assets, addAsset } = assetStore();
const { assets, addAsset, setPosition, updateAsset, removeAsset, getAssetById } = assetStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { userId, organization } = getUserData();
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 calculateDragOffset = useCallback((point: THREE.Vector3, hitPoint: THREE.Vector3) => {
const pointPosition = new THREE.Vector3().copy(point);
return new THREE.Vector3().subVectors(pointPosition, hitPoint);
}, []);
useEffect(() => {
if (!camera || !scene || toggleView) return;
const canvasElement = gl.domElement;
canvasElement.tabIndex = 0;
let isMoving = false;
let isPointerMoving = false;
const onPointerDown = () => {
isMoving = false;
const onPointerDown = (event: PointerEvent) => {
isPointerMoving = false;
if (event.button === 0) mouseButtonsDown.current.left = true;
if (event.button === 2) mouseButtonsDown.current.right = true;
};
const onPointerMove = () => {
isMoving = true;
isPointerMoving = true;
};
const onPointerUp = (event: PointerEvent) => {
if (!isMoving && duplicatedObjects.length > 0 && event.button === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) {
if (event.button === 0) mouseButtonsDown.current.left = false;
if (event.button === 2) mouseButtonsDown.current.right = false;
if (!isPointerMoving && duplicatedObjects.length > 0 && event.button === 0) {
event.preventDefault();
addDuplicatedAssets();
}
if (!isPointerMoving && duplicatedObjects.length > 0 && event.button === 2) {
event.preventDefault();
clearSelection();
duplicatedObjects.forEach((obj: THREE.Object3D) => {
removeAsset(obj.userData.modelUuid);
});
}
};
const onKeyDown = (event: KeyboardEvent) => {
const keyCombination = detectModifierKeys(event);
if (keyCombination === "Ctrl+D" && selectedAssets.length > 0 && duplicatedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) {
if (keyCombination === "Ctrl+D" && movedObjects.length === 0 && rotatedObjects.length === 0) {
duplicateSelection();
}
if (keyCombination === "ESCAPE" && duplicatedObjects.length > 0) {
event.preventDefault();
clearSelection();
duplicatedObjects.forEach((obj: THREE.Object3D) => {
removeAsset(obj.userData.modelUuid);
});
}
};
if (!toggleView) {
@@ -79,82 +107,125 @@ const DuplicationControls3D = ({
canvasElement.removeEventListener("pointerup", onPointerUp);
canvasElement.removeEventListener("keydown", onKeyDown);
};
}, [assets, camera, controls, scene, toggleView, selectedAssets, duplicatedObjects, movedObjects, socket, rotatedObjects]);
useFrame(() => {
if (duplicatedObjects.length > 0) {
const intersectionPoint = new THREE.Vector3();
raycaster.setFromCamera(pointer, camera);
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
if (point) {
const position = new THREE.Vector3();
if (boundingBoxRef.current) {
boundingBoxRef.current?.getWorldPosition(position)
selectionGroup.current.position.set(point.x - (position.x - selectionGroup.current.position.x), selectionGroup.current.position.y, point.z - (position.z - selectionGroup.current.position.z));
} else {
const box = new THREE.Box3();
duplicatedObjects.forEach((obj: THREE.Object3D) => box.expandByObject(obj.clone()));
const center = new THREE.Vector3();
box.getCenter(center);
selectionGroup.current.position.set(point.x - (center.x - selectionGroup.current.position.x), selectionGroup.current.position.y, point.z - (center.z - selectionGroup.current.position.z));
if (!isDuplicating || duplicatedObjects.length === 0) return;
const intersectionPoint = new THREE.Vector3();
raycaster.setFromCamera(pointer, camera);
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
if (hit) {
if (mouseButtonsDown.current.left || mouseButtonsDown.current.right) {
const assetUuid = duplicatedObjects[0].userData.modelUuid;
const asset = getAssetById(assetUuid);
if (!asset) return;
if (duplicatedObjects[0]) {
const newOffset = calculateDragOffset(new THREE.Vector3(...asset.position), intersectionPoint);
setDragOffset(newOffset);
}
return;
}
if (dragOffset) {
const adjustedHit = new THREE.Vector3().addVectors(intersectionPoint, dragOffset);
duplicatedObjects.forEach((duplicatedObject: THREE.Object3D) => {
if (duplicatedObject.userData.modelUuid) {
const initialPosition = initialPositions[duplicatedObject.userData.modelUuid];
if (initialPosition) {
const relativeOffset = new THREE.Vector3().subVectors(
initialPosition,
initialPositions[duplicatedObjects[0].userData.modelUuid]
);
const newPosition = new THREE.Vector3().addVectors(adjustedHit, relativeOffset);
const positionArray: [number, number, number] = [newPosition.x, newPosition.y, newPosition.z];
setPosition(duplicatedObject.userData.modelUuid, positionArray);
}
}
});
}
}
});
const duplicateSelection = () => {
const duplicateSelection = useCallback(() => {
if (selectedAssets.length > 0 && duplicatedObjects.length === 0) {
const newClones = selectedAssets.map((asset: any) => {
const clone = SkeletonUtils.clone(asset);
clone.position.copy(asset.position);
const positions: Record<string, THREE.Vector3> = {};
const newDuplicatedObjects = selectedAssets.map((obj: any) => {
const clone = SkeletonUtils.clone(obj);
clone.userData.modelUuid = THREE.MathUtils.generateUUID();
positions[clone.userData.modelUuid] = new THREE.Vector3().copy(obj.position);
return clone;
});
selectionGroup.current.add(...newClones);
setDuplicatedObjects(newClones);
setDuplicatedObjects(newDuplicatedObjects);
setInitialPositions(positions);
const intersectionPoint = new THREE.Vector3();
raycaster.setFromCamera(pointer, camera);
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
const intersectionPoint = new THREE.Vector3();
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
if (point) {
const position = new THREE.Vector3();
boundingBoxRef.current?.getWorldPosition(position)
selectionGroup.current.position.set(point.x - (position.x - selectionGroup.current.position.x), selectionGroup.current.position.y, point.z - (position.z - selectionGroup.current.position.z));
if (hit) {
const offset = calculateDragOffset(selectedAssets[0].position, hit);
setDragOffset(offset);
}
setIsDuplicating(true);
newDuplicatedObjects.forEach((obj: THREE.Object3D) => {
const asset: Asset = {
modelUuid: obj.userData.modelUuid,
modelName: obj.userData.modelName,
assetId: obj.userData.assetId,
position: [obj.position.x, 0, obj.position.z],
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
isLocked: false,
isVisible: true,
isCollidable: false,
opacity: 0.5,
};
addAsset(asset);
});
}
};
}, [selectedAssets, duplicatedObjects]);
const addDuplicatedAssets = () => {
if (duplicatedObjects.length === 0) return;
duplicatedObjects.forEach(async (obj: THREE.Object3D) => {
if (obj) {
const worldPosition = new THREE.Vector3();
obj.getWorldPosition(worldPosition);
obj.position.copy(worldPosition);
duplicatedObjects.forEach(async (duplicatedAsset: THREE.Object3D) => {
if (duplicatedAsset) {
const assetUuid = duplicatedAsset.userData.modelUuid;
const asset = getAssetById(assetUuid);
if (!asset) return;
const newFloorItem: Types.FloorItemType = {
modelUuid: THREE.MathUtils.generateUUID(),
modelName: obj.userData.modelName,
assetId: obj.userData.assetId,
position: [worldPosition.x, worldPosition.y, worldPosition.z],
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, },
modelUuid: duplicatedAsset.userData.modelUuid,
modelName: duplicatedAsset.userData.modelName,
assetId: duplicatedAsset.userData.assetId,
position: asset.position,
rotation: { x: asset.rotation[0], y: asset.rotation[1], z: asset.rotation[2] },
isLocked: false,
isVisible: true,
};
let updatedEventData = null;
if (obj.userData.eventData) {
updatedEventData = JSON.parse(JSON.stringify(obj.userData.eventData));
if (duplicatedAsset.userData.eventData) {
updatedEventData = JSON.parse(JSON.stringify(duplicatedAsset.userData.eventData));
updatedEventData.modelUuid = newFloorItem.modelUuid;
const eventData: any = {
type: obj.userData.eventData.type,
type: duplicatedAsset.userData.eventData.type,
};
if (obj.userData.eventData.type === "Conveyor") {
if (duplicatedAsset.userData.eventData.type === "Conveyor") {
const ConveyorEvent: ConveyorEventSchema = {
modelUuid: newFloorItem.modelUuid,
modelName: newFloorItem.modelName,
@@ -186,7 +257,7 @@ const DuplicationControls3D = ({
rotation: point.rotation
}));
} else if (obj.userData.eventData.type === "Vehicle") {
} else if (duplicatedAsset.userData.eventData.type === "Vehicle") {
const vehicleEvent: VehicleEventSchema = {
modelUuid: newFloorItem.modelUuid,
modelName: newFloorItem.modelName,
@@ -224,7 +295,7 @@ const DuplicationControls3D = ({
rotation: vehicleEvent.point.rotation
};
} else if (obj.userData.eventData.type === "ArmBot") {
} else if (duplicatedAsset.userData.eventData.type === "ArmBot") {
const roboticArmEvent: RoboticArmEventSchema = {
modelUuid: newFloorItem.modelUuid,
modelName: newFloorItem.modelName,
@@ -258,7 +329,7 @@ const DuplicationControls3D = ({
rotation: roboticArmEvent.point.rotation
};
} else if (obj.userData.eventData.type === "StaticMachine") {
} else if (duplicatedAsset.userData.eventData.type === "StaticMachine") {
const machineEvent: MachineEventSchema = {
modelUuid: newFloorItem.modelUuid,
modelName: newFloorItem.modelName,
@@ -286,7 +357,7 @@ const DuplicationControls3D = ({
position: machineEvent.point.position,
rotation: machineEvent.point.rotation
};
} else if (obj.userData.eventData.type === "Storage") {
} else if (duplicatedAsset.userData.eventData.type === "Storage") {
const storageEvent: StorageEventSchema = {
modelUuid: newFloorItem.modelUuid,
modelName: newFloorItem.modelName,
@@ -313,7 +384,7 @@ const DuplicationControls3D = ({
position: storageEvent.point.position,
rotation: storageEvent.point.rotation
};
} else if (obj.userData.eventData.type === "Human") {
} else if (duplicatedAsset.userData.eventData.type === "Human") {
const humanEvent: HumanEventSchema = {
modelUuid: newFloorItem.modelUuid,
modelName: newFloorItem.modelName,
@@ -353,11 +424,11 @@ const DuplicationControls3D = ({
// await setAssetsApi(
// organization,
// obj.uuid,
// obj.userData.name,
// pastedAsset.uuid,
// pastedAsset.userData.name,
// [worldPosition.x, worldPosition.y, worldPosition.z],
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
// obj.userData.modelId,
// { "x": pastedAsset.rotation.x, "y": pastedAsset.rotation.y, "z": pastedAsset.rotation.z },
// pastedAsset.userData.modelId,
// false,
// true,
// );
@@ -370,17 +441,16 @@ const DuplicationControls3D = ({
modelName: newFloorItem.modelName,
assetId: newFloorItem.assetId,
position: newFloorItem.position,
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
rotation: { x: duplicatedAsset.rotation.x, y: duplicatedAsset.rotation.y, z: duplicatedAsset.rotation.z },
isLocked: false,
isVisible: true,
socketId: socket.id,
eventData: eventData,
versionId: selectedVersion?.versionId || '',
projectId,
userId
userId,
projectId
};
// console.log('data: ', data);
socket.emit("v1:model-asset:add", data);
const asset: Asset = {
@@ -394,43 +464,25 @@ const DuplicationControls3D = ({
isVisible: data.isVisible,
opacity: 1,
eventData: data.eventData
}
addAsset(asset);
};
updateAsset(asset.modelUuid, asset);
} else {
//REST
// await setAssetsApi(
// organization,
// obj.uuid,
// obj.userData.name,
// [worldPosition.x, worldPosition.y, worldPosition.z],
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
// obj.userData.modelId,
// false,
// true,
// );
//SOCKET
const data = {
organization,
modelUuid: newFloorItem.modelUuid,
modelName: newFloorItem.modelName,
assetId: newFloorItem.assetId,
position: newFloorItem.position,
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
rotation: { x: duplicatedAsset.rotation.x, y: duplicatedAsset.rotation.y, z: duplicatedAsset.rotation.z },
isLocked: false,
isVisible: true,
socketId: socket.id,
versionId: selectedVersion?.versionId || '',
userId,
projectId
projectId,
userId
};
// console.log('data: ', data);/
socket.emit("v1:model-asset:add", data);
const asset: Asset = {
@@ -443,27 +495,26 @@ const DuplicationControls3D = ({
isCollidable: false,
isVisible: data.isVisible,
opacity: 1,
}
};
addAsset(asset);
updateAsset(asset.modelUuid, asset);
}
}
});
echo.success("Object duplicated!");
clearSelection();
}
};
const clearSelection = () => {
selectionGroup.current.children = [];
selectionGroup.current.position.set(0, 0, 0);
selectionGroup.current.rotation.set(0, 0, 0);
setMovedObjects([]);
setpastedObjects([]);
setDuplicatedObjects([]);
setRotatedObjects([]);
setSelectedAssets([]);
}
setIsDuplicating(false);
setDragOffset(null);
};
return null;
};