added undo redo for builder (not for simulation data)
This commit is contained in:
@@ -28,7 +28,8 @@ const CopyPasteControls3D = ({
|
||||
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
||||
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
||||
const { socket } = useSocketStore();
|
||||
const { assetStore, eventStore } = useSceneContext();
|
||||
const { assetStore, eventStore, undoRedo3DStore } = useSceneContext();
|
||||
const { push3D } = undoRedo3DStore();
|
||||
const { addEvent } = eventStore();
|
||||
const { projectId } = useParams();
|
||||
const { assets, addAsset, updateAsset, removeAsset, getAssetById } = assetStore();
|
||||
@@ -198,6 +199,9 @@ const CopyPasteControls3D = ({
|
||||
const addPastedObjects = () => {
|
||||
if (pastedObjects.length === 0) return;
|
||||
|
||||
const undoActions: UndoRedo3DAction[] = [];
|
||||
const assetsToCopy: AssetData[] = [];
|
||||
|
||||
pastedObjects.forEach(async (pastedAsset: THREE.Object3D) => {
|
||||
if (pastedAsset) {
|
||||
const assetUuid = pastedAsset.userData.modelUuid;
|
||||
@@ -529,9 +533,45 @@ const CopyPasteControls3D = ({
|
||||
|
||||
updateAsset(asset.modelUuid, asset);
|
||||
}
|
||||
|
||||
assetsToCopy.push({
|
||||
type: "Asset",
|
||||
assetData: {
|
||||
modelUuid: newFloorItem.modelUuid,
|
||||
modelName: newFloorItem.modelName,
|
||||
assetId: newFloorItem.assetId,
|
||||
position: [position.x, position.y, position.z],
|
||||
rotation: [pastedAsset.rotation.x, pastedAsset.rotation.y, pastedAsset.rotation.z],
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
isCollidable: false,
|
||||
opacity: 1,
|
||||
eventData: newFloorItem.eventData || undefined
|
||||
},
|
||||
timeStap: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (assetsToCopy.length === 1) {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Asset-Copied",
|
||||
asset: assetsToCopy[0]
|
||||
});
|
||||
} else {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Assets-Copied",
|
||||
assets: assetsToCopy
|
||||
});
|
||||
}
|
||||
|
||||
push3D({
|
||||
type: 'Scene',
|
||||
actions: undoActions
|
||||
});
|
||||
|
||||
echo.success("Object added!");
|
||||
clearSelection();
|
||||
};
|
||||
|
||||
@@ -26,7 +26,8 @@ const DuplicationControls3D = ({
|
||||
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
||||
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
||||
const { socket } = useSocketStore();
|
||||
const { assetStore, eventStore } = useSceneContext();
|
||||
const { assetStore, eventStore, undoRedo3DStore } = useSceneContext();
|
||||
const { push3D } = undoRedo3DStore();
|
||||
const { addEvent } = eventStore();
|
||||
const { projectId } = useParams();
|
||||
const { assets, addAsset, updateAsset, removeAsset, getAssetById } = assetStore();
|
||||
@@ -199,6 +200,9 @@ const DuplicationControls3D = ({
|
||||
const addDuplicatedAssets = () => {
|
||||
if (duplicatedObjects.length === 0) return;
|
||||
|
||||
const undoActions: UndoRedo3DAction[] = [];
|
||||
const assetsToDuplicate: AssetData[] = [];
|
||||
|
||||
duplicatedObjects.forEach(async (duplicatedAsset: THREE.Object3D) => {
|
||||
if (duplicatedAsset) {
|
||||
const assetUuid = duplicatedAsset.userData.modelUuid;
|
||||
@@ -530,9 +534,45 @@ const DuplicationControls3D = ({
|
||||
|
||||
updateAsset(asset.modelUuid, asset);
|
||||
}
|
||||
|
||||
assetsToDuplicate.push({
|
||||
type: "Asset",
|
||||
assetData: {
|
||||
modelUuid: newFloorItem.modelUuid,
|
||||
modelName: newFloorItem.modelName,
|
||||
assetId: newFloorItem.assetId,
|
||||
position: [position.x, position.y, position.z],
|
||||
rotation: [duplicatedAsset.rotation.x, duplicatedAsset.rotation.y, duplicatedAsset.rotation.z],
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
isCollidable: false,
|
||||
opacity: 1,
|
||||
eventData: newFloorItem.eventData || undefined
|
||||
},
|
||||
timeStap: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (assetsToDuplicate.length === 1) {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Asset-Copied",
|
||||
asset: assetsToDuplicate[0]
|
||||
});
|
||||
} else {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Assets-Copied",
|
||||
assets: assetsToDuplicate
|
||||
});
|
||||
}
|
||||
|
||||
push3D({
|
||||
type: 'Scene',
|
||||
actions: undoActions
|
||||
});
|
||||
|
||||
echo.success("Object duplicated!");
|
||||
clearSelection();
|
||||
};
|
||||
|
||||
@@ -37,7 +37,8 @@ function MoveControls3D({
|
||||
const [keyEvent, setKeyEvent] = useState<"Ctrl" | "Shift" | "Ctrl+Shift" | "">("");
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
const { assetStore, eventStore, productStore } = useSceneContext();
|
||||
const { assetStore, eventStore, productStore, undoRedo3DStore } = useSceneContext();
|
||||
const { push3D } = undoRedo3DStore();
|
||||
const { updateAsset, getAssetById } = assetStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
@@ -284,6 +285,9 @@ function MoveControls3D({
|
||||
const placeMovedAssets = () => {
|
||||
if (movedObjects.length === 0) return;
|
||||
|
||||
const undoActions: UndoRedo3DAction[] = [];
|
||||
const assetsToUpdate: AssetData[] = [];
|
||||
|
||||
movedObjects.forEach(async (movedAsset: THREE.Object3D) => {
|
||||
if (movedAsset) {
|
||||
const assetUuid = movedAsset.userData.modelUuid;
|
||||
@@ -291,6 +295,32 @@ function MoveControls3D({
|
||||
const model = scene.getObjectByProperty("uuid", movedAsset.userData.modelUuid);
|
||||
if (!asset || !model) return;
|
||||
const position = new THREE.Vector3().copy(model.position);
|
||||
const initialState = initialStates[movedAsset.uuid];
|
||||
|
||||
if (initialState) {
|
||||
assetsToUpdate.push({
|
||||
type: "Asset",
|
||||
assetData: {
|
||||
...asset,
|
||||
position: [
|
||||
initialState.position.x,
|
||||
initialState.position.y,
|
||||
initialState.position.z
|
||||
],
|
||||
rotation: [
|
||||
initialState.rotation?.x || 0,
|
||||
initialState.rotation?.y || 0,
|
||||
initialState.rotation?.z || 0
|
||||
]
|
||||
},
|
||||
newData: {
|
||||
...asset,
|
||||
position: [position.x, position.y, position.z],
|
||||
rotation: [movedAsset.rotation.x, movedAsset.rotation.y, movedAsset.rotation.z]
|
||||
},
|
||||
timeStap: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
|
||||
const newFloorItem: Types.FloorItemType = {
|
||||
modelUuid: movedAsset.userData.modelUuid,
|
||||
@@ -368,6 +398,27 @@ function MoveControls3D({
|
||||
}
|
||||
});
|
||||
|
||||
if (assetsToUpdate.length > 0) {
|
||||
if (assetsToUpdate.length === 1) {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Asset-Update",
|
||||
asset: assetsToUpdate[0]
|
||||
});
|
||||
} else {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Assets-Update",
|
||||
assets: assetsToUpdate
|
||||
});
|
||||
}
|
||||
|
||||
push3D({
|
||||
type: 'Scene',
|
||||
actions: undoActions
|
||||
});
|
||||
}
|
||||
|
||||
echo.success("Object moved!");
|
||||
setIsMoving(false);
|
||||
clearSelection();
|
||||
|
||||
@@ -32,7 +32,8 @@ function RotateControls3D({
|
||||
const { socket } = useSocketStore();
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
const { assetStore, eventStore, productStore } = useSceneContext();
|
||||
const { assetStore, eventStore, productStore, undoRedo3DStore } = useSceneContext();
|
||||
const { push3D } = undoRedo3DStore();
|
||||
const { updateAsset } = assetStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
@@ -222,12 +223,43 @@ function RotateControls3D({
|
||||
const placeRotatedAssets = useCallback(() => {
|
||||
if (rotatedObjects.length === 0) return;
|
||||
|
||||
const undoActions: UndoRedo3DAction[] = [];
|
||||
const assetsToUpdate: AssetData[] = [];
|
||||
|
||||
rotatedObjects.forEach((obj: THREE.Object3D) => {
|
||||
if (obj && obj.userData.modelUuid) {
|
||||
const asset = assetStore.getState().getAssetById(obj.userData.modelUuid);
|
||||
if (!asset) return;
|
||||
|
||||
const rotationArray: [number, number, number] = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||
|
||||
const positionArray: [number, number, number] = [obj.position.x, obj.position.y, obj.position.z];
|
||||
|
||||
if (initialRotations[obj.uuid] && initialPositions[obj.uuid]) {
|
||||
assetsToUpdate.push({
|
||||
type: "Asset",
|
||||
assetData: {
|
||||
...asset,
|
||||
position: [
|
||||
initialPositions[obj.uuid].x,
|
||||
initialPositions[obj.uuid].y,
|
||||
initialPositions[obj.uuid].z
|
||||
],
|
||||
rotation: [
|
||||
initialRotations[obj.uuid].x,
|
||||
initialRotations[obj.uuid].y,
|
||||
initialRotations[obj.uuid].z
|
||||
]
|
||||
},
|
||||
newData: {
|
||||
...asset,
|
||||
position: positionArray,
|
||||
rotation: rotationArray
|
||||
},
|
||||
timeStap: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
|
||||
const newFloorItem: Types.FloorItemType = {
|
||||
modelUuid: obj.userData.modelUuid,
|
||||
modelName: obj.userData.modelName,
|
||||
@@ -305,6 +337,27 @@ function RotateControls3D({
|
||||
}
|
||||
});
|
||||
|
||||
if (assetsToUpdate.length > 0) {
|
||||
if (assetsToUpdate.length === 1) {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Asset-Update",
|
||||
asset: assetsToUpdate[0]
|
||||
});
|
||||
} else {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Assets-Update",
|
||||
assets: assetsToUpdate
|
||||
});
|
||||
}
|
||||
|
||||
push3D({
|
||||
type: 'Scene',
|
||||
actions: undoActions
|
||||
});
|
||||
}
|
||||
|
||||
setIsRotating(false);
|
||||
clearSelection();
|
||||
}, [rotatedObjects, eventStore, productStore, selectedProduct, updateBackend, projectId, updateAsset, organization, socket, selectedVersion, userId]);
|
||||
|
||||
@@ -31,8 +31,9 @@ const SelectionControls3D: React.FC = () => {
|
||||
const boundingBoxRef = useRef<THREE.Mesh>();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { socket } = useSocketStore();
|
||||
const { assetStore, eventStore, productStore } = useSceneContext();
|
||||
const { removeAsset } = assetStore();
|
||||
const { assetStore, eventStore, productStore, undoRedo3DStore } = useSceneContext();
|
||||
const { push3D } = undoRedo3DStore();
|
||||
const { removeAsset, getAssetById } = assetStore();
|
||||
const selectionBox = useMemo(() => new SelectionBox(camera, scene), [camera, scene]);
|
||||
const { toolMode } = useToolMode();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
@@ -266,12 +267,18 @@ const SelectionControls3D: React.FC = () => {
|
||||
const deleteSelection = () => {
|
||||
if (selectedAssets.length > 0 && duplicatedObjects.length === 0) {
|
||||
|
||||
const undoActions: UndoRedo3DAction[] = [];
|
||||
const assetsToDelete: AssetData[] = [];
|
||||
|
||||
const selectedUUIDs = selectedAssets.map((mesh: THREE.Object3D) => mesh.uuid);
|
||||
|
||||
selectedAssets.forEach((selectedMesh: THREE.Object3D) => {
|
||||
const asset = getAssetById(selectedMesh.userData.modelUuid);
|
||||
if (!asset) return;
|
||||
|
||||
//REST
|
||||
|
||||
// const response = await deleteFloorItem(organization, selectedMesh.userData.modelUuid, selectedMesh.userData.modelName);
|
||||
// const response = deleteFloorItem(organization, selectedMesh.userData.modelUuid, selectedMesh.userData.modelName);
|
||||
|
||||
//SOCKET
|
||||
|
||||
@@ -321,6 +328,31 @@ const SelectionControls3D: React.FC = () => {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
assetsToDelete.push({
|
||||
type: "Asset",
|
||||
assetData: asset,
|
||||
timeStap: new Date().toISOString()
|
||||
});
|
||||
});
|
||||
|
||||
if (assetsToDelete.length === 1) {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Asset-Delete",
|
||||
asset: assetsToDelete[0]
|
||||
});
|
||||
} else {
|
||||
undoActions.push({
|
||||
module: "builder",
|
||||
actionType: "Assets-Delete",
|
||||
assets: assetsToDelete
|
||||
});
|
||||
}
|
||||
|
||||
push3D({
|
||||
type: 'Scene',
|
||||
actions: undoActions
|
||||
});
|
||||
|
||||
selectedUUIDs.forEach((uuid: string) => {
|
||||
|
||||
Reference in New Issue
Block a user