view org/test-creature.org @ 78:77b506ac64f3

trying to make offset cone joints
author Robert McIntyre <rlm@mit.edu>
date Wed, 04 Jan 2012 20:34:00 -0700
parents 1f84f425e05d
children 01dbdb0d5500
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 (defn load-blender-model
54 "Load a .blend file using an asset folder relative path."
55 [^String model]
56 (.loadModel
57 (doto (asset-manager)
58 (.registerLoader BlenderModelLoader (into-array String ["blend"])))
59 model))
61 (defn meta-data [blender-node key]
62 (if-let [data (.getUserData blender-node "properties")]
63 (.findValue data key)
64 nil))
66 (defn blender-to-jme
67 "Convert from Blender coordinates to JME coordinates"
68 [#^Vector3f in]
69 (Vector3f. (.getX in)
70 (.getZ in)
71 (- (.getY in))))
73 (defn joint-targets
74 "Return the two closest two objects to the joint object, ordered
75 from bottom to top according to the joint's rotation."
76 [#^Node parts #^Node joint]
77 ;;(println (meta-data joint "joint"))
78 (.getWorldRotation joint)
79 (loop [radius (float 0.01)]
80 (let [results (CollisionResults.)]
81 (.collideWith
82 parts
83 (BoundingBox. (.getWorldTranslation joint)
84 radius radius radius)
85 results)
86 (let [targets
87 (distinct
88 (map #(.getGeometry %) results))]
89 (if (>= (count targets) 2)
90 (sort-by
91 #(.getY
92 (.mult
93 (.inverse (.getWorldRotation joint))
94 (.subtract (.getWorldTranslation %)
95 (.getWorldTranslation joint))))
96 (take 2 targets))
97 (recur (float (* radius 2))))))))
99 (defn connect
100 "here are some examples:
101 {:type :point}
102 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}
103 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)
105 {:type :cone :limit-xz 0]
106 :limit-yz 0]
107 :twist 0]}"
108 ([#^Node obj-a #^Node obj-b #^Node joint]
109 (let [center-a (.getWorldTranslation obj-a)
110 center-b (.getWorldTranslation obj-b)
111 joint-center (.getWorldTranslation joint)
112 pivot-a (.subtract joint-center center-a)
113 pivot-b (.subtract joint-center center-b)
114 control-a (.getControl obj-a RigidBodyControl)
115 control-b (.getControl obj-b RigidBodyControl)]
116 ;; A side-effect of creating a joint registers
117 ;; it with both physics objects which in turn
118 ;; will register the joint with the physics system
119 ;; when the simulation is started.
120 (if-let [constraints
121 (map-vals
122 eval
123 (read-string
124 (meta-data joint "joint")))]
126 (let [joint-type (:type constraints)]
127 (println-repl "creating joint between"
128 (.getName obj-a) "and" (.getName obj-b))
129 (cond (= :point joint-type)
130 (do
131 (println-repl "creating POINT joint")
132 (Point2PointJoint.
133 control-a
134 control-b
135 pivot-a
136 pivot-b))
137 (= :hinge joint-type)
138 (do
139 (println-repl "creating HINGE joint")
140 (let [axis (if-let
141 [axis (:axis constraints)]
142 axis
143 Vector3f/UNIT_X)
144 [limit-1 limit-2] (:limit constraints)
145 hinge-axis
146 (.mult
147 (.getWorldRotation joint)
148 (blender-to-jme axis))]
149 (doto
150 (HingeJoint.
151 control-a
152 control-b
153 pivot-a
154 pivot-b
155 hinge-axis
156 hinge-axis)
157 (.setLimit limit-1 limit-2))))
158 (= :cone joint-type)
159 (do
160 (let [limit-xy (:limit-xz constraints)
161 limit-yz (:limit-yz constraints)
162 twist (:twist constraints)]
164 (println-repl "creating CONE joint")
165 (doto
166 (ConeJoint.
167 control-a
168 control-b
169 pivot-a
170 pivot-b
171 (doto (Matrix3f.)
172 (.fromStartEndVectors
173 Vector3f/UNIT_X
174 (.normalize
175 (.subtract (.getWorldTranslation joint)
176 (.getWorldTranslation obj-a)))))
177 (doto (Matrix3f.)
178 (.fromStartEndVectors
179 Vector3f/UNIT_X
180 (.normalize
181 (.subtract
182 (.getWorldTranslation obj-b)
183 (.getWorldTranslation joint))))))
184 (.setLimit (float limit-xy)
185 (float limit-yz)
186 (float twist)))))
187 true
188 (println-repl
189 "joint-type" joint-type "not recognized")))
191 (println-repl "could not find joint meta-data!")))))
193 (defn assemble-creature [#^Node pieces joints]
194 (dorun
195 (map
196 (fn [geom]
197 (let [physics-control
198 (RigidBodyControl.
199 (HullCollisionShape.
200 (.getMesh geom))
201 (if-let [mass (meta-data geom "mass")]
202 (do
203 (println-repl
204 "setting" (.getName geom) "mass to" (float mass))
205 (float mass))
206 (float 1)))]
208 (.addControl geom physics-control)))
209 (filter #(isa? (class %) Geometry )
210 (node-seq pieces))))
212 (dorun
213 (map
214 (fn [joint]
215 (let [[obj-a obj-b]
216 (joint-targets pieces joint)]
217 (connect obj-a obj-b joint)))
218 joints))
219 pieces)
221 (defn blender-creature [blender-path]
222 (let [model (load-blender-model blender-path)
223 joints
224 (if-let [joint-node (.getChild model "joints")]
225 (seq (.getChildren joint-node))
226 (do (println-repl "could not find joints node")
227 []))]
228 (assemble-creature model joints)))
230 (def hand "Models/creature1/one.blend")
232 (def worm "Models/creature1/try-again.blend")
234 (defn test-creature [thing]
235 (world
236 (nodify [(blender-creature thing)
237 (box 10 2 10 :position (Vector3f. 0 -5.5 0)
238 :color ColorRGBA/Gray :mass 0)])
239 standard-debug-controls
240 (comp light-up-everything enable-debug
241 (fn [world]
242 (.setTimer world (NanoTimer.))
243 ;;(set-gravity world (Vector3f. 0 0 0))
244 (speed-up world)
245 world
246 ))
247 no-op))
249 (defn world-setup [joint]
250 (let [top (doto
251 (sphere 0.1 :physical? false :color ColorRGBA/Yellow
252 :position (Vector3f. 0 7 0))
253 (.addControl
254 (RigidBodyControl.
255 (CapsuleCollisionShape. 0.5 1.5 1) (float 15))))
256 bottom (doto
257 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray
258 :position (Vector3f. 0 -1 0))
259 (.addControl
260 (RigidBodyControl.
261 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))
262 table (box 10 2 10 :position (Vector3f. 0 -6 0)
263 :color ColorRGBA/Gray :mass 0)
264 a (.getControl top RigidBodyControl)
265 b (.getControl bottom RigidBodyControl)]
266 (cond
267 (= joint :point)
268 (doto
269 (Point2PointJoint. a b
270 (Vector3f. 0 -2 0)
271 (Vector3f. 0 2 0))
272 (.setCollisionBetweenLinkedBodys false))
273 (= joint :hinge)
274 (doto
275 (HingeJoint.
276 a b
277 (Vector3f. 0 -2 0)
278 (Vector3f. 0 2 0)
279 (Vector3f. 0 0 1)
280 (Vector3f. 0 0 1)
282 )
283 (.setCollisionBetweenLinkedBodys false)
284 ;;(.setLimit (- Math/PI) Math/PI)
285 )
286 (= joint :cone)
287 ;; note to self -- jbullet does NOT implement cone joints
288 ;; correctly. You must use plain ol' bullet for this to work.
289 ;; It's faster anyway, so whatever.
291 (doto (ConeJoint.
292 a b
293 (Vector3f. 0 -5 0)
294 (Vector3f. 0 2 0)
296 (doto (Matrix3f.)
297 (.fromStartEndVectors Vector3f/UNIT_X
298 Vector3f/UNIT_Y))
299 (doto (Matrix3f.)
300 (.fromStartEndVectors Vector3f/UNIT_X
301 (.normalize
302 (Vector3f. 5 5 0))))
303 )
304 ;;(.setAngularOnly true)
306 (.setCollisionBetweenLinkedBodys false)
307 (.setLimit (* 1 (/ Math/PI 4))
308 (* 1 (/ Math/PI 2))
309 (* 0 (/ Math/PI 4)))
311 )
312 (= joint :six)
313 (doto
314 (SixDofJoint.
315 a b
316 (Vector3f. 0 -2 0)
317 (Vector3f. 0 2 0)
318 ;;(doto (Matrix3f.)
319 ;; (.fromStartEndVectors Vector3f/UNIT_X
320 ;; Vector3f/UNIT_Y))
321 ;;(doto (Matrix3f.)
322 ;; (.fromStartEndVectors Vector3f/UNIT_X
323 ;; Vector3f/UNIT_Y))
324 true)
325 (.setCollisionBetweenLinkedBodys false)
326 (.setAngularLowerLimit (Vector3f. 0
327 (- (/ Math/PI 2))
328 0))
330 (.setAngularUpperLimit (Vector3f. 0
331 (/ Math/PI 2)
332 0))
333 (.setLinearLowerLimit (Vector3f. 0 0 0))
334 (.setLinearUpperLimit (Vector3f. 0 0 0))
336 )
342 )
344 [top bottom table]))
347 (defn test-joint [joint]
348 (let [[top bottom floor] (world-setup joint)
349 control (.getControl top RigidBodyControl)
350 move-up? (atom false)
351 move-down? (atom false)
352 move-left? (atom false)
353 move-right? (atom false)
354 roll-left? (atom false)
355 roll-right? (atom false)
356 timer (atom 0)]
358 (world
359 (nodify [top bottom floor])
360 (merge standard-debug-controls
361 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
362 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
363 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
364 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
365 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
366 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
368 (fn [world]
369 (light-up-everything world)
370 (enable-debug world)
371 (set-gravity world (Vector3f. 0 0 0))
372 )
374 (fn [world _]
375 (if (zero? (rem (swap! timer inc) 100))
376 (do
377 ;; (println-repl @timer)
378 (.attachChild (.getRootNode world)
379 (sphere 0.05 :color ColorRGBA/Yellow
380 :position (.getWorldTranslation top)
381 :physical? false))))
382 (if @move-up?
383 (.applyTorque control
384 (.mult (.getPhysicsRotation control)
385 (Vector3f. 0 0 10))))
386 (if @move-down?
387 (.applyTorque control
388 (.mult (.getPhysicsRotation control)
389 (Vector3f. 0 0 -10))))
390 (if @move-left?
391 (.applyTorque control
392 (.mult (.getPhysicsRotation control)
393 (Vector3f. 0 10 0))))
394 (if @move-right?
395 (.applyTorque control
396 (.mult (.getPhysicsRotation control)
397 (Vector3f. 0 -10 0))))
398 (if @roll-left?
399 (.applyTorque control
400 (.mult (.getPhysicsRotation control)
401 (Vector3f. -1 0 0))))
402 (if @roll-right?
403 (.applyTorque control
404 (.mult (.getPhysicsRotation control)
405 (Vector3f. 1 0 0))))))))
406 #+end_src
409 * COMMENT purgatory
410 #+begin_src clojure
411 (defn bullet-trans []
412 (let [obj-a (sphere 0.5 :color ColorRGBA/Red
413 :position (Vector3f. -10 5 0))
414 obj-b (sphere 0.5 :color ColorRGBA/Blue
415 :position (Vector3f. -10 -5 0)
416 :mass 0)
417 control-a (.getControl obj-a RigidBodyControl)
418 control-b (.getControl obj-b RigidBodyControl)
419 swivel
420 (.toRotationMatrix
421 (doto (Quaternion.)
422 (.fromAngleAxis (/ Math/PI 2)
423 Vector3f/UNIT_X)))]
424 (doto
425 (ConeJoint.
426 control-a control-b
427 (Vector3f. 0 5 0)
428 (Vector3f. 0 -5 0)
429 swivel swivel)
430 (.setLimit (* 0.6 (/ Math/PI 4))
431 (/ Math/PI 4)
432 (* Math/PI 0.8)))
433 (world (nodify
434 [obj-a obj-b])
435 standard-debug-controls
436 enable-debug
437 no-op)))
440 (defn bullet-trans* []
441 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red
442 :position (Vector3f. 5 0 0)
443 :mass 90)
444 obj-b (sphere 0.5 :color ColorRGBA/Blue
445 :position (Vector3f. -5 0 0)
446 :mass 0)
447 control-a (.getControl obj-a RigidBodyControl)
448 control-b (.getControl obj-b RigidBodyControl)
449 move-up? (atom nil)
450 move-down? (atom nil)
451 move-left? (atom nil)
452 move-right? (atom nil)
453 roll-left? (atom nil)
454 roll-right? (atom nil)
455 force 100
456 swivel
457 (.toRotationMatrix
458 (doto (Quaternion.)
459 (.fromAngleAxis (/ Math/PI 2)
460 Vector3f/UNIT_X)))
461 x-move
462 (doto (Matrix3f.)
463 (.fromStartEndVectors Vector3f/UNIT_X
464 (.normalize (Vector3f. 1 1 0))))
466 timer (atom 0)]
467 (doto
468 (ConeJoint.
469 control-a control-b
470 (Vector3f. -8 0 0)
471 (Vector3f. 2 0 0)
472 ;;swivel swivel
473 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY
474 x-move Matrix3f/IDENTITY
475 )
476 (.setCollisionBetweenLinkedBodys false)
477 (.setLimit (* 1 (/ Math/PI 4)) ;; twist
478 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane
479 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane
480 (world (nodify
481 [obj-a obj-b])
482 (merge standard-debug-controls
483 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
484 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
485 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
486 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
487 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
488 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
490 (fn [world]
491 (enable-debug world)
492 (set-gravity world Vector3f/ZERO)
493 )
495 (fn [world _]
497 (if @move-up?
498 (.applyForce control-a
499 (Vector3f. force 0 0)
500 (Vector3f. 0 0 0)))
501 (if @move-down?
502 (.applyForce control-a
503 (Vector3f. (- force) 0 0)
504 (Vector3f. 0 0 0)))
505 (if @move-left?
506 (.applyForce control-a
507 (Vector3f. 0 force 0)
508 (Vector3f. 0 0 0)))
509 (if @move-right?
510 (.applyForce control-a
511 (Vector3f. 0 (- force) 0)
512 (Vector3f. 0 0 0)))
514 (if @roll-left?
515 (.applyForce control-a
516 (Vector3f. 0 0 force)
517 (Vector3f. 0 0 0)))
518 (if @roll-right?
519 (.applyForce control-a
520 (Vector3f. 0 0 (- force))
521 (Vector3f. 0 0 0)))
523 (if (zero? (rem (swap! timer inc) 100))
524 (.attachChild
525 (.getRootNode world)
526 (sphere 0.05 :color ColorRGBA/Yellow
527 :physical? false :position
528 (.getWorldTranslation obj-a)))))
529 )
530 ))
534 #+end_src
537 * COMMENT generate source
538 #+begin_src clojure :tangle ../src/cortex/silly.clj
539 <<body-1>>
540 #+end_src