moveControls and other controls altered
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import * as THREE from "three";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useSelectedAssets, useSocketStore, useToggleView, } from "../../../../../store/builder/store";
|
||||
import * as Types from "../../../../../types/world/worldTypes";
|
||||
@@ -22,7 +22,6 @@ function MoveControls3D({
|
||||
setpastedObjects,
|
||||
duplicatedObjects,
|
||||
setDuplicatedObjects,
|
||||
selectionGroup,
|
||||
rotatedObjects,
|
||||
setRotatedObjects,
|
||||
boundingBoxRef,
|
||||
@@ -39,11 +38,19 @@ function MoveControls3D({
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
const { assetStore, eventStore, productStore } = useSceneContext();
|
||||
const { updateAsset } = assetStore();
|
||||
const AssetGroup = useRef<THREE.Group | undefined>(undefined);
|
||||
const { updateAsset, setPosition, getAssetById } = assetStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
|
||||
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,
|
||||
});
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
@@ -65,22 +72,10 @@ function MoveControls3D({
|
||||
const canvasElement = gl.domElement;
|
||||
canvasElement.tabIndex = 0;
|
||||
|
||||
const itemsGroup: any = scene.getObjectByName("Asset Group");
|
||||
AssetGroup.current = itemsGroup;
|
||||
|
||||
if (!AssetGroup.current) {
|
||||
console.error("Asset Group not found in the scene.");
|
||||
return;
|
||||
}
|
||||
|
||||
let isMoving = false;
|
||||
|
||||
const onPointerDown = () => {
|
||||
isMoving = false;
|
||||
};
|
||||
let isPointerMoving = false;
|
||||
|
||||
const onPointerMove = () => {
|
||||
isMoving = true;
|
||||
isPointerMoving = true;
|
||||
};
|
||||
|
||||
const onKeyUp = (event: KeyboardEvent) => {
|
||||
@@ -91,21 +86,25 @@ function MoveControls3D({
|
||||
}
|
||||
};
|
||||
|
||||
const onPointerDown = (event: PointerEvent) => {
|
||||
isPointerMoving = false;
|
||||
|
||||
if (event.button === 0) mouseButtonsDown.current.left = true;
|
||||
if (event.button === 2) mouseButtonsDown.current.right = true;
|
||||
};
|
||||
|
||||
const onPointerUp = (event: PointerEvent) => {
|
||||
if (!isMoving && movedObjects.length > 0 && event.button === 0) {
|
||||
if (event.button === 0) mouseButtonsDown.current.left = false;
|
||||
if (event.button === 2) mouseButtonsDown.current.right = false;
|
||||
|
||||
if (!isPointerMoving && movedObjects.length > 0 && event.button === 0) {
|
||||
event.preventDefault();
|
||||
placeMovedAssets();
|
||||
}
|
||||
if (!isMoving && movedObjects.length > 0 && event.button === 2) {
|
||||
if (!isPointerMoving && movedObjects.length > 0 && event.button === 2) {
|
||||
event.preventDefault();
|
||||
|
||||
resetToInitialPositions();
|
||||
clearSelection();
|
||||
movedObjects.forEach((asset: any) => {
|
||||
if (AssetGroup.current) {
|
||||
AssetGroup.current.attach(asset);
|
||||
}
|
||||
});
|
||||
|
||||
setMovedObjects([]);
|
||||
}
|
||||
setKeyEvent("");
|
||||
@@ -131,14 +130,8 @@ function MoveControls3D({
|
||||
|
||||
if (keyCombination === "ESCAPE") {
|
||||
event.preventDefault();
|
||||
|
||||
resetToInitialPositions();
|
||||
clearSelection();
|
||||
movedObjects.forEach((asset: any) => {
|
||||
if (AssetGroup.current) {
|
||||
AssetGroup.current.attach(asset);
|
||||
}
|
||||
});
|
||||
|
||||
setMovedObjects([]);
|
||||
}
|
||||
};
|
||||
@@ -158,118 +151,154 @@ function MoveControls3D({
|
||||
canvasElement.removeEventListener("keydown", onKeyDown);
|
||||
canvasElement?.removeEventListener("keyup", onKeyUp);
|
||||
};
|
||||
}, [camera, controls, scene, toggleView, selectedAssets, socket, pastedObjects, duplicatedObjects, movedObjects, rotatedObjects, keyEvent,]);
|
||||
}, [camera, controls, scene, toggleView, selectedAssets, socket, pastedObjects, duplicatedObjects, movedObjects, rotatedObjects, keyEvent]);
|
||||
|
||||
let moveSpeed = keyEvent === "Ctrl" || "Ctrl+Shift" ? 1 : 0.25;
|
||||
const calculateDragOffset = useCallback((point: THREE.Object3D, hitPoint: THREE.Vector3) => {
|
||||
const pointPosition = new THREE.Vector3().copy(point.position);
|
||||
return new THREE.Vector3().subVectors(pointPosition, hitPoint);
|
||||
}, []);
|
||||
|
||||
const resetToInitialPositions = useCallback(() => {
|
||||
setTimeout(() => {
|
||||
movedObjects.forEach((movedObject: THREE.Object3D) => {
|
||||
if (movedObject.userData.modelUuid && initialStates[movedObject.uuid]) {
|
||||
const initialState = initialStates[movedObject.uuid];
|
||||
const positionArray: [number, number, number] = [
|
||||
initialState.position.x,
|
||||
initialState.position.y,
|
||||
initialState.position.z
|
||||
];
|
||||
|
||||
updateAsset(movedObject.userData.modelUuid, {
|
||||
position: positionArray,
|
||||
rotation: [
|
||||
initialState.rotation?.x || 0,
|
||||
initialState.rotation?.y || 0,
|
||||
initialState.rotation?.z || 0
|
||||
],
|
||||
});
|
||||
|
||||
movedObject.position.copy(initialState.position);
|
||||
if (initialState.rotation) {
|
||||
movedObject.rotation.copy(initialState.rotation);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 0)
|
||||
}, [movedObjects, initialStates, updateAsset]);
|
||||
|
||||
useFrame(() => {
|
||||
if (movedObjects.length > 0) {
|
||||
const intersectionPoint = new THREE.Vector3();
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
let point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
const floorsGroup = scene.getObjectByName("Floors-Group") as Types.Group | null;
|
||||
const floorChildren = floorsGroup?.children ?? [];
|
||||
const floorIntersections = raycaster.intersectObjects([...floorChildren], true);
|
||||
const intersectedFloor = floorIntersections.find((intersect) => intersect.object.name.includes("Floor"));
|
||||
if (!isMoving || movedObjects.length === 0) return;
|
||||
|
||||
if (intersectedFloor && selectedAssets.length === 1) {
|
||||
if (intersectedFloor.object.userData.floorUuid) {
|
||||
point = new THREE.Vector3(intersectedFloor.point.x, intersectedFloor.object.userData.floorDepth, intersectedFloor.point.z);
|
||||
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) {
|
||||
if (movedObjects[0]) {
|
||||
const newOffset = calculateDragOffset(movedObjects[0], intersectionPoint);
|
||||
setDragOffset(newOffset);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (point) {
|
||||
let targetX = point.x;
|
||||
let targetY = point.y;
|
||||
let targetZ = point.z;
|
||||
if (dragOffset) {
|
||||
const baseNewPosition = new THREE.Vector3().addVectors(intersectionPoint, dragOffset);
|
||||
|
||||
let moveSpeed = keyEvent === "Shift" || "Ctrl+Shift" ? 0.25 : 1;
|
||||
|
||||
if (keyEvent === "Ctrl") {
|
||||
targetX = snapControls(targetX, "Ctrl");
|
||||
targetZ = snapControls(targetZ, "Ctrl");
|
||||
baseNewPosition.x = snapControls(baseNewPosition.x, "Ctrl");
|
||||
baseNewPosition.z = snapControls(baseNewPosition.z, "Ctrl");
|
||||
}
|
||||
|
||||
// else if (keyEvent === "Ctrl+Shift") {
|
||||
// targetX = snapControls(targetX, "Ctrl+Shift");
|
||||
// targetZ = snapControls(targetZ, "Ctrl+Shift");
|
||||
// } else if (keyEvent === "Shift") {
|
||||
// targetX = snapControls(targetX, "Shift");
|
||||
// targetZ = snapControls(targetZ, "Shift");
|
||||
// } else {
|
||||
// }
|
||||
movedObjects.forEach((movedAsset: THREE.Object3D) => {
|
||||
if (movedAsset.userData.modelUuid) {
|
||||
const initialPosition = initialPositions[movedAsset.userData.modelUuid];
|
||||
|
||||
if (initialPosition) {
|
||||
const relativeOffset = new THREE.Vector3().subVectors(
|
||||
initialPosition,
|
||||
initialPositions[movedObjects[0].uuid]
|
||||
);
|
||||
|
||||
const newPosition = new THREE.Vector3().addVectors(baseNewPosition, relativeOffset);
|
||||
const positionArray: [number, number, number] = [newPosition.x, newPosition.y, newPosition.z];
|
||||
|
||||
setPosition(movedAsset.userData.modelUuid, positionArray);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const position = new THREE.Vector3();
|
||||
|
||||
if (boundingBoxRef.current) {
|
||||
boundingBoxRef.current.getWorldPosition(position);
|
||||
selectionGroup.current.position.lerp(
|
||||
new THREE.Vector3(
|
||||
targetX - (position.x - selectionGroup.current.position.x),
|
||||
targetY - (position.y - selectionGroup.current.position.y),
|
||||
targetZ - (position.z - selectionGroup.current.position.z)
|
||||
),
|
||||
moveSpeed
|
||||
);
|
||||
} else {
|
||||
const box = new THREE.Box3();
|
||||
movedObjects.forEach((obj: THREE.Object3D) =>
|
||||
box.expandByObject(obj)
|
||||
);
|
||||
movedObjects.forEach((obj: THREE.Object3D) => box.expandByObject(obj));
|
||||
const center = new THREE.Vector3();
|
||||
box.getCenter(center);
|
||||
|
||||
selectionGroup.current.position.lerp(
|
||||
new THREE.Vector3(
|
||||
targetX - (center.x - selectionGroup.current.position.x),
|
||||
selectionGroup.current.position.y,
|
||||
targetZ - (center.z - selectionGroup.current.position.z)
|
||||
),
|
||||
moveSpeed
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const moveAssets = () => {
|
||||
setMovedObjects(selectedAssets);
|
||||
selectedAssets.forEach((asset: any) => {
|
||||
selectionGroup.current.attach(asset);
|
||||
const states: Record<string, { position: THREE.Vector3; rotation?: THREE.Euler; }> = {};
|
||||
const positions: Record<string, THREE.Vector3> = {};
|
||||
|
||||
selectedAssets.forEach((asset: THREE.Object3D) => {
|
||||
states[asset.uuid] = {
|
||||
position: new THREE.Vector3().copy(asset.position),
|
||||
rotation: asset.rotation ? new THREE.Euler().copy(asset.rotation) : undefined
|
||||
};
|
||||
positions[asset.uuid] = new THREE.Vector3().copy(asset.position);
|
||||
});
|
||||
|
||||
setInitialStates(states);
|
||||
setInitialPositions(positions);
|
||||
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const intersectionPoint = new THREE.Vector3();
|
||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
|
||||
if (hit && selectedAssets[0]) {
|
||||
const offset = calculateDragOffset(selectedAssets[0], hit);
|
||||
setDragOffset(offset);
|
||||
}
|
||||
|
||||
setMovedObjects(selectedAssets);
|
||||
setIsMoving(true);
|
||||
};
|
||||
|
||||
const placeMovedAssets = () => {
|
||||
if (movedObjects.length === 0) return;
|
||||
|
||||
movedObjects.forEach(async (obj: THREE.Object3D) => {
|
||||
if (obj && AssetGroup.current) {
|
||||
let worldPosition = new THREE.Vector3();
|
||||
obj.getWorldPosition(worldPosition);
|
||||
|
||||
if (worldPosition.y < 0) {
|
||||
worldPosition.y = 0;
|
||||
}
|
||||
|
||||
selectionGroup.current.remove(obj);
|
||||
obj.position.copy(worldPosition);
|
||||
movedObjects.forEach(async (movedAsset: THREE.Object3D) => {
|
||||
if (movedAsset) {
|
||||
const assetUuid = movedAsset.userData.modelUuid;
|
||||
const asset = getAssetById(assetUuid);
|
||||
if (!asset) return;
|
||||
|
||||
const newFloorItem: Types.FloorItemType = {
|
||||
modelUuid: obj.userData.modelUuid,
|
||||
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: movedAsset.userData.modelUuid,
|
||||
modelName: movedAsset.userData.modelName,
|
||||
assetId: movedAsset.userData.assetId,
|
||||
position: asset.position,
|
||||
rotation: { x: movedAsset.rotation.x, y: movedAsset.rotation.y, z: movedAsset.rotation.z },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
};
|
||||
|
||||
if (obj.userData.eventData) {
|
||||
const eventData = eventStore.getState().getEventByModelUuid(obj.userData.modelUuid);
|
||||
const productData = productStore.getState().getEventByModelUuid(selectedProduct.productUuid, obj.userData.modelUuid);
|
||||
if (movedAsset.userData.eventData) {
|
||||
const eventData = eventStore.getState().getEventByModelUuid(movedAsset.userData.modelUuid);
|
||||
const productData = productStore.getState().getEventByModelUuid(selectedProduct.productUuid, movedAsset.userData.modelUuid);
|
||||
|
||||
if (eventData) {
|
||||
eventStore.getState().updateEvent(obj.userData.modelUuid, {
|
||||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||
eventStore.getState().updateEvent(movedAsset.userData.modelUuid, {
|
||||
position: asset.position,
|
||||
rotation: [movedAsset.rotation.x, movedAsset.rotation.y, movedAsset.rotation.z],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -278,10 +307,10 @@ function MoveControls3D({
|
||||
.getState()
|
||||
.updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
obj.userData.modelUuid,
|
||||
movedAsset.userData.modelUuid,
|
||||
{
|
||||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||
position: asset.position,
|
||||
rotation: [movedAsset.rotation.x, movedAsset.rotation.y, movedAsset.rotation.z],
|
||||
}
|
||||
);
|
||||
|
||||
@@ -298,9 +327,9 @@ function MoveControls3D({
|
||||
}
|
||||
}
|
||||
|
||||
updateAsset(obj.userData.modelUuid, {
|
||||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||
updateAsset(movedAsset.userData.modelUuid, {
|
||||
position: asset.position,
|
||||
rotation: [movedAsset.rotation.x, movedAsset.rotation.y, movedAsset.rotation.z],
|
||||
});
|
||||
|
||||
//REST
|
||||
@@ -324,7 +353,7 @@ function MoveControls3D({
|
||||
modelName: newFloorItem.modelName,
|
||||
assetId: newFloorItem.assetId,
|
||||
position: newFloorItem.position,
|
||||
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||
rotation: { x: movedAsset.rotation.x, y: movedAsset.rotation.y, z: movedAsset.rotation.z },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
socketId: socket.id,
|
||||
@@ -333,22 +362,16 @@ function MoveControls3D({
|
||||
userId
|
||||
};
|
||||
|
||||
// console.log('data: ', data);
|
||||
socket.emit("v1:model-asset:add", data);
|
||||
|
||||
AssetGroup.current.add(obj);
|
||||
}
|
||||
});
|
||||
|
||||
echo.success("Object moved!");
|
||||
|
||||
setIsMoving(false);
|
||||
clearSelection();
|
||||
};
|
||||
|
||||
const clearSelection = () => {
|
||||
selectionGroup.current.children = [];
|
||||
selectionGroup.current.position.set(0, 0, 0);
|
||||
selectionGroup.current.rotation.set(0, 0, 0);
|
||||
setpastedObjects([]);
|
||||
setDuplicatedObjects([]);
|
||||
setMovedObjects([]);
|
||||
@@ -365,4 +388,4 @@ function MoveControls3D({
|
||||
);
|
||||
}
|
||||
|
||||
export default MoveControls3D;
|
||||
export default MoveControls3D;
|
||||
Reference in New Issue
Block a user