Mercurial > cortex
view org/test-creature.org @ 104:ee302b65213b
removed outdated code
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 14 Jan 2012 23:05:52 -0700 |
parents | 85ee8bb80edf |
children | 3334bf15854b |
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 * objectives10 - [X] get an overall bitmap-like image for touch11 - [X] write code to visuliaze this bitmap12 - [ ] directly change the UV-pixels to show touch sensor activation13 - [ ] write an explination for why b&w bitmaps for senses is appropiate14 - [ ] clean up touch code and write visulazation test15 - [ ] do the same for eyes17 * Intro18 So far, I've made the following senses --19 - Vision20 - Hearing21 - Touch22 - Proprioception24 And one effector:25 - Movement27 However, the code so far has only enabled these senses, but has not28 actually implemented them. For example, there is still a lot of work29 to be done for vision. I need to be able to create an /eyeball/ in30 simulation that can be moved around and see the world from different31 angles. I also need to determine weather to use log-polar or cartesian32 for the visual input, and I need to determine how/wether to33 disceritise the visual input.35 I also want to be able to visualize both the sensors and the36 effectors in pretty pictures. This semi-retarted creature will be my37 first attempt at bringing everything together.39 * The creature's body41 Still going to do an eve-like body in blender, but due to problems42 importing the joints, etc into jMonkeyEngine3, I'm going to do all43 the connecting here in clojure code, using the names of the individual44 components and trial and error. Later, I'll maybe make some sort of45 creature-building modifications to blender that support whatever46 discreitized senses I'm going to make.48 #+name: body-149 #+begin_src clojure50 (ns cortex.silly51 "let's play!"52 {:author "Robert McIntyre"})54 ;; TODO remove this!55 (require 'cortex.import)56 (cortex.import/mega-import-jme3)57 (use '(cortex world util body hearing touch vision))59 (rlm.rlm-commands/help)60 (import java.awt.image.BufferedImage)61 (import javax.swing.JPanel)62 (import javax.swing.SwingUtilities)63 (import java.awt.Dimension)64 (import javax.swing.JFrame)65 (import java.awt.Dimension)66 (declare joint-create)68 (defn view-image69 "Initailizes a JPanel on which you may draw a BufferedImage.70 Returns a function that accepts a BufferedImage and draws it to the71 JPanel."72 []73 (let [image74 (atom75 (BufferedImage. 1 1 BufferedImage/TYPE_4BYTE_ABGR))76 panel77 (proxy [JPanel] []78 (paint79 [graphics]80 (proxy-super paintComponent graphics)81 (.drawImage graphics @image 0 0 nil)))82 frame (JFrame. "Display Image")]83 (SwingUtilities/invokeLater84 (fn []85 (doto frame86 (-> (.getContentPane) (.add panel))87 (.pack)88 (.setLocationRelativeTo nil)89 (.setResizable true)90 (.setVisible true))))91 (fn [#^BufferedImage i]92 (reset! image i)93 (.setSize frame (+ 8 (.getWidth i)) (+ 28 (.getHeight i)))94 (.repaint panel 0 0 (.getWidth i) (.getHeight i)))))96 (defn points->image97 "Take a sparse collection of points and visuliaze it as a98 BufferedImage."100 ;; TODO maybe parallelize this since it's easy102 [points]103 (let [xs (vec (map first points))104 ys (vec (map second points))105 x0 (apply min xs)106 y0 (apply min ys)107 width (- (apply max xs) x0)108 height (- (apply max ys) y0)109 image (BufferedImage. (inc width) (inc height)110 BufferedImage/TYPE_BYTE_BINARY)]111 (dorun112 (for [index (range (count points))]113 (.setRGB image (- (xs index) x0) (- (ys index) y0) -1)))115 image))117 (defn test-data118 []119 (vec120 (for [a (range 0 1000 2)121 b (range 0 1000 2)]122 (vector a b))123 ))125 (defn average [coll]126 (/ (reduce + coll) (count coll)))128 (defn collapse-1d129 "One dimensional analogue of collapse"130 [center line]131 (let [length (count line)132 num-above (count (filter (partial < center) line))133 num-below (- length num-above)]134 (range (- center num-below)135 (+ center num-above))136 ))138 (defn collapse139 "Take a set of pairs of integers and collapse them into a140 contigous bitmap."141 [points]142 (let143 [num-points (count points)144 center (vector145 (int (average (map first points)))146 (int (average (map first points))))147 flattened148 (reduce149 concat150 (map151 (fn [column]152 (map vector153 (map first column)154 (collapse-1d (second center)155 (map second column))))156 (partition-by first (sort-by first points))))157 squeezed158 (reduce159 concat160 (map161 (fn [row]162 (map vector163 (collapse-1d (first center)164 (map first row))165 (map second row)))166 (partition-by second (sort-by second flattened))))167 relocate168 (let [min-x (apply min (map first squeezed))169 min-y (apply min (map second squeezed))]170 (map (fn [[x y]]171 [(- x min-x)172 (- y min-y)])173 squeezed))]174 relocate175 ))177 (defn load-bullet []178 (let [sim (world (Node.) {} no-op no-op)]179 (doto sim180 (.enqueue181 (fn []182 (.stop sim)))183 (.start))))185 (defn load-blender-model186 "Load a .blend file using an asset folder relative path."187 [^String model]188 (.loadModel189 (doto (asset-manager)190 (.registerLoader BlenderModelLoader (into-array String ["blend"])))191 model))193 (defn meta-data [blender-node key]194 (if-let [data (.getUserData blender-node "properties")]195 (.findValue data key)196 nil))198 (defn blender-to-jme199 "Convert from Blender coordinates to JME coordinates"200 [#^Vector3f in]201 (Vector3f. (.getX in)202 (.getZ in)203 (- (.getY in))))205 (defn jme-to-blender206 "Convert from JME coordinates to Blender coordinates"207 [#^Vector3f in]208 (Vector3f. (.getX in)209 (- (.getZ in))210 (.getY in)))212 (defn joint-targets213 "Return the two closest two objects to the joint object, ordered214 from bottom to top according to the joint's rotation."215 [#^Node parts #^Node joint]216 ;;(println (meta-data joint "joint"))217 (.getWorldRotation joint)218 (loop [radius (float 0.01)]219 (let [results (CollisionResults.)]220 (.collideWith221 parts222 (BoundingBox. (.getWorldTranslation joint)223 radius radius radius)224 results)225 (let [targets226 (distinct227 (map #(.getGeometry %) results))]228 (if (>= (count targets) 2)229 (sort-by230 #(let [v231 (jme-to-blender232 (.mult233 (.inverse (.getWorldRotation joint))234 (.subtract (.getWorldTranslation %)235 (.getWorldTranslation joint))))]236 (println-repl (.getName %) ":" v)237 (.dot (Vector3f. 1 1 1)238 v))239 (take 2 targets))240 (recur (float (* radius 2))))))))242 (defn world-to-local243 "Convert the world coordinates into coordinates relative to the244 object (i.e. local coordinates), taking into account the rotation245 of object."246 [#^Spatial object world-coordinate]247 (let [out (Vector3f.)]248 (.worldToLocal object world-coordinate out) out))250 (defn local-to-world251 "Convert the local coordinates into coordinates into world relative252 coordinates"253 [#^Spatial object local-coordinate]254 (let [world-coordinate (Vector3f.)]255 (.localToWorld object local-coordinate world-coordinate)256 world-coordinate))259 (defmulti joint-dispatch260 "Translate blender pseudo-joints into real JME joints."261 (fn [constraints & _]262 (:type constraints)))264 (defmethod joint-dispatch :point265 [constraints control-a control-b pivot-a pivot-b rotation]266 (println-repl "creating POINT2POINT joint")267 (Point2PointJoint.268 control-a269 control-b270 pivot-a271 pivot-b))273 (defmethod joint-dispatch :hinge274 [constraints control-a control-b pivot-a pivot-b rotation]275 (println-repl "creating HINGE joint")276 (let [axis277 (if-let278 [axis (:axis constraints)]279 axis280 Vector3f/UNIT_X)281 [limit-1 limit-2] (:limit constraints)282 hinge-axis283 (.mult284 rotation285 (blender-to-jme axis))]286 (doto287 (HingeJoint.288 control-a289 control-b290 pivot-a291 pivot-b292 hinge-axis293 hinge-axis)294 (.setLimit limit-1 limit-2))))296 (defmethod joint-dispatch :cone297 [constraints control-a control-b pivot-a pivot-b rotation]298 (let [limit-xz (:limit-xz constraints)299 limit-xy (:limit-xy constraints)300 twist (:twist constraints)]302 (println-repl "creating CONE joint")303 (println-repl rotation)304 (println-repl305 "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0)))306 (println-repl307 "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0)))308 (println-repl309 "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1)))310 (doto311 (ConeJoint.312 control-a313 control-b314 pivot-a315 pivot-b316 rotation317 rotation)318 (.setLimit (float limit-xz)319 (float limit-xy)320 (float twist)))))322 (defn connect323 "here are some examples:324 {:type :point}325 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}326 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)328 {:type :cone :limit-xz 0]329 :limit-xy 0]330 :twist 0]} (use XZY rotation mode in blender!)"331 [#^Node obj-a #^Node obj-b #^Node joint]332 (let [control-a (.getControl obj-a RigidBodyControl)333 control-b (.getControl obj-b RigidBodyControl)334 joint-center (.getWorldTranslation joint)335 joint-rotation (.toRotationMatrix (.getWorldRotation joint))336 pivot-a (world-to-local obj-a joint-center)337 pivot-b (world-to-local obj-b joint-center)]339 (if-let [constraints340 (map-vals341 eval342 (read-string343 (meta-data joint "joint")))]344 ;; A side-effect of creating a joint registers345 ;; it with both physics objects which in turn346 ;; will register the joint with the physics system347 ;; when the simulation is started.348 (do349 (println-repl "creating joint between"350 (.getName obj-a) "and" (.getName obj-b))351 (joint-dispatch constraints352 control-a control-b353 pivot-a pivot-b354 joint-rotation))355 (println-repl "could not find joint meta-data!"))))357 (defn assemble-creature [#^Node pieces joints]358 (dorun359 (map360 (fn [geom]361 (let [physics-control362 (RigidBodyControl.363 (HullCollisionShape.364 (.getMesh geom))365 (if-let [mass (meta-data geom "mass")]366 (do367 (println-repl368 "setting" (.getName geom) "mass to" (float mass))369 (float mass))370 (float 1)))]372 (.addControl geom physics-control)))373 (filter #(isa? (class %) Geometry )374 (node-seq pieces))))375 (dorun376 (map377 (fn [joint]378 (let [[obj-a obj-b]379 (joint-targets pieces joint)]380 (connect obj-a obj-b joint)))381 joints))382 pieces)384 (defn blender-creature [blender-path]385 (let [model (load-blender-model blender-path)386 joints387 (if-let [joint-node (.getChild model "joints")]388 (seq (.getChildren joint-node))389 (do (println-repl "could not find joints node")390 []))]391 (assemble-creature model joints)))393 (def hand "Models/creature1/one.blend")395 (def worm "Models/creature1/try-again.blend")397 (def touch "Models/creature1/touch.blend")399 (defn worm-model [] (load-blender-model worm))401 (defn x-ray [#^ColorRGBA color]402 (doto (Material. (asset-manager)403 "Common/MatDefs/Misc/Unshaded.j3md")404 (.setColor "Color" color)405 (-> (.getAdditionalRenderState)406 (.setDepthTest false))))408 (defn test-creature [thing]409 (let [x-axis410 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)411 y-axis412 (box 0.01 1 0.01 :physical? false :color ColorRGBA/Green)413 z-axis414 (box 0.01 0.01 1 :physical? false :color ColorRGBA/Blue)]415 (world416 (nodify [(blender-creature thing)417 (box 10 2 10 :position (Vector3f. 0 -9 0)418 :color ColorRGBA/Gray :mass 0)419 x-axis y-axis z-axis420 ])421 standard-debug-controls422 (fn [world]423 (light-up-everything world)424 (enable-debug world)425 ;;(com.aurellem.capture.Capture/captureVideo426 ;; world (file-str "/home/r/proj/ai-videos/hand"))427 (.setTimer world (NanoTimer.))428 (set-gravity world (Vector3f. 0 0 0))429 (speed-up world)430 )431 no-op432 ;;(let [timer (atom 0)]433 ;; (fn [_ _]434 ;; (swap! timer inc)435 ;; (if (= (rem @timer 60) 0)436 ;; (println-repl (float (/ @timer 60))))))437 )))439 (defn colorful []440 (.getChild (worm-model) "worm-21"))442 (import jme3tools.converters.ImageToAwt)444 (import ij.ImagePlus)446 (defn triangle-indices447 "Get the triangle vertex indices of a given triangle from a given448 mesh."449 [#^Mesh mesh triangle-index]450 (let [indices (int-array 3)]451 (.getTriangle mesh triangle-index indices)452 (vec indices)))454 (defn uv-coord455 "Get the uv-coordinates of the vertex named by vertex-index"456 [#^Mesh mesh vertex-index]457 (let [UV-buffer458 (.getData459 (.getBuffer460 mesh461 VertexBuffer$Type/TexCoord))]462 (Vector2f.463 (.get UV-buffer (* vertex-index 2))464 (.get UV-buffer (+ 1 (* vertex-index 2))))))466 (defn tri-uv-coord467 "Get the uv-cooridnates of the triangle's verticies."468 [#^Mesh mesh #^Triangle triangle]469 (map (partial uv-coord mesh)470 (triangle-indices mesh (.getIndex triangle))))472 (defn touch-receptor-image473 "Return the touch-sensor distribution image in ImagePlus format, or474 nil if it does not exist."475 [#^Geometry obj]476 (let [mat (.getMaterial obj)]477 (if-let [texture-param478 (.getTextureParam479 mat480 MaterialHelper/TEXTURE_TYPE_DIFFUSE)]481 (let482 [texture483 (.getTextureValue texture-param)484 im (.getImage texture)]485 (ImagePlus.486 "UV-map"487 (ImageToAwt/convert im false false 0))))))489 (import ij.process.ImageProcessor)490 (import java.awt.image.BufferedImage)492 (defprotocol Frame493 (frame [this]))495 (extend-type BufferedImage496 Frame497 (frame [image]498 (merge499 (apply500 hash-map501 (interleave502 (doall (for [x (range (.getWidth image)) y (range (.getHeight image))]503 (vector x y)))504 (doall (for [x (range (.getWidth image)) y (range (.getHeight image))]505 (let [data (.getRGB image x y)]506 (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16)507 :g (bit-shift-right (bit-and 0x00ff00 data) 8)508 :b (bit-and 0x0000ff data)))))))509 {:width (.getWidth image) :height (.getHeight image)})))512 (extend-type ImagePlus513 Frame514 (frame [image+]515 (frame (.getBufferedImage image+))))518 (def white -1)520 (defn filter-pixels521 "List the coordinates of all pixels matching pred."522 {:author "Dylan Holmes"}523 [pred #^ImageProcessor ip]524 (let525 [width (.getWidth ip)526 height (.getHeight ip)]527 ((fn accumulate [x y matches]528 (cond529 (>= y height) matches530 (>= x width) (recur 0 (inc y) matches)531 (pred (.getPixel ip x y))532 (recur (inc x) y (conj matches (Vector2f. x y)))533 :else (recur (inc x) y matches)))534 0 0 [])))536 (defn white-coordinates537 "List the coordinates of all the white pixels in an image."538 [#^ImageProcessor ip]539 (filter-pixels #(= % white) ip))541 (defn same-side?542 "Given the points p1 and p2 and the reference point ref, is point p543 on the same side of the line that goes through p1 and p2 as ref is?"544 [p1 p2 ref p]545 (<=546 0547 (.dot548 (.cross (.subtract p2 p1) (.subtract p p1))549 (.cross (.subtract p2 p1) (.subtract ref p1)))))551 (defn triangle->matrix4f552 "Converts the triangle into a 4x4 matrix of vertices: The first553 three columns contain the vertices of the triangle; the last554 contains the unit normal of the triangle. The bottom row is filled555 with 1s."556 [#^Triangle t]557 (let [mat (Matrix4f.)558 [vert-1 vert-2 vert-3]559 ((comp vec map) #(.get t %) (range 3))560 unit-normal (do (.calculateNormal t)(.getNormal t))561 vertices [vert-1 vert-2 vert-3 unit-normal]]562 (dorun563 (for [row (range 4) col (range 3)]564 (do565 (.set mat col row (.get (vertices row)col))566 (.set mat 3 row 1))))567 mat))569 (defn triangle-transformation570 "Returns the affine transformation that converts each vertex in the571 first triangle into the corresponding vertex in the second572 triangle."573 [#^Triangle tri-1 #^Triangle tri-2]574 (.mult575 (triangle->matrix4f tri-2)576 (.invert (triangle->matrix4f tri-1))))578 (def death (Triangle.579 (Vector3f. 1 1 1)580 (Vector3f. 1 2 3)581 (Vector3f. 5 6 7)))583 (def death-2 (Triangle.584 (Vector3f. 2 2 2)585 (Vector3f. 1 1 1)586 (Vector3f. 0 1 0)))588 (defn vector2f->vector3f [v]589 (Vector3f. (.getX v) (.getY v) 0))591 (extend-type Triangle592 Textual593 (text [t]594 (println "Triangle: " \newline (.get1 t) \newline595 (.get2 t) \newline (.get3 t))))597 (defn map-triangle [f #^Triangle tri]598 (Triangle.599 (f 0 (.get1 tri))600 (f 1 (.get2 tri))601 (f 2 (.get3 tri))))603 (defn triangle-seq [#^Triangle tri]604 [(.get1 tri) (.get2 tri) (.get3 tri)])606 (defn vector3f-seq [#^Vector3f v]607 [(.getX v) (.getY v) (.getZ v)])609 (defn inside-triangle?610 "Is the point inside the triangle? Now what do we do?611 You might want to hold on there"612 {:author "Dylan Holmes"}613 [tri p]614 (let [[vert-1 vert-2 vert-3] (triangle-seq tri)]615 (and616 (same-side? vert-1 vert-2 vert-3 p)617 (same-side? vert-2 vert-3 vert-1 p)618 (same-side? vert-3 vert-1 vert-2 p))))620 (defn uv-triangle621 "Convert the mesh triangle into the cooresponding triangle in622 UV-space. Z-component of these triangles is always zero."623 [#^Mesh mesh #^Triangle tri]624 (apply #(Triangle. %1 %2 %3)625 (map vector2f->vector3f626 (tri-uv-coord mesh tri))))628 (defn pixel-triangle629 "Convert the mesh triangle into the corresponding triangle in630 UV-pixel-space. Z compenent will be zero."631 [#^Mesh mesh #^Triangle tri width height]632 (map-triangle (fn [_ v]633 (Vector3f. (* width (.getX v))634 (* height (.getY v))635 0))636 (uv-triangle mesh tri)))638 (def rasterize pixel-triangle)641 (defn triangle-bounds642 "Dimensions of the bounding square of the triangle in the form643 [x y width height].644 Assumes that the triangle lies in the XY plane."645 [#^Triangle tri]646 (let [verts (map vector3f-seq (triangle-seq tri))647 x (apply min (map first verts))648 y (apply min (map second verts))]649 [x y650 (- (apply max (map first verts)) x)651 (- (apply max (map second verts)) y)652 ]))655 (defn locate-feelers656 "Search the geometry's tactile UV image for touch sensors, returning657 their positions in geometry-relative coordinates."658 [#^Geometry geo]659 (if-let [image (touch-receptor-image geo)]660 (let [mesh (.getMesh geo)661 tris (triangles geo)663 width (.getWidth image)664 height (.getHeight image)666 ;; for each triangle667 sensor-coords668 (fn [tri]669 ;; translate triangle to uv-pixel-space670 (let [uv-tri671 (pixel-triangle mesh tri width height)672 bounds (vec (triangle-bounds uv-tri))]674 ;; get that part of the picture676 (apply #(.setRoi image %1 %2 %3 %4) bounds)677 (let [cutout (.crop (.getProcessor image))678 ;; extract white pixels inside triangle679 cutout-tri680 (map-triangle681 (fn [_ v]682 (.subtract683 v684 (Vector3f. (bounds 0) (bounds 1) (float 0))))685 uv-tri)686 whites (filter (partial inside-triangle? cutout-tri)687 (map vector2f->vector3f688 (white-coordinates cutout)))689 ;; translate pixel coordinates to world-space690 transform (triangle-transformation cutout-tri tri)]691 (map #(.mult transform %) whites))))]692 (vec (map sensor-coords tris)))693 (repeat (count (triangles geo)) [])))695 (use 'clojure.contrib.def)697 (defn-memo touch-topology [#^Gemoetry geo]698 (let [feeler-coords699 (map700 #(vector (int (.getX %)) (int (.getY %)))701 (white-coordinates702 (.getProcessor (touch-receptor-image (colorful)))))]703 (vec (collapse feeler-coords))))705 (defn enable-touch [#^Geometry geo]706 (let [feeler-coords (locate-feelers geo)707 tris (triangles geo)708 limit 0.1]709 (fn [node]710 (let [sensor-origins711 (map712 #(map (partial local-to-world geo) %)713 feeler-coords)714 triangle-normals715 (map (partial get-ray-direction geo)716 tris)717 rays718 (flatten719 (map (fn [origins norm]720 (map #(doto (Ray. % norm)721 (.setLimit limit)) origins))722 sensor-origins triangle-normals))]723 (vector724 (touch-topology geo)725 (vec726 (for [ray rays]727 (do728 (let [results (CollisionResults.)]729 (.collideWith node ray results)730 (let [touch-objects731 (set732 (filter #(not (= geo %))733 (map #(.getGeometry %) results)))]734 (if (> (count touch-objects) 0)735 1 0)))))))))))737 (defn touch [#^Node pieces]738 (map enable-touch739 (filter #(isa? (class %) Geometry)740 (node-seq pieces))))742 (defn debug-window743 "creates function that offers a debug view of sensor data"744 []745 (let [vi (view-image)]746 (fn747 [[coords sensor-data]]748 (let [image (points->image coords)]749 (dorun750 (for [i (range (count coords))]751 (.setRGB image ((coords i) 0) ((coords i) 1)752 ({0 -16777216753 1 -1} (sensor-data i)))))754 (vi image)))))757 (defn all-names []758 (concat759 (re-split #"\n" (slurp (file-str760 "/home/r/proj/names/dist.female.first")))761 (re-split #"\n" (slurp (file-str762 "/home/r/proj/names/dist.male.first")))763 (re-split #"\n" (slurp (file-str764 "/home/r/proj/names/dist.all.last")))))774 (defrecord LulzLoader [])775 (defprotocol Lulzable (load-lulz [this]))776 (extend-type LulzLoader777 Lulzable778 (load-lulz [this] (println "the lulz have arrived!")))781 (defn world-setup [joint]782 (let [joint-position (Vector3f. 0 0 0)783 joint-rotation784 (.toRotationMatrix785 (.mult786 (doto (Quaternion.)787 (.fromAngleAxis788 (* 1 (/ Math/PI 4))789 (Vector3f. -1 0 0)))790 (doto (Quaternion.)791 (.fromAngleAxis792 (* 1 (/ Math/PI 2))793 (Vector3f. 0 0 1)))))794 top-position (.mult joint-rotation (Vector3f. 8 0 0))796 origin (doto797 (sphere 0.1 :physical? false :color ColorRGBA/Cyan798 :position top-position))799 top (doto800 (sphere 0.1 :physical? false :color ColorRGBA/Yellow801 :position top-position)803 (.addControl804 (RigidBodyControl.805 (CapsuleCollisionShape. 0.5 1.5 1) (float 20))))806 bottom (doto807 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray808 :position (Vector3f. 0 0 0))809 (.addControl810 (RigidBodyControl.811 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))812 table (box 10 2 10 :position (Vector3f. 0 -20 0)813 :color ColorRGBA/Gray :mass 0)814 a (.getControl top RigidBodyControl)815 b (.getControl bottom RigidBodyControl)]817 (cond818 (= joint :cone)820 (doto (ConeJoint.821 a b822 (world-to-local top joint-position)823 (world-to-local bottom joint-position)824 joint-rotation825 joint-rotation826 )829 (.setLimit (* (/ 10) Math/PI)830 (* (/ 4) Math/PI)831 0)))832 [origin top bottom table]))834 (defn test-joint [joint]835 (let [[origin top bottom floor] (world-setup joint)836 control (.getControl top RigidBodyControl)837 move-up? (atom false)838 move-down? (atom false)839 move-left? (atom false)840 move-right? (atom false)841 roll-left? (atom false)842 roll-right? (atom false)843 timer (atom 0)]845 (world846 (nodify [top bottom floor origin])847 (merge standard-debug-controls848 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))849 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))850 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))851 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))852 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))853 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})855 (fn [world]856 (light-up-everything world)857 (enable-debug world)858 (set-gravity world (Vector3f. 0 0 0))859 )861 (fn [world _]862 (if (zero? (rem (swap! timer inc) 100))863 (do864 ;; (println-repl @timer)865 (.attachChild (.getRootNode world)866 (sphere 0.05 :color ColorRGBA/Yellow867 :position (.getWorldTranslation top)868 :physical? false))869 (.attachChild (.getRootNode world)870 (sphere 0.05 :color ColorRGBA/LightGray871 :position (.getWorldTranslation bottom)872 :physical? false))))874 (if @move-up?875 (.applyTorque control876 (.mult (.getPhysicsRotation control)877 (Vector3f. 0 0 10))))878 (if @move-down?879 (.applyTorque control880 (.mult (.getPhysicsRotation control)881 (Vector3f. 0 0 -10))))882 (if @move-left?883 (.applyTorque control884 (.mult (.getPhysicsRotation control)885 (Vector3f. 0 10 0))))886 (if @move-right?887 (.applyTorque control888 (.mult (.getPhysicsRotation control)889 (Vector3f. 0 -10 0))))890 (if @roll-left?891 (.applyTorque control892 (.mult (.getPhysicsRotation control)893 (Vector3f. -1 0 0))))894 (if @roll-right?895 (.applyTorque control896 (.mult (.getPhysicsRotation control)897 (Vector3f. 1 0 0))))))))900 #+end_src902 #+results: body-1903 : #'cortex.silly/tactile-coords906 * COMMENT purgatory907 #+begin_src clojure908 (defn bullet-trans []909 (let [obj-a (sphere 0.5 :color ColorRGBA/Red910 :position (Vector3f. -10 5 0))911 obj-b (sphere 0.5 :color ColorRGBA/Blue912 :position (Vector3f. -10 -5 0)913 :mass 0)914 control-a (.getControl obj-a RigidBodyControl)915 control-b (.getControl obj-b RigidBodyControl)916 swivel917 (.toRotationMatrix918 (doto (Quaternion.)919 (.fromAngleAxis (/ Math/PI 2)920 Vector3f/UNIT_X)))]921 (doto922 (ConeJoint.923 control-a control-b924 (Vector3f. 0 5 0)925 (Vector3f. 0 -5 0)926 swivel swivel)927 (.setLimit (* 0.6 (/ Math/PI 4))928 (/ Math/PI 4)929 (* Math/PI 0.8)))930 (world (nodify931 [obj-a obj-b])932 standard-debug-controls933 enable-debug934 no-op)))937 (defn bullet-trans* []938 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red939 :position (Vector3f. 5 0 0)940 :mass 90)941 obj-b (sphere 0.5 :color ColorRGBA/Blue942 :position (Vector3f. -5 0 0)943 :mass 0)944 control-a (.getControl obj-a RigidBodyControl)945 control-b (.getControl obj-b RigidBodyControl)946 move-up? (atom nil)947 move-down? (atom nil)948 move-left? (atom nil)949 move-right? (atom nil)950 roll-left? (atom nil)951 roll-right? (atom nil)952 force 100953 swivel954 (.toRotationMatrix955 (doto (Quaternion.)956 (.fromAngleAxis (/ Math/PI 2)957 Vector3f/UNIT_X)))958 x-move959 (doto (Matrix3f.)960 (.fromStartEndVectors Vector3f/UNIT_X961 (.normalize (Vector3f. 1 1 0))))963 timer (atom 0)]964 (doto965 (ConeJoint.966 control-a control-b967 (Vector3f. -8 0 0)968 (Vector3f. 2 0 0)969 ;;swivel swivel970 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY971 x-move Matrix3f/IDENTITY972 )973 (.setCollisionBetweenLinkedBodys false)974 (.setLimit (* 1 (/ Math/PI 4)) ;; twist975 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane976 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane977 (world (nodify978 [obj-a obj-b])979 (merge standard-debug-controls980 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))981 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))982 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))983 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))984 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))985 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})987 (fn [world]988 (enable-debug world)989 (set-gravity world Vector3f/ZERO)990 )992 (fn [world _]994 (if @move-up?995 (.applyForce control-a996 (Vector3f. force 0 0)997 (Vector3f. 0 0 0)))998 (if @move-down?999 (.applyForce control-a1000 (Vector3f. (- force) 0 0)1001 (Vector3f. 0 0 0)))1002 (if @move-left?1003 (.applyForce control-a1004 (Vector3f. 0 force 0)1005 (Vector3f. 0 0 0)))1006 (if @move-right?1007 (.applyForce control-a1008 (Vector3f. 0 (- force) 0)1009 (Vector3f. 0 0 0)))1011 (if @roll-left?1012 (.applyForce control-a1013 (Vector3f. 0 0 force)1014 (Vector3f. 0 0 0)))1015 (if @roll-right?1016 (.applyForce control-a1017 (Vector3f. 0 0 (- force))1018 (Vector3f. 0 0 0)))1020 (if (zero? (rem (swap! timer inc) 100))1021 (.attachChild1022 (.getRootNode world)1023 (sphere 0.05 :color ColorRGBA/Yellow1024 :physical? false :position1025 (.getWorldTranslation obj-a)))))1026 )1027 ))1029 (defn transform-trianglesdsd1030 "Transform that converts each vertex in the first triangle1031 into the corresponding vertex in the second triangle."1032 [#^Triangle tri-1 #^Triangle tri-2]1033 (let [in [(.get1 tri-1)1034 (.get2 tri-1)1035 (.get3 tri-1)]1036 out [(.get1 tri-2)1037 (.get2 tri-2)1038 (.get3 tri-2)]]1039 (let [translate (doto (Matrix4f.) (.setTranslation (.negate (in 0))))1040 in* [(.mult translate (in 0))1041 (.mult translate (in 1))1042 (.mult translate (in 2))]1043 final-translation1044 (doto (Matrix4f.)1045 (.setTranslation (out 1)))1047 rotate-11048 (doto (Matrix3f.)1049 (.fromStartEndVectors1050 (.normalize1051 (.subtract1052 (in* 1) (in* 0)))1053 (.normalize1054 (.subtract1055 (out 1) (out 0)))))1056 in** [(.mult rotate-1 (in* 0))1057 (.mult rotate-1 (in* 1))1058 (.mult rotate-1 (in* 2))]1059 scale-factor-11060 (.mult1061 (.normalize1062 (.subtract1063 (out 1)1064 (out 0)))1065 (/ (.length1066 (.subtract (out 1)1067 (out 0)))1068 (.length1069 (.subtract (in** 1)1070 (in** 0)))))1071 scale-1 (doto (Matrix4f.) (.setScale scale-factor-1))1072 in*** [(.mult scale-1 (in** 0))1073 (.mult scale-1 (in** 1))1074 (.mult scale-1 (in** 2))]1080 ]1082 (dorun (map println in))1083 (println)1084 (dorun (map println in*))1085 (println)1086 (dorun (map println in**))1087 (println)1088 (dorun (map println in***))1089 (println)1091 ))))1096 #+end_src1099 * COMMENT generate source1100 #+begin_src clojure :tangle ../src/cortex/silly.clj1101 <<body-1>>1102 #+end_src