From 371549e1a9b9681cabe6a38b6e21511ca39a0809 Mon Sep 17 00:00:00 2001 From: luxiaotao1123 <t1341870251@163.com> Date: 星期五, 19 四月 2024 10:31:10 +0800 Subject: [PATCH] # --- src/components/house.jsx | 567 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 19 + package.json | 5 src/pages/base.jsx | 2 4 files changed, 590 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac1d605..c560fa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "three-asrs", "version": "0.0.0", "dependencies": { + "@react-three/csg": "^3.2.0", "@react-three/drei": "9.92.0", "@react-three/fiber": "8.15.12", "@react-three/postprocessing": "2.15.11", @@ -1061,6 +1062,15 @@ "version": "9.6.1", "resolved": "https://registry.npmmirror.com/@react-spring/types/-/types-9.6.1.tgz", "integrity": "sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==" + }, + "node_modules/@react-three/csg": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/@react-three/csg/-/csg-3.2.0.tgz", + "integrity": "sha512-POnakTYaJqmqKsk9Q23oCL78JmaitN2+s/ciOHDK8dQu6GsSa2eMzlhR7J7kI9VdjmV/cW2cRz9XJEWNJ4XmfA==", + "dependencies": { + "three-bvh-csg": "^0.0.16", + "three-mesh-bvh": "^0.6.8" + } }, "node_modules/@react-three/drei": { "version": "9.92.0", @@ -5077,6 +5087,15 @@ "resolved": "https://registry.npmmirror.com/three/-/three-0.159.0.tgz", "integrity": "sha512-eCmhlLGbBgucuo4VEA9IO3Qpc7dh8Bd4VKzr7WfW4+8hMcIfoAVi1ev0pJYN9PTTsCslbcKgBwr2wNZ1EvLInA==" }, + "node_modules/three-bvh-csg": { + "version": "0.0.16", + "resolved": "https://registry.npmmirror.com/three-bvh-csg/-/three-bvh-csg-0.0.16.tgz", + "integrity": "sha512-RgC5dY0hAKdfd1bmD3o2CDfmK9GTkvsA1ECzoqTMhSkjSc2zp1z4Wpa5+emLi/EosF5P6+aK2veTxTLZA9+Mhw==", + "peerDependencies": { + "three": ">=0.151.0", + "three-mesh-bvh": ">=0.6.6" + } + }, "node_modules/three-mesh-bvh": { "version": "0.6.8", "resolved": "https://registry.npmmirror.com/three-mesh-bvh/-/three-mesh-bvh-0.6.8.tgz", diff --git a/package.json b/package.json index 5e0efba..2c6d630 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,11 @@ "preview": "vite preview" }, "dependencies": { - "@tweenjs/tween.js": "^21.0.0", + "@react-three/csg": "^3.2.0", "@react-three/drei": "9.92.0", "@react-three/fiber": "8.15.12", "@react-three/postprocessing": "2.15.11", + "@tweenjs/tween.js": "^21.0.0", "axios": "^1.6.2", "maath": "0.10.7", "react": "^18.2.0", @@ -35,4 +36,4 @@ "tailwindcss": "^3.4.3", "vite": "^5.2.0" } -} \ No newline at end of file +} diff --git a/src/components/house.jsx b/src/components/house.jsx new file mode 100644 index 0000000..d41a378 --- /dev/null +++ b/src/components/house.jsx @@ -0,0 +1,567 @@ +import React, { useEffect, useRef } from 'react'; +import * as THREE from 'three'; +import { ThreeElements, useLoader, extend } from '@react-three/fiber'; +import { Geometry, Base, Subtraction, Addition } from '@react-three/csg'; +import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'; +import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'; +extend({ TextGeometry }); + +const House = (props) => { + const { + wallThickness = 2, + width = 1400, + length = 1200, + height = 400, + aside_width = 130, + aside_length = 130, + position = new THREE.Vector3(200, 0, 0), + space_width = 10000, + space_length = 12000, + road_width = 600, + grass_width = 400, + cross_width = 100, + } = props; + + const getPointToShape = (points, extra) => { + const shape = new THREE.Shape(); + const obj = {}; + extra?.forEach((item) => { + obj[item.i] = item.setShape; + }); + points.forEach((point, index) => { + const { x, y } = point; + if (!index) { + shape.moveTo(x, y); + } + if (obj[index]) { + obj[index](shape, point); + } else { + shape.lineTo(x, y); + } + }); + return shape; + }; + + // const texture = new THREE.TextureLoader().load('/static/wall_pic5.jpg'); + const texture = new THREE.TextureLoader().load( + process.env.NODE_ENV == 'development' + ? '/static/wall_pic5.jpg' + : `/degital-twin-3d/static/wall_pic5.jpg` + ); + console.log('env', process.env.NODE_ENV); + + texture.wrapS = THREE.RepeatWrapping; // 姘村钩鏂瑰悜閲嶅 + texture.repeat.set(0.02, 0.02); + + const roofTexture = new THREE.TextureLoader().load( + process.env.NODE_ENV == 'development' + ? '/static/wall_pic7.png' + : `/degital-twin-3d/static/wall_pic7.png` + ); + roofTexture.wrapS = THREE.RepeatWrapping; // 姘村钩鏂瑰悜閲嶅 + roofTexture.wrapT = THREE.RepeatWrapping; // 鍨傜洿鏂瑰悜閲嶅 + roofTexture.rotation = Math.PI / 2; + roofTexture.repeat.set(0.005, 0.005); + + const floorTexture = new THREE.TextureLoader().load( + process.env.NODE_ENV == 'development' + ? '/static/floor_02.png' + : `/degital-twin-3d/static/floor_02.png` + ); + floorTexture.wrapS = THREE.RepeatWrapping; // 姘村钩鏂瑰悜閲嶅 + floorTexture.wrapT = THREE.RepeatWrapping; // 鍨傜洿鏂瑰悜閲嶅 + floorTexture.repeat.set(0.01, 0.01); + + const roadTexture = new THREE.TextureLoader().load( + process.env.NODE_ENV == 'development' + ? '/static/road2.jpg' + : `/degital-twin-3d/static/road2.jpg` + ); + roadTexture.wrapS = THREE.RepeatWrapping; // 姘村钩鏂瑰悜閲嶅 + roadTexture.wrapT = THREE.RepeatWrapping; // 鍨傜洿鏂瑰悜閲嶅 + roadTexture.repeat.set(5, 1); + + const grassTexture = new THREE.TextureLoader().load( + process.env.NODE_ENV == 'development' + ? '/static/grass.jpg' + : `/degital-twin-3d/static/grass.jpg` + ); + grassTexture.wrapS = THREE.RepeatWrapping; // 姘村钩鏂瑰悜閲嶅 + grassTexture.wrapT = THREE.RepeatWrapping; // 鍨傜洿鏂瑰悜閲嶅 + grassTexture.repeat.set(20, 1); + + const surfaceTexture = new THREE.TextureLoader().load( + process.env.NODE_ENV == 'development' + ? '/static/surface.jpg' + : `/degital-twin-3d/static/surface.jpg` + ); + surfaceTexture.wrapS = THREE.RepeatWrapping; // 姘村钩鏂瑰悜閲嶅 + surfaceTexture.wrapT = THREE.RepeatWrapping; // 鍨傜洿鏂瑰悜閲嶅 + surfaceTexture.repeat.set(0.01, 0.01); + + const crossTexture = new THREE.TextureLoader().load( + process.env.NODE_ENV == 'development' + ? '/static/cross.png' + : `/degital-twin-3d/static/cross.png` + ); + crossTexture.wrapS = THREE.RepeatWrapping; // 姘村钩鏂瑰悜閲嶅 + crossTexture.wrapT = THREE.RepeatWrapping; // 鍨傜洿鏂瑰悜閲嶅 + crossTexture.repeat.set(70, 1); + + const getBackWallShape = () => { + const shape = getPointToShape([ + new THREE.Vector2(-length, -height), + new THREE.Vector2(-length, height), + new THREE.Vector2(length, height), + new THREE.Vector2(length, -height), + ]); + const doorHoles = new THREE.Path(); + doorHoles.moveTo(-width / 30, -height); + doorHoles.lineTo(-width / 30, (-2 * height) / 5); + doorHoles.lineTo(width / 30, (-2 * height) / 5); + doorHoles.lineTo(width / 30, -height); + doorHoles.moveTo(-width / 30, -height); + shape.holes.push(doorHoles); + return shape; + }; + + // 绗竴灞� + const getBackWallTopShape = () => { + const shape = getPointToShape([ + new THREE.Vector2(-length, -height / 2), + new THREE.Vector2(-length, -(height / 2 - 5)), + new THREE.Vector2(-length / 2, height / 4), + new THREE.Vector2(0, -(height / 2 - 5)), + new THREE.Vector2(length / 2, height / 4), + new THREE.Vector2(length, -(height / 2 - 5)), // 鍙宠竟銆倄杞存槸涓�鏍风殑锛屼笉鏂姞鍘氬害 + new THREE.Vector2(length, -height / 2), + new THREE.Vector2(-length, -height / 2), + ]); + return shape; + }; + + // 绗簩灞� + const getRoofShape = () => { + const shape = getPointToShape( + [ + new THREE.Vector2(-length, -(height / 2 - 5)), // 绗竴涓偣,妞渾鏇茬嚎鍔犺浇绗竴绗簩涓偣涔嬮棿 + new THREE.Vector2(-length, -(height / 2 + 5)), + new THREE.Vector2(-length - wallThickness - 5, -(height / 2 + 5)), + // new THREE.Vector2(-length - (5 * length) / (height / 2 - 10), -(height / 2 + 10)), + new THREE.Vector2(-length - wallThickness - 5, -(height / 2 - 5) + 2 * wallThickness), // 鍋氭洸绾跨殑閭d竴鏉� + // new THREE.Vector2(-length - wallThickness, -(height / 2 - 5) + wallThickness), + new THREE.Vector2(-length, -(height / 2 - 5) + 2 * wallThickness), + new THREE.Vector2(-length, -(height / 2 - 5) + wallThickness), // 绗簩涓偣 + new THREE.Vector2(-length / 2, height / 4 + wallThickness), + new THREE.Vector2(0, -(height / 2 - 5) + wallThickness), // 绗簩浣庣偣椤剁偣 + new THREE.Vector2(length / 2, height / 4 + wallThickness), + new THREE.Vector2(length, -(height / 2 - 5) + wallThickness), // 绗笁浣庣偣椤剁偣 + // 鍦ㄨ繖閲屽仛鍦嗘煴 + new THREE.Vector2(length, -(height / 2 - 5) + 2 * wallThickness), + new THREE.Vector2(length + 5, -(height / 2 - 5) + 2 * wallThickness), + new THREE.Vector2(length + 5, -(height / 2 - 5) + 2 * wallThickness - 15), // 鍋氭洸绾跨殑閭d竴鏉� + new THREE.Vector2(length, -(height / 2 - 5) + 2 * wallThickness - 15), + // over + new THREE.Vector2(length, -(height / 2 - 5)), // 绗笁浣庣偣搴曠偣 + new THREE.Vector2(length / 2, height / 4), + new THREE.Vector2(0, -(height / 2 - 5)), // 绗簩浣庣偣搴曠偣 + new THREE.Vector2(-length / 2, height / 4), + new THREE.Vector2(-length, -(height / 2 - 5)), // 鍘熺偣 + ], + [ + { + i: 3, + setShape: (shape, point) => { + const { x, y } = point; + shape.bezierCurveTo( + -length - wallThickness - 5 - 2.5, + -(height / 2 + 5 - 14 / 4), + -length - wallThickness - 5 - 2.5, + -(height / 2 + 5 - (14 * 3) / 4), + x, + y + ); + }, + }, + { + i: 12, + setShape: (shape, point) => { + const { x, y } = point; + shape.bezierCurveTo( + length + 5 + 2.5, + -(height / 2 - 5) + 2 * wallThickness - 14 / 4, + length + 5 + 2.5, + -(height / 2 - 5) + 2 * wallThickness - (14 * 3) / 4, + x, + y + ); + }, + }, + ] + ); + return shape; + }; + + // 绗笁灞� + const getTopRoofShape = () => { + const shape = getPointToShape([ + new THREE.Vector2(-length, -(height / 2 - 5) + wallThickness), + new THREE.Vector2(-length, -(height / 2 - 5) + 2 * wallThickness), + new THREE.Vector2(-length / 2, height / 4 + 2 * wallThickness), + new THREE.Vector2(0, -(height / 2 - 5) + 2 * wallThickness), + new THREE.Vector2(length / 2, height / 4 + 2 * wallThickness), + new THREE.Vector2(length, -(height / 2 - 5) + 2 * wallThickness), + new THREE.Vector2(length, -(height / 2 - 5) + wallThickness), + new THREE.Vector2(length / 2, height / 4 + wallThickness), + new THREE.Vector2(0, -(height / 2 - 5) + wallThickness), + new THREE.Vector2(-length / 2, height / 4 + wallThickness), + ]); + return shape; + }; + + // const Text = (props: any) => { + // const font = useLoader(THREE.FontLoader, '/static/STXingkai_Regular.json'); + // return ( + // <mesh + // scale={[-1, 1, 1]} + // position={new THREE.Vector3(width - 50, 2 * height - 150, -length - 10)} + // > + // <textGeometry args={[props.text, { font, size: 100, height: 10 }]} /> + // <meshStandardMaterial color={'#22d0d1'} /> + // </mesh> + // ); + // }; + + // 浠撳簱搴曚笅鐨勯偅涓�鍧楀湴鏉匡紝浼氭瘮浠撳簱鐣ュぇ + const HouseFloor = () => { + return ( + <extrudeGeometry + args={[ + getPointToShape([ + // 涓嬮潰鐨勪笉瑕� + new THREE.Vector2(-width - aside_width, -length - aside_length), + new THREE.Vector2(width + aside_width, -length - aside_length), + new THREE.Vector2(width + aside_width, length + aside_length), + new THREE.Vector2(-width - aside_width, length + aside_length), + ]), + { depth: wallThickness }, + ]} + /> + ); + }; + + // 鍓嶉潰鐨勮矾锛屾湁鎷涚墝鐨勯偅涓�闈� + const FrontRoad = () => { + return ( + <extrudeGeometry + args={[ + getPointToShape([ + new THREE.Vector2(width + aside_width, -length - aside_length), + new THREE.Vector2(width + aside_width, -space_length), + new THREE.Vector2(-width - aside_width, -space_length), + new THREE.Vector2(-width - aside_width, -length - aside_length), + ]), + { depth: wallThickness }, + ]} + /> + ); + }; + //鍚庨潰鐨勮矾锛屾嫑鐗岀殑閭d竴杈圭殑鍙嶉潰 + const BackRoad = () => { + return ( + <extrudeGeometry + args={[ + getPointToShape([ + new THREE.Vector2(-width - aside_width, length + aside_length), + new THREE.Vector2(-width - aside_width, space_length), + new THREE.Vector2(width + aside_width, space_length), + new THREE.Vector2(width + aside_width, length + aside_length), + ]), + { depth: wallThickness }, + ]} + /> + ); + }; + + // 鍙宠竟鐨勯晜绌虹殑锛屽氨鏄病鏈夊鐨勯偅涓�闈� + const RightRoad = () => { + return ( + <extrudeGeometry + args={[ + getPointToShape([ + new THREE.Vector2(-width - aside_width, -length - aside_length), + new THREE.Vector2(-space_width, -length - aside_length), + new THREE.Vector2(-space_width, length + aside_length), + new THREE.Vector2(-width - aside_width, length + aside_length), + ]), + { depth: wallThickness }, + ]} + /> + ); + }; + + const LeftRoad = () => { + return ( + <extrudeGeometry + args={[ + getPointToShape([ + new THREE.Vector2(width + aside_width, length + aside_length), + new THREE.Vector2(space_width, length + aside_length), + new THREE.Vector2(space_width, -length - aside_length), + new THREE.Vector2(width + aside_width, -length - aside_length), + ]), + { depth: wallThickness }, + ]} + /> + ); + }; + + const RoadMaterial = () => { + return <meshBasicMaterial map={roadTexture}></meshBasicMaterial>; + }; + + const GrassMaterial = () => { + return <meshBasicMaterial map={grassTexture}></meshBasicMaterial>; + }; + + const SurfaceMaterial = () => { + return <meshBasicMaterial map={surfaceTexture}></meshBasicMaterial>; + }; + + const CrossMaterial = () => { + return <meshBasicMaterial map={crossTexture}></meshBasicMaterial>; + }; + + const OutSideSurface = (props) => { + return ( + <group rotation={[0, props.rotation, 0]}> + {/* 绗竴涓亾璺� */} + <mesh rotation={[Math.PI / 2, 0, 0]}> + <Geometry> + <Base position={[0, road_width / 2, 0]}> + <boxGeometry args={[props.length * 2, road_width, 10]} /> + </Base> + <Addition position={[0, -road_width / 2, 0]}> + <boxGeometry args={[props.length * 2, road_width, 10]} /> + </Addition> + <Subtraction position={[0, 0, 0]}> + <boxGeometry args={props.subArgs} /> + </Subtraction> + </Geometry> + <RoadMaterial></RoadMaterial> + </mesh> + <mesh rotation={[Math.PI / 2, 0, 0]}> + <Geometry> + <Base position={[0, road_width + grass_width / 2, 0]}> + <boxGeometry args={[props.length * 2, grass_width, 10]} /> + </Base> + <Addition position={[0, -(road_width + grass_width / 2), 0]}> + <boxGeometry args={[props.length * 2, grass_width, 10]} /> + </Addition> + <Subtraction position={[0, 0, 0]}> + <boxGeometry args={props.subArgs} /> + </Subtraction> + </Geometry> + <GrassMaterial></GrassMaterial> + </mesh> + <mesh rotation={[Math.PI / 2, 0, 0]}> + <Geometry> + <Base position={[0, road_width + grass_width + cross_width / 2, 0]}> + <boxGeometry args={[props.length * 2, cross_width, 10]} /> + </Base> + <Addition position={[0, -(road_width + grass_width + cross_width / 2), 0]}> + <boxGeometry args={[props.length * 2, cross_width, 10]} /> + </Addition> + <Subtraction position={[0, 0, 0]}> + <boxGeometry args={props.subArgs} /> + </Subtraction> + </Geometry> + <CrossMaterial></CrossMaterial> + </mesh> + </group> + ); + }; + + const floorColor = '#535760'; + + return ( + <group position={position} receiveShadow> + {/* 鑽夊潽鍜屽満鏅� */} + <mesh rotation={[Math.PI / 2, 0, 0]}> + {/* <mesh> */} + <Geometry> + <Base> + <extrudeGeometry + args={[ + getPointToShape([ + new THREE.Vector2(-space_width, -space_length), + new THREE.Vector2(space_width, -space_length), + new THREE.Vector2(space_width, space_length), + new THREE.Vector2(-space_width, space_length), + new THREE.Vector2(-space_width, -space_length), + ]), + { depth: wallThickness }, + ]} + /> + </Base> + {/* 涓棿鐨勯晜绌虹殑 */} + <Subtraction> + <HouseFloor></HouseFloor> + </Subtraction> + {/* 姝i潰鐨勯晜绌虹殑 */} + <Subtraction> + <FrontRoad></FrontRoad> + </Subtraction> + {/* 鍚庤竟鐨勯晜绌虹殑,灏辨槸姝i潰瀵归潰鐨勯偅涓�闈� */} + <Subtraction> + <BackRoad></BackRoad> + </Subtraction> + {/* 鍙抽潰鐨勯晜绌虹殑锛屾病鏈夊鐨勯偅涓�闈� */} + <Subtraction> + <RightRoad></RightRoad> + </Subtraction> + {/* 宸﹁竟鐨勯晜绌虹殑,鏈変釜灏忛棬鐨勯偅涓�杈� */} + <Subtraction> + <LeftRoad></LeftRoad> + </Subtraction> + </Geometry> + <meshStandardMaterial color={'white'} /> + </mesh> + {/* <Text text="鍔㈠井鏈哄櫒浜�"></Text> */} + {/* 鍦版澘 */} + <mesh rotation={[Math.PI / 2, 0, 0]} receiveShadow> + <HouseFloor></HouseFloor> + <meshPhongMaterial map={floorTexture} reflectivity={1.5}></meshPhongMaterial> + </mesh> + {/* 鍚庨潰鐨勫澹�,鎷涚墝鐨勫彟涓�闈� */} + <mesh position={new THREE.Vector3(0, height, length - wallThickness)} receiveShadow> + <extrudeGeometry + args={[ + getPointToShape([ + new THREE.Vector2(-width, -height), + new THREE.Vector2(-width, height), + new THREE.Vector2(width, height), + new THREE.Vector2(width, -height), + ]), + { depth: wallThickness }, + ]} + /> + <meshPhongMaterial map={texture} metalness={1.0} reflectivity={1.5}></meshPhongMaterial> + </mesh> + {/* 鍚庨潰鐨勮矾 */} + <mesh rotation={[Math.PI / 2, 0, 0]}> + <BackRoad></BackRoad> + <SurfaceMaterial></SurfaceMaterial> + {/* <meshPhysicalMaterial color={floorColor}></meshPhysicalMaterial> */} + </mesh> + {/* 鍓嶉潰鐨勫澹�,鏈夋嫑鐗岀殑閭d竴杈� */} + <mesh position={new THREE.Vector3(0, height, -length)} receiveShadow> + <extrudeGeometry + args={[ + getPointToShape([ + new THREE.Vector2(-width, -height), + new THREE.Vector2(-width, height), + new THREE.Vector2(width, height), + new THREE.Vector2(width, -height), + ]), + { depth: wallThickness }, + ]} + /> + <meshPhongMaterial map={texture} metalness={1.0} reflectivity={1.5}></meshPhongMaterial> + </mesh> + {/* 鍓嶉潰鐨勫澹佷笅闈㈢殑璺� */} + <mesh rotation={[Math.PI / 2, 0, 0]}> + <FrontRoad></FrontRoad> + <SurfaceMaterial></SurfaceMaterial> + {/* <meshPhongMaterial + // color={floorColor} + map={roadTexture} + metalness={1.0} + roughness={0.8} + ></meshPhongMaterial> */} + </mesh> + {/* 娌℃湁澧欑殑閭d竴闈笅闈㈢殑璺� */} + <mesh rotation={[Math.PI / 2, 0, 0]}> + <RightRoad></RightRoad> + <SurfaceMaterial></SurfaceMaterial> + {/* <meshPhysicalMaterial + color={floorColor} + metalness={1.0} + roughness={0.8} + ></meshPhysicalMaterial> */} + </mesh> + {/* 宸﹁竟鐨勫澹侊紝鏈変釜鏍¢棬鐨勯偅涓�杈� */} + <mesh + position={new THREE.Vector3(width, height, 0)} + rotation={[0, Math.PI / 2, 0]} + receiveShadow + > + <extrudeGeometry args={[getBackWallShape(), { depth: wallThickness }]} /> + <meshPhysicalMaterial map={texture} metalness={1.0} roughness={0.8}></meshPhysicalMaterial> + </mesh> + <mesh rotation={[Math.PI / 2, 0, 0]}> + <LeftRoad></LeftRoad> + <SurfaceMaterial></SurfaceMaterial> + {/* <meshPhysicalMaterial + color={floorColor} + metalness={1.0} + roughness={0.8} + ></meshPhysicalMaterial> */} + </mesh> + + {/* 涓や釜杞寸殑璺潰鍙傛暟 */} + <OutSideSurface + rotation={0} + length={space_width} + subArgs={[width * 2 + aside_width * 2, length * 2 + aside_length * 2, 10]} + ></OutSideSurface> + <OutSideSurface + rotation={Math.PI / 2} + length={space_length} + subArgs={[length * 2 + aside_length * 2, width * 2 + aside_width * 2, 10]} + ></OutSideSurface> + + {/* 鍚庨潰澧欏鐨勯《閮� */} + <mesh + position={new THREE.Vector3(width, (5 / 2) * height, 0)} + rotation={[0, Math.PI / 2, 0]} + receiveShadow + > + <extrudeGeometry args={[getBackWallTopShape(), { depth: 2 || wallThickness }]} /> + <meshPhysicalMaterial + color={'#0069c5'} + metalness={1.0} + roughness={0.8} + ></meshPhysicalMaterial> + </mesh> + {/* 椤堕儴绗簩灞� */} + <mesh + position={new THREE.Vector3(-width - 5, (5 / 2) * height, 0)} + rotation={[0, Math.PI / 2, 0]} + receiveShadow + > + <extrudeGeometry args={[getRoofShape(), { depth: 2 * width + 10 || wallThickness }]} /> + <meshPhysicalMaterial + color={'#4895f6'} + metalness={1.0} + roughness={0.8} + ></meshPhysicalMaterial> + </mesh> + {/* 椤堕儴绗笁灞� */} + <mesh + position={new THREE.Vector3(-width, (5 / 2) * height, 0)} + rotation={[0, Math.PI / 2, 0]} + receiveShadow + > + <extrudeGeometry args={[getTopRoofShape(), { depth: 2 * width || wallThickness }]} /> + <meshPhysicalMaterial + map={roofTexture} + metalness={1.0} + roughness={0.8} + ></meshPhysicalMaterial> + </mesh> + </group> + ); +}; + +export default House; diff --git a/src/pages/base.jsx b/src/pages/base.jsx index 61680f6..6240fba 100644 --- a/src/pages/base.jsx +++ b/src/pages/base.jsx @@ -8,6 +8,7 @@ import Buildings from '@/components/buidings' import TreeGroup from '../components/tree-group' import GridModule from '../components/grid' +import House from '../components/house' const Base = (props) => { return ( @@ -22,7 +23,6 @@ <Camera /> <Sky distance={450000} sunPosition={[0, 1, 0]} inclination={0} azimuth={0.25} /> <Buildings /> - <TreeGroup /> <TreeGroup /> <Box position={[0, 0, 0]} /> <OrbitControls /> -- Gitblit v1.9.1