Mercurial > cortex
view org/test-creature.org @ 94:69174ed0f9f6
Working sensor coordinate code. Dylan helped!
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 10 Jan 2012 08:38:04 -0700 |
parents | 7b739503836a |
children | e4bcd0c481ba |
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.org9 * Intro10 So far, I've made the following senses --11 - Vision12 - Hearing13 - Touch14 - Proprioception16 And one effector:17 - Movement19 However, the code so far has only enabled these senses, but has not20 actually implemented them. For example, there is still a lot of work21 to be done for vision. I need to be able to create an /eyeball/ in22 simulation that can be moved around and see the world from different23 angles. I also need to determine weather to use log-polar or cartesian24 for the visual input, and I need to determine how/wether to25 disceritise the visual input.27 I also want to be able to visualize both the sensors and the28 effectors in pretty pictures. This semi-retarted creature will by my29 first attempt at bringing everything together.31 * The creature's body33 Still going to do an eve-like body in blender, but due to problems34 importing the joints, etc into jMonkeyEngine3, I',m going to do all35 the connecting here in clojure code, using the names of the individual36 components and trial and error. Later, I'll maybe make some sort of37 creature-building modifications to blender that support whatever38 discreitized senses I'm going to make.40 #+name: body-141 #+begin_src clojure42 (ns cortex.silly43 "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 (.enqueue58 sim59 (fn []60 (.stop sim)))61 (.start sim)))63 (defn load-blender-model64 "Load a .blend file using an asset folder relative path."65 [^String model]66 (.loadModel67 (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-jme77 "Convert from Blender coordinates to JME coordinates"78 [#^Vector3f in]79 (Vector3f. (.getX in)80 (.getZ in)81 (- (.getY in))))83 (defn jme-to-blender84 "Convert from JME coordinates to Blender coordinates"85 [#^Vector3f in]86 (Vector3f. (.getX in)87 (- (.getZ in))88 (.getY in)))90 (defn joint-targets91 "Return the two closest two objects to the joint object, ordered92 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 (.collideWith99 parts100 (BoundingBox. (.getWorldTranslation joint)101 radius radius radius)102 results)103 (let [targets104 (distinct105 (map #(.getGeometry %) results))]106 (if (>= (count targets) 2)107 (sort-by108 #(let [v109 (jme-to-blender110 (.mult111 (.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-local121 "Convert the world coordinates into coordinates relative to the122 object (i.e. local coordinates), taking into account the rotation123 of object."124 [#^Spatial object world-coordinate]125 (let [out (Vector3f.)]126 (.worldToLocal object world-coordinate out) out))128 (defmulti joint-dispatch129 "Translate blender pseudo-joints into real JME joints."130 (fn [constraints & _]131 (:type constraints)))133 (defmethod joint-dispatch :point134 [constraints control-a control-b pivot-a pivot-b rotation]135 (println-repl "creating POINT2POINT joint")136 (Point2PointJoint.137 control-a138 control-b139 pivot-a140 pivot-b))142 (defmethod joint-dispatch :hinge143 [constraints control-a control-b pivot-a pivot-b rotation]144 (println-repl "creating HINGE joint")145 (let [axis146 (if-let147 [axis (:axis constraints)]148 axis149 Vector3f/UNIT_X)150 [limit-1 limit-2] (:limit constraints)151 hinge-axis152 (.mult153 rotation154 (blender-to-jme axis))]155 (doto156 (HingeJoint.157 control-a158 control-b159 pivot-a160 pivot-b161 hinge-axis162 hinge-axis)163 (.setLimit limit-1 limit-2))))165 (defmethod joint-dispatch :cone166 [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-repl174 "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0)))175 (println-repl176 "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0)))177 (println-repl178 "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1)))179 (doto180 (ConeJoint.181 control-a182 control-b183 pivot-a184 pivot-b185 rotation186 rotation)187 (.setLimit (float limit-xz)188 (float limit-xy)189 (float twist)))))191 (defn connect192 "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 [constraints209 (map-vals210 eval211 (read-string212 (meta-data joint "joint")))]213 ;; A side-effect of creating a joint registers214 ;; it with both physics objects which in turn215 ;; will register the joint with the physics system216 ;; when the simulation is started.217 (do218 (println-repl "creating joint between"219 (.getName obj-a) "and" (.getName obj-b))220 (joint-dispatch constraints221 control-a control-b222 pivot-a pivot-b223 joint-rotation))224 (println-repl "could not find joint meta-data!"))))226 (defn assemble-creature [#^Node pieces joints]227 (dorun228 (map229 (fn [geom]230 (let [physics-control231 (RigidBodyControl.232 (HullCollisionShape.233 (.getMesh geom))234 (if-let [mass (meta-data geom "mass")]235 (do236 (println-repl237 "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 (dorun246 (map247 (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 joints257 (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 (def touch "Models/creature1/touch.blend")269 (defn worm-model [] (load-blender-model worm))271 (defn x-ray [#^ColorRGBA color]272 (doto (Material. (asset-manager)273 "Common/MatDefs/Misc/Unshaded.j3md")274 (.setColor "Color" color)275 (-> (.getAdditionalRenderState)276 (.setDepthTest false))))278 (defn test-creature [thing]279 (let [x-axis280 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)281 y-axis282 (box 0.01 1 0.01 :physical? false :color ColorRGBA/Green)283 z-axis284 (box 0.01 0.01 1 :physical? false :color ColorRGBA/Blue)]285 (world286 (nodify [(blender-creature thing)287 (box 10 2 10 :position (Vector3f. 0 -9 0)288 :color ColorRGBA/Gray :mass 0)289 x-axis y-axis z-axis290 ])291 standard-debug-controls292 (fn [world]293 (light-up-everything world)294 (enable-debug world)295 ;;(com.aurellem.capture.Capture/captureVideo296 ;; world (file-str "/home/r/proj/ai-videos/hand"))297 (.setTimer world (NanoTimer.))298 (set-gravity world (Vector3f. 0 0 0))299 (speed-up world)300 )301 no-op302 ;;(let [timer (atom 0)]303 ;; (fn [_ _]304 ;; (swap! timer inc)305 ;; (if (= (rem @timer 60) 0)306 ;; (println-repl (float (/ @timer 60))))))307 )))310 (defn colorful []311 (.getChild (worm-model) "worm-21"))313 (import jme3tools.converters.ImageToAwt)315 (import ij.ImagePlus)317 (defn triangle-indices318 "Get the triangle vertex indices of a given triangle from a given319 mesh."320 [#^Mesh mesh triangle-index]321 (let [indices (int-array 3)]322 (.getTriangle mesh triangle-index indices)323 (vec indices)))325 (defn uv-coord326 "Get the uv-coordinates of the vertex named by vertex-index"327 [#^Mesh mesh vertex-index]328 (let [UV-buffer329 (.getData330 (.getBuffer331 mesh332 VertexBuffer$Type/TexCoord))]333 (Vector2f.334 (.get UV-buffer (* vertex-index 2))335 (.get UV-buffer (+ 1 (* vertex-index 2))))))337 (defn tri-uv-coord338 "Get the uv-cooridnates of the triangle's verticies."339 [#^Mesh mesh #^Triangle triangle]340 (map (partial uv-coord mesh)341 (triangle-indices mesh (.getIndex triangle))))343 (defn touch-receptor-image344 "Return the touch-sensor distribution image in ImagePlus format."345 [#^Geometry obj]346 (let347 [mat (.getMaterial obj)348 texture349 (.getTextureValue350 (.getTextureParam351 mat352 MaterialHelper/TEXTURE_TYPE_DIFFUSE))353 im (.getImage texture)]354 (ImagePlus.355 "UV-map"356 (ImageToAwt/convert im false false 0))))359 (import ij.process.ImageProcessor)360 (import java.awt.image.BufferedImage)362 (defprotocol Frame363 (frame [this]))365 (extend-type BufferedImage366 Frame367 (frame [image]368 (merge369 (apply370 hash-map371 (interleave372 (doall (for [x (range (.getWidth image)) y (range (.getHeight image))]373 (vector x y)))374 (doall (for [x (range (.getWidth image)) y (range (.getHeight image))]375 (let [data (.getRGB image x y)]376 (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16)377 :g (bit-shift-right (bit-and 0x00ff00 data) 8)378 :b (bit-and 0x0000ff data)))))))379 {:width (.getWidth image) :height (.getHeight image)})))382 (extend-type ImagePlus383 Frame384 (frame [image+]385 (frame (.getBufferedImage image+))))388 (def white -1)390 (defn filter-pixels391 "List the coordinates of all pixels matching pred."392 {:author "Dylan Holmes"}393 [pred #^ImageProcessor ip]394 (let395 [width (.getWidth ip)396 height (.getHeight ip)]397 ((fn accumulate [x y matches]398 (cond399 (>= y height) matches400 (>= x width) (recur 0 (inc y) matches)401 (pred (.getPixel ip x y))402 (recur (inc x) y (conj matches (Vector2f. x y)))403 :else (recur (inc x) y matches)))404 0 0 [])))406 (defn white-coordinates407 "List the coordinates of all the white pixels in an image."408 [#^ImageProcessor ip]409 (filter-pixels #(= % white) ip))411 (defn same-side? [p1 p2 ref p]412 (<=413 0414 (.dot415 (.cross (.subtract p2 p1) (.subtract p p1))416 (.cross (.subtract p2 p1) (.subtract ref p1)))))419 (defn triangle->matrix4f420 "Converts the triangle into a 4x4 matrix of vertices: The first421 three columns contain the vertices of the triangle; the last422 contains the unit normal of the triangle. The bottom row is filled423 with 1s."424 [#^Triangle t]425 (let [mat (Matrix4f.)426 [vert-1 vert-2 vert-3]427 ((comp vec map) #(.get t %) (range 3))428 unit-normal (do (.calculateNormal t)(.getNormal t))429 vertices [vert-1 vert-2 vert-3 unit-normal]]431 (dorun432 (for [row (range 4) col (range 3)]433 (do434 (.set mat col row (.get (vertices row)col))435 (.set mat 3 row 1))))436 mat))438 (defn triangle-transformation439 "Returns the affine transformation that converts each vertex in the440 first triangle into the corresponding vertex in the second441 triangle."442 [#^Triangle tri-1 #^Triangle tri-2]443 (.mult444 (triangle->matrix4f tri-2)445 (.invert (triangle->matrix4f tri-1))))447 (def death (Triangle.448 (Vector3f. 1 1 1)449 (Vector3f. 1 2 3)450 (Vector3f. 5 6 7)))452 (def death-2 (Triangle.453 (Vector3f. 2 2 2)454 (Vector3f. 1 1 1)455 (Vector3f. 0 1 0)))457 (defn vector2f->vector3f [v]458 (Vector3f. (.getX v) (.getY v) 0))461 (extend-type Triangle462 Textual463 (text [t]464 (println "Triangle: " \newline (.get1 t) \newline465 (.get2 t) \newline (.get3 t))))468 (defn map-triangle [f #^Triangle tri]469 (Triangle.470 (f 0 (.get1 tri))471 (f 1 (.get2 tri))472 (f 2 (.get3 tri))))474 (defn triangle-seq [#^Triangle tri]475 [(.get1 tri) (.get2 tri) (.get3 tri)])477 (defn vector3f-seq [#^Vector3f v]478 [(.getX v) (.getY v) (.getZ v)])480 (defn inside-triangle?481 "Is the point inside the triangle? Now what do we do?482 You might want to hold on there"483 {:author "God"}484 [tri p]485 (let [[vert-1 vert-2 vert-3] (triangle-seq tri)]486 (and487 (same-side? vert-1 vert-2 vert-3 p)488 (same-side? vert-2 vert-3 vert-1 p)489 (same-side? vert-3 vert-1 vert-2 p))))491 (defn uv-triangle492 "Convert the mesh triangle into the cooresponding triangle in493 UV-space. Z-component of these triangles is always zero."494 [#^Mesh mesh #^Triangle tri]495 (apply #(Triangle. %1 %2 %3)496 (map vector2f->vector3f497 (tri-uv-coord mesh tri))))499 (defn pixel-triangle500 "Convert the mesh triange into the corresponding triangle in501 UV-pixel-space. Z compenent will be zero."502 [#^Mesh mesh #^Triangle tri width height]503 (map-triangle (fn [_ v]504 (Vector3f. (* width (.getX v))505 (* height (.getY v))506 0))507 (uv-triangle mesh tri)))509 (defn triangle-bounds510 "Dimensions of the bounding square of the triangle in the form511 [x y width height].512 Assumes that the triangle lies in the XY plane."513 [#^Triangle tri]514 (let [verts (map vector3f-seq (triangle-seq tri))515 x (apply min (map first verts))516 y (apply min (map second verts))]518 [x y519 (- (apply max (map first verts)) x)520 (- (apply max (map second verts)) y)521 ]))524 (defn locate-tactile-sensors525 "Search the geometry's tactile UV image for touch sensors, returning526 their positions in geometry-relative coordinates."527 [#^Geometry geo]529 ;; inside-triangle? white-coordinates triangle-transformation530 ;; tri-uv-coord touch-receptor-image531 (let [mesh (.getMesh geo)532 image (touch-receptor-image geo)533 width (.getWidth image)534 height (.getHeight image)535 tris (triangles geo)537 ;; for each triangle538 sensor-coords539 (fn [tri]540 ;; translate triangle to uv-pixel-space541 (let [uv-tri542 (pixel-triangle mesh tri width height)543 bounds (vec (triangle-bounds uv-tri))]545 ;; get that part of the picture547 (apply #(.setRoi image %1 %2 %3 %4) bounds)548 (let [cutout (.crop (.getProcessor image))549 ;; extract white pixels inside triangle550 cutout-tri551 (map-triangle552 (fn [_ v]553 (.subtract554 v555 (Vector3f. (bounds 0) (bounds 1) (float 0))))556 uv-tri)557 whites (filter (partial inside-triangle? cutout-tri)558 (map vector2f->vector3f559 (white-coordinates cutout)))560 ;; translate pixel coordinates to world-space561 transform (triangle-transformation cutout-tri tri)]562 (map #(.mult transform %) whites))))]563 (map sensor-coords tris)))577 ;; for each triangle in the mesh,578 ;; get the normal to the triangle,579 ;; look at the UV touch map, restricted to that triangle,580 ;; get the positions of those touch sensors in geometry-relative581 ;; coordinates.582 (defn tactile-coords [#^Geometry obj]583 (let [mesh (.getMesh obj)584 num-triangles (.getTriangleCount mesh)585 num-verticies (.getVertexCount mesh)586 uv-coord (partial uv-coord mesh)587 triangle-indices (partial triangle-indices mesh)588 receptors (touch-receptor-image obj)589 tris (triangles obj)590 ]591 (map592 (fn [[tri-1 tri-2 tri-3]]593 (let [width (.getWidth receptors)594 height (.getHeight receptors)595 uv-1 (uv-coord tri-1)596 uv-2 (uv-coord tri-2)597 uv-3 (uv-coord tri-3)598 x-coords (map #(.getX %) [uv-1 uv-2 uv-3])599 y-coords (map #(.getY %) [uv-1 uv-2 uv-3])600 max-x (Math/ceil (* width (apply max x-coords)))601 min-x (Math/floor (* width (apply min x-coords)))602 max-y (Math/ceil (* height (apply max y-coords)))603 min-y (Math/floor (* height (apply min y-coords)))605 image-1 (Vector2f. (* width (.getX uv-1))606 (* height (.getY uv-1)))607 image-2 (Vector2f. (* width (.getX uv-2))608 (* height (.getY uv-2)))609 image-3 (Vector2f. (* width (.getX uv-3))610 (* height (.getY uv-3)))611 left-corner612 (Vector2f. min-x min-y)613 ]615 (.setRoi receptors min-x min-y (- max-x min-x) (- max-y min-y))616 (let [processor (.crop (.getProcessor receptors))]617 (map618 #(.add left-corner %)620 (filter621 (partial622 inside-triangle?623 (.subtract image-1 left-corner)624 (.subtract image-2 left-corner)625 (.subtract image-3 left-corner))626 (white-coordinates processor))))627 )) (map triangle-indices (range num-triangles)))))635 (defn all-names []636 (concat637 (re-split #"\n" (slurp (file-str638 "/home/r/proj/names/dist.female.first")))639 (re-split #"\n" (slurp (file-str640 "/home/r/proj/names/dist.male.first")))641 (re-split #"\n" (slurp (file-str642 "/home/r/proj/names/dist.all.last")))))652 (defrecord LulzLoader [])653 (defprotocol Lulzable (load-lulz [this]))654 (extend-type LulzLoader655 Lulzable656 (load-lulz [this] (println "the lulz have arrived!")))659 (defn world-setup [joint]660 (let [joint-position (Vector3f. 0 0 0)661 joint-rotation662 (.toRotationMatrix663 (.mult664 (doto (Quaternion.)665 (.fromAngleAxis666 (* 1 (/ Math/PI 4))667 (Vector3f. -1 0 0)))668 (doto (Quaternion.)669 (.fromAngleAxis670 (* 1 (/ Math/PI 2))671 (Vector3f. 0 0 1)))))672 top-position (.mult joint-rotation (Vector3f. 8 0 0))674 origin (doto675 (sphere 0.1 :physical? false :color ColorRGBA/Cyan676 :position top-position))677 top (doto678 (sphere 0.1 :physical? false :color ColorRGBA/Yellow679 :position top-position)681 (.addControl682 (RigidBodyControl.683 (CapsuleCollisionShape. 0.5 1.5 1) (float 20))))684 bottom (doto685 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray686 :position (Vector3f. 0 0 0))687 (.addControl688 (RigidBodyControl.689 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))690 table (box 10 2 10 :position (Vector3f. 0 -20 0)691 :color ColorRGBA/Gray :mass 0)692 a (.getControl top RigidBodyControl)693 b (.getControl bottom RigidBodyControl)]695 (cond696 (= joint :cone)698 (doto (ConeJoint.699 a b700 (world-to-local top joint-position)701 (world-to-local bottom joint-position)702 joint-rotation703 joint-rotation704 )707 (.setLimit (* (/ 10) Math/PI)708 (* (/ 4) Math/PI)709 0)))710 [origin top bottom table]))712 (defn test-joint [joint]713 (let [[origin top bottom floor] (world-setup joint)714 control (.getControl top RigidBodyControl)715 move-up? (atom false)716 move-down? (atom false)717 move-left? (atom false)718 move-right? (atom false)719 roll-left? (atom false)720 roll-right? (atom false)721 timer (atom 0)]723 (world724 (nodify [top bottom floor origin])725 (merge standard-debug-controls726 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))727 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))728 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))729 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))730 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))731 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})733 (fn [world]734 (light-up-everything world)735 (enable-debug world)736 (set-gravity world (Vector3f. 0 0 0))737 )739 (fn [world _]740 (if (zero? (rem (swap! timer inc) 100))741 (do742 ;; (println-repl @timer)743 (.attachChild (.getRootNode world)744 (sphere 0.05 :color ColorRGBA/Yellow745 :position (.getWorldTranslation top)746 :physical? false))747 (.attachChild (.getRootNode world)748 (sphere 0.05 :color ColorRGBA/LightGray749 :position (.getWorldTranslation bottom)750 :physical? false))))752 (if @move-up?753 (.applyTorque control754 (.mult (.getPhysicsRotation control)755 (Vector3f. 0 0 10))))756 (if @move-down?757 (.applyTorque control758 (.mult (.getPhysicsRotation control)759 (Vector3f. 0 0 -10))))760 (if @move-left?761 (.applyTorque control762 (.mult (.getPhysicsRotation control)763 (Vector3f. 0 10 0))))764 (if @move-right?765 (.applyTorque control766 (.mult (.getPhysicsRotation control)767 (Vector3f. 0 -10 0))))768 (if @roll-left?769 (.applyTorque control770 (.mult (.getPhysicsRotation control)771 (Vector3f. -1 0 0))))772 (if @roll-right?773 (.applyTorque control774 (.mult (.getPhysicsRotation control)775 (Vector3f. 1 0 0))))))))779 #+end_src781 #+results: body-1782 : #'cortex.silly/test-joint785 * COMMENT purgatory786 #+begin_src clojure787 (defn bullet-trans []788 (let [obj-a (sphere 0.5 :color ColorRGBA/Red789 :position (Vector3f. -10 5 0))790 obj-b (sphere 0.5 :color ColorRGBA/Blue791 :position (Vector3f. -10 -5 0)792 :mass 0)793 control-a (.getControl obj-a RigidBodyControl)794 control-b (.getControl obj-b RigidBodyControl)795 swivel796 (.toRotationMatrix797 (doto (Quaternion.)798 (.fromAngleAxis (/ Math/PI 2)799 Vector3f/UNIT_X)))]800 (doto801 (ConeJoint.802 control-a control-b803 (Vector3f. 0 5 0)804 (Vector3f. 0 -5 0)805 swivel swivel)806 (.setLimit (* 0.6 (/ Math/PI 4))807 (/ Math/PI 4)808 (* Math/PI 0.8)))809 (world (nodify810 [obj-a obj-b])811 standard-debug-controls812 enable-debug813 no-op)))816 (defn bullet-trans* []817 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red818 :position (Vector3f. 5 0 0)819 :mass 90)820 obj-b (sphere 0.5 :color ColorRGBA/Blue821 :position (Vector3f. -5 0 0)822 :mass 0)823 control-a (.getControl obj-a RigidBodyControl)824 control-b (.getControl obj-b RigidBodyControl)825 move-up? (atom nil)826 move-down? (atom nil)827 move-left? (atom nil)828 move-right? (atom nil)829 roll-left? (atom nil)830 roll-right? (atom nil)831 force 100832 swivel833 (.toRotationMatrix834 (doto (Quaternion.)835 (.fromAngleAxis (/ Math/PI 2)836 Vector3f/UNIT_X)))837 x-move838 (doto (Matrix3f.)839 (.fromStartEndVectors Vector3f/UNIT_X840 (.normalize (Vector3f. 1 1 0))))842 timer (atom 0)]843 (doto844 (ConeJoint.845 control-a control-b846 (Vector3f. -8 0 0)847 (Vector3f. 2 0 0)848 ;;swivel swivel849 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY850 x-move Matrix3f/IDENTITY851 )852 (.setCollisionBetweenLinkedBodys false)853 (.setLimit (* 1 (/ Math/PI 4)) ;; twist854 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane855 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane856 (world (nodify857 [obj-a obj-b])858 (merge standard-debug-controls859 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))860 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))861 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))862 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))863 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))864 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})866 (fn [world]867 (enable-debug world)868 (set-gravity world Vector3f/ZERO)869 )871 (fn [world _]873 (if @move-up?874 (.applyForce control-a875 (Vector3f. force 0 0)876 (Vector3f. 0 0 0)))877 (if @move-down?878 (.applyForce control-a879 (Vector3f. (- force) 0 0)880 (Vector3f. 0 0 0)))881 (if @move-left?882 (.applyForce control-a883 (Vector3f. 0 force 0)884 (Vector3f. 0 0 0)))885 (if @move-right?886 (.applyForce control-a887 (Vector3f. 0 (- force) 0)888 (Vector3f. 0 0 0)))890 (if @roll-left?891 (.applyForce control-a892 (Vector3f. 0 0 force)893 (Vector3f. 0 0 0)))894 (if @roll-right?895 (.applyForce control-a896 (Vector3f. 0 0 (- force))897 (Vector3f. 0 0 0)))899 (if (zero? (rem (swap! timer inc) 100))900 (.attachChild901 (.getRootNode world)902 (sphere 0.05 :color ColorRGBA/Yellow903 :physical? false :position904 (.getWorldTranslation obj-a)))))905 )906 ))910 #+end_src913 * COMMENT generate source914 #+begin_src clojure :tangle ../src/cortex/silly.clj915 <<body-1>>916 #+end_src922 (defn transform-trianglesdsd923 "Transform that converts each vertex in the first triangle924 into the corresponding vertex in the second triangle."925 [#^Triangle tri-1 #^Triangle tri-2]926 (let [in [(.get1 tri-1)927 (.get2 tri-1)928 (.get3 tri-1)]929 out [(.get1 tri-2)930 (.get2 tri-2)931 (.get3 tri-2)]]932 (let [translate (doto (Matrix4f.) (.setTranslation (.negate (in 0))))933 in* [(.mult translate (in 0))934 (.mult translate (in 1))935 (.mult translate (in 2))]936 final-translation937 (doto (Matrix4f.)938 (.setTranslation (out 1)))940 rotate-1941 (doto (Matrix3f.)942 (.fromStartEndVectors943 (.normalize944 (.subtract945 (in* 1) (in* 0)))946 (.normalize947 (.subtract948 (out 1) (out 0)))))949 in** [(.mult rotate-1 (in* 0))950 (.mult rotate-1 (in* 1))951 (.mult rotate-1 (in* 2))]952 scale-factor-1953 (.mult954 (.normalize955 (.subtract956 (out 1)957 (out 0)))958 (/ (.length959 (.subtract (out 1)960 (out 0)))961 (.length962 (.subtract (in** 1)963 (in** 0)))))964 scale-1 (doto (Matrix4f.) (.setScale scale-factor-1))965 in*** [(.mult scale-1 (in** 0))966 (.mult scale-1 (in** 1))967 (.mult scale-1 (in** 2))]973 ]975 (dorun (map println in))976 (println)977 (dorun (map println in*))978 (println)979 (dorun (map println in**))980 (println)981 (dorun (map println in***))982 (println)984 )))1003 )