ground-plane.tsx 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. "use client";
  2. import * as THREE from "three";
  3. import { RigidBody, CuboidCollider } from "@react-three/rapier";
  4. import { useEditorStore } from "@/lib/store";
  5. interface GroundPlaneProps {
  6. position?: [number, number, number] | null;
  7. rotation?: [number, number, number] | null;
  8. scale?: [number, number, number] | null;
  9. material?: {
  10. color?: string | null;
  11. metalness?: number | null;
  12. roughness?: number | null;
  13. } | null;
  14. size?: number | null;
  15. }
  16. export function GroundPlane({ position, material, size }: GroundPlaneProps) {
  17. const isPlaying = useEditorStore((s) => s.isPlaying);
  18. const s = size ?? 5000;
  19. const pos: [number, number, number] = position ?? [0, -0.1, 0];
  20. const plane = (
  21. <mesh rotation={[-Math.PI / 2, 0, 0]} position={pos} receiveShadow>
  22. <planeGeometry args={[s, s]} />
  23. <meshStandardMaterial
  24. color={material?.color ?? "#4CAF50"}
  25. metalness={material?.metalness ?? 0}
  26. roughness={material?.roughness ?? 0.9}
  27. side={THREE.DoubleSide}
  28. />
  29. </mesh>
  30. );
  31. if (!isPlaying) return plane;
  32. return (
  33. <RigidBody type="fixed" position={pos} colliders={false}>
  34. <mesh rotation={[-Math.PI / 2, 0, 0]} receiveShadow>
  35. <planeGeometry args={[s, s]} />
  36. <meshStandardMaterial
  37. color={material?.color ?? "#4CAF50"}
  38. metalness={material?.metalness ?? 0}
  39. roughness={material?.roughness ?? 0.9}
  40. side={THREE.DoubleSide}
  41. />
  42. </mesh>
  43. <CuboidCollider args={[s / 2, 0.01, s / 2]} position={[0, 0, 0]} />
  44. </RigidBody>
  45. );
  46. }