Skip to content

Commit

Permalink
Add axes w/ rotation sync w/ main model viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
ochafik committed Dec 23, 2024
1 parent b271658 commit 009033d
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 22 deletions.
46 changes: 46 additions & 0 deletions axes.scad
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module arrow(length=30, shaft_radius=1, head_radius=2, head_length=5) {
cylinder(h=length-head_length, r=shaft_radius, center=false);

translate([0, 0, length-head_length])
cylinder(h=head_length, r1=head_radius, r2=0, center=false);
}

color("red")
rotate([0, 90, 0])
arrow();

color("green")
rotate([-90, 0, 0])
arrow();

color("blue")
rotate([0, 0, 90])
arrow();

module letter(text)
linear_extrude(1) text(text, halign="center", valign="center");

letter_dist = 38;
union() {
color("red")
translate([letter_dist, 0, 0])
rotate([45, 0, 45])
letter("X");
color("green")
rotate([0, 0, 90])
translate([letter_dist, 0, 0])
rotate([45, 0, -45])
letter("Y");
color("blue")
rotate([0, -90, 0])
translate([letter_dist, 0, 0])
rotate([90+45, 0, 0])
rotate([0, 0, -90])
letter("Z");
}

color("grey")
cube(10, center=true);

color([0, 0, 0, $preview ? 0.05 : 0])
sphere(r=43);
Binary file added public/axes.glb
Binary file not shown.
85 changes: 63 additions & 22 deletions src/components/ViewerPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.

import { CSSProperties, useContext, useRef } from 'react';
import { CSSProperties, useContext, useEffect, useRef, useState } from 'react';
import { ModelContext } from './contexts';
import { StlViewer} from "react-stl-viewer";
import { ColorPicker } from 'primereact/colorpicker';
import { defaultModelColor } from '../state/initial-state';

declare global {
namespace JSX {
Expand All @@ -19,34 +16,78 @@ export default function ViewerPanel({className, style}: {className?: string, sty
if (!model) throw new Error('No model');

const state = model.state;
const modelRef = useRef();
const modelViewerRef = useRef<any>();
const axesViewerRef = useRef<any>();

for (const ref of [modelViewerRef, axesViewerRef]) {
const otherRef = ref === modelViewerRef ? axesViewerRef : modelViewerRef;
useEffect(() => {
function handleCameraChange(e: any) {
if (e.detail.source === 'user-interaction') {
const cameraOrbit = ref.current.getCameraOrbit();
cameraOrbit.radius = otherRef.current.getCameraOrbit().radius;

otherRef.current.cameraOrbit = cameraOrbit.toString();
}
}
ref.current.addEventListener('camera-change', handleCameraChange);
return () => ref.current.removeEventListener('camera-change', handleCameraChange);
}, [ref.current, otherRef.current]);
}

return (
<div className={className}
style={{
display: 'flex',
flexDirection: 'column',
position: 'relative',
flex: 1,
width: '100%',
...(style ?? {})
}}>
{(state.output?.displayFileURL || state.output?.outFile && state.output.outFile.name.endsWith('.glb') && state.output?.outFileURL) && (
<model-viewer
orientation="0deg -90deg 0deg"
src={state.output?.displayFileURL ?? state.output?.outFileURL ?? ''}
style={{
width: '100%',
height: '100%',
}}
environment-image="./skybox-lights.jpg"
max-camera-orbit="auto 180deg auto"
min-camera-orbit="auto 0deg auto"
camera-controls
ar
ref={(ref: any) => {
modelRef.current = ref;
}}
/>
<model-viewer
orientation="0deg -90deg 0deg"
src={state.output?.displayFileURL ?? state.output?.outFileURL ?? ''}
style={{
width: '100%',
height: '100%',
}}
environment-image="./skybox-lights.jpg"
max-camera-orbit="auto 180deg auto"
min-camera-orbit="auto 0deg auto"
camera-controls
ar
ref={modelViewerRef}
>
<span slot="progress-bar"></span>
</model-viewer>
{state.view.showAxes && (
<model-viewer
orientation="0deg -90deg 0deg"
src="./axes.glb"
style={{
position: 'absolute',
bottom: 0,
right: 0,
zIndex: 10,
height: '200px',
width: '200px',
}}
loading="eager"
interpolation-decay="0"
environment-image="./skybox-lights.jpg"
max-camera-orbit="auto 180deg auto"
min-camera-orbit="auto 0deg auto"
orbit-sensitivity="5"
interaction-prompt="none"
disable-zoom
camera-controls="false"
disable-tap
disable-pan
ref={axesViewerRef}
>
<span slot="progress-bar"></span>
</model-viewer>
)}
</div>
)
Expand Down

0 comments on commit 009033d

Please sign in to comment.