@wandelbots/wandelbots-js-react-components 4.0.3 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/3d.cjs.js +1 -1
- package/dist/3d.d.ts +3 -1
- package/dist/3d.d.ts.map +1 -1
- package/dist/3d.es.js +12 -10
- package/dist/auth0-spa-js.production.esm-D_IhPirK.cjs +5 -0
- package/dist/auth0-spa-js.production.esm-D_IhPirK.cjs.map +1 -0
- package/dist/{auth0-spa-js.production.esm-BMSlxZC5.js → auth0-spa-js.production.esm-mvPojIrB.js} +1526 -1360
- package/dist/auth0-spa-js.production.esm-mvPojIrB.js.map +1 -0
- package/dist/components/robots/DHLinearAxis.d.ts +3 -0
- package/dist/components/robots/DHLinearAxis.d.ts.map +1 -0
- package/dist/components/robots/LinearAxis.d.ts +25 -0
- package/dist/components/robots/LinearAxis.d.ts.map +1 -0
- package/dist/components/robots/LinearAxisAnimator.d.ts +12 -0
- package/dist/components/robots/LinearAxisAnimator.d.ts.map +1 -0
- package/dist/components/robots/SupportedLinearAxis.d.ts +18 -0
- package/dist/components/robots/SupportedLinearAxis.d.ts.map +1 -0
- package/dist/core.cjs.js +1 -1
- package/dist/core.es.js +2 -2
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +63 -61
- package/dist/{interpolation-DAXKfoDS.cjs → interpolation-DZhBKo-u.cjs} +2 -2
- package/dist/{interpolation-DAXKfoDS.cjs.map → interpolation-DZhBKo-u.cjs.map} +1 -1
- package/dist/{interpolation-DcPbemBD.js → interpolation-baUmFLkh.js} +2 -2
- package/dist/{interpolation-DcPbemBD.js.map → interpolation-baUmFLkh.js.map} +1 -1
- package/dist/manufacturerHomePositions-BCgn-SCy.js +1262 -0
- package/dist/manufacturerHomePositions-BCgn-SCy.js.map +1 -0
- package/dist/manufacturerHomePositions-B_nLYNzG.cjs +2 -0
- package/dist/manufacturerHomePositions-B_nLYNzG.cjs.map +1 -0
- package/dist/{theming-Hr605E6v.js → theming-BTlS2afw.js} +2 -2
- package/dist/{theming-Hr605E6v.js.map → theming-BTlS2afw.js.map} +1 -1
- package/dist/{theming-CPShzNuV.cjs → theming-DPoEjzxv.cjs} +2 -2
- package/dist/{theming-CPShzNuV.cjs.map → theming-DPoEjzxv.cjs.map} +1 -1
- package/package.json +2 -2
- package/src/3d.ts +4 -2
- package/src/components/robots/DHLinearAxis.tsx +128 -0
- package/src/components/robots/LinearAxis.tsx +73 -0
- package/src/components/robots/LinearAxisAnimator.tsx +116 -0
- package/src/components/robots/SupportedLinearAxis.tsx +99 -0
- package/dist/auth0-spa-js.production.esm-BMSlxZC5.js.map +0 -1
- package/dist/auth0-spa-js.production.esm-DZ6lsBvD.cjs +0 -5
- package/dist/auth0-spa-js.production.esm-DZ6lsBvD.cjs.map +0 -1
- package/dist/manufacturerHomePositions-BD6C5qZJ.js +0 -1040
- package/dist/manufacturerHomePositions-BD6C5qZJ.js.map +0 -1
- package/dist/manufacturerHomePositions-DRNjU1pU.cjs +0 -2
- package/dist/manufacturerHomePositions-DRNjU1pU.cjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wandelbots/wandelbots-js-react-components",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "React UI toolkit for building applications on top of the Wandelbots platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
"dependencies": {
|
|
177
177
|
"@mui/x-charts": "^8.27.0",
|
|
178
178
|
"@mui/x-data-grid": "^8.27.0",
|
|
179
|
-
"@wandelbots/nova-js": "3.5.
|
|
179
|
+
"@wandelbots/nova-js": "3.5.1",
|
|
180
180
|
"axios": "^1.13.2",
|
|
181
181
|
"dotenv": "^17.2.3",
|
|
182
182
|
"i18next-browser-languagedetector": "^8.2.0",
|
package/src/3d.ts
CHANGED
|
@@ -5,11 +5,13 @@ export * from "./components/3d-viewport/SafetyZonesRenderer"
|
|
|
5
5
|
export * from "./components/3d-viewport/TrajectoryRenderer"
|
|
6
6
|
export * from "./components/RobotCard"
|
|
7
7
|
export * from "./components/robots/AxisConfig"
|
|
8
|
+
export * from "./components/robots/LinearAxis"
|
|
8
9
|
export {
|
|
9
|
-
MANUFACTURER_HOME_CONFIGS,
|
|
10
10
|
extractManufacturer,
|
|
11
|
-
getDefaultHomeConfig,
|
|
11
|
+
getDefaultHomeConfig, MANUFACTURER_HOME_CONFIGS
|
|
12
12
|
} from "./components/robots/manufacturerHomePositions"
|
|
13
13
|
export * from "./components/robots/Robot"
|
|
14
14
|
export { defaultGetModel } from "./components/robots/robotModelLogic"
|
|
15
|
+
export * from "./components/robots/SupportedLinearAxis"
|
|
15
16
|
export * from "./components/robots/SupportedRobot"
|
|
17
|
+
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Line } from "@react-three/drei"
|
|
2
|
+
import type { DHParameter } from "@wandelbots/nova-js/v2"
|
|
3
|
+
import React, { useRef } from "react"
|
|
4
|
+
import type * as THREE from "three"
|
|
5
|
+
import { Matrix4, Quaternion, Vector3 } from "three"
|
|
6
|
+
import LinearAxisAnimator from "./LinearAxisAnimator"
|
|
7
|
+
import type { DHLinearAxisProps } from "./SupportedLinearAxis"
|
|
8
|
+
|
|
9
|
+
export function DHLinearAxis({
|
|
10
|
+
rapidlyChangingMotionState,
|
|
11
|
+
dhParameters,
|
|
12
|
+
...props
|
|
13
|
+
}: DHLinearAxisProps) {
|
|
14
|
+
// reused in every update
|
|
15
|
+
const accumulatedMatrix = new Matrix4()
|
|
16
|
+
|
|
17
|
+
const tcpMeshRef = useRef<THREE.Mesh | null>(null)
|
|
18
|
+
const tcpLineRef = useRef<any>(null)
|
|
19
|
+
|
|
20
|
+
// Calculate initial TCP position
|
|
21
|
+
function calculateTcpPosition(jointValues: number[]): Vector3 {
|
|
22
|
+
const tempMatrix = new Matrix4()
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < dhParameters.length; i++) {
|
|
25
|
+
const param = dhParameters[i]
|
|
26
|
+
const jointValue = jointValues[i] ?? 0
|
|
27
|
+
|
|
28
|
+
const matrix = new Matrix4()
|
|
29
|
+
.makeRotationY(param.theta!) // Base rotation (if any)
|
|
30
|
+
.multiply(
|
|
31
|
+
new Matrix4().makeTranslation(
|
|
32
|
+
param.a! / 1000,
|
|
33
|
+
(param.d! + jointValue * (param.reverse_rotation_direction ? -1 : 1)) / 1000,
|
|
34
|
+
0
|
|
35
|
+
)
|
|
36
|
+
) // Translate along X by a, and Y by d + joint_position
|
|
37
|
+
.multiply(new Matrix4().makeRotationX(param.alpha!)) // Rotate around X
|
|
38
|
+
|
|
39
|
+
tempMatrix.multiply(matrix)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const position = new Vector3()
|
|
43
|
+
const quaternion = new Quaternion()
|
|
44
|
+
const scale = new Vector3()
|
|
45
|
+
tempMatrix.decompose(position, quaternion, scale)
|
|
46
|
+
return position
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Calculate initial TCP position for rendering
|
|
50
|
+
const initialTcpPosition = calculateTcpPosition(rapidlyChangingMotionState.joint_position)
|
|
51
|
+
|
|
52
|
+
function setTranslation(joints: THREE.Object3D[], jointValues: number[]) {
|
|
53
|
+
accumulatedMatrix.identity()
|
|
54
|
+
|
|
55
|
+
let tcpPosition = new Vector3()
|
|
56
|
+
|
|
57
|
+
// Process all joints based on dhParameters length, not joints array
|
|
58
|
+
// Since we're using DHLinearAxis directly without a model, we don't have joint objects
|
|
59
|
+
for (let jointIndex = 0; jointIndex < dhParameters.length; jointIndex++) {
|
|
60
|
+
const jointValue = jointValues[jointIndex] ?? 0
|
|
61
|
+
const param = dhParameters[jointIndex]
|
|
62
|
+
|
|
63
|
+
// Calculate and accumulate transformation
|
|
64
|
+
const matrix = new Matrix4()
|
|
65
|
+
.makeRotationY(param.theta!) // Base rotation (if any)
|
|
66
|
+
.multiply(
|
|
67
|
+
new Matrix4().makeTranslation(
|
|
68
|
+
param.a! / 1000,
|
|
69
|
+
(param.d! + jointValue * (param.reverse_rotation_direction ? -1 : 1)) / 1000,
|
|
70
|
+
0
|
|
71
|
+
)
|
|
72
|
+
)
|
|
73
|
+
.multiply(new Matrix4().makeRotationX(param.alpha!))
|
|
74
|
+
|
|
75
|
+
accumulatedMatrix.multiply(matrix)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Get final TCP position from accumulated matrix
|
|
79
|
+
const position = new Vector3()
|
|
80
|
+
const quaternion = new Quaternion()
|
|
81
|
+
const scale = new Vector3()
|
|
82
|
+
accumulatedMatrix.decompose(position, quaternion, scale)
|
|
83
|
+
tcpPosition = position
|
|
84
|
+
|
|
85
|
+
// Update TCP marker
|
|
86
|
+
if (tcpMeshRef.current) {
|
|
87
|
+
tcpMeshRef.current.position.set(tcpPosition.x, tcpPosition.y, tcpPosition.z)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Update TCP line
|
|
91
|
+
if (tcpLineRef.current) {
|
|
92
|
+
const lineGeometry = tcpLineRef.current.geometry
|
|
93
|
+
if (lineGeometry && lineGeometry.setPositions) {
|
|
94
|
+
lineGeometry.setPositions([0, 0, 0, tcpPosition.x, tcpPosition.y, tcpPosition.z])
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<>
|
|
101
|
+
<LinearAxisAnimator
|
|
102
|
+
rapidlyChangingMotionState={rapidlyChangingMotionState}
|
|
103
|
+
dhParameters={dhParameters}
|
|
104
|
+
onTranslationChanged={setTranslation}
|
|
105
|
+
>
|
|
106
|
+
<group {...props} name="Scene">
|
|
107
|
+
{/* Base (origin) - Green sphere representing initial previous position */}
|
|
108
|
+
<mesh name="Base" position={[0, 0, 0]}>
|
|
109
|
+
<sphereGeometry args={[0.02, 32, 32]} />
|
|
110
|
+
<meshStandardMaterial color={"green"} depthTest={true} />
|
|
111
|
+
</mesh>
|
|
112
|
+
{/* Line from Base to TCP */}
|
|
113
|
+
<Line
|
|
114
|
+
ref={tcpLineRef}
|
|
115
|
+
points={[new Vector3(0, 0, 0), initialTcpPosition]}
|
|
116
|
+
color={"White"}
|
|
117
|
+
lineWidth={5}
|
|
118
|
+
/>
|
|
119
|
+
{/* TCP (Tool Center Point) - Red sphere that shows final position */}
|
|
120
|
+
<mesh ref={tcpMeshRef} name="TCP" position={initialTcpPosition}>
|
|
121
|
+
<sphereGeometry args={[0.025, 32, 32]} />
|
|
122
|
+
<meshStandardMaterial color={"red"} depthTest={true} />
|
|
123
|
+
</mesh>
|
|
124
|
+
</group>
|
|
125
|
+
</LinearAxisAnimator>
|
|
126
|
+
</>
|
|
127
|
+
)
|
|
128
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { ThreeElements } from "@react-three/fiber"
|
|
2
|
+
|
|
3
|
+
import type { Group } from "three"
|
|
4
|
+
import type { ConnectedMotionGroup } from "../../lib/ConnectedMotionGroup"
|
|
5
|
+
import { DHLinearAxis } from "./DHLinearAxis"
|
|
6
|
+
import { defaultGetModel } from "./robotModelLogic"
|
|
7
|
+
import { SupportedLinearAxis } from "./SupportedLinearAxis"
|
|
8
|
+
|
|
9
|
+
export type LinearAxisProps = {
|
|
10
|
+
connectedMotionGroup: ConnectedMotionGroup
|
|
11
|
+
getModel?: (modelFromController: string) => Promise<string>
|
|
12
|
+
flangeRef?: React.Ref<Group>
|
|
13
|
+
transparentColor?: string
|
|
14
|
+
postModelRender?: () => void
|
|
15
|
+
} & ThreeElements["group"]
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The LinearAxis component is a wrapper that renders SupportedLinearAxis if a model is available,
|
|
19
|
+
* otherwise falls back to DHLinearAxis for usage with @wandelbots/nova-js ConnectedMotionGroup object.
|
|
20
|
+
*
|
|
21
|
+
* @param {LinearAxisProps} props - The properties for the LinearAxis component.
|
|
22
|
+
* @param {ConnectedMotionGroup} props.connectedMotionGroup - The connected motion group containing motion state and parameters.
|
|
23
|
+
* @param {Function} [props.getModel=defaultGetModel] - Optional function to get the model URL. Defaults to defaultGetModel.
|
|
24
|
+
* @param {Object} props - Additional properties passed to the underlying component.
|
|
25
|
+
*
|
|
26
|
+
* @returns {JSX.Element} The rendered SupportedLinearAxis or DHLinearAxis component.
|
|
27
|
+
*/
|
|
28
|
+
export function LinearAxis({
|
|
29
|
+
connectedMotionGroup,
|
|
30
|
+
getModel = defaultGetModel,
|
|
31
|
+
flangeRef,
|
|
32
|
+
transparentColor,
|
|
33
|
+
postModelRender,
|
|
34
|
+
...props
|
|
35
|
+
}: LinearAxisProps) {
|
|
36
|
+
if (!connectedMotionGroup.dhParameters) {
|
|
37
|
+
return null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const modelFromController = connectedMotionGroup.modelFromController || ""
|
|
41
|
+
const hasModel = modelFromController && getModel(modelFromController)
|
|
42
|
+
|
|
43
|
+
// Use SupportedLinearAxis if model is available, otherwise fall back to DHLinearAxis
|
|
44
|
+
if (hasModel) {
|
|
45
|
+
return (
|
|
46
|
+
<SupportedLinearAxis
|
|
47
|
+
rapidlyChangingMotionState={
|
|
48
|
+
connectedMotionGroup.rapidlyChangingMotionState
|
|
49
|
+
}
|
|
50
|
+
modelFromController={modelFromController}
|
|
51
|
+
dhParameters={connectedMotionGroup.dhParameters}
|
|
52
|
+
getModel={getModel}
|
|
53
|
+
flangeRef={flangeRef}
|
|
54
|
+
transparentColor={transparentColor}
|
|
55
|
+
postModelRender={postModelRender}
|
|
56
|
+
{...props}
|
|
57
|
+
/>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<DHLinearAxis
|
|
63
|
+
rapidlyChangingMotionState={
|
|
64
|
+
connectedMotionGroup.rapidlyChangingMotionState
|
|
65
|
+
}
|
|
66
|
+
dhParameters={connectedMotionGroup.dhParameters}
|
|
67
|
+
{...props}
|
|
68
|
+
/>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { defaultGetModel }
|
|
73
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { useFrame, useThree } from "@react-three/fiber"
|
|
2
|
+
import type { DHParameter, MotionGroupState } from "@wandelbots/nova-js/v2"
|
|
3
|
+
import React, { useCallback, useEffect, useRef } from "react"
|
|
4
|
+
import type { Group, Object3D } from "three"
|
|
5
|
+
import { useAutorun } from "../utils/hooks"
|
|
6
|
+
import { ValueInterpolator } from "../utils/interpolation"
|
|
7
|
+
import { collectJoints } from "./robotModelLogic"
|
|
8
|
+
|
|
9
|
+
type LinearAxisAnimatorProps = {
|
|
10
|
+
rapidlyChangingMotionState: MotionGroupState
|
|
11
|
+
dhParameters: DHParameter[]
|
|
12
|
+
onTranslationChanged?: (joints: Object3D[], jointValues: number[]) => void
|
|
13
|
+
children: React.ReactNode
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default function LinearAxisAnimator({
|
|
17
|
+
rapidlyChangingMotionState,
|
|
18
|
+
dhParameters,
|
|
19
|
+
onTranslationChanged,
|
|
20
|
+
children,
|
|
21
|
+
}: LinearAxisAnimatorProps) {
|
|
22
|
+
const jointValues = useRef<number[]>([])
|
|
23
|
+
const jointObjects = useRef<Object3D[]>([])
|
|
24
|
+
const interpolatorRef = useRef<ValueInterpolator | null>(null)
|
|
25
|
+
const { invalidate } = useThree()
|
|
26
|
+
|
|
27
|
+
// Initialize interpolator
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const initialJointValues = rapidlyChangingMotionState.joint_position.filter(
|
|
30
|
+
(item) => item !== undefined,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
interpolatorRef.current = new ValueInterpolator(initialJointValues, {
|
|
34
|
+
tension: 120, // Controls spring stiffness - higher values create faster, more responsive motion
|
|
35
|
+
friction: 20, // Controls damping - higher values reduce oscillation and create smoother settling
|
|
36
|
+
threshold: 0.001,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
return () => {
|
|
40
|
+
interpolatorRef.current?.destroy()
|
|
41
|
+
}
|
|
42
|
+
}, [])
|
|
43
|
+
|
|
44
|
+
// Animation loop that runs at the display's refresh rate
|
|
45
|
+
useFrame((state, delta) => {
|
|
46
|
+
if (interpolatorRef.current) {
|
|
47
|
+
const isComplete = interpolatorRef.current.update(delta)
|
|
48
|
+
setTranslation()
|
|
49
|
+
|
|
50
|
+
// Trigger a re-render only if the animation is still running
|
|
51
|
+
if (!isComplete) {
|
|
52
|
+
invalidate()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
function setGroupRef(group: Group | null) {
|
|
58
|
+
if (!group) return
|
|
59
|
+
|
|
60
|
+
jointObjects.current = collectJoints(group)
|
|
61
|
+
|
|
62
|
+
// Set initial position
|
|
63
|
+
setTranslation()
|
|
64
|
+
invalidate()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function setTranslation() {
|
|
68
|
+
const updatedJointValues = interpolatorRef.current?.getCurrentValues() || []
|
|
69
|
+
|
|
70
|
+
if (onTranslationChanged) {
|
|
71
|
+
onTranslationChanged(jointObjects.current, updatedJointValues)
|
|
72
|
+
} else {
|
|
73
|
+
// For linear axes, we apply translation instead of rotation
|
|
74
|
+
for (const [index, object] of jointObjects.current.entries()) {
|
|
75
|
+
const dhParam = dhParameters[index]
|
|
76
|
+
const translationSign = dhParam.reverse_rotation_direction ? -1 : 1
|
|
77
|
+
|
|
78
|
+
// Apply linear translation along X axis
|
|
79
|
+
// Convert from millimeters to meters
|
|
80
|
+
// ToDo: change back to y axis when we want to display the proper orientation
|
|
81
|
+
object.position.x =
|
|
82
|
+
(translationSign * (updatedJointValues[index] || 0)) / 1000
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const updateJoints = useCallback(() => {
|
|
88
|
+
const newJointValues = rapidlyChangingMotionState.joint_position.filter(
|
|
89
|
+
(item) => item !== undefined,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
requestAnimationFrame(() => {
|
|
93
|
+
jointValues.current = newJointValues
|
|
94
|
+
interpolatorRef.current?.setTarget(newJointValues)
|
|
95
|
+
})
|
|
96
|
+
}, [rapidlyChangingMotionState])
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Fire an update joints call on every motion state change.
|
|
100
|
+
* requestAnimationFrame used to avoid blocking main thread
|
|
101
|
+
*/
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
updateJoints()
|
|
104
|
+
}, [rapidlyChangingMotionState, updateJoints])
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* As some consumer applications (eg. storybook) deliver
|
|
108
|
+
* mobx observable for rapidlyChangingMotionState, we need to
|
|
109
|
+
* register the watcher to get the newest value updates
|
|
110
|
+
*/
|
|
111
|
+
useAutorun(() => {
|
|
112
|
+
updateJoints()
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
return <group ref={setGroupRef}>{children}</group>
|
|
116
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { ThreeElements } from "@react-three/fiber"
|
|
2
|
+
import type { DHParameter, MotionGroupState } from "@wandelbots/nova-js/v2"
|
|
3
|
+
import { Suspense, useCallback, useEffect, useState } from "react"
|
|
4
|
+
import { ErrorBoundary } from "react-error-boundary"
|
|
5
|
+
import type * as THREE from "three"
|
|
6
|
+
import { externalizeComponent } from "../../externalizeComponent"
|
|
7
|
+
import ConsoleFilter from "../ConsoleFilter"
|
|
8
|
+
import { DHLinearAxis } from "./DHLinearAxis"
|
|
9
|
+
import { GenericRobot } from "./GenericRobot"
|
|
10
|
+
import LinearAxisAnimator from "./LinearAxisAnimator"
|
|
11
|
+
import { applyGhostStyle, removeGhostStyle } from "./ghostStyle"
|
|
12
|
+
import { defaultGetModel } from "./robotModelLogic"
|
|
13
|
+
|
|
14
|
+
export type DHLinearAxisProps = {
|
|
15
|
+
rapidlyChangingMotionState: MotionGroupState
|
|
16
|
+
dhParameters: Array<DHParameter>
|
|
17
|
+
} & ThreeElements["group"]
|
|
18
|
+
|
|
19
|
+
export type SupportedLinearAxisProps = {
|
|
20
|
+
rapidlyChangingMotionState: MotionGroupState
|
|
21
|
+
modelFromController: string
|
|
22
|
+
dhParameters: DHParameter[]
|
|
23
|
+
flangeRef?: React.Ref<THREE.Group>
|
|
24
|
+
getModel?: (modelFromController: string) => Promise<string> | undefined
|
|
25
|
+
postModelRender?: () => void
|
|
26
|
+
transparentColor?: string
|
|
27
|
+
} & ThreeElements["group"]
|
|
28
|
+
|
|
29
|
+
export const SupportedLinearAxis = externalizeComponent(
|
|
30
|
+
({
|
|
31
|
+
rapidlyChangingMotionState,
|
|
32
|
+
modelFromController,
|
|
33
|
+
dhParameters,
|
|
34
|
+
getModel = defaultGetModel,
|
|
35
|
+
flangeRef,
|
|
36
|
+
postModelRender,
|
|
37
|
+
transparentColor,
|
|
38
|
+
...props
|
|
39
|
+
}: SupportedLinearAxisProps) => {
|
|
40
|
+
const [robotGroup, setRobotGroup] = useState<THREE.Group | null>(null)
|
|
41
|
+
|
|
42
|
+
const setRobotRef = useCallback((instance: THREE.Group | null) => {
|
|
43
|
+
setRobotGroup(instance)
|
|
44
|
+
}, [])
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!robotGroup) return
|
|
48
|
+
|
|
49
|
+
if (transparentColor) {
|
|
50
|
+
applyGhostStyle(robotGroup, transparentColor)
|
|
51
|
+
} else {
|
|
52
|
+
removeGhostStyle(robotGroup)
|
|
53
|
+
}
|
|
54
|
+
}, [robotGroup, transparentColor])
|
|
55
|
+
|
|
56
|
+
const dhLinearAxis = (
|
|
57
|
+
<DHLinearAxis
|
|
58
|
+
rapidlyChangingMotionState={rapidlyChangingMotionState}
|
|
59
|
+
dhParameters={dhParameters}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<ErrorBoundary
|
|
66
|
+
fallback={dhLinearAxis}
|
|
67
|
+
onError={(err) => {
|
|
68
|
+
// Missing model; show the fallback for now
|
|
69
|
+
console.warn(err)
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
<Suspense fallback={dhLinearAxis}>
|
|
73
|
+
<group ref={setRobotRef}>
|
|
74
|
+
<LinearAxisAnimator
|
|
75
|
+
rapidlyChangingMotionState={rapidlyChangingMotionState}
|
|
76
|
+
dhParameters={dhParameters}
|
|
77
|
+
>
|
|
78
|
+
<GenericRobot
|
|
79
|
+
modelURL={(() => {
|
|
80
|
+
const result = getModel(modelFromController)
|
|
81
|
+
if (!result) {
|
|
82
|
+
const mockBlob = new Blob([], { type: 'model/gltf-binary' })
|
|
83
|
+
const mockFile = new File([mockBlob], `${modelFromController}.glb`, { type: 'model/gltf-binary' })
|
|
84
|
+
return Promise.resolve(URL.createObjectURL(mockFile))
|
|
85
|
+
}
|
|
86
|
+
return result
|
|
87
|
+
})()}
|
|
88
|
+
postModelRender={postModelRender}
|
|
89
|
+
flangeRef={flangeRef}
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
</LinearAxisAnimator>
|
|
93
|
+
</group>
|
|
94
|
+
</Suspense>
|
|
95
|
+
<ConsoleFilter />
|
|
96
|
+
</ErrorBoundary>
|
|
97
|
+
)
|
|
98
|
+
},
|
|
99
|
+
)
|