The camera does something lol

This commit is contained in:
Denis Manherz 2023-05-11 22:26:01 +02:00
parent 654c1ca1ca
commit b2f7aab8aa
6 changed files with 218 additions and 22 deletions

View file

@ -7,6 +7,8 @@ import React, {
memo, memo,
useState, useState,
useContext, useContext,
useEffect,
useLayoutEffect,
} from "react"; } from "react";
import * as THREE from "three"; import * as THREE from "three";
@ -20,19 +22,43 @@ export const CameraController = () => {
const [distance, setDistance] = useState(5); const [distance, setDistance] = useState(5);
const [lookAt, setLookAt] = useState(new THREE.Vector3(0, 0, 0)); const [lookAt, setLookAt] = useState(new THREE.Vector3(0, 0, 0));
const [position, setPosition] = useState(new THREE.Vector3(0, 0, 200)); const [position, setPosition] = useState(new THREE.Vector3(0, 0, 200));
const [animate, setAnimate] = useState(true); const [animate, setAnimate] = useState(false);
const { camera } = useThree(); 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) => { const handleLookAt = (pos) => {
setLookAt(pos); setLookAt(pos);
}; };
customData.current["handleLookAt"] = handleLookAt; customData.current["handleLookAt"] = handleLookAt;
const handlePosition = (pos) => { const handleDistance = (obj) => {
const newPosition = pos.clone().add(relativePosition); 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); setPosition(newPosition);
setAnimate(true); setAnimate(true);
//console.log(newPosition); //console.log(newPosition);
@ -40,11 +66,33 @@ export const CameraController = () => {
customData.current["handlePosition"] = handlePosition; customData.current["handlePosition"] = handlePosition;
useFrame(() => { 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); //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); 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); setAnimate(false);
} }
} }
@ -52,5 +100,16 @@ export const CameraController = () => {
//camera.position.addScalar(1); //camera.position.addScalar(1);
//console.log(camera); //console.log(camera);
}); });
return <></>; return (
<group ref={cameraGroupRef}>
<perspectiveCamera
ref={mycam}
position={[0, 0, 100]}
fov={75}
aspect={window.innerWidth / window.innerHeight}
near={0.1}
far={1000}
/>
</group>
);
}; };

View file

@ -1,11 +1,11 @@
import { Canvas } from "@react-three/fiber"; import { Canvas, useThree } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei"; import { OrbitControls } from "@react-three/drei";
import React, { Suspense, useRef, createContext, memo } from "react"; import React, { Suspense, useRef, createContext, memo } from "react";
import { ScreenOverlay } from "./omnioverlay.jsx"; import { ScreenOverlay } from "./omnioverlay.jsx";
import { SharedPlanetState } from "./SharedPlanetState.jsx"; import { SharedPlanetState } from "./SharedPlanetState.jsx";
import { Skybox } from "./skybox.jsx"; import { Skybox } from "./skybox.jsx";
import { CameraController } from "./CameraControls.jsx"; import { CustomCamera } from "./customCamera.jsx";
export const MyContext = createContext(); export const MyContext = createContext();
@ -19,18 +19,17 @@ const SolarSystemScene = () => {
<ScreenOverlay /> <ScreenOverlay />
<Suspense fallback={null}> <Suspense fallback={null}>
<Canvas <Canvas
camera={{ /*camera={{
position: [0, 0, 100],
fov: 75, fov: 75,
near: 0.1, near: 0.1,
far: 1000000, far: 1000,
position: [0, 100, 200], }}*/
}}
> >
<CameraController /> <CustomCamera />
<Skybox /> <Skybox />
<ambientLight intensity={0.5} /> <ambientLight intensity={0.5} />
<SharedPlanetState /> <SharedPlanetState />
<OrbitControls ref={controls} />
</Canvas> </Canvas>
</Suspense> </Suspense>
</MyContext.Provider> </MyContext.Provider>

View file

@ -58,7 +58,7 @@ export const SharedPlanetState = () => {
customData.current["handleReset"] = handleReset; customData.current["handleReset"] = handleReset;
//set speed (timeinterval between positions 60000ms*speed) //set speed (timeinterval between positions 60000ms*speed)
const [speed, setSpeed] = useState(100); const [speed, setSpeed] = useState(1);
const updateSpeed = (newSpeed) => { const updateSpeed = (newSpeed) => {
setSpeed(newSpeed); setSpeed(newSpeed);
setSpeedChanged(true); setSpeedChanged(true);

135
src/customCamera.jsx Normal file
View file

@ -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 (
<group ref={camGroup} position={[0, 0, 200]}>
<perspectiveCamera
ref={cameraRef}
position={[0, 0, 0]}
fov={75}
near={0.1}
far={1000}
/>
</group>
);
}

View file

@ -125,7 +125,7 @@ export const Earth = ({ speed, getPosition, speedChanged }) => {
linePos={lineArr.current} linePos={lineArr.current}
planet={group} planet={group}
color={"lightgreen"} color={"lightgreen"}
lineLength={100} lineLength={300}
/> />
<group ref={group}> <group ref={group}>
<PlanetOverlay planet={group} /> <PlanetOverlay planet={group} />

View file

@ -60,11 +60,14 @@ export const PlanetOverlay = ({ planet }) => {
// native event // native event
switch (event.nativeEvent.button) { switch (event.nativeEvent.button) {
case 0: 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.showInfo(planet.current.userData);
customData.current.handlePosition(planet.current.position); customData.current.handlePosition(
planet.current.position,
planet.current
);
customData.current.handleLookAt(planet.current.position); customData.current.handleLookAt(planet.current.position);
console.log(customData); //console.log(customData);
//startFollow(); //startFollow();
break; break;
case 2: case 2: