import { Base, Geometry, Subtraction } from "@react-three/csg"; import { useTexture, useGLTF, Stats } from "@react-three/drei"; import { useContext, useEffect, useRef, useState, useCallback, useMemo, } from "react"; import { debounce, throttle } from "lodash"; import * as THREE from "three"; import { MyContext } from "./data/contextapi"; import { invalidate, useLoader, useThree } from "@react-three/fiber"; import { gsap } from "gsap/gsap-core"; import Stalen from "./Stalen"; import Structure from "./Structure"; import Handle from "./handle"; import { Box } from "@react-three/drei"; // Add these definitions at the top const bulbGeometry = new THREE.SphereGeometry(0.0002, 16, 8); const bulbMat = new THREE.MeshStandardMaterial({ emissive: 0xffffff, emissiveIntensity: 1, color: 0x000000, }); export default function DoorHole() { const { type, width, height, frameType, frameSize, doorConfig, sidePannel, sidePannelSize, setStalenPart, stalenType, setWidth, stalenPart, sidePannelConfig, open, setOpen, holeWidth, setHoleWidth, inprogress, setInprogress, } = useContext(MyContext); const [maxWidth, setMaxWidth] = useState(); const containerRef = useRef(null); const [sizePannel, setSizePannel] = useState(0); const [rSizePannel, setRSizePannel] = useState(0); const [firstStructure, setFirstStructure] = useState({ fixedPosition: 0, viewPosition: 0, handlePostion: 0, }); const [secondStructure, setSecondStructure] = useState({ fixedPosition: 0, viewPosition: 0, handlePostion: 0, sizePannel: 0, }); const [thirdStructure, setThirdStructure] = useState({ fixedPosition: 0, viewPosition: 0, handlePostion: 0, sizePannel: 0, }); const [wallStructure, setWallStructure] = useState({ position: 0, width: 0, }); const secondStructureRef = useRef({}); const firstStructureRef = useRef({}); const thirdStructureRef = useRef({}); const [updated, setUpdated] = useState(false); const isInitialRender = useRef(true); const texture_bottom = useTexture(frameType); const texture_wall = useTexture(frameType); const texture = useTexture(frameType); const texture_wall_door = useTexture(frameType); const bulbLight = useRef(); const ambientLight = useRef(); // Inside your component, probably near the return statement useEffect(() => { // Create a new directional light // const light = new THREE.DirectionalLight(0xffffff, 2, 0, 0); // Increased intensity to 2 // light.add(new THREE.Mesh(bulbGeometry, bulbMat)); // light.position.set(-5, 7, 15); // Adjust the position as needed // light.castShadow = true; // Enable shadow casting // // Set the rotatio9n of the light // light.rotation.set(0, 0, 0); // Example rotation values in radians // // Assign the light to a variable or add to the scene // bulbLight.current = light; // Create a SpotLight const directionalLight = new THREE.PointLight(0xffffe3, 70); // White light with intensity 1 // Set the position of the light directionalLight.position.set(-5, 7, 15); // Configure shadow properties directionalLight.castShadow = true; // Shadow map size (higher values give better quality shadows) directionalLight.shadow.mapSize.width = 4096; // Default is 512 directionalLight.shadow.mapSize.height = 4096; // Default is 512 // Shadow camera properties directionalLight.shadow.camera.left = -10; directionalLight.shadow.camera.right = 20; directionalLight.shadow.camera.top = 10; directionalLight.shadow.camera.bottom = -10; directionalLight.shadow.camera.near = 1; directionalLight.shadow.camera.far = 20; // Optionally adjust shadow bias to reduce shadow artifacts directionalLight.shadow.bias = -0.001; bulbLight.current = directionalLight; // Create an ambient light with a specified intensity const ambientlight = new THREE.AmbientLight(0xffffff, 30); // Color is white (0xffffff) and intensity is 0.5 // Optionally, you can change the intensity or color later ambientlight.intensity = 1.3; // Adjust intensity as needed ambientLight.current = ambientlight; // = console.log("Light setup completed"); }, []); useEffect(() => { const wallPosition = doorConfig == "enkele" && (sidePannel == "links" || sidePannel == "rechts") ? sidePannel == "links" ? (doorWidth - sidePannelWidth) / 2 : -(doorWidth - sidePannelWidth) / 2 : doorConfig == "enkele" && sidePannel == "beide" ? 0 : doorConfig == "dubbele" && (sidePannel == "links" || sidePannel == "rechts" || sidePannel == "beide") ? 0 : sizePannel; const wallWidth = type == "vast-stalen" && (stalenType == "divider" || stalenType == "tussen") ? stalenType == "divider" ? 4 * (doorWidth + 4 * frameSize) : (0.06 * width + 4 * frameSize + (stalenPart - 1) * 3.5 * frameSize) : ((doorConfig == "enkele" && (sidePannel == "links" || sidePannel == "rechts")) || (doorConfig != "enkele" && sidePannel == "geen") ? doorConfig != "enkele" && sidePannel == "geen" ? doorWidth * 2 + 8 * frameSize : doorWidth + sidePannelWidth + 8 * frameSize : (doorConfig == "enkele" && sidePannel == "beide") || (doorConfig == "dubbele" && (sidePannel == "rechts" || sidePannel == "links")) ? doorConfig == "enkele" ? doorWidth + 2 * sidePannelWidth + 12 * frameSize : 2 * doorWidth + sidePannelWidth + 12 * frameSize : doorConfig == "dubbele" && sidePannel == "beide" ? 2 * doorWidth + 2 * sidePannelWidth + 16 * frameSize : doorWidth + 4 * frameSize) + (type == "Scharnier" ? 2 * frameWidth : 0); setWallStructure({ position: wallPosition, width: wallWidth, }); const firstDoorWidth = (doorConfig == "enkele" && sidePannel == "links" ? sidePannelSize : width) * 0.06 + 3 * frameSize; const secondDoorWidth = (doorConfig == "enkele" && (sidePannel == "rechts" || sidePannel == "beide") ? sidePannelSize : doorConfig == "dubbele" && sidePannel == "rechts" ? sidePannelSize : width) * 0.06 + 3 * frameSize; const thirdDoorWidth = (doorConfig == "dubbele" && (sidePannel == "links" || sidePannel == "beide") ? sidePannelSize : doorConfig == "enkele" && sidePannel == "beide" ? sidePannelSize : width) * 0.06 + 3 * frameSize; let fixedPosition = -firstDoorWidth / 2 - 1.25 * frameSize; let viewPosition = firstDoorWidth / 2; let handlePostion = firstDoorWidth / 2; let secondFixedPosition = -secondDoorWidth / 2 - 1.25 * frameSize; let secondViewPosition = secondDoorWidth / 2; let secondHandlePostion = secondDoorWidth / 2; let thirdFixedPosition = -thirdDoorWidth / 2 - 1.25 * frameSize; let thirdViewPosition = thirdDoorWidth / 2; let thirdHandlePostion = thirdDoorWidth / 2; if (doorConfig == "enkele") { if (sidePannel == "links" || sidePannel == "rechts") { fixedPosition = -firstDoorWidth - 1.25 * frameSize; secondFixedPosition = secondDoorWidth - 1.25 * frameSize; secondHandlePostion = secondDoorWidth / 2; } else if (sidePannel == "beide") { secondFixedPosition = doorWidth / 2 + secondDoorWidth + 0.55 * frameSize; thirdFixedPosition = -(doorWidth / 2 + secondDoorWidth + 3 * frameSize); } } else { if (sidePannel == "geen") { fixedPosition = -firstDoorWidth - 1.25 * frameSize; secondFixedPosition = secondDoorWidth - 1.25 * frameSize; } else if (sidePannel == "rechts") { fixedPosition = doorWidth - sidePannelWidth / 2 + 0.5 * frameSize; secondFixedPosition = doorWidth + sidePannelWidth / 2 + 4 * frameSize; viewPosition = -firstDoorWidth / 2; handlePostion = -firstDoorWidth / 2; thirdFixedPosition = -doorWidth - sidePannelWidth / 2 - 6 * frameSize; } else if (sidePannel == "beide") { fixedPosition = -firstDoorWidth - 1.25 * frameSize; secondFixedPosition = secondDoorWidth - 1 * frameSize; // thirdFixedPosition = (-maxWidth / 2) * 0.06 - 7.5 * frameSize; thirdFixedPosition = -doorWidth - sidePannelSize * 0.06 - 7.5 * frameSize; } else if (sidePannel == "links") { fixedPosition = -doorWidth + sidePannelWidth / 2 - 2.5 * frameSize; secondFixedPosition = doorWidth + sidePannelWidth / 2 + 4 * frameSize; thirdFixedPosition = -doorWidth - sidePannelWidth / 2 - 6 * frameSize; } } const firstStructure = { fixedPosition: fixedPosition, viewPosition: viewPosition, handlePostion: handlePostion, }; const secondStructure = { fixedPosition: secondFixedPosition, viewPosition: secondViewPosition, handlePostion: secondHandlePostion, }; const thirdStructure = { fixedPosition: thirdFixedPosition, viewPosition: thirdViewPosition, handlePostion: thirdHandlePostion, }; setFirstStructure(firstStructure); setSecondStructure(secondStructure); setThirdStructure(thirdStructure); firstStructureRef.current = firstStructure; secondStructureRef.current = secondStructure; thirdStructureRef.current = thirdStructure; }, [ doorConfig, maxWidth, sidePannel, sizePannel, sidePannelSize, stalenType, type, width, stalenPart, ]); // Load textures using useLoader const [diffuse_bottom, bump_bottom, roughness_bottom] = useLoader( THREE.TextureLoader, [ "textures/floor texture.jpeg", "textures/bump_map.png", "textures/roughness_map.png", ] ); const [diffuse_wall, bump_wall, roughness_wall] = useLoader( THREE.TextureLoader, ["textures/wall-1.jpg", "textures/wall-1.jpg", "textures/wall-1.jpg"] ); const [diffuse_wall_door, bump_wall_door, roughness_wall_door] = useLoader( THREE.TextureLoader, ["textures/wall-2.jpg", "textures/wall-2.jpg", "textures/wall-2.jpg"] ); // Set texture properties [diffuse_bottom, bump_bottom, roughness_bottom].forEach((texture_bottom) => { texture_bottom.wrapS = THREE.RepeatWrapping; texture_bottom.wrapT = THREE.RepeatWrapping; texture_bottom.anisotropy = 4; texture_bottom.repeat.set(2, 4); texture_bottom.bumpScale = 0.00001; // Set bumpScale on the texture itself }); [diffuse_wall, bump_wall, roughness_wall].forEach((texture_wall) => { texture_wall.wrapS = THREE.RepeatWrapping; texture_wall.wrapT = THREE.RepeatWrapping; texture_wall.anisotropy = 4; texture_wall.repeat.set(25.2, 25.2); texture_wall.bumpScale = 0.01; // Set bumpScale on the texture itself }); [diffuse_wall_door, bump_wall_door, roughness_wall_door].forEach( (texture_wall_door) => { texture_wall_door.wrapS = THREE.RepeatWrapping; texture_wall_door.wrapT = THREE.RepeatWrapping; texture_wall_door.anisotropy = 4; texture_wall_door.repeat.set(25.2, 25.2); texture_wall_door.bumpScale = 0.01; // Set bumpScale on the texture itself } ); const frameWidth = 0.19; const frameHeight = 0.053 * height; const frameDepth = 0.19; const doorWidth = useMemo(() => 0.06 * width, [width]); const sidePannelWidth = useMemo( () => 0.06 * sidePannelSize, [sidePannelSize] ); const doorHeightn = useMemo(() => 0.053 * height, [height]); const floorMat = useMemo(() => { const material = new THREE.MeshStandardMaterial({ roughness: 0.8, color: 0xffffff, metalness: 0.2, map: diffuse_bottom, bumpMap: bump_bottom, roughnessMap: roughness_bottom, castShadow: true, }); material.bumpScale = 1; return material; }, [diffuse_bottom, bump_bottom, roughness_bottom]); const wallMat = useMemo(() => { const material = new THREE.MeshStandardMaterial({ roughness: 0.8, color: 0x777777, metalness: 0.2, map: diffuse_wall, bumpMap: bump_wall, roughnessMap: roughness_wall, castShadow: true, }); material.bumpScale = 1; return material; }, [diffuse_wall, bump_wall, roughness_wall]); const behindWallMat = useMemo(() => { const material = new THREE.MeshStandardMaterial({ roughness: 0.8, color: 0x777777, metalness: 0.2, map: diffuse_wall_door, bumpMap: bump_wall_door, roughnessMap: roughness_wall_door, castShadow: true, }); material.bumpScale = 1; return material; }, [diffuse_wall_door, bump_wall_door, roughness_wall_door]); const basewidth = useMemo(() => { return ( 0.06 * width * (sidePannel === "beide" && doorConfig === "enkele" ? 3 : sidePannel !== "geen" && doorConfig === "dubbele" ? 4 : 2) ); }, [width, sidePannel, doorConfig]); const Csg = useRef(); const groupRef = useRef(); const groupref2 = useRef(); const groupref3 = useRef(); const handleAnimation = () => { setOpen((prevOpen) => !prevOpen); startAnimation(); }; const startAnimation = (isClosing = false) => { if (doorConfig === "enkele") { if (type === "Schuifdeur") { if (sidePannel === "links") { gsap.to(groupref2.current.position, { x: isClosing ? secondStructureRef.current.fixedPosition : open ? secondStructureRef.current.fixedPosition : doorConfig === "dubbele" || sidePannel === "links" || sidePannel === "rechts" ? -doorWidth * 0.01 : doorWidth * 1.3, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); } else { gsap.to(groupRef.current.position, { x: isClosing ? firstStructureRef.current.fixedPosition : open ? firstStructureRef.current.fixedPosition : sidePannel === "rechts" ? -doorWidth * 0.05 : -doorWidth * 1.3, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); } } else { if (sidePannel !== "links") { gsap.to(groupRef.current.rotation, { y: isClosing ? 0 : open ? 0 : -Math.PI / 2, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); } if (doorConfig === "dubbele" || sidePannel === "links") { gsap.to(groupref2.current.rotation, { y: isClosing ? -Math.PI : open ? -Math.PI : -Math.PI / 2, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); } } } else { if (type === "Schuifdeur") { if (sidePannel === "links") { gsap.to(groupref2.current.position, { x: isClosing ? secondStructureRef.current.fixedPosition : open ? secondStructureRef.current.fixedPosition : doorWidth * 2.2, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); gsap.to(groupRef.current.position, { x: isClosing ? firstStructureRef.current.fixedPosition : open ? firstStructureRef.current.fixedPosition : -doorWidth * 1.5, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); } else if (sidePannel === "rechts") { gsap.to(groupRef.current.position, { x: isClosing ? firstStructureRef.current.fixedPosition : open ? firstStructureRef.current.fixedPosition : doorWidth * 1.4, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); gsap.to(thirdStructure.fixedPosition, { x: isClosing ? (-doorWidth / 2) * 3.15 : open ? (-doorWidth / 2) * 3.15 : -doorWidth * 2.2, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); } else { gsap.to(groupref2.current.position, { x: isClosing ? secondStructureRef.current.fixedPosition : open ? secondStructureRef.current.fixedPosition : doorConfig === "dubbele" || sidePannel === "links" || sidePannel === "rechts" ? doorWidth * 1.8 : doorWidth * 1.3, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); gsap.to(groupRef.current.position, { x: isClosing ? firstStructureRef.current.fixedPosition : open ? firstStructureRef.current.fixedPosition : doorConfig === "dubbele" || sidePannel === "links" || sidePannel === "rechts" ? -doorWidth * 1.8 : -doorWidth * 1.3, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); } } else { if (sidePannel === "rechts") { gsap.to(groupRef.current.rotation, { y: isClosing ? 0 : open ? 0 : Math.PI / 2, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); gsap.to(groupref3.current.rotation, { y: isClosing ? 0 : open ? 0 : -Math.PI / 2, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); } else if (sidePannel === "links") { gsap.to(groupref2.current.rotation, { y: isClosing ? -Math.PI : open ? -Math.PI : -Math.PI / 2, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); gsap.to(groupRef.current.rotation, { y: isClosing ? 0 : open ? 0 : -Math.PI / 2, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); } else { gsap.to(groupref2.current.rotation, { y: isClosing ? -Math.PI : open ? -Math.PI : -Math.PI / 2, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); gsap.to(groupRef.current.rotation, { y: isClosing ? 0 : open ? 0 : -Math.PI / 2, duration: 1.5, ease: "power3.out", onUpdate: invalidate, }); } } } if (type === "Schuifdeur" && isClosing) { setTimeout(() => { setInprogress(false); }, 1500); } else { setInprogress(isClosing ? false : !open); } }; useEffect(() => { if (isInitialRender.current) { isInitialRender.current = false; return; } const openDoor = () => { setOpen(false); startAnimation(); }; const closeDoor = () => { setOpen(false); startAnimation(true); }; let closeTimeout; if (type != "vast-stalen") { openDoor(); closeTimeout = setTimeout(() => { closeDoor(); }, 1500); } return () => clearTimeout(closeTimeout); }, [type, doorConfig, sidePannel]); return ( <> {/* bottom */} {/* celling */} {/* */} {/* behind */} {/* */} {/* front */} {/* wall-right */} {bulbLight.current && } {ambientLight.current && } {type == "Scharnier" && ( <> )} {type == "Schuifdeur" && ( <> {doorConfig == "enkele" && sidePannel != "geen" && ( )} {doorConfig == "enkele" && sidePannel == "geen" && ( )} {doorConfig == "dubbele" && ( <> {sidePannel == "geen" || sidePannel == "beide" ? ( <> ) : ( <> )} )} )} {type != "vast-stalen" ? ( <> { event.stopPropagation(); handleAnimation(); }} > {doorConfig == "enkele" && sidePannel == "links" ? ( <> ) : ( )} {(doorConfig == "dubbele" || sidePannel == "links" || sidePannel == "rechts" || sidePannel == "beide") && ( { event.stopPropagation(); handleAnimation(); }} > {((doorConfig == "enkele" && sidePannel == "links") || (doorConfig == "dubbele" && sidePannel != "rechts")) && ( )} )} {(sidePannel == "beide" || (doorConfig == "dubbele" && (sidePannel == "links" || sidePannel == "rechts"))) && ( { event.stopPropagation(); handleAnimation(); }} > {doorConfig == "dubbele" && sidePannel == "rechts" && ( )} )} {sidePannel == "beide" && doorConfig == "dubbele" && ( { event.stopPropagation(); handleAnimation(); }} > )} ) : ( <> )} ); }