changed the orbital camera to allow for an offset without messing with the rotation, added a moisture heatmap, updated the bin3dvisualizer to look cleaner, re-implemented a new version of the dialog box that pops up when clicking a node
This commit is contained in:
parent
619f9b7bf4
commit
f54d4b5375
15 changed files with 1349 additions and 214 deletions
|
|
@ -33,6 +33,11 @@ interface Props {
|
|||
* larger when initialRadius is large.
|
||||
*/
|
||||
maxRadius?: number;
|
||||
/**
|
||||
* used to control the offset of the target from the center that the camera rotates around
|
||||
*/
|
||||
offset?: { x: number; y: number; z: number };
|
||||
viewOffset?: number;
|
||||
/**
|
||||
* Called when the camera is reset to its initial position.
|
||||
* OrbitCameraControls manages the reset internally — use this to
|
||||
|
|
@ -48,6 +53,10 @@ export default function OrbitCameraControls(props: Props) {
|
|||
clampVerticalRotation,
|
||||
minPhi = 0.01,
|
||||
maxPhi = Math.PI - 0.01,
|
||||
offset,
|
||||
viewOffset,
|
||||
initialRadius,
|
||||
maxRadius,
|
||||
onReset,
|
||||
} = props;
|
||||
|
||||
|
|
@ -55,9 +64,9 @@ export default function OrbitCameraControls(props: Props) {
|
|||
|
||||
const mouse = useRef(new Vector2());
|
||||
const targetRef = useRef({
|
||||
x: target?.x ?? 0,
|
||||
y: target?.y ?? 0,
|
||||
z: target?.z ?? 0,
|
||||
x: (target?.x ?? 0) + (offset?.x ?? 0),
|
||||
y: (target?.y ?? 0) + (offset?.y ?? 0),
|
||||
z: (target?.z ?? 0) + (offset?.z ?? 0),
|
||||
});
|
||||
|
||||
const isDragging = useRef(false);
|
||||
|
|
@ -67,7 +76,7 @@ export default function OrbitCameraControls(props: Props) {
|
|||
|
||||
// Spherical coords
|
||||
const spherical = useRef({
|
||||
radius: props.initialRadius ?? 10,
|
||||
radius: initialRadius ?? 10,
|
||||
theta: 0, // horizontal angle
|
||||
phi: Math.PI / 2, // vertical angle
|
||||
});
|
||||
|
|
@ -78,11 +87,11 @@ export default function OrbitCameraControls(props: Props) {
|
|||
|
||||
const updateCamera = () => {
|
||||
const { radius, theta, phi } = spherical.current;
|
||||
|
||||
|
||||
const x = radius * Math.sin(phi) * Math.sin(theta);
|
||||
const y = radius * Math.cos(phi);
|
||||
const z = radius * Math.sin(phi) * Math.cos(theta);
|
||||
|
||||
|
||||
camera.position.set(
|
||||
targetRef.current.x + x,
|
||||
targetRef.current.y + y,
|
||||
|
|
@ -93,19 +102,23 @@ export default function OrbitCameraControls(props: Props) {
|
|||
targetRef.current.y,
|
||||
targetRef.current.z
|
||||
);
|
||||
|
||||
// Shift the projected image without affecting orbit
|
||||
const { width, height } = gl.domElement.getBoundingClientRect();
|
||||
(camera as any).setViewOffset(width, height, viewOffset ?? 0, 0, width, height);
|
||||
};
|
||||
|
||||
// Hand the reset function to the caller so they can trigger it
|
||||
// (e.g. from a button in CameraOverlay) without needing an external ref.
|
||||
if (onReset) {
|
||||
onReset(() => {
|
||||
spherical.current.radius = props.initialRadius ?? 10;
|
||||
spherical.current.radius = initialRadius ?? 10;
|
||||
spherical.current.theta = 0;
|
||||
spherical.current.phi = Math.PI / 2;
|
||||
targetRef.current = {
|
||||
x: target?.x ?? 0,
|
||||
y: target?.y ?? 0,
|
||||
z: target?.z ?? 0,
|
||||
x: (target?.x ?? 0) + (offset?.x ?? 0),
|
||||
y: (target?.y ?? 0) + (offset?.y ?? 0),
|
||||
z: (target?.z ?? 0) + (offset?.z ?? 0),
|
||||
};
|
||||
updateCamera();
|
||||
});
|
||||
|
|
@ -200,7 +213,7 @@ export default function OrbitCameraControls(props: Props) {
|
|||
spherical.current.radius += e.deltaY * 0.01;
|
||||
spherical.current.radius = Math.max(
|
||||
3,
|
||||
Math.min(props.maxRadius ?? 30, spherical.current.radius)
|
||||
Math.min(maxRadius ?? 30, spherical.current.radius)
|
||||
);
|
||||
|
||||
updateCamera();
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ export default function BaseMesh(props: BaseMeshProps) {
|
|||
};
|
||||
|
||||
return (
|
||||
<group position={position} rotation={rotation}>
|
||||
<group position={position} rotation={rotation} renderOrder={renderOrder}>
|
||||
{/* Main surface */}
|
||||
<mesh geometry={geometry} onClick={onClick} renderOrder={renderOrder}>
|
||||
{buildMaterial()}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue