move controls snapping and slow movement added
This commit is contained in:
@@ -1,22 +1,75 @@
|
||||
export function snapControls(value: number, event: string): number {
|
||||
const CTRL_DISTANCE = 1; // Snap to whole numbers when Ctrl is pressed
|
||||
const SHIFT_DISTANCE = 0.01; // Snap to half-step increments when Shift is pressed
|
||||
const CTRL_SHIFT_DISTANCE = 0.1; // Snap to fine increments when both Ctrl and Shift are pressed
|
||||
import * as THREE from "three";
|
||||
|
||||
switch (event) {
|
||||
case "Ctrl":
|
||||
return Math.round(value / CTRL_DISTANCE) * CTRL_DISTANCE;
|
||||
export function getSnappedBasePosition({
|
||||
rawBasePosition,
|
||||
intersectionPoint,
|
||||
movedObjects,
|
||||
axisConstraint,
|
||||
keyEvent,
|
||||
fineMoveBaseRef,
|
||||
lastPointerPositionRef,
|
||||
wasShiftHeldRef
|
||||
}: {
|
||||
rawBasePosition: THREE.Vector3;
|
||||
intersectionPoint: THREE.Vector3;
|
||||
movedObjects: THREE.Object3D[];
|
||||
axisConstraint: "x" | "z" | null;
|
||||
keyEvent: string;
|
||||
fineMoveBaseRef: React.MutableRefObject<THREE.Vector3 | null>;
|
||||
lastPointerPositionRef: React.MutableRefObject<THREE.Vector3 | null>;
|
||||
wasShiftHeldRef: React.MutableRefObject<boolean>;
|
||||
}): THREE.Vector3 {
|
||||
const CTRL_DISTANCE = 0.5;
|
||||
const SHIFT_DISTANCE = 0.05;
|
||||
const CTRL_SHIFT_DISTANCE = 0.05;
|
||||
|
||||
case "Shift":
|
||||
return Math.round(value / SHIFT_DISTANCE) * SHIFT_DISTANCE;
|
||||
const isShiftHeld = keyEvent.includes("Shift");
|
||||
|
||||
case "Ctrl+Shift":
|
||||
const base = Math.floor(value / CTRL_DISTANCE) * CTRL_DISTANCE;
|
||||
const offset =
|
||||
Math.round((value - base) / CTRL_SHIFT_DISTANCE) * CTRL_SHIFT_DISTANCE;
|
||||
return base + offset;
|
||||
// Handle Shift toggle state
|
||||
if (isShiftHeld !== wasShiftHeldRef.current) {
|
||||
if (isShiftHeld) {
|
||||
fineMoveBaseRef.current = movedObjects[0].position.clone();
|
||||
lastPointerPositionRef.current = intersectionPoint.clone();
|
||||
} else {
|
||||
fineMoveBaseRef.current = null;
|
||||
}
|
||||
wasShiftHeldRef.current = isShiftHeld;
|
||||
}
|
||||
|
||||
default:
|
||||
return value; // No snapping if no modifier key is pressed
|
||||
}
|
||||
// Start from raw
|
||||
let baseNewPosition = rawBasePosition.clone();
|
||||
|
||||
// Apply snapping / fine move
|
||||
if (keyEvent === "Ctrl") {
|
||||
baseNewPosition.set(
|
||||
Math.round(baseNewPosition.x / CTRL_DISTANCE) * CTRL_DISTANCE,
|
||||
baseNewPosition.y,
|
||||
Math.round(baseNewPosition.z / CTRL_DISTANCE) * CTRL_DISTANCE
|
||||
);
|
||||
} else if (keyEvent === "Ctrl+Shift") {
|
||||
if (isShiftHeld && fineMoveBaseRef.current && lastPointerPositionRef.current) {
|
||||
const pointerDelta = new THREE.Vector3().subVectors(intersectionPoint, lastPointerPositionRef.current);
|
||||
baseNewPosition = fineMoveBaseRef.current.clone().add(pointerDelta.multiplyScalar(SHIFT_DISTANCE));
|
||||
}
|
||||
baseNewPosition.set(
|
||||
Math.round(baseNewPosition.x / CTRL_SHIFT_DISTANCE) * CTRL_SHIFT_DISTANCE,
|
||||
baseNewPosition.y,
|
||||
Math.round(baseNewPosition.z / CTRL_SHIFT_DISTANCE) * CTRL_SHIFT_DISTANCE
|
||||
);
|
||||
} else if (isShiftHeld && fineMoveBaseRef.current && lastPointerPositionRef.current) {
|
||||
const pointerDelta = new THREE.Vector3().subVectors(intersectionPoint, lastPointerPositionRef.current);
|
||||
baseNewPosition = fineMoveBaseRef.current.clone().add(pointerDelta.multiplyScalar(SHIFT_DISTANCE));
|
||||
}
|
||||
|
||||
// Apply axis constraint last
|
||||
if (axisConstraint) {
|
||||
const currentBasePosition = movedObjects[0].position.clone();
|
||||
if (axisConstraint === 'x') {
|
||||
baseNewPosition.set(baseNewPosition.x, currentBasePosition.y, currentBasePosition.z);
|
||||
} else if (axisConstraint === 'z') {
|
||||
baseNewPosition.set(currentBasePosition.x, currentBasePosition.y, baseNewPosition.z);
|
||||
}
|
||||
}
|
||||
|
||||
return baseNewPosition;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user