refactor: enhance camera controls and improve scene project update logic

This commit is contained in:
2025-09-05 18:31:00 +05:30
parent 0f10a84215
commit 1253473a5d
3 changed files with 52 additions and 36 deletions

View File

@@ -97,6 +97,7 @@ export function useModelEventHandlers({ boundingBox, groupRef, asset }: { boundi
} else {
const collisionPos = new THREE.Vector3();
groupRef.current.getWorldPosition(collisionPos);
const size = boundingBox.getSize(new THREE.Vector3());
const currentPos = new THREE.Vector3().copy(camera.position);
@@ -109,7 +110,7 @@ export function useModelEventHandlers({ boundingBox, groupRef, asset }: { boundi
const newCameraPos = new THREE.Vector3().copy(collisionPos).sub(direction.multiplyScalar(offsetDistance));
camera.position.copy(newCameraPos);
(controls as CameraControls).setLookAt(newCameraPos.x, newCameraPos.y, newCameraPos.z, collisionPos.x, 0, collisionPos.z, true);
(controls as CameraControls).setLookAt(newCameraPos.x, size.y > newCameraPos.y ? size.y : newCameraPos.y, newCameraPos.z, collisionPos.x, 0, collisionPos.z, true);
}
setSelectedFloorAsset(groupRef.current);

View File

@@ -1,11 +1,13 @@
import { useFrame, useThree } from "@react-three/fiber";
import { useSceneContext } from "../sceneContext";
import { CameraControls } from "@react-three/drei";
import { useIsComparing } from "../../../store/builder/store";
import useModuleStore from "../../../store/ui/useModuleStore";
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
import { useSceneStore } from "../../../store/scene/useSceneStore";
import { Vector3 } from "three";
import { useFrame, useThree } from "@react-three/fiber";
import { CameraControls } from "@react-three/drei";
import { useSceneContext } from "../sceneContext";
import { useIsComparing } from "../../../store/builder/store";
import { useSceneStore } from "../../../store/scene/useSceneStore";
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
import useModuleStore from "../../../store/ui/useModuleStore";
import * as CONSTANTS from "../../../types/world/worldConstants";
function SyncCam() {
const { layout } = useSceneContext();
@@ -17,6 +19,10 @@ function SyncCam() {
useFrame(() => {
if (layout === "Comparison Layout" && controls && camState) {
(controls as any).mouseButtons.left = CONSTANTS.controlsTransition.leftMouse;
(controls as any).mouseButtons.right = CONSTANTS.controlsTransition.rightMouse;
(controls as any).mouseButtons.wheel = CONSTANTS.controlsTransition.wheelMouse;
(controls as any).mouseButtons.middle = CONSTANTS.controlsTransition.middleMouse;
(controls as CameraControls).setLookAt(camState.position.x, camState.position.y, camState.position.z, camState.target.x, camState.target.y, camState.target.z, true);
}
if (layout === "Main Layout" && controls && isComparing && activeModule === "simulation" && comparisonProduct) {

View File

@@ -16,13 +16,16 @@ import { useLoadingProgress, useSocketStore } from "../../store/builder/store";
import { Color, SRGBColorSpace } from "three";
import { compressImage } from "../../utils/compressImage";
export default function Scene({ layout }: { readonly layout: "Main Layout" | "Comparison Layout"; }) {
const map = useMemo(() => [
{ name: "forward", keys: ["ArrowUp", "w", "W"] },
{ name: "backward", keys: ["ArrowDown", "s", "S"] },
{ name: "left", keys: ["ArrowLeft", "a", "A"] },
{ name: "right", keys: ["ArrowRight", "d", "D"] },
], []);
export default function Scene({ layout }: { readonly layout: "Main Layout" | "Comparison Layout" }) {
const map = useMemo(
() => [
{ name: "forward", keys: ["ArrowUp", "w", "W"] },
{ name: "backward", keys: ["ArrowDown", "s", "S"] },
{ name: "left", keys: ["ArrowLeft", "a", "A"] },
{ name: "right", keys: ["ArrowRight", "d", "D"] },
],
[]
);
const { assetStore } = useSceneContext();
const { assets } = assetStore();
const { userId, organization } = getUserData();
@@ -33,26 +36,28 @@ export default function Scene({ layout }: { readonly layout: "Main Layout" | "Co
useEffect(() => {
if (!projectId || loadingProgress !== 0) return;
getAllProjects(userId, organization).then((projects) => {
if (!projects.Projects) return;
let project = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId);
const canvas = document.getElementById("sceneCanvas")?.getElementsByTagName("canvas")[0];
if (!canvas) return;
compressImage(canvas.toDataURL("image/png")).then((screenshotDataUrl) => {
const updateProjects = {
projectId: project?._id,
organization,
userId,
projectName: project?.projectName,
thumbnail: screenshotDataUrl,
};
if (projectSocket) {
projectSocket.emit("v1:project:update", updateProjects);
}
getAllProjects(userId, organization)
.then((projects) => {
if (!projects.Projects) return;
let project = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId);
const canvas = document.getElementById("sceneCanvas")?.getElementsByTagName("canvas")[0];
if (!canvas) return;
compressImage(canvas.toDataURL("image/png")).then((screenshotDataUrl) => {
const updateProjects = {
projectId: project?._id,
organization,
userId,
projectName: project?.projectName,
thumbnail: screenshotDataUrl,
};
if (projectSocket) {
projectSocket.emit("v1:project:update", updateProjects);
}
});
})
.catch((err) => {
console.error(err);
});
}).catch((err) => {
console.error(err);
});
// eslint-disable-next-line
}, [activeModule, assets, loadingProgress]);
@@ -63,9 +68,13 @@ export default function Scene({ layout }: { readonly layout: "Main Layout" | "Co
shadows
color="#aaaa"
eventPrefix="client"
onContextMenu={(e) => { e.preventDefault(); }}
onContextMenu={(e) => {
e.preventDefault();
}}
performance={{ min: 0.9, max: 1.0 }}
onCreated={(e) => { e.scene.background = layout === "Main Layout" ? null : new Color(0x19191d); }}
onCreated={(e) => {
e.scene.background = layout === "Main Layout" ? null : new Color(0x19191d);
}}
gl={{ outputColorSpace: SRGBColorSpace, powerPreference: "high-performance", antialias: true, preserveDrawingBuffer: true }}
>
<Setup />