view org/test-creature.org @ 89:cd5151b5e7c3

starting automatic touch for blender models
author Robert McIntyre <rlm@mit.edu>
date Sat, 07 Jan 2012 10:49:49 -0700
parents 3e929630a25f
children 6d7c17c847a3
line wrap: on
line source
1 #+title: First attempt at a creature!
2 #+author: Robert McIntyre
3 #+email: rlm@mit.edu
4 #+description:
5 #+keywords: simulation, jMonkeyEngine3, clojure
6 #+SETUPFILE: ../../aurellem/org/setup.org
7 #+INCLUDE: ../../aurellem/org/level-0.org
9 * Intro
10 So far, I've made the following senses --
11 - Vision
12 - Hearing
13 - Touch
14 - Proprioception
16 And one effector:
17 - Movement
19 However, the code so far has only enabled these senses, but has not
20 actually implemented them. For example, there is still a lot of work
21 to be done for vision. I need to be able to create an /eyeball/ in
22 simulation that can be moved around and see the world from different
23 angles. I also need to determine weather to use log-polar or cartesian
24 for the visual input, and I need to determine how/wether to
25 disceritise the visual input.
27 I also want to be able to visualize both the sensors and the
28 effectors in pretty pictures. This semi-retarted creature will by my
29 first attempt at bringing everything together.
31 * The creature's body
33 Still going to do an eve-like body in blender, but due to problems
34 importing the joints, etc into jMonkeyEngine3, I',m going to do all
35 the connecting here in clojure code, using the names of the individual
36 components and trial and error. Later, I'll maybe make some sort of
37 creature-building modifications to blender that support whatever
38 discreitized senses I'm going to make.
40 #+name: body-1
41 #+begin_src clojure
42 (ns cortex.silly
43 "let's play!"
44 {:author "Robert McIntyre"})
46 ;; TODO remove this!
47 (require 'cortex.import)
48 (cortex.import/mega-import-jme3)
49 (use '(cortex world util body hearing touch vision))
51 (rlm.rlm-commands/help)
53 (declare joint-create)
55 (defn load-bullet []
56 (let [sim (world (Node.) {} no-op no-op)]
57 (.enqueue
58 sim
59 (fn []
60 (.stop sim)))
61 (.start sim)))
63 (defn load-blender-model
64 "Load a .blend file using an asset folder relative path."
65 [^String model]
66 (.loadModel
67 (doto (asset-manager)
68 (.registerLoader BlenderModelLoader (into-array String ["blend"])))
69 model))
71 (defn meta-data [blender-node key]
72 (if-let [data (.getUserData blender-node "properties")]
73 (.findValue data key)
74 nil))
76 (defn blender-to-jme
77 "Convert from Blender coordinates to JME coordinates"
78 [#^Vector3f in]
79 (Vector3f. (.getX in)
80 (.getZ in)
81 (- (.getY in))))
83 (defn jme-to-blender
84 "Convert from JME coordinates to Blender coordinates"
85 [#^Vector3f in]
86 (Vector3f. (.getX in)
87 (- (.getZ in))
88 (.getY in)))
90 (defn joint-targets
91 "Return the two closest two objects to the joint object, ordered
92 from bottom to top according to the joint's rotation."
93 [#^Node parts #^Node joint]
94 ;;(println (meta-data joint "joint"))
95 (.getWorldRotation joint)
96 (loop [radius (float 0.01)]
97 (let [results (CollisionResults.)]
98 (.collideWith
99 parts
100 (BoundingBox. (.getWorldTranslation joint)
101 radius radius radius)
102 results)
103 (let [targets
104 (distinct
105 (map #(.getGeometry %) results))]
106 (if (>= (count targets) 2)
107 (sort-by
108 #(let [v
109 (jme-to-blender
110 (.mult
111 (.inverse (.getWorldRotation joint))
112 (.subtract (.getWorldTranslation %)
113 (.getWorldTranslation joint))))]
114 (println-repl (.getName %) ":" v)
115 (.dot (Vector3f. 1 1 1)
116 v))
117 (take 2 targets))
118 (recur (float (* radius 2))))))))
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))
128 (defmulti joint-dispatch
129 "Translate blender pseudo-joints into real JME joints."
130 (fn [constraints & _]
131 (:type constraints)))
133 (defmethod joint-dispatch :point
134 [constraints control-a control-b pivot-a pivot-b rotation]
135 (println-repl "creating POINT2POINT joint")
136 (Point2PointJoint.
137 control-a
138 control-b
139 pivot-a
140 pivot-b))
142 (defmethod joint-dispatch :hinge
143 [constraints control-a control-b pivot-a pivot-b rotation]
144 (println-repl "creating HINGE joint")
145 (let [axis
146 (if-let
147 [axis (:axis constraints)]
148 axis
149 Vector3f/UNIT_X)
150 [limit-1 limit-2] (:limit constraints)
151 hinge-axis
152 (.mult
153 rotation
154 (blender-to-jme axis))]
155 (doto
156 (HingeJoint.
157 control-a
158 control-b
159 pivot-a
160 pivot-b
161 hinge-axis
162 hinge-axis)
163 (.setLimit limit-1 limit-2))))
165 (defmethod joint-dispatch :cone
166 [constraints control-a control-b pivot-a pivot-b rotation]
167 (let [limit-xz (:limit-xz constraints)
168 limit-xy (:limit-xy constraints)
169 twist (:twist constraints)]
171 (println-repl "creating CONE joint")
172 (println-repl rotation)
173 (println-repl
174 "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0)))
175 (println-repl
176 "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0)))
177 (println-repl
178 "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1)))
179 (doto
180 (ConeJoint.
181 control-a
182 control-b
183 pivot-a
184 pivot-b
185 rotation
186 rotation)
187 (.setLimit (float limit-xz)
188 (float limit-xy)
189 (float twist)))))
191 (defn connect
192 "here are some examples:
193 {:type :point}
194 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}
195 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)
197 {:type :cone :limit-xz 0]
198 :limit-xy 0]
199 :twist 0]} (use XZY rotation mode in blender!)"
200 [#^Node obj-a #^Node obj-b #^Node joint]
201 (let [control-a (.getControl obj-a RigidBodyControl)
202 control-b (.getControl obj-b RigidBodyControl)
203 joint-center (.getWorldTranslation joint)
204 joint-rotation (.toRotationMatrix (.getWorldRotation joint))
205 pivot-a (world-to-local obj-a joint-center)
206 pivot-b (world-to-local obj-b joint-center)]
208 (if-let [constraints
209 (map-vals
210 eval
211 (read-string
212 (meta-data joint "joint")))]
213 ;; A side-effect of creating a joint registers
214 ;; it with both physics objects which in turn
215 ;; will register the joint with the physics system
216 ;; when the simulation is started.
217 (do
218 (println-repl "creating joint between"
219 (.getName obj-a) "and" (.getName obj-b))
220 (joint-dispatch constraints
221 control-a control-b
222 pivot-a pivot-b
223 joint-rotation))
224 (println-repl "could not find joint meta-data!"))))
226 (defn assemble-creature [#^Node pieces joints]
227 (dorun
228 (map
229 (fn [geom]
230 (let [physics-control
231 (RigidBodyControl.
232 (HullCollisionShape.
233 (.getMesh geom))
234 (if-let [mass (meta-data geom "mass")]
235 (do
236 (println-repl
237 "setting" (.getName geom) "mass to" (float mass))
238 (float mass))
239 (float 1)))]
241 (.addControl geom physics-control)))
242 (filter #(isa? (class %) Geometry )
243 (node-seq pieces))))
245 (dorun
246 (map
247 (fn [joint]
248 (let [[obj-a obj-b]
249 (joint-targets pieces joint)]
250 (connect obj-a obj-b joint)))
251 joints))
252 pieces)
254 (defn blender-creature [blender-path]
255 (let [model (load-blender-model blender-path)
256 joints
257 (if-let [joint-node (.getChild model "joints")]
258 (seq (.getChildren joint-node))
259 (do (println-repl "could not find joints node")
260 []))]
261 (assemble-creature model joints)))
263 (def hand "Models/creature1/one.blend")
265 (def worm "Models/creature1/try-again.blend")
267 (defn x-ray [#^ColorRGBA color]
268 (doto (Material. (asset-manager)
269 "Common/MatDefs/Misc/Unshaded.j3md")
270 (.setColor "Color" color)
271 (-> (.getAdditionalRenderState)
272 (.setDepthTest false))))
274 (defn test-creature [thing]
275 (let [x-axis
276 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)
277 y-axis
278 (box 0.01 1 0.01 :physical? false :color ColorRGBA/Green)
279 z-axis
280 (box 0.01 0.01 1 :physical? false :color ColorRGBA/Blue)]
281 (world
282 (nodify [(blender-creature thing)
283 (box 10 2 10 :position (Vector3f. 0 -9 0)
284 :color ColorRGBA/Gray :mass 0)
285 x-axis y-axis z-axis
286 ])
287 standard-debug-controls
288 (comp light-up-everything enable-debug
289 (fn [world]
290 (.setTimer world (NanoTimer.))
291 ;;(set-gravity world (Vector3f. 0 0 0))
292 (speed-up world)
293 world
294 ))
295 no-op)))
297 (defn world-setup [joint]
298 (let [
300 joint-position (Vector3f. 0 0 0)
301 joint-rotation
302 (.toRotationMatrix
303 (.mult
304 (doto (Quaternion.)
305 (.fromAngleAxis
306 (* 1 (/ Math/PI 4))
307 (Vector3f. -1 0 0)))
308 (doto (Quaternion.)
309 (.fromAngleAxis
310 (* 1 (/ Math/PI 2))
311 (Vector3f. 0 0 1)))))
312 top-position (.mult joint-rotation (Vector3f. 8 0 0))
314 origin (doto
315 (sphere 0.1 :physical? false :color ColorRGBA/Cyan
316 :position top-position))
317 top (doto
318 (sphere 0.1 :physical? false :color ColorRGBA/Yellow
319 :position top-position)
321 (.addControl
322 (RigidBodyControl.
323 (CapsuleCollisionShape. 0.5 1.5 1) (float 20))))
324 bottom (doto
325 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray
326 :position (Vector3f. 0 0 0))
327 (.addControl
328 (RigidBodyControl.
329 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))
330 table (box 10 2 10 :position (Vector3f. 0 -20 0)
331 :color ColorRGBA/Gray :mass 0)
332 a (.getControl top RigidBodyControl)
333 b (.getControl bottom RigidBodyControl)]
335 (cond
336 (= joint :cone)
338 (doto (ConeJoint.
339 a b
340 (world-to-local top joint-position)
341 (world-to-local bottom joint-position)
342 joint-rotation
343 joint-rotation
344 )
347 (.setLimit (* (/ 10) Math/PI)
348 (* (/ 4) Math/PI)
349 0)))
350 [origin top bottom table]))
352 (defn test-joint [joint]
353 (let [[origin top bottom floor] (world-setup joint)
354 control (.getControl top RigidBodyControl)
355 move-up? (atom false)
356 move-down? (atom false)
357 move-left? (atom false)
358 move-right? (atom false)
359 roll-left? (atom false)
360 roll-right? (atom false)
361 timer (atom 0)]
363 (world
364 (nodify [top bottom floor origin])
365 (merge standard-debug-controls
366 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
367 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
368 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
369 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
370 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
371 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
373 (fn [world]
374 (light-up-everything world)
375 (enable-debug world)
376 (set-gravity world (Vector3f. 0 0 0))
377 )
379 (fn [world _]
380 (if (zero? (rem (swap! timer inc) 100))
381 (do
382 ;; (println-repl @timer)
383 (.attachChild (.getRootNode world)
384 (sphere 0.05 :color ColorRGBA/Yellow
385 :position (.getWorldTranslation top)
386 :physical? false))
387 (.attachChild (.getRootNode world)
388 (sphere 0.05 :color ColorRGBA/LightGray
389 :position (.getWorldTranslation bottom)
390 :physical? false))))
392 (if @move-up?
393 (.applyTorque control
394 (.mult (.getPhysicsRotation control)
395 (Vector3f. 0 0 10))))
396 (if @move-down?
397 (.applyTorque control
398 (.mult (.getPhysicsRotation control)
399 (Vector3f. 0 0 -10))))
400 (if @move-left?
401 (.applyTorque control
402 (.mult (.getPhysicsRotation control)
403 (Vector3f. 0 10 0))))
404 (if @move-right?
405 (.applyTorque control
406 (.mult (.getPhysicsRotation control)
407 (Vector3f. 0 -10 0))))
408 (if @roll-left?
409 (.applyTorque control
410 (.mult (.getPhysicsRotation control)
411 (Vector3f. -1 0 0))))
412 (if @roll-right?
413 (.applyTorque control
414 (.mult (.getPhysicsRotation control)
415 (Vector3f. 1 0 0))))))))
419 #+end_src
421 #+results: body-1
422 : #'cortex.silly/test-joint
425 * COMMENT purgatory
426 #+begin_src clojure
427 (defn bullet-trans []
428 (let [obj-a (sphere 0.5 :color ColorRGBA/Red
429 :position (Vector3f. -10 5 0))
430 obj-b (sphere 0.5 :color ColorRGBA/Blue
431 :position (Vector3f. -10 -5 0)
432 :mass 0)
433 control-a (.getControl obj-a RigidBodyControl)
434 control-b (.getControl obj-b RigidBodyControl)
435 swivel
436 (.toRotationMatrix
437 (doto (Quaternion.)
438 (.fromAngleAxis (/ Math/PI 2)
439 Vector3f/UNIT_X)))]
440 (doto
441 (ConeJoint.
442 control-a control-b
443 (Vector3f. 0 5 0)
444 (Vector3f. 0 -5 0)
445 swivel swivel)
446 (.setLimit (* 0.6 (/ Math/PI 4))
447 (/ Math/PI 4)
448 (* Math/PI 0.8)))
449 (world (nodify
450 [obj-a obj-b])
451 standard-debug-controls
452 enable-debug
453 no-op)))
456 (defn bullet-trans* []
457 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red
458 :position (Vector3f. 5 0 0)
459 :mass 90)
460 obj-b (sphere 0.5 :color ColorRGBA/Blue
461 :position (Vector3f. -5 0 0)
462 :mass 0)
463 control-a (.getControl obj-a RigidBodyControl)
464 control-b (.getControl obj-b RigidBodyControl)
465 move-up? (atom nil)
466 move-down? (atom nil)
467 move-left? (atom nil)
468 move-right? (atom nil)
469 roll-left? (atom nil)
470 roll-right? (atom nil)
471 force 100
472 swivel
473 (.toRotationMatrix
474 (doto (Quaternion.)
475 (.fromAngleAxis (/ Math/PI 2)
476 Vector3f/UNIT_X)))
477 x-move
478 (doto (Matrix3f.)
479 (.fromStartEndVectors Vector3f/UNIT_X
480 (.normalize (Vector3f. 1 1 0))))
482 timer (atom 0)]
483 (doto
484 (ConeJoint.
485 control-a control-b
486 (Vector3f. -8 0 0)
487 (Vector3f. 2 0 0)
488 ;;swivel swivel
489 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY
490 x-move Matrix3f/IDENTITY
491 )
492 (.setCollisionBetweenLinkedBodys false)
493 (.setLimit (* 1 (/ Math/PI 4)) ;; twist
494 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane
495 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane
496 (world (nodify
497 [obj-a obj-b])
498 (merge standard-debug-controls
499 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
500 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
501 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
502 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
503 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
504 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
506 (fn [world]
507 (enable-debug world)
508 (set-gravity world Vector3f/ZERO)
509 )
511 (fn [world _]
513 (if @move-up?
514 (.applyForce control-a
515 (Vector3f. force 0 0)
516 (Vector3f. 0 0 0)))
517 (if @move-down?
518 (.applyForce control-a
519 (Vector3f. (- force) 0 0)
520 (Vector3f. 0 0 0)))
521 (if @move-left?
522 (.applyForce control-a
523 (Vector3f. 0 force 0)
524 (Vector3f. 0 0 0)))
525 (if @move-right?
526 (.applyForce control-a
527 (Vector3f. 0 (- force) 0)
528 (Vector3f. 0 0 0)))
530 (if @roll-left?
531 (.applyForce control-a
532 (Vector3f. 0 0 force)
533 (Vector3f. 0 0 0)))
534 (if @roll-right?
535 (.applyForce control-a
536 (Vector3f. 0 0 (- force))
537 (Vector3f. 0 0 0)))
539 (if (zero? (rem (swap! timer inc) 100))
540 (.attachChild
541 (.getRootNode world)
542 (sphere 0.05 :color ColorRGBA/Yellow
543 :physical? false :position
544 (.getWorldTranslation obj-a)))))
545 )
546 ))
550 #+end_src
553 * COMMENT generate source
554 #+begin_src clojure :tangle ../src/cortex/silly.clj
555 <<body-1>>
556 #+end_src