view org/test-creature.org @ 155:95bf55614211

moved goals and deleted old test
author Robert McIntyre <rlm@mit.edu>
date Fri, 03 Feb 2012 06:04:30 -0700
parents bb235258f835
children e8df6e76c3e5
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
12 * Intro
13 So far, I've made the following senses --
14 - Vision
15 - Hearing
16 - Touch
17 - Proprioception
19 And one effector:
20 - Movement
22 However, the code so far has only enabled these senses, but has not
23 actually implemented them. For example, there is still a lot of work
24 to be done for vision. I need to be able to create an /eyeball/ in
25 simulation that can be moved around and see the world from different
26 angles. I also need to determine weather to use log-polar or cartesian
27 for the visual input, and I need to determine how/wether to
28 disceritise the visual input.
30 I also want to be able to visualize both the sensors and the
31 effectors in pretty pictures. This semi-retarted creature will be my
32 first attempt at bringing everything together.
34 * The creature's body
36 Still going to do an eve-like body in blender, but due to problems
37 importing the joints, etc into jMonkeyEngine3, I'm going to do all
38 the connecting here in clojure code, using the names of the individual
39 components and trial and error. Later, I'll maybe make some sort of
40 creature-building modifications to blender that support whatever
41 discreitized senses I'm going to make.
43 #+name: body-1
44 #+begin_src clojure
45 (ns cortex.silly
46 "let's play!"
47 {:author "Robert McIntyre"})
49 ;; TODO remove this!
50 (require 'cortex.import)
51 (cortex.import/mega-import-jme3)
52 (use '(cortex world util body hearing touch vision sense))
54 (rlm.rlm-commands/help)
55 (import java.awt.image.BufferedImage)
56 (import javax.swing.JPanel)
57 (import javax.swing.SwingUtilities)
58 (import java.awt.Dimension)
59 (import javax.swing.JFrame)
60 (import java.awt.Dimension)
61 (import com.aurellem.capture.RatchetTimer)
62 (declare joint-create)
63 (use 'clojure.contrib.def)
65 (defn load-blender-model
66 "Load a .blend file using an asset folder relative path."
67 [^String model]
68 (.loadModel
69 (doto (asset-manager)
70 (.registerLoader BlenderModelLoader (into-array String ["blend"])))
71 model))
73 (defn blender-to-jme
74 "Convert from Blender coordinates to JME coordinates"
75 [#^Vector3f in]
76 (Vector3f. (.getX in)
77 (.getZ in)
78 (- (.getY in))))
80 (defn world-to-local
81 "Convert the world coordinates into coordinates relative to the
82 object (i.e. local coordinates), taking into account the rotation
83 of object."
84 [#^Spatial object world-coordinate]
85 (.worldToLocal object world-coordinate nil))
87 (defn local-to-world
88 "Convert the local coordinates into coordinates into world relative
89 coordinates"
90 [#^Spatial object local-coordinate]
91 (.localToWorld object local-coordinate nil))
93 (defmulti joint-dispatch
94 "Translate blender pseudo-joints into real JME joints."
95 (fn [constraints & _]
96 (:type constraints)))
98 (defmethod joint-dispatch :point
99 [constraints control-a control-b pivot-a pivot-b rotation]
100 (println-repl "creating POINT2POINT joint")
101 ;; bullet's point2point joints are BROKEN, so we must use the
102 ;; generic 6DOF joint instead of an actual Point2Point joint!
104 ;; should be able to do this:
105 (comment
106 (Point2PointJoint.
107 control-a
108 control-b
109 pivot-a
110 pivot-b))
112 ;; but instead we must do this:
113 (println-repl "substuting 6DOF joint for POINT2POINT joint!")
114 (doto
115 (SixDofJoint.
116 control-a
117 control-b
118 pivot-a
119 pivot-b
120 false)
121 (.setLinearLowerLimit Vector3f/ZERO)
122 (.setLinearUpperLimit Vector3f/ZERO)
123 ;;(.setAngularLowerLimit (Vector3f. 1 1 1))
124 ;;(.setAngularUpperLimit (Vector3f. 0 0 0))
126 ))
129 (defmethod joint-dispatch :hinge
130 [constraints control-a control-b pivot-a pivot-b rotation]
131 (println-repl "creating HINGE joint")
132 (let [axis
133 (if-let
134 [axis (:axis constraints)]
135 axis
136 Vector3f/UNIT_X)
137 [limit-1 limit-2] (:limit constraints)
138 hinge-axis
139 (.mult
140 rotation
141 (blender-to-jme axis))]
142 (doto
143 (HingeJoint.
144 control-a
145 control-b
146 pivot-a
147 pivot-b
148 hinge-axis
149 hinge-axis)
150 (.setLimit limit-1 limit-2))))
152 (defmethod joint-dispatch :cone
153 [constraints control-a control-b pivot-a pivot-b rotation]
154 (let [limit-xz (:limit-xz constraints)
155 limit-xy (:limit-xy constraints)
156 twist (:twist constraints)]
158 (println-repl "creating CONE joint")
159 (println-repl rotation)
160 (println-repl
161 "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0)))
162 (println-repl
163 "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0)))
164 (println-repl
165 "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1)))
166 (doto
167 (ConeJoint.
168 control-a
169 control-b
170 pivot-a
171 pivot-b
172 rotation
173 rotation)
174 (.setLimit (float limit-xz)
175 (float limit-xy)
176 (float twist)))))
178 (defn connect
179 "here are some examples:
180 {:type :point}
181 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}
182 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)
184 {:type :cone :limit-xz 0]
185 :limit-xy 0]
186 :twist 0]} (use XZY rotation mode in blender!)"
187 [#^Node obj-a #^Node obj-b #^Node joint]
188 (let [control-a (.getControl obj-a RigidBodyControl)
189 control-b (.getControl obj-b RigidBodyControl)
190 joint-center (.getWorldTranslation joint)
191 joint-rotation (.toRotationMatrix (.getWorldRotation joint))
192 pivot-a (world-to-local obj-a joint-center)
193 pivot-b (world-to-local obj-b joint-center)]
195 (if-let [constraints
196 (map-vals
197 eval
198 (read-string
199 (meta-data joint "joint")))]
200 ;; A side-effect of creating a joint registers
201 ;; it with both physics objects which in turn
202 ;; will register the joint with the physics system
203 ;; when the simulation is started.
204 (do
205 (println-repl "creating joint between"
206 (.getName obj-a) "and" (.getName obj-b))
207 (joint-dispatch constraints
208 control-a control-b
209 pivot-a pivot-b
210 joint-rotation))
211 (println-repl "could not find joint meta-data!"))))
216 (defn assemble-creature [#^Node pieces joints]
217 (dorun
218 (map
219 (fn [geom]
220 (let [physics-control
221 (RigidBodyControl.
222 (HullCollisionShape.
223 (.getMesh geom))
224 (if-let [mass (meta-data geom "mass")]
225 (do
226 (println-repl
227 "setting" (.getName geom) "mass to" (float mass))
228 (float mass))
229 (float 1)))]
231 (.addControl geom physics-control)))
232 (filter #(isa? (class %) Geometry )
233 (node-seq pieces))))
234 (dorun
235 (map
236 (fn [joint]
237 (let [[obj-a obj-b] (joint-targets pieces joint)]
238 (connect obj-a obj-b joint)))
239 joints))
240 pieces)
242 (declare blender-creature)
244 (def hand "Models/creature1/one.blend")
246 (def worm "Models/creature1/try-again.blend")
248 (def touch "Models/creature1/touch.blend")
250 (defn worm-model [] (load-blender-model worm))
252 (defn x-ray [#^ColorRGBA color]
253 (doto (Material. (asset-manager)
254 "Common/MatDefs/Misc/Unshaded.j3md")
255 (.setColor "Color" color)
256 (-> (.getAdditionalRenderState)
257 (.setDepthTest false))))
259 (defn colorful []
260 (.getChild (worm-model) "worm-21"))
262 (import jme3tools.converters.ImageToAwt)
264 (import ij.ImagePlus)
266 ;; Every Mesh has many triangles, each with its own index.
267 ;; Every vertex has its own index as well.
269 (defn tactile-sensor-image
270 "Return the touch-sensor distribution image in BufferedImage format,
271 or nil if it does not exist."
272 [#^Geometry obj]
273 (if-let [image-path (meta-data obj "touch")]
274 (ImageToAwt/convert
275 (.getImage
276 (.loadTexture
277 (asset-manager)
278 image-path))
279 false false 0)))
283 (defn triangle
284 "Get the triangle specified by triangle-index from the mesh within
285 bounds."
286 [#^Mesh mesh triangle-index]
287 (let [scratch (Triangle.)]
288 (.getTriangle mesh triangle-index scratch)
289 scratch))
291 (defn triangle-vertex-indices
292 "Get the triangle vertex indices of a given triangle from a given
293 mesh."
294 [#^Mesh mesh triangle-index]
295 (let [indices (int-array 3)]
296 (.getTriangle mesh triangle-index indices)
297 (vec indices)))
299 (defn vertex-UV-coord
300 "Get the uv-coordinates of the vertex named by vertex-index"
301 [#^Mesh mesh vertex-index]
302 (let [UV-buffer
303 (.getData
304 (.getBuffer
305 mesh
306 VertexBuffer$Type/TexCoord))]
307 [(.get UV-buffer (* vertex-index 2))
308 (.get UV-buffer (+ 1 (* vertex-index 2)))]))
310 (defn triangle-UV-coord
311 "Get the uv-cooridnates of the triangle's verticies."
312 [#^Mesh mesh width height triangle-index]
313 (map (fn [[u v]] (vector (* width u) (* height v)))
314 (map (partial vertex-UV-coord mesh)
315 (triangle-vertex-indices mesh triangle-index))))
317 (defn same-side?
318 "Given the points p1 and p2 and the reference point ref, is point p
319 on the same side of the line that goes through p1 and p2 as ref is?"
320 [p1 p2 ref p]
321 (<=
322 0
323 (.dot
324 (.cross (.subtract p2 p1) (.subtract p p1))
325 (.cross (.subtract p2 p1) (.subtract ref p1)))))
327 (defn triangle-seq [#^Triangle tri]
328 [(.get1 tri) (.get2 tri) (.get3 tri)])
330 (defn vector3f-seq [#^Vector3f v]
331 [(.getX v) (.getY v) (.getZ v)])
333 (defn inside-triangle?
334 "Is the point inside the triangle?"
335 {:author "Dylan Holmes"}
336 [#^Triangle tri #^Vector3f p]
337 (let [[vert-1 vert-2 vert-3] (triangle-seq tri)]
338 (and
339 (same-side? vert-1 vert-2 vert-3 p)
340 (same-side? vert-2 vert-3 vert-1 p)
341 (same-side? vert-3 vert-1 vert-2 p))))
343 (defn triangle->matrix4f
344 "Converts the triangle into a 4x4 matrix: The first three columns
345 contain the vertices of the triangle; the last contains the unit
346 normal of the triangle. The bottom row is filled with 1s."
347 [#^Triangle t]
348 (let [mat (Matrix4f.)
349 [vert-1 vert-2 vert-3]
350 ((comp vec map) #(.get t %) (range 3))
351 unit-normal (do (.calculateNormal t)(.getNormal t))
352 vertices [vert-1 vert-2 vert-3 unit-normal]]
353 (dorun
354 (for [row (range 4) col (range 3)]
355 (do
356 (.set mat col row (.get (vertices row)col))
357 (.set mat 3 row 1))))
358 mat))
360 (defn triangle-transformation
361 "Returns the affine transformation that converts each vertex in the
362 first triangle into the corresponding vertex in the second
363 triangle."
364 [#^Triangle tri-1 #^Triangle tri-2]
365 (.mult
366 (triangle->matrix4f tri-2)
367 (.invert (triangle->matrix4f tri-1))))
369 (defn point->vector2f [[u v]]
370 (Vector2f. u v))
372 (defn vector2f->vector3f [v]
373 (Vector3f. (.getX v) (.getY v) 0))
375 (defn map-triangle [f #^Triangle tri]
376 (Triangle.
377 (f 0 (.get1 tri))
378 (f 1 (.get2 tri))
379 (f 2 (.get3 tri))))
381 (defn points->triangle
382 "Convert a list of points into a triangle."
383 [points]
384 (apply #(Triangle. %1 %2 %3)
385 (map (fn [point]
386 (let [point (vec point)]
387 (Vector3f. (get point 0 0)
388 (get point 1 0)
389 (get point 2 0))))
390 (take 3 points))))
392 (defn convex-bounds
393 ;;dylan
394 "Returns the smallest square containing the given
395 vertices, as a vector of integers [left top width height]."
396 ;; "Dimensions of the smallest integer bounding square of the list of
397 ;; 2D verticies in the form: [x y width height]."
398 [uv-verts]
399 (let [xs (map first uv-verts)
400 ys (map second uv-verts)
401 x0 (Math/floor (apply min xs))
402 y0 (Math/floor (apply min ys))
403 x1 (Math/ceil (apply max xs))
404 y1 (Math/ceil (apply max ys))]
405 [x0 y0 (- x1 x0) (- y1 y0)]))
407 (defn sensors-in-triangle
408 ;;dylan
409 "Locate the touch sensors in the triangle, returning a map of their UV and geometry-relative coordinates."
410 ;;"Find the locations of the touch sensors within a triangle in both
411 ;; UV and gemoetry relative coordinates."
412 [image mesh tri-index]
413 (let [width (.getWidth image)
414 height (.getHeight image)
415 UV-vertex-coords (triangle-UV-coord mesh width height tri-index)
416 bounds (convex-bounds UV-vertex-coords)
418 cutout-triangle (points->triangle UV-vertex-coords)
419 UV-sensor-coords
420 (filter (comp (partial inside-triangle? cutout-triangle)
421 (fn [[u v]] (Vector3f. u v 0)))
422 (white-coordinates image bounds))
423 UV->geometry (triangle-transformation
424 cutout-triangle
425 (triangle mesh tri-index))
426 geometry-sensor-coords
427 (map (fn [[u v]] (.mult UV->geometry (Vector3f. u v 0)))
428 UV-sensor-coords)]
429 {:UV UV-sensor-coords :geometry geometry-sensor-coords}))
431 (defn-memo locate-feelers
432 "Search the geometry's tactile UV image for touch sensors, returning
433 their positions in geometry-relative coordinates."
434 [#^Geometry geo]
435 (let [mesh (.getMesh geo)
436 num-triangles (.getTriangleCount mesh)]
437 (if-let [image (tactile-sensor-image geo)]
438 (map
439 (partial sensors-in-triangle image mesh)
440 (range num-triangles))
441 (repeat (.getTriangleCount mesh) {:UV nil :geometry nil}))))
443 (use 'clojure.contrib.def)
445 (defn-memo touch-topology [#^Gemoetry geo]
446 (vec (collapse (reduce concat (map :UV (locate-feelers geo))))))
448 (defn-memo feeler-coordinates [#^Geometry geo]
449 (vec (map :geometry (locate-feelers geo))))
451 (defn enable-touch [#^Geometry geo]
452 (let [feeler-coords (feeler-coordinates geo)
453 tris (triangles geo)
454 limit 0.1
455 ;;results (CollisionResults.)
456 ]
457 (if (empty? (touch-topology geo))
458 nil
459 (fn [node]
460 (let [sensor-origins
461 (map
462 #(map (partial local-to-world geo) %)
463 feeler-coords)
464 triangle-normals
465 (map (partial get-ray-direction geo)
466 tris)
467 rays
468 (flatten
469 (map (fn [origins norm]
470 (map #(doto (Ray. % norm)
471 (.setLimit limit)) origins))
472 sensor-origins triangle-normals))]
473 (vector
474 (touch-topology geo)
475 (vec
476 (for [ray rays]
477 (do
478 (let [results (CollisionResults.)]
479 (.collideWith node ray results)
480 (let [touch-objects
481 (filter #(not (= geo (.getGeometry %)))
482 results)]
483 (- 255
484 (if (empty? touch-objects) 255
485 (rem
486 (int
487 (* 255 (/ (.getDistance
488 (first touch-objects)) limit)))
489 256))))))))))))))
492 (defn touch [#^Node pieces]
493 (filter (comp not nil?)
494 (map enable-touch
495 (filter #(isa? (class %) Geometry)
496 (node-seq pieces)))))
499 (defn test-eye []
500 (.getChild
501 (.getChild (worm-model) "eyes")
502 "eye"))
506 ;; Ears work the same way as vision.
508 ;; (hearing creature) will return [init-functions
509 ;; sensor-functions]. The init functions each take the world and
510 ;; register a SoundProcessor that does foureier transforms on the
511 ;; incommong sound data, making it available to each sensor function.
513 (defn creature-ears
514 "Return the children of the creature's \"ears\" node."
515 ;;dylan
516 ;;"The ear nodes which are children of the \"ears\" node in the
517 ;;creature."
518 [#^Node creature]
519 (if-let [ear-node (.getChild creature "ears")]
520 (seq (.getChildren ear-node))
521 (do (println-repl "could not find ears node") [])))
524 ;;dylan (defn follow-sense, adjoin-sense, attach-stimuli,
525 ;;anchor-qualia, augment-organ, with-organ
528 (defn update-listener-velocity
529 "Update the listener's velocity every update loop."
530 [#^Spatial obj #^Listener lis]
531 (let [old-position (atom (.getLocation lis))]
532 (.addControl
533 obj
534 (proxy [AbstractControl] []
535 (controlUpdate [tpf]
536 (let [new-position (.getLocation lis)]
537 (.setVelocity
538 lis
539 (.mult (.subtract new-position @old-position)
540 (float (/ tpf))))
541 (reset! old-position new-position)))
542 (controlRender [_ _])))))
544 (import com.aurellem.capture.audio.AudioSendRenderer)
546 (defn attach-ear
547 [#^Application world #^Node creature #^Spatial ear continuation]
548 (let [target (closest-node creature ear)
549 lis (Listener.)
550 audio-renderer (.getAudioRenderer world)
551 sp (sound-processor continuation)]
552 (.setLocation lis (.getWorldTranslation ear))
553 (.setRotation lis (.getWorldRotation ear))
554 (bind-sense target lis)
555 (update-listener-velocity target lis)
556 (.addListener audio-renderer lis)
557 (.registerSoundProcessor audio-renderer lis sp)))
559 (defn enable-hearing
560 [#^Node creature #^Spatial ear]
561 (let [hearing-data (atom [])]
562 [(fn [world]
563 (attach-ear world creature ear
564 (fn [data]
565 (reset! hearing-data (vec data)))))
566 [(fn []
567 (let [data @hearing-data
568 topology
569 (vec (map #(vector % 0) (range 0 (count data))))
570 scaled-data
571 (vec
572 (map
573 #(rem (int (* 255 (/ (+ 1 %) 2))) 256)
574 data))]
575 [topology scaled-data]))
576 ]]))
578 (defn hearing
579 [#^Node creature]
580 (reduce
581 (fn [[init-a senses-a]
582 [init-b senses-b]]
583 [(conj init-a init-b)
584 (into senses-a senses-b)])
585 [[][]]
586 (for [ear (creature-ears creature)]
587 (enable-hearing creature ear))))
594 ;; lower level --- nodes
595 ;; closest-node "parse/compile-x" -> makes organ, which is spatial, fn pair
597 ;; higher level -- organs
598 ;;
600 ;; higher level --- sense/effector
601 ;; these are the functions that provide world i/o, chinese-room style
606 (defn blender-creature
607 "Return a creature with all joints in place."
608 [blender-path]
609 (let [model (load-blender-model blender-path)
610 joints (creature-joints model)]
611 (assemble-creature model joints)))
613 (defn gray-scale [num]
614 (+ num
615 (bit-shift-left num 8)
616 (bit-shift-left num 16)))
618 (defn debug-touch-window
619 "creates function that offers a debug view of sensor data"
620 []
621 (let [vi (view-image)]
622 (fn
623 [[coords sensor-data]]
624 (let [image (points->image coords)]
625 (dorun
626 (for [i (range (count coords))]
627 (.setRGB image ((coords i) 0) ((coords i) 1)
628 (gray-scale (sensor-data i)))))
631 (vi image)))))
633 (defn debug-vision-window
634 "creates function that offers a debug view of sensor data"
635 []
636 (let [vi (view-image)]
637 (fn
638 [[coords sensor-data]]
639 (let [image (points->image coords)]
640 (dorun
641 (for [i (range (count coords))]
642 (.setRGB image ((coords i) 0) ((coords i) 1)
643 (sensor-data i))))
644 (vi image)))))
646 (defn debug-hearing-window
647 "view audio data"
648 [height]
649 (let [vi (view-image)]
650 (fn [[coords sensor-data]]
651 (let [image (BufferedImage. (count coords) height
652 BufferedImage/TYPE_INT_RGB)]
653 (dorun
654 (for [x (range (count coords))]
655 (dorun
656 (for [y (range height)]
657 (let [raw-sensor (sensor-data x)]
658 (.setRGB image x y (gray-scale raw-sensor)))))))
660 (vi image)))))
664 ;;(defn test-touch [world creature]
669 ;; here's how motor-control/ proprioception will work: Each muscle is
670 ;; defined by a 1-D array of numbers (the "motor pool") each of which
671 ;; represent muscle fibers. A muscle also has a scalar :strength
672 ;; factor which determines how strong the muscle as a whole is.
673 ;; The effector function for a muscle takes a number < (count
674 ;; motor-pool) and that number is said to "activate" all the muscle
675 ;; fibers whose index is lower than the number. Each fiber will apply
676 ;; force in proportion to its value in the array. Lower values cause
677 ;; less force. The lower values can be put at the "beginning" of the
678 ;; 1-D array to simulate the layout of actual human muscles, which are
679 ;; capable of more percise movements when exerting less force.
681 ;; I don't know how to encode proprioception, so for now, just return
682 ;; a function for each joint that returns a triplet of floats which
683 ;; represent relative roll, pitch, and yaw. Write display code for
684 ;; this though.
686 (defn muscle-fiber-values
687 "get motor pool strengths"
688 [#^BufferedImage image]
689 (vec
690 (let [width (.getWidth image)]
691 (for [x (range width)]
692 (- 255
693 (bit-and
694 0x0000FF
695 (.getRGB image x 0)))))))
698 (defn creature-muscles
699 "Return the children of the creature's \"muscles\" node."
700 [#^Node creature]
701 (if-let [muscle-node (.getChild creature "muscles")]
702 (seq (.getChildren muscle-node))
703 (do (println-repl "could not find muscles node") [])))
705 (defn single-muscle [#^Node parts #^Node muscle]
706 (let [target (closest-node parts muscle)
707 axis
708 (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y)
709 strength (meta-data muscle "strength")
710 image-name (read-string (meta-data muscle "muscle"))
711 image
712 (ImageToAwt/convert
713 (.getImage (.loadTexture (asset-manager) image-name))
714 false false 0)
715 fibers (muscle-fiber-values image)
716 fiber-integral (reductions + fibers)
717 force-index (vec
718 (map
719 #(float (* strength (/ % (last
720 fiber-integral))))
721 fiber-integral))
722 control (.getControl target RigidBodyControl)]
723 (fn [n]
724 (let [pool-index (min n (count fibers))]
725 (.applyTorque control (.mult axis (force-index n)))))))
728 (defn enable-muscles
729 "Must be called on a creature after RigidBodyControls have been
730 created."
731 [#^Node creature]
732 (let [muscles (creature-muscles creature)]
733 (for [muscle muscles]
734 (single-muscle creature muscle))))
736 (defn test-creature [thing]
737 (let [x-axis
738 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)
739 y-axis
740 (box 0.01 1 0.01 :physical? false :color ColorRGBA/Green)
741 z-axis
742 (box 0.01 0.01 1 :physical? false :color ColorRGBA/Blue)
743 creature (blender-creature thing)
744 touch-nerves (touch creature)
745 touch-debug-windows (map (fn [_] (debug-touch-window)) touch-nerves)
746 [init-vision-fns vision-data] (vision creature)
747 vision-debug (map (fn [_] (debug-vision-window)) vision-data)
748 me (sphere 0.5 :color ColorRGBA/Blue :physical? false)
749 [init-hearing-fns hearing-senses] (hearing creature)
750 hearing-windows (map (fn [_] (debug-hearing-window 50))
751 hearing-senses)
752 bell (AudioNode. (asset-manager)
753 "Sounds/pure.wav" false)
754 prop (proprioception creature)
755 prop-debug (proprioception-debug-window)
757 muscle-fns (enable-muscles creature)
758 ;; dream
760 ]
763 (apply
764 world
765 (with-movement
766 (.getChild creature "worm-21")
767 ["key-r" "key-t"
768 "key-f" "key-g"
769 "key-v" "key-b"]
770 [10 10 10 10 1 1]
771 [(nodify [creature
772 (box 10 2 10 :position (Vector3f. 0 -9 0)
773 :color ColorRGBA/Gray :mass 0)
774 x-axis y-axis z-axis
775 me
776 ])
777 (merge standard-debug-controls
778 {"key-return"
779 (fn [_ value]
780 (if value
781 (do
782 (println-repl "play-sound")
783 (.play bell))))
784 "key-h"
785 (fn [_ value]
786 (if value
787 (do
788 (println-repl "muscle activating!")
789 ((first muscle-fns) 199))))
791 })
792 (fn [world]
793 (light-up-everything world)
794 (enable-debug world)
795 (dorun (map #(% world) init-vision-fns))
796 (dorun (map #(% world) init-hearing-fns))
798 (add-eye world
799 (attach-eye creature (test-eye))
800 (comp (view-image) BufferedImage!))
802 (add-eye world (.getCamera world) no-op)
803 ;;(set-gravity world (Vector3f. 0 0 0))
804 ;;(com.aurellem.capture.Capture/captureVideo
805 ;; world (file-str "/home/r/proj/ai-videos/hand"))
806 ;;(.setTimer world (RatchetTimer. 60))
807 (speed-up world)
808 (set-gravity world (Vector3f. 0 0 0))
809 )
810 (fn [world tpf]
811 ;;(dorun
812 ;; (map #(%1 %2) touch-nerves (repeat (.getRootNode world))))
814 (prop-debug (prop))
816 (dorun
817 (map #(%1 (%2 (.getRootNode world)))
818 touch-debug-windows touch-nerves))
820 (dorun
821 (map #(%1 (%2))
822 vision-debug vision-data))
823 (dorun
824 (map #(%1 (%2)) hearing-windows hearing-senses))
827 ;;(println-repl (vision-data))
828 (.setLocalTranslation me (.getLocation (.getCamera world)))
831 )]
832 ;;(let [timer (atom 0)]
833 ;; (fn [_ _]
834 ;; (swap! timer inc)
835 ;; (if (= (rem @timer 60) 0)
836 ;; (println-repl (float (/ @timer 60))))))
837 ))))
841 ;; the camera will stay in its initial position/rotation with relation
842 ;; to the spatial.
845 (defn follow-test
846 "show a camera that stays in the same relative position to a blue cube."
847 []
848 (let [camera-pos (Vector3f. 0 30 0)
849 rock (box 1 1 1 :color ColorRGBA/Blue
850 :position (Vector3f. 0 10 0)
851 :mass 30
852 )
853 rot (.getWorldRotation rock)
855 table (box 3 1 10 :color ColorRGBA/Gray :mass 0
856 :position (Vector3f. 0 -3 0))]
858 (world
859 (nodify [rock table])
860 standard-debug-controls
861 (fn [world]
862 (let
863 [cam (doto (.clone (.getCamera world))
864 (.setLocation camera-pos)
865 (.lookAt Vector3f/ZERO
866 Vector3f/UNIT_X))]
867 (bind-sense rock cam)
869 (.setTimer world (RatchetTimer. 60))
870 (add-eye world cam (comp (view-image) BufferedImage!))
871 (add-eye world (.getCamera world) no-op))
872 )
873 (fn [_ _] (println-repl rot)))))
877 #+end_src
879 #+results: body-1
880 : #'cortex.silly/follow-test
883 * COMMENT purgatory
884 #+begin_src clojure
886 (defn bullet-trans* []
887 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red
888 :position (Vector3f. 5 0 0)
889 :mass 90)
890 obj-b (sphere 0.5 :color ColorRGBA/Blue
891 :position (Vector3f. -5 0 0)
892 :mass 0)
893 control-a (.getControl obj-a RigidBodyControl)
894 control-b (.getControl obj-b RigidBodyControl)
895 move-up? (atom nil)
896 move-down? (atom nil)
897 move-left? (atom nil)
898 move-right? (atom nil)
899 roll-left? (atom nil)
900 roll-right? (atom nil)
901 force 100
902 swivel
903 (.toRotationMatrix
904 (doto (Quaternion.)
905 (.fromAngleAxis (/ Math/PI 2)
906 Vector3f/UNIT_X)))
907 x-move
908 (doto (Matrix3f.)
909 (.fromStartEndVectors Vector3f/UNIT_X
910 (.normalize (Vector3f. 1 1 0))))
912 timer (atom 0)]
913 (doto
914 (ConeJoint.
915 control-a control-b
916 (Vector3f. -8 0 0)
917 (Vector3f. 2 0 0)
918 ;;swivel swivel
919 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY
920 x-move Matrix3f/IDENTITY
921 )
922 (.setCollisionBetweenLinkedBodys false)
923 (.setLimit (* 1 (/ Math/PI 4)) ;; twist
924 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane
925 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane
926 (world (nodify
927 [obj-a obj-b])
928 (merge standard-debug-controls
929 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
930 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
931 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
932 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
933 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
934 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
936 (fn [world]
937 (enable-debug world)
938 (set-gravity world Vector3f/ZERO)
939 )
941 (fn [world _]
943 (if @move-up?
944 (.applyForce control-a
945 (Vector3f. force 0 0)
946 (Vector3f. 0 0 0)))
947 (if @move-down?
948 (.applyForce control-a
949 (Vector3f. (- force) 0 0)
950 (Vector3f. 0 0 0)))
951 (if @move-left?
952 (.applyForce control-a
953 (Vector3f. 0 force 0)
954 (Vector3f. 0 0 0)))
955 (if @move-right?
956 (.applyForce control-a
957 (Vector3f. 0 (- force) 0)
958 (Vector3f. 0 0 0)))
960 (if @roll-left?
961 (.applyForce control-a
962 (Vector3f. 0 0 force)
963 (Vector3f. 0 0 0)))
964 (if @roll-right?
965 (.applyForce control-a
966 (Vector3f. 0 0 (- force))
967 (Vector3f. 0 0 0)))
969 (if (zero? (rem (swap! timer inc) 100))
970 (.attachChild
971 (.getRootNode world)
972 (sphere 0.05 :color ColorRGBA/Yellow
973 :physical? false :position
974 (.getWorldTranslation obj-a)))))
975 )
976 ))
978 (defn test-joint [joint]
979 (let [[origin top bottom floor] (world-setup joint)
980 control (.getControl top RigidBodyControl)
981 move-up? (atom false)
982 move-down? (atom false)
983 move-left? (atom false)
984 move-right? (atom false)
985 roll-left? (atom false)
986 roll-right? (atom false)
987 timer (atom 0)]
989 (world
990 (nodify [top bottom floor origin])
991 (merge standard-debug-controls
992 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
993 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
994 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
995 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
996 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
997 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
999 (fn [world]
1000 (light-up-everything world)
1001 (enable-debug world)
1002 (set-gravity world (Vector3f. 0 0 0))
1005 (fn [world _]
1006 (if (zero? (rem (swap! timer inc) 100))
1007 (do
1008 ;; (println-repl @timer)
1009 (.attachChild (.getRootNode world)
1010 (sphere 0.05 :color ColorRGBA/Yellow
1011 :position (.getWorldTranslation top)
1012 :physical? false))
1013 (.attachChild (.getRootNode world)
1014 (sphere 0.05 :color ColorRGBA/LightGray
1015 :position (.getWorldTranslation bottom)
1016 :physical? false))))
1018 (if @move-up?
1019 (.applyTorque control
1020 (.mult (.getPhysicsRotation control)
1021 (Vector3f. 0 0 10))))
1022 (if @move-down?
1023 (.applyTorque control
1024 (.mult (.getPhysicsRotation control)
1025 (Vector3f. 0 0 -10))))
1026 (if @move-left?
1027 (.applyTorque control
1028 (.mult (.getPhysicsRotation control)
1029 (Vector3f. 0 10 0))))
1030 (if @move-right?
1031 (.applyTorque control
1032 (.mult (.getPhysicsRotation control)
1033 (Vector3f. 0 -10 0))))
1034 (if @roll-left?
1035 (.applyTorque control
1036 (.mult (.getPhysicsRotation control)
1037 (Vector3f. -1 0 0))))
1038 (if @roll-right?
1039 (.applyTorque control
1040 (.mult (.getPhysicsRotation control)
1041 (Vector3f. 1 0 0))))))))
1042 #+end_src
1045 * COMMENT generate source
1046 #+begin_src clojure :tangle ../src/cortex/silly.clj
1047 <<body-1>>
1048 #+end_src