diff --git a/app/design/ui-3d/fresh/gestures/move.ts b/app/design/ui-3d/fresh/gestures/move.ts index e093d3f3..0979768c 100644 --- a/app/design/ui-3d/fresh/gestures/move.ts +++ b/app/design/ui-3d/fresh/gestures/move.ts @@ -2,15 +2,9 @@ import { ThreeEvent } from "@react-three/fiber" import { Handler } from "@use-gesture/react" import { pipe } from "fp-ts/lib/function" import { useRef } from "react" -import { Matrix4, Vector3 } from "three" +import { Vector3 } from "three" import { ref } from "valtio" -import { - A, - O, - pipeLog, - pipeLogWith, - someOrError, -} from "../../../../utils/functions" +import { A, O, someOrError } from "../../../../utils/functions" import pointer from "../../../state/pointer" import scope from "../../../state/scope" import { dispatchOutline } from "../events/outlines" @@ -34,7 +28,7 @@ const useOnDragMove = () => { point0: Vector3 houseTransformsGroup: HouseTransformsGroup layoutGroup: HouseLayoutGroup - nearHouseTransformGroups: HouseTransformsGroup[] + nearNeighbours: HouseTransformsGroup[] thresholdFactor: number } | null>(null) @@ -45,34 +39,6 @@ const useOnDragMove = () => { event: { intersections }, } = state - const computeNearHouseTransformsGroups = ( - houseTransformsGroup: HouseTransformsGroup - ): HouseTransformsGroup[] => - pipe( - houseTransformsGroup.parent, - O.fromNullable, - O.map((scene) => - pipe( - scene.children, - A.filterMap((htg) => { - if ( - !isHouseTransformsGroup(htg) || - htg.uuid === houseTransformsGroup.uuid - ) { - return O.none - } - - const { aabb } = getActiveHouseUserData(houseTransformsGroup) - - return getActiveHouseUserData(htg).aabb.intersectsBox(aabb) - ? O.some(htg) - : O.none - }) - ) - ), - O.getOrElse((): HouseTransformsGroup[] => []) - ) - switch (true) { case first: { pipe( @@ -86,9 +52,6 @@ const useOnDragMove = () => { object, findFirstGuardUp(isHouseTransformsGroup), O.map((houseTransformsGroup) => { - const nearHouseTransformGroups = - computeNearHouseTransformsGroups(houseTransformsGroup) - const layoutGroup = pipe( houseTransformsGroup.userData.getActiveLayoutGroup(), someOrError(`no active layout group in move`) @@ -100,7 +63,8 @@ const useOnDragMove = () => { houseTransformsGroup, lastPoint: point, point0: point, - nearHouseTransformGroups, + nearNeighbours: + houseTransformsGroup.userData.computeNearNeighbours(), thresholdFactor: 1, layoutGroup, } @@ -134,34 +98,25 @@ const useOnDragMove = () => { const { lastPoint, houseTransformsGroup, - nearHouseTransformGroups, + nearNeighbours, point0, thresholdFactor, layoutGroup, } = moveData.current - let collision = false - const [px, pz] = pointer.xz const thisPoint = new Vector3(px, 0, pz) const delta: Vector3 = thisPoint.clone().sub(lastPoint) - const { obb: thisOBB } = getActiveHouseUserData(houseTransformsGroup) + const { obb } = layoutGroup.userData - thisOBB.center.add(delta) + obb.center.add(delta) - for (const nearHouse of nearHouseTransformGroups) { - const { obb: nearOBB } = getActiveHouseUserData(nearHouse) - - console.log(`obb check`) - - if (thisOBB.intersectsOBB(nearOBB)) { - collision = true - } - } + const collision = + houseTransformsGroup.userData.checkCollisions(nearNeighbours) if (collision) { - thisOBB.center.sub(delta) + obb.center.sub(delta) return } @@ -175,8 +130,8 @@ const useOnDragMove = () => { const threshold = (AABB_OFFSET - 1) ** 2 if (dts >= threshold * thresholdFactor) { - moveData.current.nearHouseTransformGroups = - computeNearHouseTransformsGroups(houseTransformsGroup) + moveData.current.nearNeighbours = + houseTransformsGroup.userData.computeNearNeighbours() moveData.current.thresholdFactor++ } diff --git a/app/design/ui-3d/fresh/gestures/rotate.ts b/app/design/ui-3d/fresh/gestures/rotate.ts index 0c66a3c3..617e463a 100644 --- a/app/design/ui-3d/fresh/gestures/rotate.ts +++ b/app/design/ui-3d/fresh/gestures/rotate.ts @@ -11,6 +11,7 @@ import { getActiveHouseUserData, } from "../helpers/sceneQueries" import { + HouseLayoutGroup, HouseTransformsGroup, isHouseTransformsGroup, UserDataTypeEnum, @@ -19,6 +20,8 @@ import { const useOnDragRotate = () => { const rotateData = useRef<{ houseTransformsGroup: HouseTransformsGroup + nearNeighbours: HouseTransformsGroup[] + layoutGroup: HouseLayoutGroup center: Vector3 rotation0: number angle0: number @@ -47,12 +50,15 @@ const useOnDragRotate = () => { object, findFirstGuardUp(isHouseTransformsGroup), O.map((houseTransformsGroup) => { + const layoutGroup = + houseTransformsGroup.userData.unsafeGetActiveLayoutGroup() + const { obb: { center, center: { x: cx, z: cz }, }, - } = getActiveHouseUserData(houseTransformsGroup) + } = layoutGroup.userData const { x: x0, z: z0 } = point @@ -60,6 +66,9 @@ const useOnDragRotate = () => { rotateData.current = { houseTransformsGroup, + nearNeighbours: + houseTransformsGroup.userData.computeNearNeighbours(), + layoutGroup, center, rotation0: houseTransformsGroup.rotation.y, angle0, @@ -87,6 +96,8 @@ const useOnDragRotate = () => { const { center: { x: cx, z: cz }, houseTransformsGroup, + layoutGroup, + nearNeighbours, } = rotateData.current rotateData.current.angle = atan2(cz - pz, cx - px) @@ -94,9 +105,23 @@ const useOnDragRotate = () => { const angleDifference = rotateData.current.angle - rotateData.current.angle0 + const { obb } = layoutGroup.userData + + // obb.??? how do I rotate the OBB by (-angleDifference)? + houseTransformsGroup.rotation.y = rotateData.current.rotation0 - angleDifference + obb.rotation.setFromMatrix4(houseTransformsGroup.matrix) + + if (houseTransformsGroup.userData.checkCollisions(nearNeighbours)) { + houseTransformsGroup.rotation.y = + rotateData.current.rotation0 + angleDifference + obb.rotation.setFromMatrix4(houseTransformsGroup.matrix) + return + } + + layoutGroup.userData.updateBBs() break } } diff --git a/app/design/ui-3d/fresh/scene/houseTransformsGroup.ts b/app/design/ui-3d/fresh/scene/houseTransformsGroup.ts index 87653b7a..3f85de45 100644 --- a/app/design/ui-3d/fresh/scene/houseTransformsGroup.ts +++ b/app/design/ui-3d/fresh/scene/houseTransformsGroup.ts @@ -36,6 +36,7 @@ import { isActiveLayoutGroup, isElementMesh, isHouseLayoutGroup, + isHouseTransformsGroup, isHouseTransformsHandlesGroup, isRotateHandlesGroup, isXStretchHandleGroup, @@ -187,6 +188,9 @@ export const createHouseTransformsGroup = ({ ) ) + const unsafeGetActiveLayoutGroup = (): HouseLayoutGroup => + pipe(getActiveLayoutGroup(), someOrError(`no active layout group`)) + const setActiveLayoutGroup = (nextLayoutGroup: HouseLayoutGroup) => { pipe( houseTransformsGroup.userData.getActiveLayoutGroup(), @@ -384,6 +388,47 @@ export const createHouseTransformsGroup = ({ activeElementMaterials[ifcTag] = specification } + const computeNearNeighbours = (): HouseTransformsGroup[] => + pipe( + houseTransformsGroup.parent, + O.fromNullable, + O.map((scene) => + pipe( + scene.children, + A.filterMap((htg) => { + if ( + !isHouseTransformsGroup(htg) || + htg.uuid === houseTransformsGroup.uuid + ) { + return O.none + } + + const { aabb } = getActiveHouseUserData(houseTransformsGroup) + + return getActiveHouseUserData(htg).aabb.intersectsBox(aabb) + ? O.some(htg) + : O.none + }) + ) + ), + O.getOrElse((): HouseTransformsGroup[] => []) + ) + + const checkCollisions = (neighbours: HouseTransformsGroup[]) => { + let collision = false + + for (const neighbour of neighbours) { + const { obb: nearOBB } = getActiveHouseUserData(neighbour) + + if (houseTransformsGroup.userData.obb.intersectsOBB(nearOBB)) { + collision = true + break + } + } + + return collision + } + const houseTransformsGroupUserData: Omit< HouseTransformsGroupUserData, "activeLayoutGroupUuid" | "activeLayoutDnas" @@ -404,6 +449,7 @@ export const createHouseTransformsGroup = ({ initRotateAndStretchXHandles, updateXStretchHandleLengths, getActiveLayoutGroup, + unsafeGetActiveLayoutGroup, setActiveLayoutGroup, setXStretchHandlesVisible, setZStretchHandlesVisible, @@ -412,6 +458,8 @@ export const createHouseTransformsGroup = ({ refreshAltSectionTypeLayouts, resetMaterials, changeMaterial, + computeNearNeighbours, + checkCollisions, } houseTransformsGroup.userData = diff --git a/app/design/ui-3d/fresh/scene/userData.ts b/app/design/ui-3d/fresh/scene/userData.ts index 5b22cf05..e001ada7 100644 --- a/app/design/ui-3d/fresh/scene/userData.ts +++ b/app/design/ui-3d/fresh/scene/userData.ts @@ -68,6 +68,7 @@ export type HouseTransformsGroupUserData = { updateActiveLayoutDnas: (x: string[]) => Promise updateXStretchHandleLengths: () => void getActiveLayoutGroup: () => O.Option + unsafeGetActiveLayoutGroup: () => HouseLayoutGroup setActiveLayoutGroup: (layoutGroup: HouseLayoutGroup) => void setXStretchHandlesVisible: (bool?: boolean) => void setZStretchHandlesVisible: (bool?: boolean) => void @@ -77,6 +78,8 @@ export type HouseTransformsGroupUserData = { dbSync: () => Promise resetMaterials: () => void updateHandlesGroupZ: () => void + computeNearNeighbours: () => HouseTransformsGroup[] + checkCollisions: (nearNeighbours: HouseTransformsGroup[]) => boolean } export type HouseTransformsHandlesGroupUserData = {