#
luxiaotao1123
2024-04-19 371549e1a9b9681cabe6a38b6e21511ca39a0809
#
1个文件已添加
3个文件已修改
593 ■■■■■ 已修改文件
package-lock.json 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/house.jsx 567 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/base.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
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",
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"
  }
}
}
src/components/house.jsx
New file
@@ -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)), // 右边。x轴是一样的,不断加厚度
      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), // 做曲线的那一条
        // 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), // 做曲线的那一条
        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 },
        ]}
      />
    );
  };
  //后面的路,招牌的那一边的反面
  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>
          {/* 正面的镂空的 */}
          <Subtraction>
            <FrontRoad></FrontRoad>
          </Subtraction>
          {/* 后边的镂空的,就是正面对面的那一面 */}
          <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>
      {/* 前面的墙壁,有招牌的那一边 */}
      <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>
      {/* 没有墙的那一面下面的路 */}
      <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;
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 />