mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
first try at custom camera controls
This commit is contained in:
1 parent
c6f8c1e6a5
commit
39aeba0766
3 files changed
+76
-4
No files matched your search
+4
-1
@@ -14,7 +14,10 @@
|
||||
"RMAO",
|
||||
"Verts",
|
||||
"drei",
|
||||
"frameloop"
|
||||
"frameloop",
|
||||
"pointermove",
|
||||
"pointerup",
|
||||
"pointerdown"
|
||||
],
|
||||
"userWords": [
|
||||
"WOTB",
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { J_HAT, K_HAT } from "@blitzkit/core";
|
||||
import { invalidate, useThree } from "@react-three/fiber";
|
||||
import { useEffect } from "react";
|
||||
import { Vector2, Vector3 } from "three";
|
||||
import { degToRad } from "three/src/math/MathUtils.js";
|
||||
|
||||
const initialDistance = 8;
|
||||
const initialRotation = new Vector2(degToRad(45), degToRad(45));
|
||||
|
||||
const clientPosition = new Vector2();
|
||||
const workingVector2 = new Vector2();
|
||||
const workingVector3 = new Vector3();
|
||||
|
||||
const cameraCenter = new Vector3(0, 1, 0);
|
||||
|
||||
const cameraRotation = initialRotation.clone();
|
||||
let cameraDistance = initialDistance;
|
||||
|
||||
export function TankopediaControls() {
|
||||
const canvas = useThree((state) => state.gl.domElement);
|
||||
const camera = useThree((state) => state.camera);
|
||||
|
||||
useEffect(() => {
|
||||
function handlePointerDown(event: PointerEvent) {
|
||||
clientPosition.set(event.clientX, event.clientY);
|
||||
|
||||
window.addEventListener("pointermove", handlePointerMove);
|
||||
window.addEventListener("pointerup", handlePointerUp);
|
||||
}
|
||||
|
||||
function handlePointerMove(event: PointerEvent) {
|
||||
workingVector2.set(event.clientX, event.clientY).sub(clientPosition);
|
||||
|
||||
workingVector2.x *= -(2 * Math.PI) / canvas.width;
|
||||
workingVector2.y *= (2 * Math.PI) / canvas.height;
|
||||
|
||||
cameraRotation.x += workingVector2.x;
|
||||
|
||||
if (cameraRotation.y + workingVector2.y < Math.PI / 2) {
|
||||
cameraRotation.y += workingVector2.y;
|
||||
}
|
||||
|
||||
clientPosition.set(event.clientX, event.clientY);
|
||||
|
||||
updateCameraPosition();
|
||||
}
|
||||
|
||||
function handlePointerUp() {
|
||||
window.removeEventListener("pointermove", handlePointerMove);
|
||||
window.removeEventListener("pointerup", handlePointerUp);
|
||||
}
|
||||
|
||||
function updateCameraPosition() {
|
||||
camera.position
|
||||
.set(cameraDistance, 0, 0)
|
||||
.applyAxisAngle(J_HAT, cameraRotation.x)
|
||||
.applyAxisAngle(K_HAT, cameraRotation.y)
|
||||
.add(cameraCenter);
|
||||
camera.lookAt(cameraCenter);
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
canvas.addEventListener("pointerdown", handlePointerDown);
|
||||
|
||||
return () => {
|
||||
canvas.removeEventListener("pointerdown", handlePointerDown);
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { type StageParameters } from "@protos/blitz_static_tank_upgrade_single_stage";
|
||||
import { OrbitControls } from "@react-three/drei";
|
||||
import { Canvas } from "@react-three/fiber";
|
||||
import { useTankChassisModel } from "../../hooks/useTankChassisModel";
|
||||
import { useTankGunModel } from "../../hooks/useTankGunModel";
|
||||
import { useTankHullModel } from "../../hooks/useTankHullModel";
|
||||
import { useTankTurretModel } from "../../hooks/useTankTurretModel";
|
||||
import { TankopediaControls } from "../TankopediaControls";
|
||||
import { TankopediaLighting } from "../TankopediaLighting";
|
||||
import { SceneProps } from "../TankopediaSceneProps";
|
||||
import styles from "./index.module.css";
|
||||
@@ -53,8 +53,7 @@ function Content({ parameters }: TankopediaSandboxProps) {
|
||||
|
||||
<TankopediaLighting />
|
||||
<SceneProps />
|
||||
|
||||
<OrbitControls />
|
||||
<TankopediaControls />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user