Mercurial > cortex
diff org/test-creature.org @ 87:af1bb43661f9
working on multimethod joint creation
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 07 Jan 2012 05:06:58 -0700 |
parents | 00ab1f10266f |
children | 3e929630a25f |
line wrap: on
line diff
1.1 --- a/org/test-creature.org Sat Jan 07 02:37:36 2012 -0700 1.2 +++ b/org/test-creature.org Sat Jan 07 05:06:58 2012 -0700 1.3 @@ -50,7 +50,7 @@ 1.4 1.5 (rlm.rlm-commands/help) 1.6 1.7 -(declare joint-create get-subjective-position) 1.8 +(declare joint-create) 1.9 1.10 (defn load-bullet [] 1.11 (let [sim (world (Node.) {} no-op no-op)] 1.12 @@ -117,6 +117,126 @@ 1.13 (take 2 targets)) 1.14 (recur (float (* radius 2)))))))) 1.15 1.16 +(defn world-to-local 1.17 + "Convert the world coordinates into coordinates relative to the 1.18 + object (i.e. local coordinates), taking into account the rotation 1.19 + of object." 1.20 + [#^Spatial object world-coordinate] 1.21 + (let [out (Vector3f.)] 1.22 + (.worldToLocal object world-coordinate out) out)) 1.23 + 1.24 +(defmulti zz 1.25 + (fn [a b _ _ _ _ _] 1.26 + 1.27 + (:type a))) 1.28 +(defmethod zz :p [a b] (println "hi")) 1.29 + 1.30 + 1.31 +(defmulti joint-dispatch 1.32 + "Translate blender pseudo-joints into real JME joints." 1.33 + (fn [constraints _ _ _ _ _] 1.34 + (:type constraints))) 1.35 + 1.36 +(defmethod joint-dispatch :point 1.37 + [constraints control-a control-b pivot-a pivot-b rotation] 1.38 + (println-repl "creating POINT2POINT joint") 1.39 + (Point2PointJoint. 1.40 + control-a 1.41 + control-b 1.42 + pivot-a 1.43 + pivot-b)) 1.44 + 1.45 +(defmethod joint-dispatch :hinge 1.46 + [constraints control-a control-b pivot-a pivot-b rotation] 1.47 + (println-repl "creating HINGE joint") 1.48 + (let [axis 1.49 + (if-let 1.50 + [axis (:axis constraints)] 1.51 + axis 1.52 + Vector3f/UNIT_X) 1.53 + [limit-1 limit-2] (:limit constraints) 1.54 + hinge-axis 1.55 + (.mult 1.56 + rotation 1.57 + (blender-to-jme axis))] 1.58 + (doto 1.59 + (HingeJoint. 1.60 + control-a 1.61 + control-b 1.62 + pivot-a 1.63 + pivot-b 1.64 + hinge-axis 1.65 + hinge-axis) 1.66 + (.setLimit limit-1 limit-2)))) 1.67 + 1.68 + 1.69 +(defmethod joint-dispatch :cone 1.70 + [constraints control-a control-b pivot-a pivot-b rotation] 1.71 + (let [limit-xz (:limit-xz constraints) 1.72 + limit-xy (:limit-xy constraints) 1.73 + twist (:twist constraints)] 1.74 + 1.75 + 1.76 + (println-repl "creating CONE joint") 1.77 + (println-repl rotation) 1.78 + (println-repl 1.79 + "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0))) 1.80 + (println-repl 1.81 + "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0))) 1.82 + (println-repl 1.83 + "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1))) 1.84 + (doto 1.85 + (ConeJoint. 1.86 + control-a 1.87 + control-b 1.88 + pivot-a 1.89 + pivot-b 1.90 + rotation 1.91 + rotation) 1.92 + (.setLimit (float limit-xz) 1.93 + (float limit-xy) 1.94 + (float twist))))) 1.95 + 1.96 + 1.97 + 1.98 +(defn connect* 1.99 + "here are some examples: 1.100 + {:type :point} 1.101 + {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)} 1.102 + (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints) 1.103 + 1.104 + {:type :cone :limit-xz 0] 1.105 + :limit-xy 0] 1.106 + :twist 0]} (use XZY rotation mode in blender!)" 1.107 + [#^Node obj-a #^Node obj-b #^Node joint] 1.108 + (let [control-a (.getControl obj-a RigidBodyControl) 1.109 + control-b (.getControl obj-b RigidBodyControl) 1.110 + joint-center (.getWorldTranslation joint) 1.111 + joint-rotation (.toRotationMatrix (.getWorldRotation joint)) 1.112 + pivot-a (world-to-local obj-a joint-center) 1.113 + pivot-b (world-to-local obj-b joint-center)] 1.114 + ;; A side-effect of creating a joint registers 1.115 + ;; it with both physics objects which in turn 1.116 + ;; will register the joint with the physics system 1.117 + ;; when the simulation is started. 1.118 + (if-let [constraints 1.119 + (map-vals 1.120 + eval 1.121 + (read-string 1.122 + (meta-data joint "joint")))] 1.123 + (do 1.124 + (println-repl "creating joint between" 1.125 + (.getName obj-a) "and" (.getName obj-b)) 1.126 + (joint-dispatch constraints 1.127 + control-a control-b 1.128 + pivot-a pivot-b 1.129 + joint-rotation)) 1.130 + 1.131 + (println-repl "could not find joint meta-data!")))) 1.132 + 1.133 + 1.134 + 1.135 + 1.136 (defn connect 1.137 "here are some examples: 1.138 {:type :point} 1.139 @@ -127,13 +247,12 @@ 1.140 :limit-xy 0] 1.141 :twist 0]} (use XZY rotation mode in blender!)" 1.142 [#^Node obj-a #^Node obj-b #^Node joint] 1.143 - (let [center-a (.getWorldTranslation obj-a) 1.144 - center-b (.getWorldTranslation obj-b) 1.145 + (let [control-a (.getControl obj-a RigidBodyControl) 1.146 + control-b (.getControl obj-b RigidBodyControl) 1.147 joint-center (.getWorldTranslation joint) 1.148 - pivot-a (.subtract joint-center center-a) 1.149 - pivot-b (.subtract joint-center center-b) 1.150 - control-a (.getControl obj-a RigidBodyControl) 1.151 - control-b (.getControl obj-b RigidBodyControl)] 1.152 + joint-rotation (.toRotationMatrix (.getWorldRotation joint)) 1.153 + pivot-a (world-to-local obj-a joint-center) 1.154 + pivot-b (world-to-local obj-b joint-center)] 1.155 ;; A side-effect of creating a joint registers 1.156 ;; it with both physics objects which in turn 1.157 ;; will register the joint with the physics system 1.158 @@ -180,25 +299,25 @@ 1.159 (do 1.160 (let [limit-xz (:limit-xz constraints) 1.161 limit-xy (:limit-xy constraints) 1.162 - twist (:twist constraints) 1.163 - rotation (.toRotationMatrix (.getWorldRotation joint))] 1.164 + twist (:twist constraints)] 1.165 + 1.166 1.167 (println-repl "creating CONE joint") 1.168 - (println-repl rotation) 1.169 + (println-repl joint-rotation) 1.170 (println-repl 1.171 - "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0))) 1.172 + "UNIT_X --> " (.mult joint-rotation (Vector3f. 1 0 0))) 1.173 (println-repl 1.174 - "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0))) 1.175 + "UNIT_Y --> " (.mult joint-rotation (Vector3f. 0 1 0))) 1.176 (println-repl 1.177 - "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1))) 1.178 + "UNIT_Z --> " (.mult joint-rotation (Vector3f. 0 0 1))) 1.179 (doto 1.180 (ConeJoint. 1.181 control-a 1.182 control-b 1.183 pivot-a 1.184 pivot-b 1.185 - rotation 1.186 - rotation 1.187 + joint-rotation 1.188 + joint-rotation 1.189 ) 1.190 (.setLimit (float limit-xz) 1.191 (float limit-xy) 1.192 @@ -234,7 +353,7 @@ 1.193 (fn [joint] 1.194 (let [[obj-a obj-b] 1.195 (joint-targets pieces joint)] 1.196 - (connect obj-a obj-b joint))) 1.197 + (connect* obj-a obj-b joint))) 1.198 joints)) 1.199 pieces) 1.200 1.201 @@ -275,7 +394,7 @@ 1.202 (comp light-up-everything enable-debug 1.203 (fn [world] 1.204 (.setTimer world (NanoTimer.)) 1.205 - (set-gravity world (Vector3f. 0 0 0)) 1.206 + ;;(set-gravity world (Vector3f. 0 0 0)) 1.207 (speed-up world) 1.208 world 1.209 )) 1.210 @@ -324,8 +443,8 @@ 1.211 1.212 (doto (ConeJoint. 1.213 a b 1.214 - (get-subjective-position joint-position top) 1.215 - (get-subjective-position joint-position bottom) 1.216 + (world-to-local top joint-position) 1.217 + (world-to-local bottom joint-position) 1.218 joint-rotation 1.219 joint-rotation 1.220 ) 1.221 @@ -405,91 +524,10 @@ 1.222 1.223 1.224 1.225 +#+end_src 1.226 1.227 - 1.228 - 1.229 - 1.230 - 1.231 - 1.232 - 1.233 - 1.234 - 1.235 - 1.236 -;; please validate these. 1.237 - 1.238 -(defn get-subjective-position 1.239 - "Convert the world coordinates into coordinates relative to 1.240 - object (i.e. local coordinates), taking into account the rotation 1.241 - of object." 1.242 - [#^Vector3f world-coordinates object] 1.243 - ;; I don't know if it's important to take into account the rotation 1.244 - ;; of the object. If it isn't, then remove the multiplication-by-inverse. 1.245 - (.mult (.inverse (.getWorldRotation object)) 1.246 - (.subtract world-coordinates (.getWorldTranslation object)))) 1.247 - 1.248 - 1.249 -(defn get-subjective-rotation 1.250 - "cf get-subjective-position. Converts a rotation specified relative 1.251 -to the world's axes into a rotation specified in terms of the object's 1.252 - coordinate system." 1.253 - [#^Quaternion world-rotation object] 1.254 - (.mult (.inverse (.getWorldRotation object)) world-rotation)) 1.255 - 1.256 - 1.257 - 1.258 - 1.259 -(defn joint-create "Connect objects 1 and 2 using a joint constraint. If 1.260 - only position is specified, creates a point-to-point joint at the 1.261 - given location 1.262 - in world coordinates. etc. etc. for other joints. 1.263 -To ensure consistency, I may alter this function 1.264 - so that it moves obj-1 to be at the apex of the cone. 1.265 - 1.266 - NOTE: 1.267 - In the usual construction method, you create a joint and, if your 1.268 - contraints are consistent, all the objects snap into position and 1.269 - orientation around it, otherwise the systen explodes. 1.270 - 1.271 - This construction method assumes that you have in mind a position and 1.272 - rotation for the joint, and that you have already put your objects 1.273 - at the required distances from that joint so that no snapping needs 1.274 - to occur. The radial distances ('pivot lengths') are therefore just set to be 1.275 - the pre-existing distances between the objects and the joint." 1.276 - [#^Node obj-1 1.277 - #^Node obj-2 1.278 - #^Vector3f joint-position 1.279 - #^Quaternion joint-rotation 1.280 - span-1 1.281 - span-2 1.282 - twist 1.283 - ] 1.284 - 1.285 - (let 1.286 - [body-1 (.getControl obj-1 RigidBodyControl) 1.287 - body-2 (.getControl obj-2 RigidBodyControl) 1.288 - ] 1.289 - (doto (ConeJoint. 1.290 - body-1 1.291 - body-2 1.292 - (get-subjective-position joint-position body-1) 1.293 - (get-subjective-position joint-position body-2) 1.294 - ;; ALIGN X-AXIS OF OBJECT-1 WITH THE CENTRAL AXIS OF THE CONE TO 1.295 - ;;LOWER THE RISK OF INCONSISTENCY 1.296 - ;;(Matrix3f/IDENTITY) 1.297 - (.toRotationMatrix (get-subjective-rotation joint-rotation body-1)) 1.298 - (.toRotationMatrix (get-subjective-rotation joint-rotation body-2)) 1.299 - ) 1.300 - (.setLimit 1.301 - span-1 1.302 - span-2 1.303 - twist)))) 1.304 - 1.305 - 1.306 - 1.307 - 1.308 - 1.309 - 1.310 -#+end_src 1.311 +#+results: body-1 1.312 +: #'cortex.silly/test-joint 1.313 1.314 1.315 * COMMENT purgatory