refactor: Add ArrowsAisle component and update aisle properties for improved functionality

This commit is contained in:
Jerald-Golden-B 2025-05-29 14:39:19 +05:30
parent 879c478753
commit d30ae34426
8 changed files with 159 additions and 11 deletions

View File

@ -26,13 +26,13 @@ const AisleProperties: React.FC = () => {
const { aisleType, aisleWidth, aisleColor, setAisleType, setAisleColor, setAisleWidth } = useBuilderStore();
const aisleTextureList: TextureItem[] = [
{ color: "gray", id: "gray", brief: "basic", texture: "" },
{
color: "yellow",
id: "yellow1",
brief: "pedestrian walkways",
texture: "",
},
{ color: "gray", id: "gray", brief: "basic", texture: "" },
{ color: "green", id: "green1", brief: "pedestrian walkways", texture: "" },
{ color: "orange", id: "orange", brief: "material flow", texture: "" },
{ color: "blue", id: "blue", brief: "vehicle paths", texture: "" },

View File

@ -1,3 +1,4 @@
import ArrowsAisle from './aisleTypes/arrowsAisle';
import DashedAisle from './aisleTypes/dashedAisle';
import DottedAisle from './aisleTypes/dottedAisle';
import SolidAisle from './aisleTypes/solidAisle';
@ -17,6 +18,10 @@ function AisleInstance({ aisle }: { readonly aisle: Aisle }) {
{aisle.type.aisleType === 'dotted-aisle' && (
<DottedAisle aisle={aisle} />
)}
{aisle.type.aisleType === 'arrows-aisle' && (
<ArrowsAisle aisle={aisle} />
)}
</>
);
}

View File

@ -0,0 +1,74 @@
import * as THREE from 'three';
import { useMemo } from 'react';
import { Extrude } from '@react-three/drei';
import * as Constants from '../../../../../../types/world/worldConstants';
function ArrowsAisle({ aisle }: { readonly aisle: Aisle }) {
const arrows = useMemo(() => {
if (aisle.points.length < 2) return [];
const start = new THREE.Vector3(...aisle.points[0].position);
const end = new THREE.Vector3(...aisle.points[1].position);
const width = aisle.type.aisleWidth || 0.1;
const arrowLength = 0.6;
const spacing = 0.6;
const direction = new THREE.Vector3().subVectors(end, start);
const length = direction.length();
direction.normalize();
const count = Math.floor((length + spacing) / (arrowLength + spacing));
const arrowShapes: { shape: THREE.Shape; position: THREE.Vector3; rotationY: number }[] = [];
for (let i = 0; i < count; i++) {
const initialOffset = 0.6;
const center = new THREE.Vector3().copy(start).addScaledVector(direction, initialOffset + i * (arrowLength + spacing));
const shape = new THREE.Shape();
const w = width * 0.8;
const h = arrowLength;
shape.moveTo(0, 0);
shape.lineTo(w, h * 0.6);
shape.lineTo(w * 0.4, h * 0.6);
shape.lineTo(w * 0.4, h);
shape.lineTo(-w * 0.4, h);
shape.lineTo(-w * 0.4, h * 0.6);
shape.lineTo(-w, h * 0.6);
shape.lineTo(0, 0);
const angle = Math.atan2(direction.x, direction.z) + Math.PI;
arrowShapes.push({ shape, position: center, rotationY: angle });
}
return arrowShapes;
}, [aisle]);
if (arrows.length === 0) return null;
return (
<group
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
rotation={[Math.PI / 2, 0, 0]}
>
{arrows.map(({ shape, position, rotationY }, index) => (
<group key={index} position={[position.x, position.z, 0]} rotation={[0, 0, -rotationY]}>
<Extrude
args={[shape, { depth: 0.01, bevelEnabled: false }]}
receiveShadow
castShadow
>
<meshStandardMaterial
color={aisle.type.aisleColor || '#ffffff'}
side={THREE.DoubleSide}
/>
</Extrude>
</group>
))}
</group>
);
}
export default ArrowsAisle;

View File

@ -17,7 +17,7 @@ function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
const perp = new THREE.Vector3(-direction.z, 0, direction.x).normalize();
const totalLength = new THREE.Vector3().subVectors(end, start).length();
const segmentCount = Math.floor(totalLength / (dashLength + gapLength));
const segmentCount = Math.floor((totalLength + gapLength) / (dashLength + gapLength));
const shapes = [];
const directionNormalized = new THREE.Vector3().subVectors(end, start).normalize();

View File

@ -11,10 +11,10 @@ function DottedAisle({ aisle }: { readonly aisle: Aisle }) {
const end = new THREE.Vector3(...aisle.points[1].position);
const width = aisle.type.aisleWidth || 0.1;
const dotSpacing = 0.5;
const dotRadius = width * 0.4;
const dotRadius = width * 0.6;
const totalLength = new THREE.Vector3().subVectors(end, start).length();
const dotCount = Math.floor(totalLength / dotSpacing);
const dotCount = Math.floor((totalLength + (dotSpacing / 2)) / dotSpacing);
const shapes = [];
const directionNormalized = new THREE.Vector3().subVectors(end, start).normalize();

View File

@ -68,6 +68,8 @@ function ReferenceAisle({ tempPoints, aisleType, aisleWidth, aisleColor }: Reado
return <DashedAisle aisle={tempAisle} />;
case 'dotted-aisle':
return <DottedAisle aisle={tempAisle} />;
case 'arrows-aisle':
return <ArrowsAisle aisle={tempAisle} />
default:
return null;
}
@ -143,7 +145,7 @@ function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
const perp = new THREE.Vector3(-direction.z, 0, direction.x).normalize();
const totalLength = new THREE.Vector3().subVectors(end, start).length();
const segmentCount = Math.floor(totalLength / (dashLength + gapLength));
const segmentCount = Math.floor((totalLength + gapLength) / (dashLength + gapLength));
const shapes = [];
const directionNormalized = new THREE.Vector3().subVectors(end, start).normalize();
@ -202,10 +204,10 @@ function DottedAisle({ aisle }: { readonly aisle: Aisle }) {
const end = new THREE.Vector3(...aisle.points[1].position);
const width = aisle.type.aisleWidth || 0.1;
const dotSpacing = 0.5;
const dotRadius = width * 0.4;
const dotRadius = width * 0.6;
const totalLength = new THREE.Vector3().subVectors(end, start).length();
const dotCount = Math.floor(totalLength / dotSpacing);
const dotCount = Math.floor((totalLength + (dotSpacing / 2)) / dotSpacing);
const shapes = [];
const directionNormalized = new THREE.Vector3().subVectors(end, start).normalize();
@ -244,4 +246,72 @@ function DottedAisle({ aisle }: { readonly aisle: Aisle }) {
))}
</group>
);
}
}
function ArrowsAisle({ aisle }: { readonly aisle: Aisle }) {
const arrows = useMemo(() => {
if (aisle.points.length < 2) return [];
const start = new THREE.Vector3(...aisle.points[0].position);
const end = new THREE.Vector3(...aisle.points[1].position);
const width = aisle.type.aisleWidth || 0.1;
const arrowLength = 0.6;
const spacing = 0.6;
const direction = new THREE.Vector3().subVectors(end, start);
const length = direction.length();
direction.normalize();
const count = Math.floor((length + spacing) / (arrowLength + spacing));
const arrowShapes: { shape: THREE.Shape; position: THREE.Vector3; rotationY: number }[] = [];
for (let i = 0; i < count; i++) {
const initialOffset = 0.6;
const center = new THREE.Vector3().copy(start).addScaledVector(direction, initialOffset + i * (arrowLength + spacing));
const shape = new THREE.Shape();
const w = width * 0.8;
const h = arrowLength;
shape.moveTo(0, 0);
shape.lineTo(w, h * 0.6);
shape.lineTo(w * 0.4, h * 0.6);
shape.lineTo(w * 0.4, h);
shape.lineTo(-w * 0.4, h);
shape.lineTo(-w * 0.4, h * 0.6);
shape.lineTo(-w, h * 0.6);
shape.lineTo(0, 0);
const angle = Math.atan2(direction.x, direction.z) + Math.PI;
arrowShapes.push({ shape, position: center, rotationY: angle });
}
return arrowShapes;
}, [aisle]);
if (arrows.length === 0) return null;
return (
<group
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
rotation={[Math.PI / 2, 0, 0]}
>
{arrows.map(({ shape, position, rotationY }, index) => (
<group key={index} position={[position.x, position.z, 0]} rotation={[0, 0, -rotationY]}>
<Extrude
args={[shape, { depth: 0.01, bevelEnabled: false }]}
receiveShadow
castShadow
>
<meshStandardMaterial
color={aisle.type.aisleColor || '#ffffff'}
side={THREE.DoubleSide}
/>
</Extrude>
</group>
))}
</group>
);
}

View File

@ -553,7 +553,7 @@ const ZoneGroup: React.FC = () => {
const midpoint = new THREE.Vector3(
(point1.x + point2.x) / 2,
CONSTANTS.zoneConfig.height / 2 +
(zone.layer - 1) * CONSTANTS.zoneConfig.height,
(zone.layer - 1) * CONSTANTS.zoneConfig.height,
(point1.z + point2.z) / 2
);
@ -564,7 +564,6 @@ const ZoneGroup: React.FC = () => {
return (
<mesh
name="zonePlane"
key={index}
position={midpoint}
rotation={[0, -angle, 0]}

View File

@ -15,7 +15,7 @@ export const useBuilderStore = create<BuilderState>()(
immer((set) => ({
aisleType: 'solid-aisle',
aisleWidth: 0.1,
aisleColor: 'gray',
aisleColor: 'yellow',
setAisleType: (type) => {
set((state) => {
state.aisleType = type;