diff --git a/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_BaseColor.001.jpg b/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_BaseColor.001.jpg new file mode 100644 index 0000000..6f7991e Binary files /dev/null and b/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_BaseColor.001.jpg differ diff --git a/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_BaseColor.001.png b/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_BaseColor.001.png new file mode 100644 index 0000000..f3f3248 Binary files /dev/null and b/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_BaseColor.001.png differ diff --git a/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_MetallicRoughness.001.jpg b/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_MetallicRoughness.001.jpg new file mode 100644 index 0000000..e181405 Binary files /dev/null and b/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_MetallicRoughness.001.jpg differ diff --git a/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_Normal.001.jpg b/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_Normal.001.jpg new file mode 100644 index 0000000..462c044 Binary files /dev/null and b/app/src/assets/textures/floor/tex1/MI_FactoryConcreteFloor01_Normal.001.jpg differ diff --git a/app/src/assets/textures/floor/tex2/MI_FloorMats01_Normal.png b/app/src/assets/textures/floor/tex2/MI_FloorMats01_Normal.png new file mode 100644 index 0000000..1ef3ee5 Binary files /dev/null and b/app/src/assets/textures/floor/tex2/MI_FloorMats01_Normal.png differ diff --git a/app/src/assets/textures/floor/tex2/MI_FloorMats01_baseColor.png b/app/src/assets/textures/floor/tex2/MI_FloorMats01_baseColor.png new file mode 100644 index 0000000..f0f2a62 Binary files /dev/null and b/app/src/assets/textures/floor/tex2/MI_FloorMats01_baseColor.png differ diff --git a/app/src/components/layout/sidebarRight/properties/FloorProperties.tsx b/app/src/components/layout/sidebarRight/properties/FloorProperties.tsx index 41e8d41..d94363c 100644 --- a/app/src/components/layout/sidebarRight/properties/FloorProperties.tsx +++ b/app/src/components/layout/sidebarRight/properties/FloorProperties.tsx @@ -4,6 +4,8 @@ import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; import defaultTexture from '../../../../assets/textures/floor/white.png'; import flootTexture1 from '../../../../assets/textures/floor/factory wall texture.jpg'; +import flootTexture2 from '../../../../assets/textures/floor/tex1/MI_FactoryConcreteFloor01_BaseColor.001.jpg'; +import flootTexture3 from '../../../../assets/textures/floor/tex2/MI_FloorMats01_baseColor.png'; import { useBuilderStore } from "../../../../store/builder/useBuilderStore"; @@ -13,9 +15,11 @@ type Material = { textureName: string; }; -const materials = [ +export const materials = [ { texture: defaultTexture, textureId: "Default Material", textureName: "Default Material" }, - { texture: flootTexture1, textureId: "Material 1", textureName: "Grunge Concrete Wall" } + { texture: flootTexture1, textureId: "Material 1", textureName: "Grunge Concrete Wall" }, + { texture: flootTexture2, textureId: "Material 2", textureName: "Tiled Floor" }, + { texture: flootTexture3, textureId: "Material 3", textureName: "Metal Floor" }, ]; const FloorProperties = () => { @@ -30,7 +34,7 @@ const FloorProperties = () => { top: materials.find((mat) => mat.textureId === topMaterial) || null, side: materials.find((mat) => mat.textureId === sideMaterial) || null, }); - }, []); + }, [sideMaterial, topMaterial]); const handleDepthChange = (val: string) => { setFloorDepth(parseFloat(val)); diff --git a/app/src/components/layout/sidebarRight/properties/SelectedFloorProperties.tsx b/app/src/components/layout/sidebarRight/properties/SelectedFloorProperties.tsx index 8df2a88..21fbdc7 100644 --- a/app/src/components/layout/sidebarRight/properties/SelectedFloorProperties.tsx +++ b/app/src/components/layout/sidebarRight/properties/SelectedFloorProperties.tsx @@ -2,15 +2,13 @@ import { useEffect, useState } from "react"; import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; import InputToggle from "../../../ui/inputs/InputToggle"; -import defaultTexture from '../../../../assets/textures/floor/white.png'; -import floorTexture1 from '../../../../assets/textures/floor/factory wall texture.jpg'; - import { useBuilderStore } from "../../../../store/builder/useBuilderStore"; import { useSceneContext } from "../../../../modules/scene/sceneContext"; import { useVersionContext } from "../../../../modules/builder/version/versionContext"; import { useParams } from "react-router-dom"; import { getUserData } from "../../../../functions/getUserData"; import { useSocketStore } from "../../../../store/builder/store"; +import { materials } from "./FloorProperties"; // import { upsertFloorApi } from "../../../../services/factoryBuilder/floor/upsertFloorApi"; @@ -29,11 +27,6 @@ const SelectedFloorProperties = () => { const [activeSurface, setActiveSurface] = useState<"top" | "side">("top"); - const materials = [ - { texture: defaultTexture, textureId: "Default Material", textureName: "Default Material" }, - { texture: floorTexture1, textureId: "Material 1", textureName: "Grunge Concrete" } - ]; - const floor = selectedFloor ? getFloorById(selectedFloor.userData.floorUuid) : null; useEffect(() => { diff --git a/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx b/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx index c6c8139..718a798 100644 --- a/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx +++ b/app/src/modules/builder/floor/Instances/Instance/floorInstance.tsx @@ -1,108 +1,181 @@ -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, +} 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.png"; +import material2NormalMap from "../../../../../assets/textures/floor/tex1/MI_FactoryConcreteFloor01_Normal.001.jpg"; +import material2MetallicRoughnessMap 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"; 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 = { - "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; + } + > = { + "Default Material": { + map: savedTheme === "dark" ? texturePathDark : texturePath, + }, + "Material 1": { + map: material1, + }, + "Material 2": { + map: material2Map, + roughnessMap: material2MetallicRoughnessMap, + metalnessMap: material2MetallicRoughnessMap, + normalMap: material2NormalMap, + textureTileScale: 0.1, + }, + "Material 3": { + map: material3Map, + normalMap: material3NormalMap, + }, + }; - 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); + 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; + + // 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] = useLoader(TextureLoader, topTexturesList); + const [sideTexture] = useLoader(TextureLoader, sideTexturesList); + + if (!materials[floor.topMaterial] || !materials[floor.sideMaterial]) + return null; + [topTexture, sideTexture].forEach((tex) => { + const tileScale = materials[floor.topMaterial].textureTileScale ?? textureScale + tex.wrapS = tex.wrapT = RepeatWrapping; + tex.repeat.set(tileScale, tileScale); + tex.colorSpace = SRGBColorSpace; + }); + + if (!shape) return null; + + return ( + { + if (!togglView && activeModule === "builder") { + if (e.object.userData.floorUuid) { + e.stopPropagation(); + setSelectedFloor(e.object); + setSelectedDecal(null); + } } - 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 ( - { - 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); - } - }} - > - - - - - - ); + }} + onPointerMissed={() => { + if ( + selectedFloor && + selectedFloor.userData.floorUuid === floor.floorUuid + ) { + setSelectedFloor(null); + } + }} + > + + + + + + ); } -export default FloorInstance; \ No newline at end of file +export default FloorInstance;