= ({ panelId, open
openLocation={openLocation}
sidePadding={sidePadding}
onAccept={() => {
- // send zone config
+ if (transformGizmo && selectedRobot) {
+ save(zoneSize, transformGizmo, selectedRobot, selectedNode)
+ selectedRobot.UpdateIntakeSensor()
+ }
}}
+ onCancel={() => {}}
+ acceptEnabled={selectedRobot?.ejectorPreferences != undefined}
>
-
-
+ {selectedRobot?.ejectorPreferences == undefined ? (
+ <>
+
+ {/** Scroll view for selecting a robot to configure */}
+
+ {robots.map(mirabufSceneObject => {
+ return (
+
+ )
+ })}
+
+ {/* TODO: remove the accept button on this version */}
+ >
+ ) : (
+ <>
+ {/* Button for user to select the parent node */}
+ trySetSelectedNode(body.GetID())}
+ />
+
+ {/* Slider for user to set velocity of ejector configuration */}
+ {
+ setZoneSize(vel as number)
+ }}
+ step={0.01}
+ />
+ {
+ if (transformGizmo) {
+ const robotTransformation = JoltMat44_ThreeMatrix4(
+ World.PhysicsSystem.GetBody(selectedRobot.GetRootNodeId()!).GetWorldTransform()
+ )
+ transformGizmo.mesh.position.setFromMatrixPosition(robotTransformation)
+ transformGizmo.mesh.rotation.setFromRotationMatrix(robotTransformation)
+ }
+ setZoneSize((MIN_ZONE_SIZE + MAX_ZONE_SIZE) / 2.0)
+ setSelectedNode(selectedRobot?.rootNodeId)
+ }}
+ />
+ >
+ )}
)
}
diff --git a/fission/src/ui/panels/configuring/ConfigureShotTrajectoryPanel.tsx b/fission/src/ui/panels/configuring/ConfigureShotTrajectoryPanel.tsx
index 29f493200b..f0e7d5714b 100644
--- a/fission/src/ui/panels/configuring/ConfigureShotTrajectoryPanel.tsx
+++ b/fission/src/ui/panels/configuring/ConfigureShotTrajectoryPanel.tsx
@@ -1,34 +1,257 @@
-import { useState } from "react"
+import * as THREE from "three"
+import { useCallback, useEffect, useMemo, useState } from "react"
import { FaGear } from "react-icons/fa6"
import Panel, { PanelPropsImpl } from "@/components/Panel"
import SelectButton from "@/components/SelectButton"
-import Slider from "@/components/Slider"
+import TransformGizmos from "@/ui/components/TransformGizmos"
+import Slider from "@/ui/components/Slider"
+import Jolt from "@barclah/jolt-physics"
+import Label from "@/ui/components/Label"
+import PreferencesSystem from "@/systems/preferences/PreferencesSystem"
+import Button from "@/ui/components/Button"
+import MirabufSceneObject, { RigidNodeAssociate } from "@/mirabuf/MirabufSceneObject"
+import World from "@/systems/World"
+import { MiraType } from "@/mirabuf/MirabufLoader"
+import {
+ Array_ThreeMatrix4,
+ JoltMat44_ThreeMatrix4,
+ ReactRgbaColor_ThreeColor,
+ ThreeMatrix4_Array,
+} from "@/util/TypeConversions"
+import { useTheme } from "@/ui/ThemeContext"
+import LabeledButton, { LabelPlacement } from "@/ui/components/LabeledButton"
+import { RigidNodeId } from "@/mirabuf/MirabufParser"
+
+// slider constants
+const MIN_VELOCITY = 0.0
+const MAX_VELOCITY = 20.0
+
+/**
+ * Saves ejector configuration to selected robot.
+ *
+ * Math Explanation:
+ * Let W be the world transformation matrix of the gizmo.
+ * Let R be the world transformation matrix of the selected robot node.
+ * Let L be the local transformation matrix of the gizmo, relative to the selected robot node.
+ *
+ * We are given W and R, and want to save L with the robot. This way when we create
+ * the ejection point afterwards, it will be relative to the selected robot node.
+ *
+ * W = L R
+ * L = W R^(-1)
+ *
+ * ThreeJS sets the standard multiplication operation for matrices to be premultiply. I really
+ * don't like this terminology as it's thrown me off multiple times, but I suppose it does go
+ * against most other multiplication operations.
+ *
+ * @param ejectorVelocity Velocity to eject gamepiece at.
+ * @param gizmo Reference to the transform gizmo object.
+ * @param selectedRobot Selected robot to save data to.
+ * @param selectedNode Selected node that configuration is relative to.
+ */
+function save(
+ ejectorVelocity: number,
+ gizmo: TransformGizmos,
+ selectedRobot: MirabufSceneObject,
+ selectedNode?: RigidNodeId
+) {
+ if (!selectedRobot?.ejectorPreferences || !gizmo) {
+ return
+ }
+
+ selectedNode ??= selectedRobot.rootNodeId
+
+ const nodeBodyId = selectedRobot.mechanism.nodeToBody.get(selectedNode)
+ if (!nodeBodyId) {
+ return
+ }
+
+ const gizmoTransformation = gizmo.mesh.matrixWorld
+ const robotTransformation = JoltMat44_ThreeMatrix4(World.PhysicsSystem.GetBody(nodeBodyId).GetWorldTransform())
+ const deltaTransformation = gizmoTransformation.premultiply(robotTransformation.invert())
+
+ selectedRobot.ejectorPreferences.deltaTransformation = ThreeMatrix4_Array(deltaTransformation)
+ selectedRobot.ejectorPreferences.parentNode = selectedNode
+ selectedRobot.ejectorPreferences.ejectorVelocity = ejectorVelocity
+
+ PreferencesSystem.savePreferences()
+}
const ConfigureShotTrajectoryPanel: React.FC