annotate org/body.org @ 58:25142dad240a

created test suite
author Robert McIntyre <rlm@mit.edu>
date Sat, 19 Nov 2011 23:42:21 -0700
parents 37a3256e1ed3
children e5e627f50a3a
rev   line source
rlm@0 1 #+title: The BODY!!!
rlm@0 2 #+author: Robert McIntyre
rlm@0 3 #+email: rlm@mit.edu
rlm@4 4 #+description: Simulating a body (movement, touch, propioception) in jMonkeyEngine3.
rlm@4 5 #+SETUPFILE: ../../aurellem/org/setup.org
rlm@4 6 #+INCLUDE: ../../aurellem/org/level-0.org
rlm@4 7
rlm@58 8 * Body
rlm@0 9
rlm@0 10 #+srcname: body-main
rlm@0 11 #+begin_src clojure
rlm@44 12 (ns cortex.body
rlm@44 13 (use (cortex world util import)))
rlm@44 14
rlm@0 15 (use 'clojure.contrib.def)
rlm@0 16 (cortex.import/mega-import-jme3)
rlm@0 17 (rlm.rlm-commands/help)
rlm@0 18
rlm@44 19 ;;(.loadModel
rlm@44 20 ;; (doto (asset-manager)
rlm@44 21 ;; (.registerLoader BlenderModelLoader (into-array String ["blend"])))
rlm@44 22 ;; "Models/person/person.blend")
rlm@44 23
rlm@44 24 (defn view-model [^String model]
rlm@44 25 (view
rlm@44 26 (.loadModel
rlm@44 27 (doto (asset-manager)
rlm@44 28 (.registerLoader BlenderModelLoader (into-array String ["blend"])))
rlm@44 29 model)))
rlm@49 30
rlm@49 31 (defn load-blender-scene [^String model]
rlm@49 32 (.loadModel
rlm@49 33 (doto (asset-manager)
rlm@49 34 (.registerLoader BlenderLoader (into-array String ["blend"])))
rlm@49 35 model))
rlm@49 36
rlm@49 37 (defn load-blender-model
rlm@49 38 [^String model]
rlm@49 39 (.loadModel
rlm@49 40 (doto (asset-manager)
rlm@49 41 (.registerLoader BlenderModelLoader (into-array String ["blend"])))
rlm@49 42 model))
rlm@49 43
rlm@49 44 (defn worm
rlm@49 45 []
rlm@50 46 (.loadModel (asset-manager) "Models/anim2/Cube.mesh.xml"))
rlm@49 47
rlm@50 48 (defn oto
rlm@49 49 []
rlm@49 50 (.loadModel (asset-manager) "Models/Oto/Oto.mesh.xml"))
rlm@49 51
rlm@50 52 (defn sinbad
rlm@50 53 []
rlm@50 54 (.loadModel (asset-manager) "Models/Sinbad/Sinbad.mesh.xml"))
rlm@50 55
rlm@50 56 (defn worm-blender
rlm@50 57 []
rlm@50 58 (first (seq (.getChildren (load-blender-model
rlm@56 59 "Models/anim2/simple-worm.blend")))))
rlm@50 60
rlm@52 61 (defn skel [node]
rlm@52 62 (doto
rlm@52 63 (.getSkeleton
rlm@52 64 (.getControl node SkeletonControl))
rlm@52 65 ;; this is necessary to force the skeleton to have accurate world
rlm@52 66 ;; transforms before it is rendered to the screen.
rlm@52 67 (.resetAndUpdate)))
rlm@52 68
rlm@50 69 (defprotocol Textual
rlm@50 70 (text [something]
rlm@50 71 "Display a detailed textual analysis of the given object."))
rlm@50 72
rlm@50 73 (extend-type com.jme3.scene.Node
rlm@50 74 Textual
rlm@50 75 (text [node]
rlm@50 76 (println "Total Vertexes: " (.getVertexCount node))
rlm@50 77 (println "Total Triangles: " (.getTriangleCount node))
rlm@50 78 (println "Controls :")
rlm@50 79 (dorun (map #(text (.getControl node %)) (range (.getNumControls node))))
rlm@50 80 (println "Has " (.getQuantity node) " Children:")
rlm@50 81 (doall (map text (.getChildren node)))))
rlm@50 82
rlm@50 83 (extend-type com.jme3.animation.AnimControl
rlm@50 84 Textual
rlm@50 85 (text [control]
rlm@50 86 (let [animations (.getAnimationNames control)]
rlm@52 87 (println "Animation Control with " (count animations) " animation(s):")
rlm@50 88 (dorun (map println animations)))))
rlm@50 89
rlm@50 90 (extend-type com.jme3.animation.SkeletonControl
rlm@50 91 Textual
rlm@50 92 (text [control]
rlm@50 93 (println "Skeleton Control with the following skeleton:")
rlm@50 94 (println (.getSkeleton control))))
rlm@50 95
rlm@52 96 (extend-type com.jme3.bullet.control.KinematicRagdollControl
rlm@52 97 Textual
rlm@52 98 (text [control]
rlm@52 99 (println "Ragdoll Control")))
rlm@52 100
rlm@52 101
rlm@50 102 (extend-type com.jme3.scene.Geometry
rlm@50 103 Textual
rlm@50 104 (text [control]
rlm@50 105 (println "...geo...")))
rlm@50 106
rlm@50 107
rlm@50 108
rlm@50 109
rlm@50 110 (defn body
rlm@52 111 "given a node with a SkeletonControl, will produce a body sutiable
rlm@52 112 for AI control with movement and proprioception."
rlm@50 113 [node]
rlm@50 114 (let [skeleton-control (.getControl node SkeletonControl)
rlm@53 115 krc (KinematicRagdollControl.)]
rlm@53 116 (comment
rlm@50 117 (dorun
rlm@50 118 (map #(.addBoneName krc %)
rlm@53 119 ["mid2" "tail" "head" "mid1" "mid3" "mid4" "Dummy-Root" ""]
rlm@53 120 ;;"mid2" "mid3" "tail" "head"]
rlm@53 121 )))
rlm@50 122 (.addControl node krc)
rlm@52 123 (.setRagdollMode krc)
rlm@52 124 )
rlm@50 125 node
rlm@50 126 )
rlm@50 127
rlm@52 128 (defn green-x-ray []
rlm@51 129 (doto (Material. (asset-manager)
rlm@51 130 "Common/MatDefs/Misc/Unshaded.j3md")
rlm@51 131 (.setColor "Color" ColorRGBA/Green)
rlm@52 132 (-> (.getAdditionalRenderState)
rlm@52 133 (.setDepthTest false))))
rlm@51 134
rlm@53 135 (defn show-skeleton [node]
rlm@50 136 (let [sd
rlm@51 137
rlm@50 138 (doto
rlm@51 139 (SkeletonDebugger. "aurellem-skel-debug"
rlm@51 140 (skel node))
rlm@51 141 (.setMaterial (green-x-ray)))]
rlm@53 142 (.attachChild node sd)
rlm@53 143 node))
rlm@50 144
rlm@51 145
rlm@50 146
rlm@50 147 (defn init-debug-skel-node
rlm@50 148 [f debug-node skeleton]
rlm@50 149 (let [bones
rlm@50 150 (map #(.getBone skeleton %)
rlm@50 151 (range (.getBoneCount skeleton)))]
rlm@50 152 (dorun (map #(.setUserControl % true) bones))
rlm@50 153 (dorun (map (fn [b]
rlm@50 154 (println (.getName b)
rlm@50 155 " -- " (f b)))
rlm@50 156 bones))
rlm@50 157 (dorun
rlm@50 158 (map #(.attachChild
rlm@50 159 debug-node
rlm@51 160 (doto
rlm@51 161 (sphere 0.1
rlm@51 162 :position (f %)
rlm@51 163 :physical? false)
rlm@51 164 (.setMaterial (green-x-ray))))
rlm@50 165 bones)))
rlm@50 166 debug-node)
rlm@50 167
rlm@52 168 (import jme3test.bullet.PhysicsTestHelper)
rlm@50 169
rlm@53 170
rlm@53 171 (defn test-zzz [the-worm world value]
rlm@53 172 (if (not value)
rlm@53 173 (let [skeleton (skel the-worm)]
rlm@53 174 (println-repl "enabling bones")
rlm@53 175 (dorun
rlm@53 176 (map
rlm@53 177 #(.setUserControl (.getBone skeleton %) true)
rlm@53 178 (range (.getBoneCount skeleton))))
rlm@53 179
rlm@53 180
rlm@56 181 (let [b (.getBone skeleton 2)]
rlm@53 182 (println-repl "moving " (.getName b))
rlm@53 183 (println-repl (.getLocalPosition b))
rlm@53 184 (.setUserTransforms b
rlm@54 185 Vector3f/UNIT_X
rlm@53 186 Quaternion/IDENTITY
rlm@54 187 ;;(doto (Quaternion.)
rlm@54 188 ;; (.fromAngles (/ Math/PI 2)
rlm@54 189 ;; 0
rlm@54 190 ;; 0
rlm@54 191
rlm@53 192 (Vector3f. 1 1 1))
rlm@53 193 )
rlm@53 194
rlm@53 195 (println-repl "hi! <3"))))
rlm@53 196
rlm@53 197
rlm@50 198 (defn test-ragdoll []
rlm@50 199
rlm@50 200 (let [the-worm
rlm@53 201
rlm@52 202 ;;(.loadModel (asset-manager) "Models/anim2/Cube.mesh.xml")
rlm@53 203 (doto (show-skeleton (worm-blender))
rlm@53 204 (.setLocalTranslation (Vector3f. 0 10 0))
rlm@53 205 ;;(worm)
rlm@52 206 ;;(oto)
rlm@52 207 ;;(sinbad)
rlm@50 208 )
rlm@50 209 ]
rlm@50 210
rlm@50 211
rlm@50 212 (.start
rlm@50 213 (world
rlm@50 214 (doto (Node.)
rlm@50 215 (.attachChild the-worm))
rlm@53 216 {"key-return" (fire-cannon-ball)
rlm@53 217 "key-space" (partial test-zzz the-worm)
rlm@53 218 }
rlm@50 219 (fn [world]
rlm@50 220 (light-up-everything world)
rlm@52 221 (PhysicsTestHelper/createPhysicsTestWorld
rlm@52 222 (.getRootNode world)
rlm@52 223 (asset-manager)
rlm@52 224 (.getPhysicsSpace
rlm@52 225 (.getState (.getStateManager world) BulletAppState)))
rlm@53 226 (set-gravity world Vector3f/ZERO)
rlm@50 227 ;;(.setTimer world (NanoTimer.))
rlm@50 228 ;;(org.lwjgl.input.Mouse/setGrabbed false)
rlm@50 229 )
rlm@50 230 no-op
rlm@50 231 )
rlm@50 232
rlm@50 233
rlm@50 234 )))
rlm@50 235
rlm@58 236
rlm@58 237
rlm@58 238
rlm@58 239
rlm@58 240 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@58 241 ;;; here is the ragdoll stuff
rlm@58 242
rlm@58 243 (def worm-mesh (.getMesh (.getChild (worm-blender) 0)))
rlm@58 244 (def mesh worm-mesh)
rlm@58 245
rlm@58 246 (.getFloatBuffer mesh VertexBuffer$Type/Position)
rlm@58 247 (.getFloatBuffer mesh VertexBuffer$Type/BoneWeight)
rlm@58 248 (.getData (.getBuffer mesh VertexBuffer$Type/BoneIndex))
rlm@58 249
rlm@58 250
rlm@58 251 (defn position [index]
rlm@58 252 (.get
rlm@58 253 (.getFloatBuffer worm-mesh VertexBuffer$Type/Position)
rlm@58 254 index))
rlm@58 255
rlm@58 256 (defn bones [index]
rlm@58 257 (.get
rlm@58 258 (.getData (.getBuffer mesh VertexBuffer$Type/BoneIndex))
rlm@58 259 index))
rlm@58 260
rlm@58 261 (defn bone-weights [index]
rlm@58 262 (.get
rlm@58 263 (.getFloatBuffer mesh VertexBuffer$Type/BoneWeight)
rlm@58 264 index))
rlm@58 265
rlm@58 266
rlm@58 267
rlm@58 268 (defn vertex-bones [vertex]
rlm@58 269 (vec (map (comp int bones) (range (* vertex 4) (+ (* vertex 4) 4)))))
rlm@58 270
rlm@58 271 (defn vertex-weights [vertex]
rlm@58 272 (vec (map (comp float bone-weights) (range (* vertex 4) (+ (* vertex 4) 4)))))
rlm@58 273
rlm@58 274 (defn vertex-position [index]
rlm@58 275 (let [offset (* index 3)]
rlm@58 276 (Vector3f. (position offset)
rlm@58 277 (position (inc offset))
rlm@58 278 (position (inc(inc offset))))))
rlm@58 279
rlm@58 280 (def vertex-info (juxt vertex-position vertex-bones vertex-weights))
rlm@58 281
rlm@58 282 (defn bone-control-color [index]
rlm@58 283 (get {[1 0 0 0] ColorRGBA/Red
rlm@58 284 [1 2 0 0] ColorRGBA/Magenta
rlm@58 285 [2 0 0 0] ColorRGBA/Blue}
rlm@58 286 (vertex-bones index)
rlm@58 287 ColorRGBA/White))
rlm@58 288
rlm@58 289 (defn influence-color [index bone-num]
rlm@58 290 (get
rlm@58 291 {(float 0) ColorRGBA/Blue
rlm@58 292 (float 0.5) ColorRGBA/Green
rlm@58 293 (float 1) ColorRGBA/Red}
rlm@58 294 ;; find the weight of the desired bone
rlm@58 295 ((zipmap (vertex-bones index)(vertex-weights index))
rlm@58 296 bone-num)
rlm@58 297 ColorRGBA/Blue))
rlm@58 298
rlm@58 299 (def worm-vertices (set (map vertex-info (range 60))))
rlm@58 300
rlm@58 301
rlm@58 302 (defn test-info []
rlm@58 303 (let [points (Node.)]
rlm@58 304 (dorun
rlm@58 305 (map #(.attachChild points %)
rlm@58 306 (map #(sphere 0.01
rlm@58 307 :position (vertex-position %)
rlm@58 308 :color (influence-color % 1)
rlm@58 309 :physical? false)
rlm@58 310 (range 60))))
rlm@58 311 (view points)))
rlm@58 312
rlm@58 313 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@58 314
rlm@58 315
rlm@58 316
rlm@58 317
rlm@58 318
rlm@58 319
rlm@58 320 ;;;;;;;;;;;; eve-style bodies ;;;;;;;;
rlm@55 321 (defn joint-control
rlm@55 322 [joint]
rlm@56 323 (let [physics-space (ref nil)]
rlm@55 324 (reify PhysicsControl
rlm@55 325 (setPhysicsSpace [this space]
rlm@55 326 (dosync
rlm@55 327 (ref-set physics-space space))
rlm@55 328 (.addJoint space joint))
rlm@55 329 (update [this tpf])
rlm@55 330 (setSpatial [this spatial])
rlm@55 331 (render [this rm vp])
rlm@55 332 (getPhysicsSpace [this] (deref physics-space))
rlm@56 333 (isEnabled [this] true)
rlm@56 334 (setEnabled [this state]))))
rlm@50 335
rlm@55 336 (defn add-joint
rlm@55 337 "Add a joint to a particular object. When the object is added to the
rlm@55 338 PhysicsSpace of a simulation, the joint will also be added"
rlm@55 339 [object joint]
rlm@55 340 (let [control (joint-control joint)]
rlm@55 341 (.addControl object control))
rlm@55 342 object)
rlm@50 343
rlm@55 344 (defn hinge-world
rlm@55 345 []
rlm@55 346 (let [sphere1 (sphere)
rlm@55 347 sphere2 (sphere 1 :position (Vector3f. 3 3 3))
rlm@55 348 joint (Point2PointJoint.
rlm@55 349 (.getControl sphere1 RigidBodyControl)
rlm@55 350 (.getControl sphere2 RigidBodyControl)
rlm@55 351 Vector3f/ZERO (Vector3f. 3 3 3))]
rlm@55 352 (add-joint sphere1 joint)
rlm@55 353 (doto (Node. "hinge-world")
rlm@55 354 (.attachChild sphere1)
rlm@55 355 (.attachChild sphere2))))
rlm@55 356
rlm@56 357 (defn test-joint []
rlm@56 358 (view (hinge-world)))
rlm@49 359
rlm@49 360
rlm@58 361 (defn worm [segment-length num-segments interstitial-space radius]
rlm@58 362 (letfn [(nth-segment
rlm@58 363 [n]
rlm@58 364 (box segment-length radius radius :mass 0.1
rlm@58 365 :position
rlm@58 366 (Vector3f.
rlm@58 367 (* 2 n (+ interstitial-space segment-length)) 0 0)
rlm@58 368 :name (str "worm-segment" n)
rlm@58 369 :color (ColorRGBA/randomColor)))]
rlm@58 370 (map nth-segment (range num-segments))))
rlm@58 371
rlm@58 372 (defn nodify
rlm@58 373 "take a sequence of things that can be attached to a node and return
rlm@58 374 a node with all of the attached"
rlm@58 375 ([name children]
rlm@58 376 (let [node (Node. name)]
rlm@58 377 (dorun (map #(.attachChild node %) children))
rlm@58 378 node))
rlm@58 379 ([children] (nodify "" children)))
rlm@58 380
rlm@58 381
rlm@58 382 (defn connect-at-midpoint
rlm@58 383 [segmentA segmentB]
rlm@58 384 (let [centerA (.getWorldTranslation segmentA)
rlm@58 385 centerB (.getWorldTranslation segmentB)
rlm@58 386 midpoint (.mult (.add centerA centerB) (float 0.5))
rlm@58 387 pivotA (.subtract midpoint centerA)
rlm@58 388 pivotB (.subtract midpoint centerB)
rlm@58 389
rlm@58 390 joint (Point2PointJoint.
rlm@58 391 (.getControl segmentA RigidBodyControl)
rlm@58 392 (.getControl segmentB RigidBodyControl)
rlm@58 393 pivotA
rlm@58 394 pivotB)]
rlm@58 395 (add-joint segmentA joint)
rlm@58 396 segmentB))
rlm@58 397
rlm@58 398
rlm@58 399 (defn point-worm []
rlm@58 400 (let [segments (worm 0.2 5 0.1 0.1)]
rlm@58 401 (dorun (map (partial apply connect-at-midpoint)
rlm@58 402 (partition 2 1 segments)))
rlm@58 403 (nodify "worm" segments)))
rlm@58 404
rlm@58 405
rlm@58 406 (defn test-worm []
rlm@58 407 (.start
rlm@58 408 (world
rlm@58 409 (doto (Node.)
rlm@58 410 ;;(.attachChild (point-worm))
rlm@58 411 (.attachChild (load-blender-model
rlm@58 412 "Models/anim2/joint-worm.blend"))
rlm@58 413
rlm@58 414 (.attachChild (box 10 1 10
rlm@58 415 :position (Vector3f. 0 -2 0) :mass 0
rlm@58 416 :color (ColorRGBA/Gray))))
rlm@58 417 {
rlm@58 418 "key-space" (fire-cannon-ball)
rlm@58 419 }
rlm@58 420 (fn [world]
rlm@58 421 (enable-debug world)
rlm@58 422 (light-up-everything world)
rlm@58 423 ;;(.setTimer world (NanoTimer.))
rlm@58 424 )
rlm@58 425 no-op)))
rlm@49 426
rlm@56 427 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@56 428
rlm@56 429
rlm@56 430
rlm@56 431
rlm@56 432
rlm@56 433
rlm@56 434
rlm@56 435
rlm@56 436
rlm@56 437
rlm@56 438
rlm@56 439
rlm@56 440
rlm@0 441 #+end_src
rlm@0 442
rlm@0 443
rlm@0 444
rlm@0 445
rlm@0 446
rlm@0 447
rlm@0 448
rlm@0 449
rlm@0 450 * COMMENT generate Source.
rlm@44 451 #+begin_src clojure :tangle ../src/cortex/body.clj
rlm@0 452 <<body-main>>
rlm@0 453 #+end_src
rlm@0 454