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