From b2f7aab8aa906d6ee5871b97f796213c79708385 Mon Sep 17 00:00:00 2001 From: Denis Manherz Date: Thu, 11 May 2023 22:26:01 +0200 Subject: [PATCH] The camera does something lol --- src/CameraControls.jsx | 77 +++++++++++++++++++--- src/Scene3.jsx | 15 ++--- src/SharedPlanetState.jsx | 2 +- src/customCamera.jsx | 135 ++++++++++++++++++++++++++++++++++++++ src/earth.jsx | 2 +- src/planetOverlay.jsx | 9 ++- 6 files changed, 218 insertions(+), 22 deletions(-) create mode 100644 src/customCamera.jsx diff --git a/src/CameraControls.jsx b/src/CameraControls.jsx index 952207d..dcac5a9 100644 --- a/src/CameraControls.jsx +++ b/src/CameraControls.jsx @@ -7,6 +7,8 @@ import React, { memo, useState, useContext, + useEffect, + useLayoutEffect, } from "react"; import * as THREE from "three"; @@ -20,19 +22,43 @@ export const CameraController = () => { const [distance, setDistance] = useState(5); const [lookAt, setLookAt] = useState(new THREE.Vector3(0, 0, 0)); const [position, setPosition] = useState(new THREE.Vector3(0, 0, 200)); - const [animate, setAnimate] = useState(true); + const [animate, setAnimate] = useState(false); const { camera } = useThree(); - const state = useThree(); + const [currObj, setCurrObj] = useState(undefined); + const mycam = useRef(); + const cameraGroupRef = useRef(); + const set = useThree(({ set }) => set); + const size = useThree(({ size }) => size); - const relativePosition = new THREE.Vector3(0, 0, distance); + useLayoutEffect(() => { + if (mycam.current) { + mycam.current.aspect = size.width / size.height; + mycam.current.updateProjectionMatrix(); + } + }, [size]); const handleLookAt = (pos) => { setLookAt(pos); }; customData.current["handleLookAt"] = handleLookAt; - const handlePosition = (pos) => { - const newPosition = pos.clone().add(relativePosition); + const handleDistance = (obj) => { + setDistance(obj.children[1].geometry.boundingSphere.radius * 1.5); + }; + + const handlePosition = (pos, obj) => { + mycam.current.updateMatrixWorld(); + const newPosition = pos + .clone() + .add( + new THREE.Vector3( + 0, + 0, + obj.children[1].geometry.boundingSphere.radius * 2.5 + ) + ); + + setCurrObj(obj); setPosition(newPosition); setAnimate(true); //console.log(newPosition); @@ -40,11 +66,33 @@ export const CameraController = () => { customData.current["handlePosition"] = handlePosition; useFrame(() => { + console.log(mycam); + let rp = undefined; + cameraGroupRef.current.position.set(new THREE.Vector3(0, 0, 200)); + //camera.updateProjectionMatrix(); + if (currObj) { + rp = currObj.position + .clone() + .add( + new THREE.Vector3( + 0, + 0, + currObj.children[1].geometry.boundingSphere.radius * 2.5 + ) + ); + } //console.log(state); - if (animate) { - camera.position.lerp(position, 0.1); + + if (animate && currObj) { + //update relative position + + setPosition(); + camera.position.lerp(rp, 0.02); camera.lookAt(lookAt); - if (camera.position.distanceTo(position) < 0.1) { + + //console.log(currObj); + if (camera.position.distanceTo(rp) < 0.1) { + //camera.quaternion.slerp(currObj.quaternion, 0.2); setAnimate(false); } } @@ -52,5 +100,16 @@ export const CameraController = () => { //camera.position.addScalar(1); //console.log(camera); }); - return <>; + return ( + + + + ); }; diff --git a/src/Scene3.jsx b/src/Scene3.jsx index a555e74..f9759c3 100644 --- a/src/Scene3.jsx +++ b/src/Scene3.jsx @@ -1,11 +1,11 @@ -import { Canvas } from "@react-three/fiber"; +import { Canvas, useThree } from "@react-three/fiber"; import { OrbitControls } from "@react-three/drei"; import React, { Suspense, useRef, createContext, memo } from "react"; import { ScreenOverlay } from "./omnioverlay.jsx"; import { SharedPlanetState } from "./SharedPlanetState.jsx"; import { Skybox } from "./skybox.jsx"; -import { CameraController } from "./CameraControls.jsx"; +import { CustomCamera } from "./customCamera.jsx"; export const MyContext = createContext(); @@ -19,18 +19,17 @@ const SolarSystemScene = () => { - + - diff --git a/src/SharedPlanetState.jsx b/src/SharedPlanetState.jsx index 14ab554..720c48c 100644 --- a/src/SharedPlanetState.jsx +++ b/src/SharedPlanetState.jsx @@ -58,7 +58,7 @@ export const SharedPlanetState = () => { customData.current["handleReset"] = handleReset; //set speed (timeinterval between positions 60000ms*speed) - const [speed, setSpeed] = useState(100); + const [speed, setSpeed] = useState(1); const updateSpeed = (newSpeed) => { setSpeed(newSpeed); setSpeedChanged(true); diff --git a/src/customCamera.jsx b/src/customCamera.jsx new file mode 100644 index 0000000..edb16ed --- /dev/null +++ b/src/customCamera.jsx @@ -0,0 +1,135 @@ +import { Canvas, useFrame, useThree } from "@react-three/fiber"; +import { OrbitControls, PositionPoint } from "@react-three/drei"; +import React, { + Suspense, + useRef, + createContext, + memo, + useState, + useContext, + useEffect, + useLayoutEffect, +} from "react"; +import * as THREE from "three"; + +import { ScreenOverlay } from "./omnioverlay.jsx"; +import { SharedPlanetState } from "./SharedPlanetState.jsx"; +import { Skybox } from "./skybox.jsx"; +import { MyContext } from "./Scene3.jsx"; + +export function CustomCamera(props) { + const { customData } = useContext(MyContext); + const [distance, setDistance] = useState(5); + const [lookAt, setLookAt] = useState(new THREE.Vector3(0, 0, 0)); + const [position, setPosition] = useState(new THREE.Vector3(0, 0, 200)); + const [animate, setAnimate] = useState(false); + + const [currObj, setCurrObj] = useState(undefined); + + const handleLookAt = (pos) => { + setLookAt(pos); + }; + customData.current["handleLookAt"] = handleLookAt; + + const handlePosition = (pos, obj) => { + const newPosition = pos + .clone() + .add( + new THREE.Vector3( + 0, + 0, + obj.children[1].geometry.boundingSphere.radius * 2.5 + ) + ); + + setCurrObj(obj); + setPosition(newPosition); + setAnimate(true); + //console.log(newPosition); + }; + customData.current["handlePosition"] = handlePosition; + + const cameraRef = useRef(); + const set = useThree(({ set }) => set); + const size = useThree(({ size }) => size); + const camGroup = useRef(); + + useLayoutEffect(() => { + if (cameraRef.current) { + cameraRef.current.aspect = size.width / size.height; + cameraRef.current.updateProjectionMatrix(); + } + }, [size, props]); + + useLayoutEffect(() => { + set({ camera: cameraRef.current }); + }, []); + + let i = 0; + + useFrame(({ clock }) => { + cameraRef.current.updateProjectionMatrix(); + //console.log(cameraRef.current.position); + //console.log(camGroup.current.position); + //cameraRef.current.position.add(new THREE.Vector3(1, 0, 0)); + //camGroup.current.position.add(new THREE.Vector3(0, 0, 1)); + //let rp = undefined; + //camGroup.current.position.copy(new THREE.Vector3(0, 0, 600)); + //camera.updateProjectionMatrix(); + let rp = undefined; + if (currObj) { + rp = currObj.position + .clone() + .add( + new THREE.Vector3( + 0, + 0, + currObj.children[1].geometry.boundingSphere.radius * 2.5 + ) + ); + } + //console.log(state); + + if (animate && currObj) { + //update relative position + + setPosition(); + camGroup.current.position.lerp(currObj.position, 0.02); + //set Camera position + /*cameraRef.current.position.lerp( + new THREE.Vector3( + 0, + 0, + currObj.children[1].geometry.boundingSphere.radius * 2.5 + ), + 0.01 + );*/ + cameraRef.current.lookAt(lookAt); + cameraRef.current.position.x = Math.cos(i) * 3; + cameraRef.current.position.y = Math.sin(2) * 3; + + i += 0.1; + + //console.log(currObj); + if (camGroup.current.position.distanceTo(currObj.position) < 0.1) { + //camera.quaternion.slerp(currObj.quaternion, 0.2); + //setAnimate(false); + } + } + //cameraRef.current.position.addScalar(2); + //camera.position.addScalar(1); + //console.log(camera);*/ + }); + + return ( + + + + ); +} diff --git a/src/earth.jsx b/src/earth.jsx index 007e3bf..1da5cfc 100644 --- a/src/earth.jsx +++ b/src/earth.jsx @@ -125,7 +125,7 @@ export const Earth = ({ speed, getPosition, speedChanged }) => { linePos={lineArr.current} planet={group} color={"lightgreen"} - lineLength={100} + lineLength={300} /> diff --git a/src/planetOverlay.jsx b/src/planetOverlay.jsx index 8090e68..c555a7c 100644 --- a/src/planetOverlay.jsx +++ b/src/planetOverlay.jsx @@ -60,11 +60,14 @@ export const PlanetOverlay = ({ planet }) => { // native event switch (event.nativeEvent.button) { case 0: - controls.current.target.copy(planet.current.position.clone()); + //controls.current.target.copy(planet.current.position.clone()); customData.current.showInfo(planet.current.userData); - customData.current.handlePosition(planet.current.position); + customData.current.handlePosition( + planet.current.position, + planet.current + ); customData.current.handleLookAt(planet.current.position); - console.log(customData); + //console.log(customData); //startFollow(); break; case 2: