blanchon's picture
Mostly UI Update
18b0fa5
<script lang="ts">
import type IUrdfJoint from "../interfaces/IUrdfJoint";
import { T } from "@threlte/core";
import UrdfLink from "./UrdfLink.svelte";
import { Vector3 } from "three";
import {
Billboard,
interactivity,
MeshLineGeometry,
Text,
type InteractivityProps
} from "@threlte/extras";
import type IUrdfLink from "../interfaces/IUrdfLink";
import type IUrdfRobot from "../interfaces/IUrdfRobot";
import { radiansToDegrees } from "@/utils";
const defaultOnClick: InteractivityProps["onclick"] = (event) => {
event.stopPropagation();
selectedLink = undefined;
selectedJoint = joint;
};
type Props = InteractivityProps & {
robot: IUrdfRobot;
joint: IUrdfJoint;
selectedJoint?: IUrdfJoint;
selectedLink?: IUrdfLink;
showName?: boolean;
nameHeight?: number;
highlightColor?: string;
jointColor?: string;
jointIndicatorColor?: string;
showLine?: boolean;
opacity?: number;
isInteractive?: boolean;
showVisual?: boolean;
showCollision?: boolean;
visualOpacity?: number;
collisionOpacity?: number;
collisionColor?: string;
jointNames?: boolean;
joints?: boolean;
};
let {
robot,
joint,
selectedJoint = $bindable(),
selectedLink = $bindable(),
showLine = false,
nameHeight = 0.02,
highlightColor = "#ff0000",
jointColor = "#000000",
jointIndicatorColor = "#000000",
opacity = 0.7,
isInteractive = false,
showName = false,
showVisual = true,
showCollision = true,
visualOpacity = 1,
collisionOpacity = 1,
collisionColor = "#000000",
jointNames = true,
onclick = defaultOnClick,
...restProps
}: Props = $props();
if (isInteractive) {
interactivity();
}
// Helper function to get current joint rotation value in degrees
function getJointRotationValue(joint: any): number {
const axis = joint.axis_xyz || [0, 0, 1];
const rotation = joint.rotation || [0, 0, 0];
// Find the primary axis and get the rotation value
for (let i = 0; i < 3; i++) {
if (Math.abs(axis[i]) > 0.001) {
return radiansToDegrees(rotation[i] / axis[i]);
}
}
return 0;
}
</script>
{@html `<!-- Joint ${joint.name} (${joint.type}) -->`}
<!-- draw line from parent-frame to joint origin -->
{#if showLine}
<T.Line>
<MeshLineGeometry
points={[
new Vector3(0, 0, 0),
new Vector3(joint.origin_xyz[0], joint.origin_xyz[1], joint.origin_xyz[2])
]}
/>
<T.LineBasicMaterial color={jointColor} />
</T.Line>
{/if}
<T.Group position={joint.origin_xyz} rotation={joint.origin_rpy}>
<T.Group rotation={joint.rotation}>
{#if joint.child}
<UrdfLink
{robot}
link={joint.child}
textScale={0.2}
{showName}
{showVisual}
{showCollision}
{visualOpacity}
{collisionOpacity}
{collisionColor}
jointNames={true}
joints={true}
{jointColor}
{jointIndicatorColor}
{nameHeight}
{selectedLink}
{selectedJoint}
{highlightColor}
{showLine}
opacity={1}
isInteractive={true}
/>
{/if}
{#if showLine}
<T.Line>
<MeshLineGeometry points={[new Vector3(0, 0, 0), new Vector3(0, -0.02, 0)]} />
<T.LineBasicMaterial color={jointIndicatorColor} />
</T.Line>
<T.Mesh rotation={[Math.PI / 2, 0, 0]} {...restProps}>
<T.CylinderGeometry args={[0.004, 0.004, 0.03]} />
<T.MeshBasicMaterial
color={selectedJoint == joint ? highlightColor : jointColor}
{opacity}
transparent={opacity < 1.0}
/>
</T.Mesh>
{/if}
</T.Group>
</T.Group>
{#if showName}
<Billboard
position.x={joint.origin_xyz[0] + 0.04}
position.y={joint.origin_xyz[1] + 0.01}
position.z={joint.origin_xyz[2] + 0.03}
renderOrder={999}
frustumCulled={false}
>
<Text
scale={nameHeight}
color={selectedJoint == joint ? highlightColor : jointColor}
text={joint.name + " " + getJointRotationValue(joint).toFixed(0) + "°"}
characters="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
renderOrder={999}
></Text>
</Billboard>
{/if}
<!-- From https://github.com/brean/urdf-viewer -->