Refactor builder store and related components: update DecalInstance to manage selectedFloor state, enhance FloorInstance with improved material handling and texture application, and modify FloorGroup to remove unnecessary console log. Update Wall component for better shadow handling and adjust useBuilderStore to change default material values.

This commit is contained in:
2025-06-27 11:56:54 +05:30
parent 04c302ea4c
commit 64f0cdb148
6 changed files with 111 additions and 20 deletions

View File

@@ -8,7 +8,7 @@ import defaultMaterial from '../../../assets/textures/floor/wall-tex.png';
import useModuleStore from '../../../store/useModuleStore';
function DecalInstance({ visible = true, decal }: { visible?: boolean, decal: Decal }) {
const { setSelectedWall, selectedDecal, setSelectedDecal } = useBuilderStore();
const { setSelectedWall, setSelectedFloor, selectedDecal, setSelectedDecal } = useBuilderStore();
const { togglView } = useToggleView();
const { activeModule } = useModuleStore();
const material = useLoader(THREE.TextureLoader, defaultMaterial);
@@ -26,6 +26,7 @@ function DecalInstance({ visible = true, decal }: { visible?: boolean, decal: De
if (e.object.userData.decalUuid) {
setSelectedDecal(e.object);
setSelectedWall(null);
setSelectedFloor(null);
}
}
}}

View File

@@ -1,33 +1,103 @@
import { useMemo } from 'react'
import { Shape, Vector2, DoubleSide } from 'three';
import { useMemo } from 'react';
import { Shape, Vector2, DoubleSide, TextureLoader, RepeatWrapping, SRGBColorSpace } from 'three';
import { useLoader } from '@react-three/fiber';
import { Extrude } from '@react-three/drei';
import useModuleStore from '../../../../../store/useModuleStore';
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
import { useToggleView } from '../../../../../store/builder/store';
import * as Constants from '../../../../../types/world/worldConstants';
import texturePath from "../../../../../assets/textures/floor/white.png";
import texturePathDark from "../../../../../assets/textures/floor/black.png";
import material1 from '../../../../../assets/textures/floor/factory wall texture.jpg';
function FloorInstance({ floor }: { floor: Floor }) {
const { togglView } = useToggleView();
const { activeModule } = useModuleStore();
const { selectedFloor, setSelectedFloor, setSelectedDecal } = useBuilderStore();
const savedTheme = localStorage.getItem('theme');
const materials: Record<string, string> = {
"Default Material": savedTheme === "dark" ? texturePathDark : texturePath,
"Material 1": savedTheme === "dark" ? material1 : material1,
};
const shape = useMemo(() => {
const shape = new Shape();
const points = floor.points.map(p => new Vector2(p.position[0], p.position[2]));
if (points.length < 3) return null;
shape.moveTo(points[0].x, points[0].y);
points.forEach((pt) => { shape.lineTo(pt.x, pt.y); });
for (let i = 1; i < points.length; i++) {
shape.lineTo(points[i].x, points[i].y);
}
return shape;
}, [floor]);
const textureScale = Constants.floorConfig.textureScale;
const [topTexture, sideTexture] = useLoader(
TextureLoader,
[
materials[floor.topMaterial] || materials['Default Material'],
materials[floor.sideMaterial] || materials['Default Material']
]
);
if (!materials[floor.topMaterial] || !materials[floor.sideMaterial]) return null;
[topTexture, sideTexture].forEach(tex => {
tex.wrapS = tex.wrapT = RepeatWrapping;
tex.repeat.set(textureScale, textureScale);
tex.colorSpace = SRGBColorSpace;
});
if (!shape) return null;
return (
<group name="Floor" rotation={[Math.PI / 2, 0, 0]}>
<mesh
castShadow
receiveShadow
name={`Floor-${floor.floorUuid}`}
rotation={[Math.PI / 2, 0, 0]}
position={[0, floor.floorDepth, 0]}
userData={floor}
onClick={(e) => {
if (!togglView && activeModule === 'builder') {
if (e.object.userData.floorUuid) {
setSelectedFloor(e.object);
setSelectedDecal(null);
}
}
}}
onPointerMissed={() => {
if (selectedFloor && selectedFloor.userData.floorUuid === floor.floorUuid) {
setSelectedFloor(null);
}
}}
>
<Extrude
args={[shape, { depth: floor.floorDepth, bevelEnabled: floor.isBeveled, bevelThickness: floor.bevelStrength }]}
position={[0, 0, 0]}
receiveShadow
args={[shape, {
depth: floor.floorDepth,
bevelEnabled: floor.isBeveled,
bevelThickness: floor.bevelStrength
}]}
userData={floor}
>
<meshStandardMaterial color={Constants.floorConfig.defaultColor} side={DoubleSide} />
<meshStandardMaterial
attach="material-0"
color={Constants.floorConfig.defaultColor}
map={topTexture}
side={DoubleSide}
/>
<meshStandardMaterial
attach="material-1"
color={Constants.floorConfig.defaultColor}
map={sideTexture}
side={DoubleSide}
/>
</Extrude>
</group>
</mesh>
);
}
export default FloorInstance
export default FloorInstance;

