Merge remote-tracking branch 'origin/main-demo' into main-dev
This commit is contained in:
@@ -95,7 +95,7 @@ export default function Builder() {
|
||||
|
||||
<AssetsGroup plane={plane} />
|
||||
|
||||
<mesh name='Walls-And-WallAssets-Group'>
|
||||
{/* <mesh name='Walls-And-WallAssets-Group'>
|
||||
<Geometry ref={csgRef} useGroups>
|
||||
|
||||
<WallGroup />
|
||||
@@ -103,7 +103,7 @@ export default function Builder() {
|
||||
<WallAssetGroup />
|
||||
|
||||
</Geometry>
|
||||
</mesh>
|
||||
</mesh> */}
|
||||
|
||||
<AislesGroup />
|
||||
|
||||
@@ -113,9 +113,9 @@ export default function Builder() {
|
||||
|
||||
<MeasurementTool />
|
||||
|
||||
<CalculateAreaGroup />
|
||||
{/* <CalculateAreaGroup /> */}
|
||||
|
||||
<NavMesh />
|
||||
{/* <NavMesh /> */}
|
||||
|
||||
<DxfFile />
|
||||
|
||||
|
||||
@@ -1,108 +1,247 @@
|
||||
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 { useMemo } from "react";
|
||||
import {
|
||||
Shape,
|
||||
Vector2,
|
||||
DoubleSide,
|
||||
TextureLoader,
|
||||
RepeatWrapping,
|
||||
SRGBColorSpace,
|
||||
NoColorSpace,
|
||||
} 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';
|
||||
import material1 from "../../../../../assets/textures/floor/factory wall texture.jpg";
|
||||
|
||||
// floor-mat1
|
||||
import material2Map from "../../../../../assets/textures/floor/tex1/MI_FactoryConcreteFloor01_BaseColor.001.jpg";
|
||||
import material2NormalMap from "../../../../../assets/textures/floor/tex1/MI_FactoryConcreteFloor01_Normal.001.jpg";
|
||||
import material2MetalicRoughnessMap from "../../../../../assets/textures/floor/tex1/MI_FactoryConcreteFloor01_MetallicRoughness.001.jpg";
|
||||
|
||||
// floor-mat2
|
||||
import material3Map from "../../../../../assets/textures/floor/tex2/MI_FloorMats01_baseColor.png";
|
||||
import material3NormalMap from "../../../../../assets/textures/floor/tex2/MI_FloorMats01_Normal.png";
|
||||
import material3MetalicRoughnessMap from "../../../../../assets/textures/floor/tex2/MI_FloorMats01_occlusionRoughnessMetallic.png";
|
||||
|
||||
// floor-mat3
|
||||
import material4Map from "../../../../../assets/textures/floor/tex3/metal_plate_diff_1k.jpg";
|
||||
import material4RoughnessMap from "../../../../../assets/textures/floor/tex3/metal_plate_rough_1k.png";
|
||||
import material4MetalicMap from "../../../../../assets/textures/floor/tex3/metal_plate_metal_1k.png";
|
||||
import material4NormalMap from "../../../../../assets/textures/floor/tex3/metal_plate_nor_gl_1k.png";
|
||||
|
||||
function FloorInstance({ floor }: { floor: Floor }) {
|
||||
const { togglView } = useToggleView();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedFloor, setSelectedFloor, setSelectedDecal } = useBuilderStore();
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
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 materials: Record<
|
||||
string,
|
||||
{
|
||||
map: string;
|
||||
roughnessMap?: string;
|
||||
metalnessMap?: string;
|
||||
normalMap?: string;
|
||||
textureTileScale?: [number, number];
|
||||
}
|
||||
> = {
|
||||
"Default Material": {
|
||||
map: savedTheme === "dark" ? texturePathDark : texturePath,
|
||||
},
|
||||
"Material 1": {
|
||||
map: material1,
|
||||
},
|
||||
"Material 2": {
|
||||
map: material2Map,
|
||||
roughnessMap: material2MetalicRoughnessMap,
|
||||
metalnessMap: material2MetalicRoughnessMap,
|
||||
normalMap: material2NormalMap,
|
||||
textureTileScale: [0.1, 0.1],
|
||||
},
|
||||
"Material 3": {
|
||||
map: material3Map,
|
||||
roughnessMap: material3MetalicRoughnessMap,
|
||||
metalnessMap: material3MetalicRoughnessMap,
|
||||
normalMap: material3NormalMap,
|
||||
textureTileScale: [0.35, 0.5],
|
||||
},
|
||||
"Material 4": {
|
||||
map: material4Map,
|
||||
roughnessMap: material4RoughnessMap,
|
||||
metalnessMap: material4MetalicMap,
|
||||
normalMap: material4NormalMap,
|
||||
},
|
||||
};
|
||||
|
||||
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);
|
||||
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']
|
||||
]
|
||||
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);
|
||||
for (let i = 1; i < points.length; i++) {
|
||||
shape.lineTo(points[i].x, points[i].y);
|
||||
}
|
||||
return shape;
|
||||
}, [floor]);
|
||||
|
||||
if (!materials[floor.topMaterial] || !materials[floor.sideMaterial]) return null;
|
||||
const textureScale = Constants.floorConfig.textureScale;
|
||||
|
||||
[topTexture, sideTexture].forEach(tex => {
|
||||
tex.wrapS = tex.wrapT = RepeatWrapping;
|
||||
tex.repeat.set(textureScale, textureScale);
|
||||
tex.colorSpace = SRGBColorSpace;
|
||||
// Helper function to handle texture maps and filter out null values
|
||||
function getMaterialMaps(material: any, defaultMap: any) {
|
||||
const materialMap = material.map || defaultMap;
|
||||
const normalMap = material.normalMap || null;
|
||||
const roughnessMap = material.roughnessMap || null;
|
||||
const metalnessMap = material.metalnessMap || null;
|
||||
|
||||
return [materialMap, normalMap, roughnessMap, metalnessMap].filter(
|
||||
(texture): texture is string => texture !== null
|
||||
);
|
||||
}
|
||||
|
||||
// Default material map
|
||||
const defaultMaterialMap = materials["Default Material"].map;
|
||||
|
||||
// Get top and side material maps
|
||||
const topMaterial = materials[floor.topMaterial];
|
||||
const sideMaterial = materials[floor.sideMaterial];
|
||||
|
||||
// Get the filtered lists for top and side textures
|
||||
const topTexturesList = getMaterialMaps(topMaterial, defaultMaterialMap);
|
||||
const sideTexturesList = getMaterialMaps(sideMaterial, defaultMaterialMap);
|
||||
|
||||
// Use loader to load top and side textures
|
||||
const [topTexture, topNormalTexture, topRoughnessTexture, topMetalicTexture] =
|
||||
useLoader(TextureLoader, topTexturesList);
|
||||
|
||||
const [
|
||||
sideTexture,
|
||||
sideNormalTexture,
|
||||
sideRoughnessTexture,
|
||||
sideMetalicTexture,
|
||||
] = useLoader(TextureLoader, sideTexturesList);
|
||||
|
||||
// Early exit if materials are missing
|
||||
if (!materials[floor.topMaterial] || !materials[floor.sideMaterial])
|
||||
return null;
|
||||
|
||||
// Combine and pair textures with their corresponding material
|
||||
const textureMaterialMap = [
|
||||
{
|
||||
textures: [
|
||||
topTexture,
|
||||
topNormalTexture,
|
||||
topRoughnessTexture,
|
||||
topMetalicTexture,
|
||||
],
|
||||
materialKey: floor.topMaterial,
|
||||
},
|
||||
{
|
||||
textures: [
|
||||
sideTexture,
|
||||
sideNormalTexture,
|
||||
sideRoughnessTexture,
|
||||
sideMetalicTexture,
|
||||
],
|
||||
materialKey: floor.sideMaterial,
|
||||
},
|
||||
];
|
||||
|
||||
// Apply texture settings
|
||||
textureMaterialMap.forEach(({ textures, materialKey }) => {
|
||||
const tileScale = materials[materialKey]?.textureTileScale ?? [
|
||||
textureScale,
|
||||
textureScale,
|
||||
];
|
||||
|
||||
textures.forEach((tex, idx) => {
|
||||
if (!tex) return;
|
||||
tex.wrapS = tex.wrapT = RepeatWrapping;
|
||||
tex.repeat.set(tileScale[0], tileScale[1]);
|
||||
tex.anisotropy = 16;
|
||||
// First texture is always the color map (use SRGB), others should be linear
|
||||
tex.colorSpace = idx < 1 ? SRGBColorSpace : NoColorSpace;
|
||||
});
|
||||
});
|
||||
|
||||
if (!shape) return null;
|
||||
if (!shape) return null;
|
||||
|
||||
return (
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
name={`Floor-${floor.floorUuid}`}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
position={[0, !floor.isBeveled ? (floor.floorDepth - 0.1) : (floor.floorDepth - 0.2), 0]}
|
||||
userData={floor}
|
||||
onDoubleClick={(e) => {
|
||||
if (!togglView && activeModule === 'builder') {
|
||||
if (e.object.userData.floorUuid) {
|
||||
e.stopPropagation();
|
||||
setSelectedFloor(e.object);
|
||||
setSelectedDecal(null);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onPointerMissed={() => {
|
||||
if (selectedFloor && selectedFloor.userData.floorUuid === floor.floorUuid) {
|
||||
setSelectedFloor(null);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Extrude
|
||||
name={`Floor-${floor.floorUuid}`}
|
||||
args={[shape, {
|
||||
depth: !floor.isBeveled ? floor.floorDepth : (floor.floorDepth - 0.1),
|
||||
bevelEnabled: floor.isBeveled,
|
||||
bevelSegments: floor.bevelStrength,
|
||||
bevelOffset: -0.1,
|
||||
bevelSize: 0.1,
|
||||
bevelThickness: 0.1,
|
||||
}]}
|
||||
userData={floor}
|
||||
>
|
||||
<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>
|
||||
</mesh>
|
||||
);
|
||||
return (
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
name={`Floor-${floor.floorUuid}`}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
position={[
|
||||
0,
|
||||
!floor.isBeveled ? floor.floorDepth - 0.1 : floor.floorDepth - 0.2,
|
||||
0,
|
||||
]}
|
||||
userData={floor}
|
||||
onDoubleClick={(e) => {
|
||||
if (!togglView && activeModule === "builder") {
|
||||
if (e.object.userData.floorUuid) {
|
||||
e.stopPropagation();
|
||||
setSelectedFloor(e.object);
|
||||
setSelectedDecal(null);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onPointerMissed={() => {
|
||||
if (
|
||||
selectedFloor &&
|
||||
selectedFloor.userData.floorUuid === floor.floorUuid
|
||||
) {
|
||||
setSelectedFloor(null);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Extrude
|
||||
name={`Floor-${floor.floorUuid}`}
|
||||
args={[
|
||||
shape,
|
||||
{
|
||||
depth: !floor.isBeveled ? floor.floorDepth : floor.floorDepth - 0.1,
|
||||
bevelEnabled: floor.isBeveled,
|
||||
bevelSegments: floor.bevelStrength,
|
||||
bevelOffset: -0.1,
|
||||
bevelSize: 0.1,
|
||||
bevelThickness: 0.1,
|
||||
},
|
||||
]}
|
||||
userData={floor}
|
||||
>
|
||||
<meshPhysicalMaterial
|
||||
attach="material-0"
|
||||
color={Constants.floorConfig.defaultColor}
|
||||
map={topTexture}
|
||||
roughnessMap={topRoughnessTexture}
|
||||
metalnessMap={topMetalicTexture}
|
||||
normalMap={topNormalTexture}
|
||||
roughness={1.5}
|
||||
metalness={1.0}
|
||||
side={DoubleSide}
|
||||
/>
|
||||
<meshStandardMaterial
|
||||
attach="material-1"
|
||||
color={Constants.floorConfig.defaultColor}
|
||||
map={sideTexture?.clone()}
|
||||
roughnessMap={sideRoughnessTexture?.clone()}
|
||||
metalnessMap={sideMetalicTexture?.clone()}
|
||||
normalMap={sideNormalTexture?.clone()}
|
||||
side={DoubleSide}
|
||||
/>
|
||||
</Extrude>
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
|
||||
export default FloorInstance;
|
||||
export default FloorInstance;
|
||||
|
||||
Reference in New Issue
Block a user