feat: Add wall classification and geometry handling, update wall rendering logic
This commit is contained in:
parent
20b6f84b38
commit
a69fd2af92
|
@ -280,7 +280,7 @@ export default function Builder() {
|
||||||
plane={plane}
|
plane={plane}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<WallGroup />
|
{/* <WallGroup /> */}
|
||||||
|
|
||||||
<AislesGroup />
|
<AislesGroup />
|
||||||
|
|
||||||
|
|
|
@ -121,9 +121,20 @@ async function loadWalls(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setWalls(Walls);
|
setWalls(Walls);
|
||||||
}else{
|
} else {
|
||||||
setWalls([]);
|
setWalls([]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default loadWalls;
|
export default loadWalls;
|
||||||
|
|
||||||
|
|
||||||
|
// A----- B----- C
|
||||||
|
// | | |
|
||||||
|
// | | |
|
||||||
|
// | | |
|
||||||
|
// F----- E----- D
|
||||||
|
|
||||||
|
// 1. A -> B, B -> C, C -> D, D -> E, E -> F, F -> A, B -> E
|
||||||
|
|
||||||
|
// 2. E -> F, F -> A, A -> B, B -> E, E -> D, D -> C, C -> B
|
|
@ -157,7 +157,7 @@ const FloorPlanGroup = ({ floorPlanGroup, floorPlanGroupLine, floorPlanGroupPoin
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toolMode === "Wall") {
|
if (toolMode === "Wall") {
|
||||||
// drawWall(raycaster, plane, floorPlanGroupPoint, snappedPoint, isSnapped, isSnappedUUID, line, ispreSnapped, anglesnappedPoint, isAngleSnapped, lines, floorPlanGroupLine, floorPlanGroup, ReferenceLineMesh, LineCreated, currentLayerPoint, dragPointControls, setNewLines, setDeletedLines, activeLayer, socket);
|
drawWall(raycaster, plane, floorPlanGroupPoint, snappedPoint, isSnapped, isSnappedUUID, line, ispreSnapped, anglesnappedPoint, isAngleSnapped, lines, floorPlanGroupLine, floorPlanGroup, ReferenceLineMesh, LineCreated, currentLayerPoint, dragPointControls, setNewLines, setDeletedLines, activeLayer, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toolMode === "Floor") {
|
if (toolMode === "Floor") {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { useThree } from '@react-three/fiber';
|
||||||
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
|
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
|
||||||
import { usePointSnapping } from './helpers/usePointSnapping';
|
import { usePointSnapping } from './helpers/usePointSnapping';
|
||||||
import { useAislePointSnapping } from './helpers/useAisleDragSnap';
|
import { useAislePointSnapping } from './helpers/useAisleDragSnap';
|
||||||
|
import { useWallStore } from '../../../store/builder/useWallStore';
|
||||||
|
|
||||||
function Point({ point }: { readonly point: Point }) {
|
function Point({ point }: { readonly point: Point }) {
|
||||||
const materialRef = useRef<THREE.ShaderMaterial>(null);
|
const materialRef = useRef<THREE.ShaderMaterial>(null);
|
||||||
|
@ -15,7 +16,8 @@ function Point({ point }: { readonly point: Point }) {
|
||||||
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
const { toolMode } = useToolMode();
|
const { toolMode } = useToolMode();
|
||||||
const { setPosition, removePoint } = useAisleStore();
|
const { setPosition: setAislePosition, removePoint: removeAislePoint } = useAisleStore();
|
||||||
|
const { setPosition: setWallPosition, removePoint: removeWallPoint } = useWallStore();
|
||||||
const { snapPosition } = useAislePointSnapping(point);
|
const { snapPosition } = useAislePointSnapping(point);
|
||||||
const { checkSnapForAisle } = usePointSnapping({ uuid: point.pointUuid, pointType: point.pointType, position: point.position });
|
const { checkSnapForAisle } = usePointSnapping({ uuid: point.pointUuid, pointType: point.pointType, position: point.position });
|
||||||
const { hoveredPoint, setHoveredPoint } = useBuilderStore();
|
const { hoveredPoint, setHoveredPoint } = useBuilderStore();
|
||||||
|
@ -95,7 +97,13 @@ function Point({ point }: { readonly point: Point }) {
|
||||||
const aisleSnappedPosition = snapPosition(newPosition);
|
const aisleSnappedPosition = snapPosition(newPosition);
|
||||||
const finalSnappedPosition = checkSnapForAisle(aisleSnappedPosition.position);
|
const finalSnappedPosition = checkSnapForAisle(aisleSnappedPosition.position);
|
||||||
|
|
||||||
setPosition(point.pointUuid, finalSnappedPosition.position);
|
setAislePosition(point.pointUuid, finalSnappedPosition.position);
|
||||||
|
}
|
||||||
|
} else if (point.pointType === 'Wall') {
|
||||||
|
if (position) {
|
||||||
|
const newPosition: [number, number, number] = [position.x, position.y, position.z];
|
||||||
|
|
||||||
|
setWallPosition(point.pointUuid, newPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +117,7 @@ function Point({ point }: { readonly point: Point }) {
|
||||||
const handlePointClick = (point: Point) => {
|
const handlePointClick = (point: Point) => {
|
||||||
if (deletePointOrLine) {
|
if (deletePointOrLine) {
|
||||||
if (point.pointType === 'Aisle') {
|
if (point.pointType === 'Aisle') {
|
||||||
const removedAisles = removePoint(point.pointUuid);
|
const removedAisles = removeAislePoint(point.pointUuid);
|
||||||
if (removedAisles.length > 0) {
|
if (removedAisles.length > 0) {
|
||||||
setHoveredPoint(null);
|
setHoveredPoint(null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import * as turf from '@turf/turf';
|
||||||
|
|
||||||
|
export function useWallClassification(walls: Walls) {
|
||||||
|
// Find all rooms from the given walls
|
||||||
|
const findRooms = () => {
|
||||||
|
if (walls.length < 3) return [];
|
||||||
|
|
||||||
|
const pointMap = new Map<string, Point>();
|
||||||
|
const connections = new Map<string, string[]>();
|
||||||
|
|
||||||
|
// Build connection graph
|
||||||
|
walls.forEach(wall => {
|
||||||
|
const [p1, p2] = wall.points;
|
||||||
|
if (!pointMap.has(p1.pointUuid)) pointMap.set(p1.pointUuid, p1);
|
||||||
|
if (!pointMap.has(p2.pointUuid)) pointMap.set(p2.pointUuid, p2);
|
||||||
|
|
||||||
|
if (!connections.has(p1.pointUuid)) connections.set(p1.pointUuid, []);
|
||||||
|
if (!connections.has(p2.pointUuid)) connections.set(p2.pointUuid, []);
|
||||||
|
|
||||||
|
connections.get(p1.pointUuid)?.push(p2.pointUuid);
|
||||||
|
connections.get(p2.pointUuid)?.push(p1.pointUuid);
|
||||||
|
});
|
||||||
|
console.log('connections: ', connections);
|
||||||
|
|
||||||
|
const visited = new Set<string>();
|
||||||
|
const rooms: Point[][] = [];
|
||||||
|
|
||||||
|
// Modified DFS to find all possible cycles
|
||||||
|
const findAllCycles = (current: string, path: string[]) => {
|
||||||
|
visited.add(current);
|
||||||
|
path.push(current);
|
||||||
|
|
||||||
|
const neighbors = connections.get(current) || [];
|
||||||
|
for (const neighbor of neighbors) {
|
||||||
|
if (path.length > 2 && neighbor === path[0]) {
|
||||||
|
// Found a cycle (potential room)
|
||||||
|
const roomPoints = [...path, neighbor].map(uuid => pointMap.get(uuid)!);
|
||||||
|
|
||||||
|
// Check if this room is valid and not already found
|
||||||
|
if (isValidRoom(roomPoints) && !roomAlreadyExists(rooms, roomPoints)) {
|
||||||
|
rooms.push(roomPoints);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path.includes(neighbor)) {
|
||||||
|
findAllCycles(neighbor, [...path]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start from each point to find all possible cycles
|
||||||
|
for (const [pointUuid] of connections) {
|
||||||
|
if (!visited.has(pointUuid)) {
|
||||||
|
findAllCycles(pointUuid, []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rooms;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function to check if room is valid
|
||||||
|
const isValidRoom = (roomPoints: Point[]) => {
|
||||||
|
if (roomPoints.length < 4) return false;
|
||||||
|
const coordinates = roomPoints.map(p => [p.position[0], p.position[2]]);
|
||||||
|
const polygon = turf.polygon([coordinates]);
|
||||||
|
return turf.booleanValid(polygon);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function to check for duplicate rooms
|
||||||
|
const roomAlreadyExists = (existingRooms: Point[][], newRoom: Point[]) => {
|
||||||
|
const newRoomIds = newRoom.map(p => p.pointUuid).sort().join('-');
|
||||||
|
return existingRooms.some(room => {
|
||||||
|
const roomIds = room.map(p => p.pointUuid).sort().join('-');
|
||||||
|
return roomIds === newRoomIds;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const rooms = useMemo(() => findRooms(), [walls]);
|
||||||
|
|
||||||
|
// Modified to track all rooms a wall belongs to
|
||||||
|
const getWallOrientation = (wall: Wall) => {
|
||||||
|
const [p1, p2] = wall.points;
|
||||||
|
const orientations: Array<{ isOutsideFacing: boolean }> = [];
|
||||||
|
|
||||||
|
for (const room of rooms) {
|
||||||
|
for (let i = 0; i < room.length - 1; i++) {
|
||||||
|
const roomP1 = room[i];
|
||||||
|
const roomP2 = room[i + 1];
|
||||||
|
|
||||||
|
// Check both directions
|
||||||
|
if ((p1.pointUuid === roomP1.pointUuid && p2.pointUuid === roomP2.pointUuid) ||
|
||||||
|
(p1.pointUuid === roomP2.pointUuid && p2.pointUuid === roomP1.pointUuid)) {
|
||||||
|
|
||||||
|
const roomPoints = room.map(p => new THREE.Vector3(p.position[0], 0, p.position[2]));
|
||||||
|
const centroid = new THREE.Vector3();
|
||||||
|
roomPoints.forEach(p => centroid.add(p));
|
||||||
|
centroid.divideScalar(roomPoints.length);
|
||||||
|
|
||||||
|
const wallVector = new THREE.Vector3(
|
||||||
|
p2.position[0] - p1.position[0],
|
||||||
|
0,
|
||||||
|
p2.position[2] - p1.position[2]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Normal depends on wall direction
|
||||||
|
let normal = new THREE.Vector3(-wallVector.z, 0, wallVector.x).normalize();
|
||||||
|
if (p1.pointUuid === roomP2.pointUuid) {
|
||||||
|
normal = new THREE.Vector3(wallVector.z, 0, -wallVector.x).normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
const testPoint = new THREE.Vector3(
|
||||||
|
(p1.position[0] + p2.position[0]) / 2 + normal.x,
|
||||||
|
0,
|
||||||
|
(p1.position[2] + p2.position[2]) / 2 + normal.z
|
||||||
|
);
|
||||||
|
|
||||||
|
const pointInside = turf.booleanPointInPolygon(
|
||||||
|
turf.point([testPoint.x, testPoint.z]),
|
||||||
|
turf.polygon([room.map(p => [p.position[0], p.position[2]])])
|
||||||
|
);
|
||||||
|
|
||||||
|
orientations.push({
|
||||||
|
isOutsideFacing: !pointInside
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
isRoomWall: orientations.length > 0,
|
||||||
|
orientations // Now tracks all orientations for walls in multiple rooms
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getWallMaterialSide = (wall: Wall) => {
|
||||||
|
const orientation = getWallOrientation(wall);
|
||||||
|
|
||||||
|
if (!orientation.isRoomWall) {
|
||||||
|
return { front: 'inside', back: 'inside' }; // Both sides same for segment walls
|
||||||
|
}
|
||||||
|
|
||||||
|
// For walls in multiple rooms, we need to determine which side faces which room
|
||||||
|
if (orientation.orientations.length === 2) {
|
||||||
|
// Wall is between two rooms - one side faces each room's interior
|
||||||
|
return {
|
||||||
|
front: 'inside',
|
||||||
|
back: 'inside'
|
||||||
|
};
|
||||||
|
} else if (orientation.orientations.length === 1) {
|
||||||
|
// Wall is part of only one room (exterior wall)
|
||||||
|
return orientation.orientations[0].isOutsideFacing
|
||||||
|
? { front: 'outside', back: 'inside' }
|
||||||
|
: { front: 'inside', back: 'outside' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default case (shouldn't normally happen)
|
||||||
|
return { front: 'inside', back: 'inside' };
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rest of the functions remain the same
|
||||||
|
const getWallType = (wall: Wall) => getWallOrientation(wall).isRoomWall ? 'room' : 'segment';
|
||||||
|
const isRoomWall = (wall: Wall) => getWallOrientation(wall).isRoomWall;
|
||||||
|
const isSegmentWall = (wall: Wall) => !getWallOrientation(wall).isRoomWall;
|
||||||
|
|
||||||
|
return {
|
||||||
|
rooms,
|
||||||
|
getWallType,
|
||||||
|
isRoomWall,
|
||||||
|
isSegmentWall,
|
||||||
|
getWallMaterialSide,
|
||||||
|
findRooms,
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
function useWallGeometry(wallLength: number, wallHeight: number, wallThickness: number) {
|
||||||
|
return useMemo(() => {
|
||||||
|
const geometry = new THREE.BufferGeometry();
|
||||||
|
|
||||||
|
const halfLength = wallLength / 2;
|
||||||
|
const halfThickness = wallThickness / 2;
|
||||||
|
const height = wallHeight;
|
||||||
|
|
||||||
|
const vertices = [
|
||||||
|
-halfLength, -height / 2, halfThickness,
|
||||||
|
-halfLength, height / 2, halfThickness,
|
||||||
|
halfLength, height / 2, halfThickness,
|
||||||
|
halfLength, -height / 2, halfThickness,
|
||||||
|
-halfLength, -height / 2, -halfThickness,
|
||||||
|
-halfLength, height / 2, -halfThickness,
|
||||||
|
halfLength, height / 2, -halfThickness,
|
||||||
|
halfLength, -height / 2, -halfThickness,
|
||||||
|
-halfLength, height / 2, halfThickness,
|
||||||
|
-halfLength, height / 2, -halfThickness,
|
||||||
|
halfLength, height / 2, -halfThickness,
|
||||||
|
halfLength, height / 2, halfThickness,
|
||||||
|
-halfLength, -height / 2, halfThickness,
|
||||||
|
-halfLength, -height / 2, -halfThickness,
|
||||||
|
halfLength, -height / 2, -halfThickness,
|
||||||
|
halfLength, -height / 2, halfThickness,
|
||||||
|
];
|
||||||
|
|
||||||
|
const indices = [
|
||||||
|
0, 1, 2, 0, 2, 3,
|
||||||
|
4, 6, 5, 4, 7, 6,
|
||||||
|
0, 4, 5, 0, 5, 1,
|
||||||
|
3, 2, 6, 3, 6, 7,
|
||||||
|
8, 9, 10, 8, 10, 11,
|
||||||
|
12, 14, 13, 12, 15, 14
|
||||||
|
];
|
||||||
|
|
||||||
|
geometry.setIndex(indices);
|
||||||
|
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
|
||||||
|
geometry.setAttribute('uv', new THREE.Float32BufferAttribute([
|
||||||
|
0, 0, 0, 1, 1, 1, 1, 0,
|
||||||
|
0, 0, 0, 1, 1, 1, 1, 0,
|
||||||
|
0, 0, 0, 1, 1, 1, 1, 0,
|
||||||
|
0, 0, 0, 1, 1, 1, 1, 0,
|
||||||
|
0, 0, 0, 1, 1, 1, 1, 0,
|
||||||
|
0, 0, 0, 1, 1, 1, 1, 0
|
||||||
|
], 2));
|
||||||
|
|
||||||
|
geometry.computeVertexNormals();
|
||||||
|
|
||||||
|
geometry.addGroup(0, 6, 0); // Front
|
||||||
|
geometry.addGroup(6, 6, 1); // Back
|
||||||
|
geometry.addGroup(12, 6, 2); // Left
|
||||||
|
geometry.addGroup(18, 6, 3); // Right
|
||||||
|
geometry.addGroup(24, 6, 4); // Top
|
||||||
|
geometry.addGroup(30, 6, 5); // Bottom
|
||||||
|
|
||||||
|
return geometry;
|
||||||
|
}, [wallLength, wallHeight, wallThickness]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useWallGeometry;
|
|
@ -0,0 +1,92 @@
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import * as Constants from '../../../../../types/world/worldConstants';
|
||||||
|
|
||||||
|
import insideMaterial from '../../../../../assets/textures/floor/wall-tex.png';
|
||||||
|
import outsideMaterial from '../../../../../assets/textures/floor/factory wall texture.jpg';
|
||||||
|
import useWallGeometry from './helpers/useWallGeometry';
|
||||||
|
import { useWallStore } from '../../../../../store/builder/useWallStore';
|
||||||
|
import { useWallClassification } from './helpers/useWallClassification';
|
||||||
|
|
||||||
|
function Wall({ wall }: { readonly wall: Wall }) {
|
||||||
|
const { walls } = useWallStore();
|
||||||
|
const { getWallMaterialSide, isRoomWall, rooms } = useWallClassification(walls);
|
||||||
|
console.log('rooms: ', rooms);
|
||||||
|
const materialSide = getWallMaterialSide(wall);
|
||||||
|
const [startPoint, endPoint] = wall.points;
|
||||||
|
|
||||||
|
const startX = startPoint.position[0];
|
||||||
|
const startZ = startPoint.position[2];
|
||||||
|
const endX = endPoint.position[0];
|
||||||
|
const endZ = endPoint.position[2];
|
||||||
|
|
||||||
|
const wallLength = Math.sqrt((endX - startX) ** 2 + (endZ - startZ) ** 2);
|
||||||
|
const angle = Math.atan2(endZ - startZ, endX - startX);
|
||||||
|
|
||||||
|
const centerX = (startX + endX) / 2;
|
||||||
|
const centerZ = (startZ + endZ) / 2;
|
||||||
|
const centerY = wall.wallHeight / 2;
|
||||||
|
|
||||||
|
const textureLoader = new THREE.TextureLoader();
|
||||||
|
|
||||||
|
const [insideWallTexture, outsideWallTexture] = useMemo(() => {
|
||||||
|
const inside = textureLoader.load(insideMaterial);
|
||||||
|
inside.wrapS = inside.wrapT = THREE.RepeatWrapping;
|
||||||
|
inside.repeat.set(wallLength / 10, wall.wallHeight / 10);
|
||||||
|
inside.colorSpace = THREE.SRGBColorSpace;
|
||||||
|
|
||||||
|
const outside = textureLoader.load(outsideMaterial);
|
||||||
|
outside.wrapS = outside.wrapT = THREE.RepeatWrapping;
|
||||||
|
outside.repeat.set(wallLength / 10, wall.wallHeight / 10);
|
||||||
|
outside.colorSpace = THREE.SRGBColorSpace;
|
||||||
|
|
||||||
|
return [inside, outside];
|
||||||
|
}, [wallLength, wall.wallHeight, textureLoader]);
|
||||||
|
|
||||||
|
const materials = useMemo(() => {
|
||||||
|
// For segment walls (not in a room), use inside material on both sides
|
||||||
|
const frontMaterial = isRoomWall(wall)
|
||||||
|
? (materialSide.front === 'inside' ? insideWallTexture : outsideWallTexture)
|
||||||
|
: insideWallTexture;
|
||||||
|
|
||||||
|
const backMaterial = isRoomWall(wall)
|
||||||
|
? (materialSide.back === 'inside' ? insideWallTexture : outsideWallTexture)
|
||||||
|
: insideWallTexture;
|
||||||
|
|
||||||
|
return [
|
||||||
|
new THREE.MeshStandardMaterial({
|
||||||
|
color: Constants.wallConfig.defaultColor,
|
||||||
|
side: THREE.DoubleSide,
|
||||||
|
map: frontMaterial
|
||||||
|
}),
|
||||||
|
new THREE.MeshStandardMaterial({
|
||||||
|
color: Constants.wallConfig.defaultColor,
|
||||||
|
side: THREE.DoubleSide,
|
||||||
|
map: backMaterial
|
||||||
|
}),
|
||||||
|
new THREE.MeshStandardMaterial({ color: Constants.wallConfig.defaultColor, side: THREE.DoubleSide }), // Left
|
||||||
|
new THREE.MeshStandardMaterial({ color: Constants.wallConfig.defaultColor, side: THREE.DoubleSide }), // Right
|
||||||
|
new THREE.MeshStandardMaterial({ color: Constants.wallConfig.defaultColor, side: THREE.DoubleSide }), // Top
|
||||||
|
new THREE.MeshStandardMaterial({ color: Constants.wallConfig.defaultColor, side: THREE.DoubleSide }) // Bottom
|
||||||
|
];
|
||||||
|
}, [insideWallTexture, outsideWallTexture, materialSide, isRoomWall, wall]);
|
||||||
|
|
||||||
|
const geometry = useWallGeometry(wallLength, wall.wallHeight, wall.wallThickness);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<group
|
||||||
|
name={`Wall-${wall.wallUuid}`}
|
||||||
|
userData={wall}
|
||||||
|
position={[centerX, centerY, centerZ]}
|
||||||
|
rotation={[0, -angle, 0]}
|
||||||
|
>
|
||||||
|
<mesh geometry={geometry}>
|
||||||
|
{materials.map((material, index) => (
|
||||||
|
<primitive key={index} object={material} attach={`material-${index}`} />
|
||||||
|
))}
|
||||||
|
</mesh>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Wall;
|
|
@ -1,18 +1,13 @@
|
||||||
import Line from '../../../line/line'
|
import { useToggleView } from "../../../../../store/builder/store";
|
||||||
import Point from '../../../point/point';
|
import Wall from "./wall"
|
||||||
import { useToggleView } from '../../../../../store/builder/store';
|
|
||||||
|
|
||||||
function WallInstance({ wall }: { readonly wall: Wall }) {
|
function WallInstance({ wall }: { readonly wall: Wall }) {
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{toggleView && (
|
{!toggleView && (
|
||||||
<>
|
<Wall wall={wall} />
|
||||||
<Point point={wall.points[0]} />
|
|
||||||
<Line points={wall.points} />
|
|
||||||
<Point point={wall.points[1]} />
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useWallStore } from '../../../../store/builder/useWallStore'
|
import { useWallStore } from '../../../../store/builder/useWallStore'
|
||||||
import WallInstance from './instance/wallInstance';
|
import WallInstance from './instance/wallInstance';
|
||||||
|
import Line from '../../line/line';
|
||||||
|
import Point from '../../point/point';
|
||||||
|
import { useToggleView } from '../../../../store/builder/store';
|
||||||
|
import { Geometry } from '@react-three/csg';
|
||||||
|
|
||||||
function WallInstances() {
|
function WallInstances() {
|
||||||
const { walls } = useWallStore();
|
const { walls } = useWallStore();
|
||||||
|
const { toggleView } = useToggleView();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// console.log('walls: ', walls);
|
// console.log('walls: ', walls);
|
||||||
|
@ -11,9 +16,25 @@ function WallInstances() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{walls.map((wall) => (
|
|
||||||
<WallInstance key={wall.wallUuid} wall={wall} />
|
<Geometry computeVertexNormals useGroups>
|
||||||
))}
|
{walls.map((wall) => (
|
||||||
|
<WallInstance key={wall.wallUuid} wall={wall} />
|
||||||
|
))}
|
||||||
|
</Geometry>
|
||||||
|
|
||||||
|
|
||||||
|
{toggleView && (
|
||||||
|
<>
|
||||||
|
{walls.map((wall) => (
|
||||||
|
<React.Fragment key={wall.wallUuid}>
|
||||||
|
<Point point={wall.points[0]} />
|
||||||
|
<Line points={wall.points} />
|
||||||
|
<Point point={wall.points[1]} />
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ export const useBuilderStore = create<BuilderState>()(
|
||||||
|
|
||||||
// Wall
|
// Wall
|
||||||
|
|
||||||
wallThickness: 2,
|
wallThickness: 0.1,
|
||||||
wallHeight: 7,
|
wallHeight: 7,
|
||||||
|
|
||||||
setWallThickness: (thickness: number) => {
|
setWallThickness: (thickness: number) => {
|
||||||
|
|
Loading…
Reference in New Issue