     (show/set-variable! :aim-group-b-y 0.0)
     (show/set-variable! :aim-group-b-z 2.0)
 
+    ;; Set up OSC bindings so Touch OSC can control these cues in a powerful way with XY pads.
+    (add-osc-var-binding :aim-group-a-x "/1/aim-a"
+                         :send-fn (fn [_ v]
+                                    (osc/osc-send @osc-client "/1/aim-a"
+                                                  (/ (- v left-wall) width)
+                                                  (/ (- (show/get-variable :aim-group-a-z) stage-wall) depth)))
+                         :receive-fn (fn [msg]
+                                       (show/set-variable! :aim-group-a-x
+                                                           (+ left-wall (* width (first (:args msg)))))
+                                       (show/set-variable! :aim-group-a-z
+                                                           (+ stage-wall (* depth (second (:args msg)))))))
+    (add-osc-var-binding :aim-group-a-z "/1/aim-a"
+                         :send-fn (fn [_ v]
+                                    (osc/osc-send @osc-client "/1/aim-a"
+                                                  (/ (- (show/get-variable :aim-group-a-x) left-wall) width)
+                                                  (/ (- v stage-wall) depth)))
+                         :receive-fn :none)
+
+    (add-osc-var-binding :aim-group-a-y "/1/aim-a-y"
+                         :send-fn (fn [_ v]
+                                    (osc/osc-send @osc-client "/1/aim-a-y" (/ v ceiling)))
+                         :receive-fn (fn [msg]
+                                       (show/set-variable! :aim-group-a-y (* ceiling (first (:args msg))))))
+
+    (add-osc-var-binding :aim-group-b-x "/1/aim-b"
+                         :send-fn (fn [_ v]
+                                    (osc/osc-send @osc-client "/1/aim-b"
+                                                  (/ (- v left-wall) width)
+                                                  (/ (- (show/get-variable :aim-group-b-z) stage-wall) depth)))
+                         :receive-fn (fn [msg]
+                                       (show/set-variable! :aim-group-b-x
+                                                           (+ left-wall (* width (first (:args msg)))))
+                                       (show/set-variable! :aim-group-b-z
+                                                           (+ stage-wall (* depth (second (:args msg)))))))
+    (add-osc-var-binding :aim-group-b-z "/1/aim-b"
+                         :send-fn (fn [_ v]
+                                    (osc/osc-send @osc-client "/1/aim-b"
+                                                  (/ (- (show/get-variable :aim-group-b-x) left-wall) width)
+                                                  (/ (- v stage-wall) depth)))
+                         :receive-fn :none)
+
+    (add-osc-var-binding :aim-group-b-y "/1/aim-b-y"
+                         :send-fn (fn [_ v]
+                                    (osc/osc-send @osc-client "/1/aim-b-y" (/ v ceiling)))
+                         :receive-fn (fn [msg]
+                                       (show/set-variable! :aim-group-b-y (* ceiling (first (:args msg))))))
+
     ;; Set up default transformation of a reflection over the Y axis
     (.setScale transform (Vector3d. -1.0 1.0 1.0))
     (show/set-variable! :aim-group-a-transform transform)

        (let [fixture (first fixtures)]
          ;; Disconnected individual aim cues
          (show/set-cue! (+ x-base index) y-base (build-aim-cue fixture nil false :white))
          ;; Group A untransformed aim cues
          (show/set-cue! (+ x-base index) (inc y-base) (build-aim-cue fixture "a" false :blue))
          ;; Group A transformed aim cues
          (show/set-cue! (+ x-base index) (+ y-base 2) (build-aim-cue fixture "a" true :cyan))
          ;; Group B untransformed aim cues
          (show/set-cue! (+ x-base index) (+ y-base 3) (build-aim-cue fixture "b" false :red))
          ;; Group B transformed aim cues
          (show/set-cue! (+ x-base index) (+ y-base 4) (build-aim-cue fixture "b" true :orange)))
        (recur (rest fixtures) (inc index))))

    ;; Transformation modifiers for group A

                                 (.setScale transform (Vector3d. 1.0 -1.0 1.0))
                                 (var-fx/variable-effect @var-binder :aim-group-b-transform transform)))
                             :color :orange :short-name "Group B flip Y"))
    (add-osc-cue-binding (+ x-base 7) (+ y-base 3) "/1/flip-b-y")
    (show/set-cue! (+ x-base 7) (+ y-base 4)
                   (cues/cue :aim-group-b-transform
                             (fn [_]
                               (let [transform (Transform3D.)]
                                 (.setScale transform (Vector3d. -1.0 -1.0 1.0))
                                 (var-fx/variable-effect @var-binder :aim-group-b-transform transform)))
                             :color :orange :short-name "Group B flip XY"))
    (add-osc-cue-binding (+ x-base 7) (+ y-base 4) "/1/flip-b-xy")))

(defn- direction-cue-var-key
  "Determine the cue variable key value to use for a variable being
