Mercurial > cortex
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 McIntyre3 #+email: rlm@mit.edu4 #+description:5 #+keywords: simulation, jMonkeyEngine3, clojure6 #+SETUPFILE: ../../aurellem/org/setup.org7 #+INCLUDE: ../../aurellem/org/level-0.org12 * Intro13 So far, I've made the following senses --14 - Vision15 - Hearing16 - Touch17 - Proprioception19 And one effector:20 - Movement22 However, the code so far has only enabled these senses, but has not23 actually implemented them. For example, there is still a lot of work24 to be done for vision. I need to be able to create an /eyeball/ in25 simulation that can be moved around and see the world from different26 angles. I also need to determine weather to use log-polar or cartesian27 for the visual input, and I need to determine how/wether to28 disceritise the visual input.30 I also want to be able to visualize both the sensors and the31 effectors in pretty pictures. This semi-retarted creature will be my32 first attempt at bringing everything together.34 * The creature's body36 Still going to do an eve-like body in blender, but due to problems37 importing the joints, etc into jMonkeyEngine3, I'm going to do all38 the connecting here in clojure code, using the names of the individual39 components and trial and error. Later, I'll maybe make some sort of40 creature-building modifications to blender that support whatever41 discreitized senses I'm going to make.43 #+name: body-144 #+begin_src clojure45 (ns cortex.silly46 "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-model66 "Load a .blend file using an asset folder relative path."67 [^String model]68 (.loadModel69 (doto (asset-manager)70 (.registerLoader BlenderModelLoader (into-array String ["blend"])))71 model))73 (defn blender-to-jme74 "Convert from Blender coordinates to JME coordinates"75 [#^Vector3f in]76 (Vector3f. (.getX in)77 (.getZ in)78 (- (.getY in))))80 (defn world-to-local81 "Convert the world coordinates into coordinates relative to the82 object (i.e. local coordinates), taking into account the rotation83 of object."84 [#^Spatial object world-coordinate]85 (.worldToLocal object world-coordinate nil))87 (defn local-to-world88 "Convert the local coordinates into coordinates into world relative89 coordinates"90 [#^Spatial object local-coordinate]91 (.localToWorld object local-coordinate nil))93 (defmulti joint-dispatch94 "Translate blender pseudo-joints into real JME joints."95 (fn [constraints & _]96 (:type constraints)))98 (defmethod joint-dispatch :point99 [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 the102 ;; generic 6DOF joint instead of an actual Point2Point joint!104 ;; should be able to do this:105 (comment106 (Point2PointJoint.107 control-a108 control-b109 pivot-a110 pivot-b))112 ;; but instead we must do this:113 (println-repl "substuting 6DOF joint for POINT2POINT joint!")114 (doto115 (SixDofJoint.116 control-a117 control-b118 pivot-a119 pivot-b120 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 :hinge130 [constraints control-a control-b pivot-a pivot-b rotation]131 (println-repl "creating HINGE joint")132 (let [axis133 (if-let134 [axis (:axis constraints)]135 axis136 Vector3f/UNIT_X)137 [limit-1 limit-2] (:limit constraints)138 hinge-axis139 (.mult140 rotation141 (blender-to-jme axis))]142 (doto143 (HingeJoint.144 control-a145 control-b146 pivot-a147 pivot-b148 hinge-axis149 hinge-axis)150 (.setLimit limit-1 limit-2))))152 (defmethod joint-dispatch :cone153 [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-repl161 "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0)))162 (println-repl163 "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0)))164 (println-repl165 "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1)))166 (doto167 (ConeJoint.168 control-a169 control-b170 pivot-a171 pivot-b172 rotation173 rotation)174 (.setLimit (float limit-xz)175 (float limit-xy)176 (float twist)))))178 (defn connect179 "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 [constraints196 (map-vals197 eval198 (read-string199 (meta-data joint "joint")))]200 ;; A side-effect of creating a joint registers201 ;; it with both physics objects which in turn202 ;; will register the joint with the physics system203 ;; when the simulation is started.204 (do205 (println-repl "creating joint between"206 (.getName obj-a) "and" (.getName obj-b))207 (joint-dispatch constraints208 control-a control-b209 pivot-a pivot-b210 joint-rotation))211 (println-repl "could not find joint meta-data!"))))216 (defn assemble-creature [#^Node pieces joints]217 (dorun218 (map219 (fn [geom]220 (let [physics-control221 (RigidBodyControl.222 (HullCollisionShape.223 (.getMesh geom))224 (if-let [mass (meta-data geom "mass")]225 (do226 (println-repl227 "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 (dorun235 (map236 (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-image270 "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/convert275 (.getImage276 (.loadTexture277 (asset-manager)278 image-path))279 false false 0)))283 (defn triangle284 "Get the triangle specified by triangle-index from the mesh within285 bounds."286 [#^Mesh mesh triangle-index]287 (let [scratch (Triangle.)]288 (.getTriangle mesh triangle-index scratch)289 scratch))291 (defn triangle-vertex-indices292 "Get the triangle vertex indices of a given triangle from a given293 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-coord300 "Get the uv-coordinates of the vertex named by vertex-index"301 [#^Mesh mesh vertex-index]302 (let [UV-buffer303 (.getData304 (.getBuffer305 mesh306 VertexBuffer$Type/TexCoord))]307 [(.get UV-buffer (* vertex-index 2))308 (.get UV-buffer (+ 1 (* vertex-index 2)))]))310 (defn triangle-UV-coord311 "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 p319 on the same side of the line that goes through p1 and p2 as ref is?"320 [p1 p2 ref p]321 (<=322 0323 (.dot324 (.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 (and339 (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->matrix4f344 "Converts the triangle into a 4x4 matrix: The first three columns345 contain the vertices of the triangle; the last contains the unit346 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 (dorun354 (for [row (range 4) col (range 3)]355 (do356 (.set mat col row (.get (vertices row)col))357 (.set mat 3 row 1))))358 mat))360 (defn triangle-transformation361 "Returns the affine transformation that converts each vertex in the362 first triangle into the corresponding vertex in the second363 triangle."364 [#^Triangle tri-1 #^Triangle tri-2]365 (.mult366 (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->triangle382 "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-bounds393 ;;dylan394 "Returns the smallest square containing the given395 vertices, as a vector of integers [left top width height]."396 ;; "Dimensions of the smallest integer bounding square of the list of397 ;; 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-triangle408 ;;dylan409 "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 both411 ;; 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-coords420 (filter (comp (partial inside-triangle? cutout-triangle)421 (fn [[u v]] (Vector3f. u v 0)))422 (white-coordinates image bounds))423 UV->geometry (triangle-transformation424 cutout-triangle425 (triangle mesh tri-index))426 geometry-sensor-coords427 (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-feelers432 "Search the geometry's tactile UV image for touch sensors, returning433 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 (map439 (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.1455 ;;results (CollisionResults.)456 ]457 (if (empty? (touch-topology geo))458 nil459 (fn [node]460 (let [sensor-origins461 (map462 #(map (partial local-to-world geo) %)463 feeler-coords)464 triangle-normals465 (map (partial get-ray-direction geo)466 tris)467 rays468 (flatten469 (map (fn [origins norm]470 (map #(doto (Ray. % norm)471 (.setLimit limit)) origins))472 sensor-origins triangle-normals))]473 (vector474 (touch-topology geo)475 (vec476 (for [ray rays]477 (do478 (let [results (CollisionResults.)]479 (.collideWith node ray results)480 (let [touch-objects481 (filter #(not (= geo (.getGeometry %)))482 results)]483 (- 255484 (if (empty? touch-objects) 255485 (rem486 (int487 (* 255 (/ (.getDistance488 (first touch-objects)) limit)))489 256))))))))))))))492 (defn touch [#^Node pieces]493 (filter (comp not nil?)494 (map enable-touch495 (filter #(isa? (class %) Geometry)496 (node-seq pieces)))))499 (defn test-eye []500 (.getChild501 (.getChild (worm-model) "eyes")502 "eye"))506 ;; Ears work the same way as vision.508 ;; (hearing creature) will return [init-functions509 ;; sensor-functions]. The init functions each take the world and510 ;; register a SoundProcessor that does foureier transforms on the511 ;; incommong sound data, making it available to each sensor function.513 (defn creature-ears514 "Return the children of the creature's \"ears\" node."515 ;;dylan516 ;;"The ear nodes which are children of the \"ears\" node in the517 ;;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-organ528 (defn update-listener-velocity529 "Update the listener's velocity every update loop."530 [#^Spatial obj #^Listener lis]531 (let [old-position (atom (.getLocation lis))]532 (.addControl533 obj534 (proxy [AbstractControl] []535 (controlUpdate [tpf]536 (let [new-position (.getLocation lis)]537 (.setVelocity538 lis539 (.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-ear547 [#^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-hearing560 [#^Node creature #^Spatial ear]561 (let [hearing-data (atom [])]562 [(fn [world]563 (attach-ear world creature ear564 (fn [data]565 (reset! hearing-data (vec data)))))566 [(fn []567 (let [data @hearing-data568 topology569 (vec (map #(vector % 0) (range 0 (count data))))570 scaled-data571 (vec572 (map573 #(rem (int (* 255 (/ (+ 1 %) 2))) 256)574 data))]575 [topology scaled-data]))576 ]]))578 (defn hearing579 [#^Node creature]580 (reduce581 (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 --- nodes595 ;; closest-node "parse/compile-x" -> makes organ, which is spatial, fn pair597 ;; higher level -- organs598 ;;600 ;; higher level --- sense/effector601 ;; these are the functions that provide world i/o, chinese-room style606 (defn blender-creature607 "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 (+ num615 (bit-shift-left num 8)616 (bit-shift-left num 16)))618 (defn debug-touch-window619 "creates function that offers a debug view of sensor data"620 []621 (let [vi (view-image)]622 (fn623 [[coords sensor-data]]624 (let [image (points->image coords)]625 (dorun626 (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-window634 "creates function that offers a debug view of sensor data"635 []636 (let [vi (view-image)]637 (fn638 [[coords sensor-data]]639 (let [image (points->image coords)]640 (dorun641 (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-window647 "view audio data"648 [height]649 (let [vi (view-image)]650 (fn [[coords sensor-data]]651 (let [image (BufferedImage. (count coords) height652 BufferedImage/TYPE_INT_RGB)]653 (dorun654 (for [x (range (count coords))]655 (dorun656 (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 is670 ;; defined by a 1-D array of numbers (the "motor pool") each of which671 ;; represent muscle fibers. A muscle also has a scalar :strength672 ;; factor which determines how strong the muscle as a whole is.673 ;; The effector function for a muscle takes a number < (count674 ;; motor-pool) and that number is said to "activate" all the muscle675 ;; fibers whose index is lower than the number. Each fiber will apply676 ;; force in proportion to its value in the array. Lower values cause677 ;; less force. The lower values can be put at the "beginning" of the678 ;; 1-D array to simulate the layout of actual human muscles, which are679 ;; capable of more percise movements when exerting less force.681 ;; I don't know how to encode proprioception, so for now, just return682 ;; a function for each joint that returns a triplet of floats which683 ;; represent relative roll, pitch, and yaw. Write display code for684 ;; this though.686 (defn muscle-fiber-values687 "get motor pool strengths"688 [#^BufferedImage image]689 (vec690 (let [width (.getWidth image)]691 (for [x (range width)]692 (- 255693 (bit-and694 0x0000FF695 (.getRGB image x 0)))))))698 (defn creature-muscles699 "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 axis708 (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y)709 strength (meta-data muscle "strength")710 image-name (read-string (meta-data muscle "muscle"))711 image712 (ImageToAwt/convert713 (.getImage (.loadTexture (asset-manager) image-name))714 false false 0)715 fibers (muscle-fiber-values image)716 fiber-integral (reductions + fibers)717 force-index (vec718 (map719 #(float (* strength (/ % (last720 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-muscles729 "Must be called on a creature after RigidBodyControls have been730 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-axis738 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)739 y-axis740 (box 0.01 1 0.01 :physical? false :color ColorRGBA/Green)741 z-axis742 (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 ;; dream760 ]763 (apply764 world765 (with-movement766 (.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 [creature772 (box 10 2 10 :position (Vector3f. 0 -9 0)773 :color ColorRGBA/Gray :mass 0)774 x-axis y-axis z-axis775 me776 ])777 (merge standard-debug-controls778 {"key-return"779 (fn [_ value]780 (if value781 (do782 (println-repl "play-sound")783 (.play bell))))784 "key-h"785 (fn [_ value]786 (if value787 (do788 (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 world799 (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/captureVideo805 ;; 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 ;;(dorun812 ;; (map #(%1 %2) touch-nerves (repeat (.getRootNode world))))814 (prop-debug (prop))816 (dorun817 (map #(%1 (%2 (.getRootNode world)))818 touch-debug-windows touch-nerves))820 (dorun821 (map #(%1 (%2))822 vision-debug vision-data))823 (dorun824 (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 relation842 ;; to the spatial.845 (defn follow-test846 "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/Blue850 :position (Vector3f. 0 10 0)851 :mass 30852 )853 rot (.getWorldRotation rock)855 table (box 3 1 10 :color ColorRGBA/Gray :mass 0856 :position (Vector3f. 0 -3 0))]858 (world859 (nodify [rock table])860 standard-debug-controls861 (fn [world]862 (let863 [cam (doto (.clone (.getCamera world))864 (.setLocation camera-pos)865 (.lookAt Vector3f/ZERO866 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_src879 #+results: body-1880 : #'cortex.silly/follow-test883 * COMMENT purgatory884 #+begin_src clojure886 (defn bullet-trans* []887 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red888 :position (Vector3f. 5 0 0)889 :mass 90)890 obj-b (sphere 0.5 :color ColorRGBA/Blue891 :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 100902 swivel903 (.toRotationMatrix904 (doto (Quaternion.)905 (.fromAngleAxis (/ Math/PI 2)906 Vector3f/UNIT_X)))907 x-move908 (doto (Matrix3f.)909 (.fromStartEndVectors Vector3f/UNIT_X910 (.normalize (Vector3f. 1 1 0))))912 timer (atom 0)]913 (doto914 (ConeJoint.915 control-a control-b916 (Vector3f. -8 0 0)917 (Vector3f. 2 0 0)918 ;;swivel swivel919 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY920 x-move Matrix3f/IDENTITY921 )922 (.setCollisionBetweenLinkedBodys false)923 (.setLimit (* 1 (/ Math/PI 4)) ;; twist924 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane925 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane926 (world (nodify927 [obj-a obj-b])928 (merge standard-debug-controls929 {"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-a945 (Vector3f. force 0 0)946 (Vector3f. 0 0 0)))947 (if @move-down?948 (.applyForce control-a949 (Vector3f. (- force) 0 0)950 (Vector3f. 0 0 0)))951 (if @move-left?952 (.applyForce control-a953 (Vector3f. 0 force 0)954 (Vector3f. 0 0 0)))955 (if @move-right?956 (.applyForce control-a957 (Vector3f. 0 (- force) 0)958 (Vector3f. 0 0 0)))960 (if @roll-left?961 (.applyForce control-a962 (Vector3f. 0 0 force)963 (Vector3f. 0 0 0)))964 (if @roll-right?965 (.applyForce control-a966 (Vector3f. 0 0 (- force))967 (Vector3f. 0 0 0)))969 (if (zero? (rem (swap! timer inc) 100))970 (.attachChild971 (.getRootNode world)972 (sphere 0.05 :color ColorRGBA/Yellow973 :physical? false :position974 (.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 (world990 (nodify [top bottom floor origin])991 (merge standard-debug-controls992 {"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))1003 )1005 (fn [world _]1006 (if (zero? (rem (swap! timer inc) 100))1007 (do1008 ;; (println-repl @timer)1009 (.attachChild (.getRootNode world)1010 (sphere 0.05 :color ColorRGBA/Yellow1011 :position (.getWorldTranslation top)1012 :physical? false))1013 (.attachChild (.getRootNode world)1014 (sphere 0.05 :color ColorRGBA/LightGray1015 :position (.getWorldTranslation bottom)1016 :physical? false))))1018 (if @move-up?1019 (.applyTorque control1020 (.mult (.getPhysicsRotation control)1021 (Vector3f. 0 0 10))))1022 (if @move-down?1023 (.applyTorque control1024 (.mult (.getPhysicsRotation control)1025 (Vector3f. 0 0 -10))))1026 (if @move-left?1027 (.applyTorque control1028 (.mult (.getPhysicsRotation control)1029 (Vector3f. 0 10 0))))1030 (if @move-right?1031 (.applyTorque control1032 (.mult (.getPhysicsRotation control)1033 (Vector3f. 0 -10 0))))1034 (if @roll-left?1035 (.applyTorque control1036 (.mult (.getPhysicsRotation control)1037 (Vector3f. -1 0 0))))1038 (if @roll-right?1039 (.applyTorque control1040 (.mult (.getPhysicsRotation control)1041 (Vector3f. 1 0 0))))))))1042 #+end_src1045 * COMMENT generate source1046 #+begin_src clojure :tangle ../src/cortex/silly.clj1047 <<body-1>>1048 #+end_src