Mercurial > cortex
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 [] |