added direction movement to asset during move and duplication
This commit is contained in:
@@ -35,6 +35,7 @@ const DuplicationControls3D = ({
|
|||||||
const { selectedVersion } = selectedVersionStore();
|
const { selectedVersion } = selectedVersionStore();
|
||||||
const { userId, organization } = getUserData();
|
const { userId, organization } = getUserData();
|
||||||
|
|
||||||
|
const [axisConstraint, setAxisConstraint] = useState<"x" | "z" | null>(null);
|
||||||
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
|
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
|
||||||
const [initialPositions, setInitialPositions] = useState<Record<string, THREE.Vector3>>({});
|
const [initialPositions, setInitialPositions] = useState<Record<string, THREE.Vector3>>({});
|
||||||
const [isDuplicating, setIsDuplicating] = useState(false);
|
const [isDuplicating, setIsDuplicating] = useState(false);
|
||||||
@@ -82,6 +83,19 @@ const DuplicationControls3D = ({
|
|||||||
const onKeyDown = (event: KeyboardEvent) => {
|
const onKeyDown = (event: KeyboardEvent) => {
|
||||||
const keyCombination = detectModifierKeys(event);
|
const keyCombination = detectModifierKeys(event);
|
||||||
|
|
||||||
|
if (isDuplicating && duplicatedObjects.length > 0) {
|
||||||
|
if (event.key.toLowerCase() === 'x') {
|
||||||
|
setAxisConstraint(prev => prev === 'x' ? null : 'x');
|
||||||
|
event.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.key.toLowerCase() === 'z') {
|
||||||
|
setAxisConstraint(prev => prev === 'z' ? null : 'z');
|
||||||
|
event.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (keyCombination === "Ctrl+D" && movedObjects.length === 0 && rotatedObjects.length === 0) {
|
if (keyCombination === "Ctrl+D" && movedObjects.length === 0 && rotatedObjects.length === 0) {
|
||||||
duplicateSelection();
|
duplicateSelection();
|
||||||
}
|
}
|
||||||
@@ -127,7 +141,28 @@ const DuplicationControls3D = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dragOffset) {
|
if (dragOffset) {
|
||||||
const adjustedHit = new THREE.Vector3().addVectors(intersectionPoint, 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
duplicatedObjects.forEach((duplicatedObject: THREE.Object3D) => {
|
duplicatedObjects.forEach((duplicatedObject: THREE.Object3D) => {
|
||||||
if (duplicatedObject.userData.modelUuid) {
|
if (duplicatedObject.userData.modelUuid) {
|
||||||
@@ -154,6 +189,21 @@ const DuplicationControls3D = ({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (duplicatedObjects.length > 0) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [axisConstraint, camera, duplicatedObjects])
|
||||||
|
|
||||||
const duplicateSelection = useCallback(() => {
|
const duplicateSelection = useCallback(() => {
|
||||||
if (selectedAssets.length > 0 && duplicatedObjects.length === 0) {
|
if (selectedAssets.length > 0 && duplicatedObjects.length === 0) {
|
||||||
const positions: Record<string, THREE.Vector3> = {};
|
const positions: Record<string, THREE.Vector3> = {};
|
||||||
@@ -585,6 +635,7 @@ const DuplicationControls3D = ({
|
|||||||
setSelectedAssets([]);
|
setSelectedAssets([]);
|
||||||
setIsDuplicating(false);
|
setIsDuplicating(false);
|
||||||
setDragOffset(null);
|
setDragOffset(null);
|
||||||
|
setAxisConstraint(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ function MoveControls3D({
|
|||||||
const { selectedVersionStore } = useVersionContext();
|
const { selectedVersionStore } = useVersionContext();
|
||||||
const { selectedVersion } = selectedVersionStore();
|
const { selectedVersion } = selectedVersionStore();
|
||||||
|
|
||||||
|
const [axisConstraint, setAxisConstraint] = useState<"x" | "z" | null>(null);
|
||||||
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
|
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
|
||||||
const [initialPositions, setInitialPositions] = useState<Record<string, THREE.Vector3>>({});
|
const [initialPositions, setInitialPositions] = useState<Record<string, THREE.Vector3>>({});
|
||||||
const [initialStates, setInitialStates] = useState<Record<string, { position: THREE.Vector3; rotation?: THREE.Euler; }>>({});
|
const [initialStates, setInitialStates] = useState<Record<string, { position: THREE.Vector3; rotation?: THREE.Euler; }>>({});
|
||||||
@@ -114,6 +115,19 @@ function MoveControls3D({
|
|||||||
if (pastedObjects.length > 0 || duplicatedObjects.length > 0 || rotatedObjects.length > 0)
|
if (pastedObjects.length > 0 || duplicatedObjects.length > 0 || rotatedObjects.length > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (isMoving && movedObjects.length > 0) {
|
||||||
|
if (event.key.toLowerCase() === 'x') {
|
||||||
|
setAxisConstraint(prev => prev === 'x' ? null : 'x');
|
||||||
|
event.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.key.toLowerCase() === 'z') {
|
||||||
|
setAxisConstraint(prev => prev === 'z' ? null : 'z');
|
||||||
|
event.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (keyCombination !== keyEvent) {
|
if (keyCombination !== keyEvent) {
|
||||||
if (keyCombination === "Ctrl" || keyCombination === "Ctrl+Shift" || keyCombination === "Shift") {
|
if (keyCombination === "Ctrl" || keyCombination === "Ctrl+Shift" || keyCombination === "Shift") {
|
||||||
setKeyEvent(keyCombination);
|
setKeyEvent(keyCombination);
|
||||||
@@ -184,9 +198,22 @@ function MoveControls3D({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 0)
|
setAxisConstraint(null);
|
||||||
|
}, 100)
|
||||||
}, [movedObjects, initialStates, updateAsset]);
|
}, [movedObjects, initialStates, updateAsset]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (movedObjects.length > 0) {
|
||||||
|
const intersectionPoint = new THREE.Vector3();
|
||||||
|
raycaster.setFromCamera(pointer, camera);
|
||||||
|
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||||
|
if (hit) {
|
||||||
|
const newOffset = calculateDragOffset(movedObjects[0], intersectionPoint);
|
||||||
|
setDragOffset(newOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [axisConstraint, camera, movedObjects])
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (!isMoving || movedObjects.length === 0) return;
|
if (!isMoving || movedObjects.length === 0) return;
|
||||||
|
|
||||||
@@ -204,7 +231,16 @@ function MoveControls3D({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dragOffset) {
|
if (dragOffset) {
|
||||||
const rawBasePosition = new THREE.Vector3().addVectors(intersectionPoint, dragOffset);
|
let rawBasePosition = new THREE.Vector3().addVectors(intersectionPoint, dragOffset);
|
||||||
|
|
||||||
|
if (axisConstraint) {
|
||||||
|
const currentBasePosition = movedObjects[0].position.clone();
|
||||||
|
if (axisConstraint === 'x') {
|
||||||
|
rawBasePosition = new THREE.Vector3(rawBasePosition.x, currentBasePosition.y, currentBasePosition.z);
|
||||||
|
} else if (axisConstraint === 'z') {
|
||||||
|
rawBasePosition = new THREE.Vector3(currentBasePosition.x, currentBasePosition.y, rawBasePosition.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let moveDistance = keyEvent.includes("Shift") ? 0.05 : 1;
|
let moveDistance = keyEvent.includes("Shift") ? 0.05 : 1;
|
||||||
|
|
||||||
@@ -422,6 +458,7 @@ function MoveControls3D({
|
|||||||
echo.success("Object moved!");
|
echo.success("Object moved!");
|
||||||
setIsMoving(false);
|
setIsMoving(false);
|
||||||
clearSelection();
|
clearSelection();
|
||||||
|
setAxisConstraint(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearSelection = () => {
|
const clearSelection = () => {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import useVersionHistoryVisibleStore, {
|
|||||||
useDfxUpload,
|
useDfxUpload,
|
||||||
useRenameModeStore,
|
useRenameModeStore,
|
||||||
useSaveVersion,
|
useSaveVersion,
|
||||||
|
useSelectedAssets,
|
||||||
useSelectedComment,
|
useSelectedComment,
|
||||||
useSelectedFloorItem,
|
useSelectedFloorItem,
|
||||||
useSelectedWallItem,
|
useSelectedWallItem,
|
||||||
@@ -40,6 +41,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
const { toggleView, setToggleView } = useToggleView();
|
const { toggleView, setToggleView } = useToggleView();
|
||||||
const { setAddAction } = useAddAction();
|
const { setAddAction } = useAddAction();
|
||||||
const { setSelectedWallItem } = useSelectedWallItem();
|
const { setSelectedWallItem } = useSelectedWallItem();
|
||||||
|
const { selectedAssets } = useSelectedAssets();
|
||||||
const { setActiveTool } = useActiveTool();
|
const { setActiveTool } = useActiveTool();
|
||||||
const { clearSelectedZone } = useSelectedZoneStore();
|
const { clearSelectedZone } = useSelectedZoneStore();
|
||||||
const { showShortcuts, setShowShortcuts } = useShortcutStore();
|
const { showShortcuts, setShowShortcuts } = useShortcutStore();
|
||||||
@@ -82,7 +84,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
H: "free-hand",
|
H: "free-hand",
|
||||||
};
|
};
|
||||||
const tool = toolMap[key];
|
const tool = toolMap[key];
|
||||||
if (tool) {
|
if (tool && selectedAssets.length === 0) {
|
||||||
setActiveTool(tool);
|
setActiveTool(tool);
|
||||||
setActiveSubTool(tool);
|
setActiveSubTool(tool);
|
||||||
}
|
}
|
||||||
@@ -278,6 +280,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
hidePlayer,
|
hidePlayer,
|
||||||
selectedFloorItem,
|
selectedFloorItem,
|
||||||
isRenameMode,
|
isRenameMode,
|
||||||
|
selectedAssets
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user