From 83bc38696fad94519186588f3a4ee7b8ababb6e4 Mon Sep 17 00:00:00 2001 From: Denis Manherz Date: Mon, 15 May 2023 13:30:19 +0200 Subject: [PATCH] rotation very unintuitive lol --- src/customCamera.jsx | 151 ++++++++++++++++++++++++++---------------- src/earth.jsx | 1 + src/mercury.jsx | 1 + src/planet.jsx | 0 src/planetOverlay.jsx | 4 +- 5 files changed, 100 insertions(+), 57 deletions(-) create mode 100644 src/planet.jsx diff --git a/src/customCamera.jsx b/src/customCamera.jsx index edb16ed..85e2024 100644 --- a/src/customCamera.jsx +++ b/src/customCamera.jsx @@ -1,5 +1,10 @@ import { Canvas, useFrame, useThree } from "@react-three/fiber"; -import { OrbitControls, PositionPoint } from "@react-three/drei"; +import { + OrbitControls, + PositionPoint, + TrackballControls, + ArcballControls, +} from "@react-three/drei"; import React, { Suspense, useRef, @@ -19,33 +24,82 @@ 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 mouseDown = useRef(false); + const mouseUp = useRef(false); + let _mouseStart = useRef(new THREE.Vector2(0, 0)); + let _mouseEnd = useRef(new THREE.Vector2(0, 0)); + let distance = useRef(0); const [currObj, setCurrObj] = useState(undefined); + let rotate = useRef(false); + + const handleMouseWheel = (event) => { + const delta = Math.sign(event.deltaY); + handleZoom(delta); + }; + + const handleMouseMove = (event) => { + if (mouseDown.current && rotate.current) { + _mouseEnd.current = new THREE.Vector2(event.clientX, event.clientY); + const deltaX = event.movementX; + const deltaY = event.movementY; + + const rotationSpeed = 0.01; + + // Create quaternions for rotation around X and Y axes + const quaternionX = new THREE.Quaternion().setFromAxisAngle( + new THREE.Vector3(1, 0, 0), + deltaY * rotationSpeed + ); + const quaternionY = new THREE.Quaternion().setFromAxisAngle( + new THREE.Vector3(0, 1, 0), + deltaX * rotationSpeed + ); + + // Combine the quaternions + const deltaQuaternion = quaternionY.multiply(quaternionX); + + // Apply the rotation to the camera quaternion + camGroup.current.quaternion.multiply(deltaQuaternion); + } + }; + + const handleMouseDown = (event) => { + _mouseStart.current = new THREE.Vector2(event.clientX, event.clientY); + mouseDown.current = true; + mouseUp.current = false; + }; + + const handleMouseUp = (event) => { + mouseDown.current = false; + mouseUp.current = true; + }; const handleLookAt = (pos) => { setLookAt(pos); }; customData.current["handleLookAt"] = handleLookAt; + const handleZoom = (delta) => { + const zoomSpeed = 0.1; + function newDistance(prevDistance) { + const newDistance = prevDistance + delta * zoomSpeed; + return Math.max(1, newDistance); // Adjust the minimum distance as needed + } + distance.current = newDistance(distance.current); + console.log(distance); + }; + customData.current["handleZoom"] = handleZoom; + const handlePosition = (pos, obj) => { - const newPosition = pos - .clone() - .add( - new THREE.Vector3( - 0, - 0, - obj.children[1].geometry.boundingSphere.radius * 2.5 - ) - ); + if (currObj) currObj.remove(camGroup.current); setCurrObj(obj); - setPosition(newPosition); + setAnimate(true); - //console.log(newPosition); }; customData.current["handlePosition"] = handlePosition; @@ -59,76 +113,61 @@ export function CustomCamera(props) { cameraRef.current.aspect = size.width / size.height; cameraRef.current.updateProjectionMatrix(); } + cameraRef.current.position.copy(new THREE.Vector3(0, 0, 1000)); + window.addEventListener("mousedown", handleMouseDown); + window.addEventListener("mouseup", handleMouseUp); + window.addEventListener("mousemove", handleMouseMove); + window.addEventListener("wheel", handleMouseWheel); }, [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(); + distance.current = + currObj.children[1].geometry.boundingSphere.radius * 2.5; camGroup.current.position.lerp(currObj.position, 0.02); - //set Camera position - /*cameraRef.current.position.lerp( + 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; + 0.02 + ); - i += 0.1; + cameraRef.current.lookAt(currObj.position); - //console.log(currObj); - if (camGroup.current.position.distanceTo(currObj.position) < 0.1) { - //camera.quaternion.slerp(currObj.quaternion, 0.2); - //setAnimate(false); + rotate.current = false; + + if (camGroup.current.position.distanceTo(currObj.position) < 0.2) { + currObj.add(camGroup.current); + camGroup.current.position.copy(new THREE.Vector3(0, 0, 0), 0.2); + rotate.current = true; + setAnimate(false); } } - //cameraRef.current.position.addScalar(2); - //camera.position.addScalar(1); - //console.log(camera);*/ + if (rotate.current) { + /* cameraRef.current.quaternion.multiply(lastQ.current); */ + //camGroup.current.rotation.x += 0.005; + cameraRef.current.position.copy( + new THREE.Vector3(0, 0, distance.current) + ); + } }); return ( - + ); diff --git a/src/earth.jsx b/src/earth.jsx index 1da5cfc..9a31e47 100644 --- a/src/earth.jsx +++ b/src/earth.jsx @@ -63,6 +63,7 @@ export const Earth = ({ speed, getPosition, speedChanged }) => { //console.log("gethis"); getPosition("earth", setPosArr, posArr, planetPositionIndex.current); lastPositionUpdate.current = clock.elapsedTime; + //console.log(group.current); } //console.log("arrlength" + posArr.length); clouds.current.rotation.y += 0.00025; diff --git a/src/mercury.jsx b/src/mercury.jsx index c0e8bb9..c779b9a 100644 --- a/src/mercury.jsx +++ b/src/mercury.jsx @@ -41,6 +41,7 @@ export const Mercury = ({ speed, getPosition, speedChanged }) => { //console.log("gethis"); getPosition("mercury", setPosArr, posArr, planetPositionIndex.current); lastPositionUpdate.current = clock.elapsedTime; + //console.log(group.current); } //if speed is 0 set the date to current date get from posArr diff --git a/src/planet.jsx b/src/planet.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/planetOverlay.jsx b/src/planetOverlay.jsx index c555a7c..2735f62 100644 --- a/src/planetOverlay.jsx +++ b/src/planetOverlay.jsx @@ -85,7 +85,9 @@ export const PlanetOverlay = ({ planet }) => { }, [planet, name, minDistance, customData, iconVis, nameVis]); useFrame(() => { - var distance = camera.position.distanceTo(planet.current.position); + let worldpos = new THREE.Vector3(); + camera.getWorldPosition(worldpos); + var distance = worldpos.distanceTo(planet.current.position); if (distance < minDistance) { setOpacity(0); } else {