comparison org/test-creature.org @ 83:14b604e955ed

still testing joints... Dylan is helping
author Robert McIntyre <rlm@mit.edu>
date Sat, 07 Jan 2012 00:58:47 -0700
parents 6b4ca076285e
children 4f5e2c629e45
comparison
equal deleted inserted replaced
82:6b4ca076285e 83:14b604e955ed
47 (require 'cortex.import) 47 (require 'cortex.import)
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
53 (declare joint-create get-subjective-position)
54
55 (defn load-bullet []
56 (.start (world (Node.) {} no-op no-op)))
52 57
53 (defn load-blender-model 58 (defn load-blender-model
54 "Load a .blend file using an asset folder relative path." 59 "Load a .blend file using an asset folder relative path."
55 [^String model] 60 [^String model]
56 (.loadModel 61 (.loadModel
177 (.toRotationMatrix 182 (.toRotationMatrix
178 (doto (Quaternion.) 183 (doto (Quaternion.)
179 (.fromAngleAxis 184 (.fromAngleAxis
180 (float 185 (float
181 (.angleBetween 186 (.angleBetween
182 pivot-a Vector3f/UNIT_X)) 187 (.normalize pivot-a) Vector3f/UNIT_X))
183 (.cross (.normalize pivot-a) 188 (.normalize
184 Vector3f/UNIT_X)))) 189 (.cross pivot-a
185 ] 190 Vector3f/UNIT_X)))))
191 ]
192 (println-repl "pivot-a" pivot-a)
186 (println-repl 193 (println-repl
187 "angle between pivot-a (" pivot-a ") and UNIT_X is" 194 "angle between pivot-a and UNIT_X is"
188 (.angleBetween Vector3f/UNIT_X (.normalize pivot-a))) 195 (.angleBetween Vector3f/UNIT_X (.normalize pivot-a)))
189 196 (println-repl "frame-a:" frame-a)
197 (println-repl
198 "frame-a moves Vector3f/UNIT_X to"
199 (.mult frame-a Vector3f/UNIT_X ))
190 200
191 201
192 (doto 202 (doto
193 (ConeJoint. 203 (ConeJoint.
194 control-a 204 control-a
195 control-b 205 control-b
196 pivot-a 206 pivot-a
197 pivot-b 207 pivot-b
198 208
199 209
200 ;; ;; frame-in-A 210 ;; frame-in-A
201 frame-a 211 ;;frame-a
202 frame-a 212 ;;frame-a
203 213
204 ;; (.toRotationMatrix 214 (.toRotationMatrix
205 ;; (doto (Quaternion.) 215 (doto (Quaternion.)
206 ;; (.fromAngles 216 (.fromAngles
207 ;; 0 0 (* -1 (/ Math/PI 2))))) 217 0 0 (* -0.5 (/ Math/PI 2)))))
208
209 218
210 ;; ;; frame-in-B 219
211 ;; (.toRotationMatrix 220 ;; frame-in-B
212 ;; (doto (Quaternion.) 221 (.toRotationMatrix
213 ;; (.fromAngles 222 (doto (Quaternion.)
214 ;; 0 0 (* -1.2 (/ Math/PI 2))))) 223 (.fromAngles
215 224 0 0 (* -0.5 (/ Math/PI 2)))))
225
216 226
217 ) 227 )
218 (.setLimit (float limit-xz) 228 (.setLimit (float limit-xz)
219 (float limit-xy) 229 (float limit-xy)
220 (float twist)))))) 230 (float twist))))))
221 true 231 true
222 (println-repl 232 (println-repl
223 "joint-type" joint-type "not recognized"))) 233 "joint-type" joint-type "not recognized")))
224 234
225 (println-repl "could not find joint meta-data!")))) 235 (println-repl "could not find joint meta-data!"))))
236
226 237
227 (defn assemble-creature [#^Node pieces joints] 238 (defn assemble-creature [#^Node pieces joints]
228 (dorun 239 (dorun
229 (map 240 (map
230 (fn [geom] 241 (fn [geom]
294 world 305 world
295 )) 306 ))
296 no-op))) 307 no-op)))
297 308
298 (defn world-setup [joint] 309 (defn world-setup [joint]
299 (let [top (doto 310 (let [
311
312 joint-position (Vector3f. 0 4 0)
313 joint-rotation
314 (.toRotationMatrix
315 (.mult
316 (doto (Quaternion.)
317 (.fromAngleAxis
318 (* 1 (/ Math/PI 4))
319 (Vector3f. -1 0 0)))
320 (doto (Quaternion.)
321 (.fromAngleAxis
322 (/ Math/PI 2)
323 (Vector3f. 0 0 1)))))
324
325 origin (doto
326 (sphere 0.1 :physical? false :color ColorRGBA/Cyan
327 :position (Vector3f. 0 0 0)))
328 top (doto
300 (sphere 0.1 :physical? false :color ColorRGBA/Yellow 329 (sphere 0.1 :physical? false :color ColorRGBA/Yellow
301 :position (Vector3f. 0 7 0)) 330 :position (.mult joint-rotation (Vector3f. 8 0 0)))
331
302 (.addControl 332 (.addControl
303 (RigidBodyControl. 333 (RigidBodyControl.
304 (CapsuleCollisionShape. 0.5 1.5 1) (float 15)))) 334 (CapsuleCollisionShape. 0.5 1.5 1) (float 20))))
305 bottom (doto 335 bottom (doto
306 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray 336 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray
307 :position (Vector3f. 0 -1 0)) 337 :position (Vector3f. 0 0 0))
308 (.addControl 338 (.addControl
309 (RigidBodyControl. 339 (RigidBodyControl.
310 (CapsuleCollisionShape. 0.5 1.5 1) (float 0)))) 340 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))
311 table (box 10 2 10 :position (Vector3f. 0 -6 0) 341 table (box 10 2 10 :position (Vector3f. 0 -20 0)
312 :color ColorRGBA/Gray :mass 0) 342 :color ColorRGBA/Gray :mass 0)
313 a (.getControl top RigidBodyControl) 343 a (.getControl top RigidBodyControl)
314 b (.getControl bottom RigidBodyControl)] 344 b (.getControl bottom RigidBodyControl)]
345
315 (cond 346 (cond
316 (= joint :point)
317 (doto
318 (Point2PointJoint. a b
319 (Vector3f. 0 -2 0)
320 (Vector3f. 0 2 0))
321 (.setCollisionBetweenLinkedBodys false))
322 (= joint :hinge)
323 (doto
324 (HingeJoint.
325 a b
326 (Vector3f. 0 -2 0)
327 (Vector3f. 0 2 0)
328 (Vector3f. 0 0 1)
329 (Vector3f. 0 0 1)
330
331 )
332 (.setCollisionBetweenLinkedBodys false)
333 ;;(.setLimit (- Math/PI) Math/PI)
334 )
335 (= joint :cone) 347 (= joint :cone)
336 ;; note to self -- jbullet does NOT implement cone joints
337 ;; correctly. You must use plain ol' bullet for this to work.
338 ;; It's faster anyway, so whatever.
339 348
340 (doto (ConeJoint. 349 (doto (ConeJoint.
341 a b 350 a b
342 (Vector3f. 0 -5 0) 351 (get-subjective-position joint-position top)
343 (Vector3f. 0 2 0) 352 (get-subjective-position joint-position bottom)
344 353 joint-rotation
345 (doto (Matrix3f.) 354 joint-rotation
346 (.fromStartEndVectors Vector3f/UNIT_X 355 )
347 Vector3f/UNIT_Y)) 356
348 (doto (Matrix3f.) 357
349 (.fromStartEndVectors Vector3f/UNIT_X 358 (.setLimit (* (/ 10) Math/PI)
350 (.normalize 359 (* (/ 4) Math/PI)
351 (Vector3f. 0 0 -1)))) 360 0)))
352 ) 361 [origin top bottom table]))
353 ;;(.setAngularOnly true)
354
355 (.setCollisionBetweenLinkedBodys false)
356 (.setLimit (* 1 (/ Math/PI 4))
357 (* 1 (/ Math/PI 2))
358 (* 0 (/ Math/PI 4)))
359
360 )
361 (= joint :six)
362 (doto
363 (SixDofJoint.
364 a b
365 (Vector3f. 0 -2 0)
366 (Vector3f. 0 2 0)
367 ;;(doto (Matrix3f.)
368 ;; (.fromStartEndVectors Vector3f/UNIT_X
369 ;; Vector3f/UNIT_Y))
370 ;;(doto (Matrix3f.)
371 ;; (.fromStartEndVectors Vector3f/UNIT_X
372 ;; Vector3f/UNIT_Y))
373 true)
374 (.setCollisionBetweenLinkedBodys false)
375 (.setAngularLowerLimit (Vector3f. 0
376 (- (/ Math/PI 2))
377 0))
378
379 (.setAngularUpperLimit (Vector3f. 0
380 (/ Math/PI 2)
381 0))
382 (.setLinearLowerLimit (Vector3f. 0 0 0))
383 (.setLinearUpperLimit (Vector3f. 0 0 0))
384
385 )
386
387 362
388
389
390
391 )
392
393 [top bottom table]))
394 363
395 364
396 (defn test-joint [joint] 365 (defn test-joint [joint]
397 (let [[top bottom floor] (world-setup joint) 366 (let [[origin top bottom floor] (world-setup joint)
398 control (.getControl top RigidBodyControl) 367 control (.getControl top RigidBodyControl)
399 move-up? (atom false) 368 move-up? (atom false)
400 move-down? (atom false) 369 move-down? (atom false)
401 move-left? (atom false) 370 move-left? (atom false)
402 move-right? (atom false) 371 move-right? (atom false)
403 roll-left? (atom false) 372 roll-left? (atom false)
404 roll-right? (atom false) 373 roll-right? (atom false)
405 timer (atom 0)] 374 timer (atom 0)]
406 375
407 (world 376 (world
408 (nodify [top bottom floor]) 377 (nodify [top bottom floor origin])
409 (merge standard-debug-controls 378 (merge standard-debug-controls
410 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?)) 379 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
411 "key-t" (fn [_ pressed?] (reset! move-down? pressed?)) 380 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
412 "key-f" (fn [_ pressed?] (reset! move-left? pressed?)) 381 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
413 "key-g" (fn [_ pressed?] (reset! move-right? pressed?)) 382 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
425 (do 394 (do
426 ;; (println-repl @timer) 395 ;; (println-repl @timer)
427 (.attachChild (.getRootNode world) 396 (.attachChild (.getRootNode world)
428 (sphere 0.05 :color ColorRGBA/Yellow 397 (sphere 0.05 :color ColorRGBA/Yellow
429 :position (.getWorldTranslation top) 398 :position (.getWorldTranslation top)
430 :physical? false)))) 399 :physical? false))
400 (.attachChild (.getRootNode world)
401 (sphere 0.05 :color ColorRGBA/LightGray
402 :position (.getWorldTranslation bottom)
403 :physical? false))))
404
431 (if @move-up? 405 (if @move-up?
432 (.applyTorque control 406 (.applyTorque control
433 (.mult (.getPhysicsRotation control) 407 (.mult (.getPhysicsRotation control)
434 (Vector3f. 0 0 10)))) 408 (Vector3f. 0 0 10))))
435 (if @move-down? 409 (if @move-down?
450 (Vector3f. -1 0 0)))) 424 (Vector3f. -1 0 0))))
451 (if @roll-right? 425 (if @roll-right?
452 (.applyTorque control 426 (.applyTorque control
453 (.mult (.getPhysicsRotation control) 427 (.mult (.getPhysicsRotation control)
454 (Vector3f. 1 0 0)))))))) 428 (Vector3f. 1 0 0))))))))
429
430
431
432
433
434
435
436
437
438
439
440
441
442 ;; please validate these.
443
444 (defn get-subjective-position
445 "Convert the world coordinates into coordinates relative to
446 object (i.e. local coordinates), taking into account the rotation
447 of object."
448 [#^Vector3f world-coordinates object]
449 ;; I don't know if it's important to take into account the rotation
450 ;; of the object. If it isn't, then remove the multiplication-by-inverse.
451 (.mult (.inverse (.getWorldRotation object))
452 (.subtract world-coordinates (.getWorldTranslation object))))
453
454
455 (defn get-subjective-rotation
456 "cf get-subjective-position. Converts a rotation specified relative
457 to the world's axes into a rotation specified in terms of the object's
458 coordinate system."
459 [#^Quaternion world-rotation object]
460 (.mult (.inverse (.getWorldRotation object)) world-rotation))
461
462
463
464
465 (defn joint-create "Connect objects 1 and 2 using a joint constraint. If
466 only position is specified, creates a point-to-point joint at the
467 given location
468 in world coordinates. etc. etc. for other joints.
469 To ensure consistency, I may alter this function
470 so that it moves obj-1 to be at the apex of the cone.
471
472 NOTE:
473 In the usual construction method, you create a joint and, if your
474 contraints are consistent, all the objects snap into position and
475 orientation around it, otherwise the systen explodes.
476
477 This construction method assumes that you have in mind a position and
478 rotation for the joint, and that you have already put your objects
479 at the required distances from that joint so that no snapping needs
480 to occur. The radial distances ('pivot lengths') are therefore just set to be
481 the pre-existing distances between the objects and the joint."
482 [#^Node obj-1
483 #^Node obj-2
484 #^Vector3f joint-position
485 #^Quaternion joint-rotation
486 span-1
487 span-2
488 twist
489 ]
490
491 (let
492 [body-1 (.getControl obj-1 RigidBodyControl)
493 body-2 (.getControl obj-2 RigidBodyControl)
494 ]
495 (doto (ConeJoint.
496 body-1
497 body-2
498 (get-subjective-position joint-position body-1)
499 (get-subjective-position joint-position body-2)
500 ;; ALIGN X-AXIS OF OBJECT-1 WITH THE CENTRAL AXIS OF THE CONE TO
501 ;;LOWER THE RISK OF INCONSISTENCY
502 ;;(Matrix3f/IDENTITY)
503 (.toRotationMatrix (get-subjective-rotation joint-rotation body-1))
504 (.toRotationMatrix (get-subjective-rotation joint-rotation body-2))
505 )
506 (.setLimit
507 span-1
508 span-2
509 twist))))
510
511
512
513
514
515
455 #+end_src 516 #+end_src
456 517
457 518
458 * COMMENT purgatory 519 * COMMENT purgatory
459 #+begin_src clojure 520 #+begin_src clojure