comparison 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
comparison
equal deleted inserted replaced
86:35f485a0c93f 87:af1bb43661f9
48 (cortex.import/mega-import-jme3) 48 (cortex.import/mega-import-jme3)
49 (use '(cortex world util body hearing touch vision)) 49 (use '(cortex world util body hearing touch vision))
50 50
51 (rlm.rlm-commands/help) 51 (rlm.rlm-commands/help)
52 52
53 (declare joint-create get-subjective-position) 53 (declare joint-create)
54 54
55 (defn load-bullet [] 55 (defn load-bullet []
56 (let [sim (world (Node.) {} no-op no-op)] 56 (let [sim (world (Node.) {} no-op no-op)]
57 (.enqueue 57 (.enqueue
58 sim 58 sim
115 (.dot (Vector3f. 1 1 1) 115 (.dot (Vector3f. 1 1 1)
116 v)) 116 v))
117 (take 2 targets)) 117 (take 2 targets))
118 (recur (float (* radius 2)))))))) 118 (recur (float (* radius 2))))))))
119 119
120 (defn world-to-local
121 "Convert the world coordinates into coordinates relative to the
122 object (i.e. local coordinates), taking into account the rotation
123 of object."
124 [#^Spatial object world-coordinate]
125 (let [out (Vector3f.)]
126 (.worldToLocal object world-coordinate out) out))
127
128 (defmulti zz
129 (fn [a b _ _ _ _ _]
130
131 (:type a)))
132 (defmethod zz :p [a b] (println "hi"))
133
134
135 (defmulti joint-dispatch
136 "Translate blender pseudo-joints into real JME joints."
137 (fn [constraints _ _ _ _ _]
138 (:type constraints)))
139
140 (defmethod joint-dispatch :point
141 [constraints control-a control-b pivot-a pivot-b rotation]
142 (println-repl "creating POINT2POINT joint")
143 (Point2PointJoint.
144 control-a
145 control-b
146 pivot-a
147 pivot-b))
148
149 (defmethod joint-dispatch :hinge
150 [constraints control-a control-b pivot-a pivot-b rotation]
151 (println-repl "creating HINGE joint")
152 (let [axis
153 (if-let
154 [axis (:axis constraints)]
155 axis
156 Vector3f/UNIT_X)
157 [limit-1 limit-2] (:limit constraints)
158 hinge-axis
159 (.mult
160 rotation
161 (blender-to-jme axis))]
162 (doto
163 (HingeJoint.
164 control-a
165 control-b
166 pivot-a
167 pivot-b
168 hinge-axis
169 hinge-axis)
170 (.setLimit limit-1 limit-2))))
171
172
173 (defmethod joint-dispatch :cone
174 [constraints control-a control-b pivot-a pivot-b rotation]
175 (let [limit-xz (:limit-xz constraints)
176 limit-xy (:limit-xy constraints)
177 twist (:twist constraints)]
178
179
180 (println-repl "creating CONE joint")
181 (println-repl rotation)
182 (println-repl
183 "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0)))
184 (println-repl
185 "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0)))
186 (println-repl
187 "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1)))
188 (doto
189 (ConeJoint.
190 control-a
191 control-b
192 pivot-a
193 pivot-b
194 rotation
195 rotation)
196 (.setLimit (float limit-xz)
197 (float limit-xy)
198 (float twist)))))
199
200
201
202 (defn connect*
203 "here are some examples:
204 {:type :point}
205 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}
206 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)
207
208 {:type :cone :limit-xz 0]
209 :limit-xy 0]
210 :twist 0]} (use XZY rotation mode in blender!)"
211 [#^Node obj-a #^Node obj-b #^Node joint]
212 (let [control-a (.getControl obj-a RigidBodyControl)
213 control-b (.getControl obj-b RigidBodyControl)
214 joint-center (.getWorldTranslation joint)
215 joint-rotation (.toRotationMatrix (.getWorldRotation joint))
216 pivot-a (world-to-local obj-a joint-center)
217 pivot-b (world-to-local obj-b joint-center)]
218 ;; A side-effect of creating a joint registers
219 ;; it with both physics objects which in turn
220 ;; will register the joint with the physics system
221 ;; when the simulation is started.
222 (if-let [constraints
223 (map-vals
224 eval
225 (read-string
226 (meta-data joint "joint")))]
227 (do
228 (println-repl "creating joint between"
229 (.getName obj-a) "and" (.getName obj-b))
230 (joint-dispatch constraints
231 control-a control-b
232 pivot-a pivot-b
233 joint-rotation))
234
235 (println-repl "could not find joint meta-data!"))))
236
237
238
239
120 (defn connect 240 (defn connect
121 "here are some examples: 241 "here are some examples:
122 {:type :point} 242 {:type :point}
123 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)} 243 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}
124 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints) 244 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)
125 245
126 {:type :cone :limit-xz 0] 246 {:type :cone :limit-xz 0]
127 :limit-xy 0] 247 :limit-xy 0]
128 :twist 0]} (use XZY rotation mode in blender!)" 248 :twist 0]} (use XZY rotation mode in blender!)"
129 [#^Node obj-a #^Node obj-b #^Node joint] 249 [#^Node obj-a #^Node obj-b #^Node joint]
130 (let [center-a (.getWorldTranslation obj-a) 250 (let [control-a (.getControl obj-a RigidBodyControl)
131 center-b (.getWorldTranslation obj-b) 251 control-b (.getControl obj-b RigidBodyControl)
132 joint-center (.getWorldTranslation joint) 252 joint-center (.getWorldTranslation joint)
133 pivot-a (.subtract joint-center center-a) 253 joint-rotation (.toRotationMatrix (.getWorldRotation joint))
134 pivot-b (.subtract joint-center center-b) 254 pivot-a (world-to-local obj-a joint-center)
135 control-a (.getControl obj-a RigidBodyControl) 255 pivot-b (world-to-local obj-b joint-center)]
136 control-b (.getControl obj-b RigidBodyControl)]
137 ;; A side-effect of creating a joint registers 256 ;; A side-effect of creating a joint registers
138 ;; it with both physics objects which in turn 257 ;; it with both physics objects which in turn
139 ;; will register the joint with the physics system 258 ;; will register the joint with the physics system
140 ;; when the simulation is started. 259 ;; when the simulation is started.
141 (if-let [constraints 260 (if-let [constraints
178 (.setLimit limit-1 limit-2)))) 297 (.setLimit limit-1 limit-2))))
179 (= :cone joint-type) 298 (= :cone joint-type)
180 (do 299 (do
181 (let [limit-xz (:limit-xz constraints) 300 (let [limit-xz (:limit-xz constraints)
182 limit-xy (:limit-xy constraints) 301 limit-xy (:limit-xy constraints)
183 twist (:twist constraints) 302 twist (:twist constraints)]
184 rotation (.toRotationMatrix (.getWorldRotation joint))] 303
185 304
186 (println-repl "creating CONE joint") 305 (println-repl "creating CONE joint")
187 (println-repl rotation) 306 (println-repl joint-rotation)
188 (println-repl 307 (println-repl
189 "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0))) 308 "UNIT_X --> " (.mult joint-rotation (Vector3f. 1 0 0)))
190 (println-repl 309 (println-repl
191 "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0))) 310 "UNIT_Y --> " (.mult joint-rotation (Vector3f. 0 1 0)))
192 (println-repl 311 (println-repl
193 "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1))) 312 "UNIT_Z --> " (.mult joint-rotation (Vector3f. 0 0 1)))
194 (doto 313 (doto
195 (ConeJoint. 314 (ConeJoint.
196 control-a 315 control-a
197 control-b 316 control-b
198 pivot-a 317 pivot-a
199 pivot-b 318 pivot-b
200 rotation 319 joint-rotation
201 rotation 320 joint-rotation
202 ) 321 )
203 (.setLimit (float limit-xz) 322 (.setLimit (float limit-xz)
204 (float limit-xy) 323 (float limit-xy)
205 (float twist))))) 324 (float twist)))))
206 true 325 true
232 (dorun 351 (dorun
233 (map 352 (map
234 (fn [joint] 353 (fn [joint]
235 (let [[obj-a obj-b] 354 (let [[obj-a obj-b]
236 (joint-targets pieces joint)] 355 (joint-targets pieces joint)]
237 (connect obj-a obj-b joint))) 356 (connect* obj-a obj-b joint)))
238 joints)) 357 joints))
239 pieces) 358 pieces)
240 359
241 (defn blender-creature [blender-path] 360 (defn blender-creature [blender-path]
242 (let [model (load-blender-model blender-path) 361 (let [model (load-blender-model blender-path)
273 ]) 392 ])
274 standard-debug-controls 393 standard-debug-controls
275 (comp light-up-everything enable-debug 394 (comp light-up-everything enable-debug
276 (fn [world] 395 (fn [world]
277 (.setTimer world (NanoTimer.)) 396 (.setTimer world (NanoTimer.))
278 (set-gravity world (Vector3f. 0 0 0)) 397 ;;(set-gravity world (Vector3f. 0 0 0))
279 (speed-up world) 398 (speed-up world)
280 world 399 world
281 )) 400 ))
282 no-op))) 401 no-op)))
283 402
322 (cond 441 (cond
323 (= joint :cone) 442 (= joint :cone)
324 443
325 (doto (ConeJoint. 444 (doto (ConeJoint.
326 a b 445 a b
327 (get-subjective-position joint-position top) 446 (world-to-local top joint-position)
328 (get-subjective-position joint-position bottom) 447 (world-to-local bottom joint-position)
329 joint-rotation 448 joint-rotation
330 joint-rotation 449 joint-rotation
331 ) 450 )
332 451
333 452
403 (.mult (.getPhysicsRotation control) 522 (.mult (.getPhysicsRotation control)
404 (Vector3f. 1 0 0)))))))) 523 (Vector3f. 1 0 0))))))))
405 524
406 525
407 526
408
409
410
411
412
413
414
415
416
417
418 ;; please validate these.
419
420 (defn get-subjective-position
421 "Convert the world coordinates into coordinates relative to
422 object (i.e. local coordinates), taking into account the rotation
423 of object."
424 [#^Vector3f world-coordinates object]
425 ;; I don't know if it's important to take into account the rotation
426 ;; of the object. If it isn't, then remove the multiplication-by-inverse.
427 (.mult (.inverse (.getWorldRotation object))
428 (.subtract world-coordinates (.getWorldTranslation object))))
429
430
431 (defn get-subjective-rotation
432 "cf get-subjective-position. Converts a rotation specified relative
433 to the world's axes into a rotation specified in terms of the object's
434 coordinate system."
435 [#^Quaternion world-rotation object]
436 (.mult (.inverse (.getWorldRotation object)) world-rotation))
437
438
439
440
441 (defn joint-create "Connect objects 1 and 2 using a joint constraint. If
442 only position is specified, creates a point-to-point joint at the
443 given location
444 in world coordinates. etc. etc. for other joints.
445 To ensure consistency, I may alter this function
446 so that it moves obj-1 to be at the apex of the cone.
447
448 NOTE:
449 In the usual construction method, you create a joint and, if your
450 contraints are consistent, all the objects snap into position and
451 orientation around it, otherwise the systen explodes.
452
453 This construction method assumes that you have in mind a position and
454 rotation for the joint, and that you have already put your objects
455 at the required distances from that joint so that no snapping needs
456 to occur. The radial distances ('pivot lengths') are therefore just set to be
457 the pre-existing distances between the objects and the joint."
458 [#^Node obj-1
459 #^Node obj-2
460 #^Vector3f joint-position
461 #^Quaternion joint-rotation
462 span-1
463 span-2
464 twist
465 ]
466
467 (let
468 [body-1 (.getControl obj-1 RigidBodyControl)
469 body-2 (.getControl obj-2 RigidBodyControl)
470 ]
471 (doto (ConeJoint.
472 body-1
473 body-2
474 (get-subjective-position joint-position body-1)
475 (get-subjective-position joint-position body-2)
476 ;; ALIGN X-AXIS OF OBJECT-1 WITH THE CENTRAL AXIS OF THE CONE TO
477 ;;LOWER THE RISK OF INCONSISTENCY
478 ;;(Matrix3f/IDENTITY)
479 (.toRotationMatrix (get-subjective-rotation joint-rotation body-1))
480 (.toRotationMatrix (get-subjective-rotation joint-rotation body-2))
481 )
482 (.setLimit
483 span-1
484 span-2
485 twist))))
486
487
488
489
490
491
492 #+end_src 527 #+end_src
528
529 #+results: body-1
530 : #'cortex.silly/test-joint
493 531
494 532
495 * COMMENT purgatory 533 * COMMENT purgatory
496 #+begin_src clojure 534 #+begin_src clojure
497 (defn bullet-trans [] 535 (defn bullet-trans []