# HG changeset patch # User Robert McIntyre # Date 1325938018 25200 # Node ID af1bb43661f95724cfc077fc271fcea4aa894ed2 # Parent 35f485a0c93f974c2317dbea28616b9bcdcf9d1b working on multimethod joint creation diff -r 35f485a0c93f -r af1bb43661f9 org/test-creature.org --- a/org/test-creature.org Sat Jan 07 02:37:36 2012 -0700 +++ b/org/test-creature.org Sat Jan 07 05:06:58 2012 -0700 @@ -50,7 +50,7 @@ (rlm.rlm-commands/help) -(declare joint-create get-subjective-position) +(declare joint-create) (defn load-bullet [] (let [sim (world (Node.) {} no-op no-op)] @@ -117,6 +117,126 @@ (take 2 targets)) (recur (float (* radius 2)))))))) +(defn world-to-local + "Convert the world coordinates into coordinates relative to the + object (i.e. local coordinates), taking into account the rotation + of object." + [#^Spatial object world-coordinate] + (let [out (Vector3f.)] + (.worldToLocal object world-coordinate out) out)) + +(defmulti zz + (fn [a b _ _ _ _ _] + + (:type a))) +(defmethod zz :p [a b] (println "hi")) + + +(defmulti joint-dispatch + "Translate blender pseudo-joints into real JME joints." + (fn [constraints _ _ _ _ _] + (:type constraints))) + +(defmethod joint-dispatch :point + [constraints control-a control-b pivot-a pivot-b rotation] + (println-repl "creating POINT2POINT joint") + (Point2PointJoint. + control-a + control-b + pivot-a + pivot-b)) + +(defmethod joint-dispatch :hinge + [constraints control-a control-b pivot-a pivot-b rotation] + (println-repl "creating HINGE joint") + (let [axis + (if-let + [axis (:axis constraints)] + axis + Vector3f/UNIT_X) + [limit-1 limit-2] (:limit constraints) + hinge-axis + (.mult + rotation + (blender-to-jme axis))] + (doto + (HingeJoint. + control-a + control-b + pivot-a + pivot-b + hinge-axis + hinge-axis) + (.setLimit limit-1 limit-2)))) + + +(defmethod joint-dispatch :cone + [constraints control-a control-b pivot-a pivot-b rotation] + (let [limit-xz (:limit-xz constraints) + limit-xy (:limit-xy constraints) + twist (:twist constraints)] + + + (println-repl "creating CONE joint") + (println-repl rotation) + (println-repl + "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0))) + (println-repl + "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0))) + (println-repl + "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1))) + (doto + (ConeJoint. + control-a + control-b + pivot-a + pivot-b + rotation + rotation) + (.setLimit (float limit-xz) + (float limit-xy) + (float twist))))) + + + +(defn connect* + "here are some examples: + {:type :point} + {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)} + (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints) + + {:type :cone :limit-xz 0] + :limit-xy 0] + :twist 0]} (use XZY rotation mode in blender!)" + [#^Node obj-a #^Node obj-b #^Node joint] + (let [control-a (.getControl obj-a RigidBodyControl) + control-b (.getControl obj-b RigidBodyControl) + joint-center (.getWorldTranslation joint) + joint-rotation (.toRotationMatrix (.getWorldRotation joint)) + pivot-a (world-to-local obj-a joint-center) + pivot-b (world-to-local obj-b joint-center)] + ;; A side-effect of creating a joint registers + ;; it with both physics objects which in turn + ;; will register the joint with the physics system + ;; when the simulation is started. + (if-let [constraints + (map-vals + eval + (read-string + (meta-data joint "joint")))] + (do + (println-repl "creating joint between" + (.getName obj-a) "and" (.getName obj-b)) + (joint-dispatch constraints + control-a control-b + pivot-a pivot-b + joint-rotation)) + + (println-repl "could not find joint meta-data!")))) + + + + (defn connect "here are some examples: {:type :point} @@ -127,13 +247,12 @@ :limit-xy 0] :twist 0]} (use XZY rotation mode in blender!)" [#^Node obj-a #^Node obj-b #^Node joint] - (let [center-a (.getWorldTranslation obj-a) - center-b (.getWorldTranslation obj-b) + (let [control-a (.getControl obj-a RigidBodyControl) + control-b (.getControl obj-b RigidBodyControl) joint-center (.getWorldTranslation joint) - pivot-a (.subtract joint-center center-a) - pivot-b (.subtract joint-center center-b) - control-a (.getControl obj-a RigidBodyControl) - control-b (.getControl obj-b RigidBodyControl)] + joint-rotation (.toRotationMatrix (.getWorldRotation joint)) + pivot-a (world-to-local obj-a joint-center) + pivot-b (world-to-local obj-b joint-center)] ;; A side-effect of creating a joint registers ;; it with both physics objects which in turn ;; will register the joint with the physics system @@ -180,25 +299,25 @@ (do (let [limit-xz (:limit-xz constraints) limit-xy (:limit-xy constraints) - twist (:twist constraints) - rotation (.toRotationMatrix (.getWorldRotation joint))] + twist (:twist constraints)] + (println-repl "creating CONE joint") - (println-repl rotation) + (println-repl joint-rotation) (println-repl - "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0))) + "UNIT_X --> " (.mult joint-rotation (Vector3f. 1 0 0))) (println-repl - "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0))) + "UNIT_Y --> " (.mult joint-rotation (Vector3f. 0 1 0))) (println-repl - "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1))) + "UNIT_Z --> " (.mult joint-rotation (Vector3f. 0 0 1))) (doto (ConeJoint. control-a control-b pivot-a pivot-b - rotation - rotation + joint-rotation + joint-rotation ) (.setLimit (float limit-xz) (float limit-xy) @@ -234,7 +353,7 @@ (fn [joint] (let [[obj-a obj-b] (joint-targets pieces joint)] - (connect obj-a obj-b joint))) + (connect* obj-a obj-b joint))) joints)) pieces) @@ -275,7 +394,7 @@ (comp light-up-everything enable-debug (fn [world] (.setTimer world (NanoTimer.)) - (set-gravity world (Vector3f. 0 0 0)) + ;;(set-gravity world (Vector3f. 0 0 0)) (speed-up world) world )) @@ -324,8 +443,8 @@ (doto (ConeJoint. a b - (get-subjective-position joint-position top) - (get-subjective-position joint-position bottom) + (world-to-local top joint-position) + (world-to-local bottom joint-position) joint-rotation joint-rotation ) @@ -405,91 +524,10 @@ +#+end_src - - - - - - - - - -;; please validate these. - -(defn get-subjective-position - "Convert the world coordinates into coordinates relative to - object (i.e. local coordinates), taking into account the rotation - of object." - [#^Vector3f world-coordinates object] - ;; I don't know if it's important to take into account the rotation - ;; of the object. If it isn't, then remove the multiplication-by-inverse. - (.mult (.inverse (.getWorldRotation object)) - (.subtract world-coordinates (.getWorldTranslation object)))) - - -(defn get-subjective-rotation - "cf get-subjective-position. Converts a rotation specified relative -to the world's axes into a rotation specified in terms of the object's - coordinate system." - [#^Quaternion world-rotation object] - (.mult (.inverse (.getWorldRotation object)) world-rotation)) - - - - -(defn joint-create "Connect objects 1 and 2 using a joint constraint. If - only position is specified, creates a point-to-point joint at the - given location - in world coordinates. etc. etc. for other joints. -To ensure consistency, I may alter this function - so that it moves obj-1 to be at the apex of the cone. - - NOTE: - In the usual construction method, you create a joint and, if your - contraints are consistent, all the objects snap into position and - orientation around it, otherwise the systen explodes. - - This construction method assumes that you have in mind a position and - rotation for the joint, and that you have already put your objects - at the required distances from that joint so that no snapping needs - to occur. The radial distances ('pivot lengths') are therefore just set to be - the pre-existing distances between the objects and the joint." - [#^Node obj-1 - #^Node obj-2 - #^Vector3f joint-position - #^Quaternion joint-rotation - span-1 - span-2 - twist - ] - - (let - [body-1 (.getControl obj-1 RigidBodyControl) - body-2 (.getControl obj-2 RigidBodyControl) - ] - (doto (ConeJoint. - body-1 - body-2 - (get-subjective-position joint-position body-1) - (get-subjective-position joint-position body-2) - ;; ALIGN X-AXIS OF OBJECT-1 WITH THE CENTRAL AXIS OF THE CONE TO - ;;LOWER THE RISK OF INCONSISTENCY - ;;(Matrix3f/IDENTITY) - (.toRotationMatrix (get-subjective-rotation joint-rotation body-1)) - (.toRotationMatrix (get-subjective-rotation joint-rotation body-2)) - ) - (.setLimit - span-1 - span-2 - twist)))) - - - - - - -#+end_src +#+results: body-1 +: #'cortex.silly/test-joint * COMMENT purgatory