View File

@@ -29,7 +29,6 @@ function FloorGroup() {
useEffect(() => {
if (projectId && selectedVersion) {
getFloorsApi(projectId, selectedVersion?.versionId || '').then((floors) => {
console.log('floors: ', floors);
if (floors && floors.length > 0) {
setFloors(floors);
} else {

View File

@@ -1,20 +1,21 @@
import * as THREE from 'three';
import { Base } from '@react-three/csg';
import { useMemo, useRef, useState } from 'react';
import { Decal, MeshDiscardMaterial } from '@react-three/drei';
import { MeshDiscardMaterial } from '@react-three/drei';
import { useFrame, useThree } from '@react-three/fiber';
import defaultMaterial from '../../../../../assets/textures/floor/wall-tex.png';
import material1 from '../../../../../assets/textures/floor/factory wall texture.jpg';
import useModuleStore from '../../../../../store/useModuleStore';
import { useSceneContext } from '../../../../scene/sceneContext';
import { useWallClassification } from './helpers/useWallClassification';
import { useToggleView, useWallVisibility } from '../../../../../store/builder/store';
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
import * as Constants from '../../../../../types/world/worldConstants';
import DecalInstance from '../../../Decal/decalInstance';
import defaultMaterial from '../../../../../assets/textures/floor/wall-tex.png';
import material1 from '../../../../../assets/textures/floor/factory wall texture.jpg';
function Wall({ wall }: { readonly wall: Wall }) {
const { wallStore } = useSceneContext();
const { walls, addDecal } = wallStore();
@@ -116,6 +117,7 @@ function Wall({ wall }: { readonly wall: Wall }) {
</Base>
<mesh
castShadow
receiveShadow
geometry={geometry}
position={[centerX, centerY, centerZ]}
rotation={[0, -angle, 0]}

View File

@@ -15,7 +15,7 @@ export default function PostProcessing() {
const { selectedWallItem } = useSelectedWallItem();
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedEventSphere } = useSelectedEventSphere();
const { selectedAisle, selectedWall, selectedDecal } = useBuilderStore();
const { selectedAisle, selectedWall, selectedDecal, selectedFloor } = useBuilderStore();
function flattenChildren(children: any[]) {
const allChildren: any[] = [];
@@ -44,6 +44,10 @@ export default function PostProcessing() {
// console.log('selectedWall: ', selectedWall);
}, [selectedWall])
useEffect(() => {
// console.log('selectedFloor: ', selectedFloor);
}, [selectedFloor])
return (
<EffectComposer autoClear={false}>
<N8AO
@@ -85,6 +89,21 @@ export default function PostProcessing() {
xRay={true}
/>
)}
{selectedFloor && (
<Outline
selection={selectedFloor}
selectionLayer={10}
width={2000}
blendFunction={BlendFunction.ALPHA}
edgeStrength={5}
resolutionScale={2}
pulseSpeed={0}
visibleEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
hiddenEdgeColor={CONSTANTS.outlineConfig.assetSelectColor}
blur={true}
xRay={true}
/>
)}
{selectedDecal && (
<Outline
selection={selectedDecal}

View File

@@ -100,8 +100,8 @@ export const useBuilderStore = create<BuilderState>()(
floorDepth: 0.1,
isBeveled: false,
bevelStrength: 0.05,
sideMaterial: 'Default Side',
topMaterial: 'Default Top',
sideMaterial: 'Material 1',
topMaterial: 'Default Material',
selectedDecal: null,