view org/test-creature.org @ 96:4a9096f31017

working on touch
author Robert McIntyre <rlm@mit.edu>
date Tue, 10 Jan 2012 21:26:41 -0700
parents e4bcd0c481ba
children 2ff8c7c4e64d
line wrap: on
line source
1 #+title: First attempt at a creature!
2 #+author: Robert McIntyre
3 #+email: rlm@mit.edu
4 #+description:
5 #+keywords: simulation, jMonkeyEngine3, clojure
6 #+SETUPFILE: ../../aurellem/org/setup.org
7 #+INCLUDE: ../../aurellem/org/level-0.org
9 * Intro
10 So far, I've made the following senses --
11 - Vision
12 - Hearing
13 - Touch
14 - Proprioception
16 And one effector:
17 - Movement
19 However, the code so far has only enabled these senses, but has not
20 actually implemented them. For example, there is still a lot of work
21 to be done for vision. I need to be able to create an /eyeball/ in
22 simulation that can be moved around and see the world from different
23 angles. I also need to determine weather to use log-polar or cartesian
24 for the visual input, and I need to determine how/wether to
25 disceritise the visual input.
27 I also want to be able to visualize both the sensors and the
28 effectors in pretty pictures. This semi-retarted creature will by my
29 first attempt at bringing everything together.
31 * The creature's body
33 Still going to do an eve-like body in blender, but due to problems
34 importing the joints, etc into jMonkeyEngine3, I',m going to do all
35 the connecting here in clojure code, using the names of the individual
36 components and trial and error. Later, I'll maybe make some sort of
37 creature-building modifications to blender that support whatever
38 discreitized senses I'm going to make.
40 #+name: body-1
41 #+begin_src clojure
42 (ns cortex.silly
43 "let's play!"
44 {:author "Robert McIntyre"})
46 ;; TODO remove this!
47 (require 'cortex.import)
48 (cortex.import/mega-import-jme3)
49 (use '(cortex world util body hearing touch vision))
51 (rlm.rlm-commands/help)
53 (declare joint-create)
55 (defn load-bullet []
56 (let [sim (world (Node.) {} no-op no-op)]
57 (.enqueue
58 sim
59 (fn []
60 (.stop sim)))
61 (.start sim)))
63 (defn load-blender-model
64 "Load a .blend file using an asset folder relative path."
65 [^String model]
66 (.loadModel
67 (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-jme
77 "Convert from Blender coordinates to JME coordinates"
78 [#^Vector3f in]
79 (Vector3f. (.getX in)
80 (.getZ in)
81 (- (.getY in))))
83 (defn jme-to-blender
84 "Convert from JME coordinates to Blender coordinates"
85 [#^Vector3f in]
86 (Vector3f. (.getX in)
87 (- (.getZ in))
88 (.getY in)))
90 (defn joint-targets
91 "Return the two closest two objects to the joint object, ordered
92 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 (.collideWith
99 parts
100 (BoundingBox. (.getWorldTranslation joint)
101 radius radius radius)
102 results)
103 (let [targets
104 (distinct
105 (map #(.getGeometry %) results))]
106 (if (>= (count targets) 2)
107 (sort-by
108 #(let [v
109 (jme-to-blender
110 (.mult
111 (.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-local
121 "Convert the world coordinates into coordinates relative to the
122 object (i.e. local coordinates), taking into account the rotation
123 of object."
124 [#^Spatial object world-coordinate]
125 (let [out (Vector3f.)]
126 (.worldToLocal object world-coordinate out) out))
128 (defn local-to-world
129 "Convert the local coordinates into coordinates into world relative
130 coordinates"
131 [#^Spatial object local-coordinate]
132 (let [world-coordinate (Vector3f.)]
133 (.localToWorld object local-coordinate world-coordinate)
134 world-coordinate))
137 (defmulti joint-dispatch
138 "Translate blender pseudo-joints into real JME joints."
139 (fn [constraints & _]
140 (:type constraints)))
142 (defmethod joint-dispatch :point
143 [constraints control-a control-b pivot-a pivot-b rotation]
144 (println-repl "creating POINT2POINT joint")
145 (Point2PointJoint.
146 control-a
147 control-b
148 pivot-a
149 pivot-b))
151 (defmethod joint-dispatch :hinge
152 [constraints control-a control-b pivot-a pivot-b rotation]
153 (println-repl "creating HINGE joint")
154 (let [axis
155 (if-let
156 [axis (:axis constraints)]
157 axis
158 Vector3f/UNIT_X)
159 [limit-1 limit-2] (:limit constraints)
160 hinge-axis
161 (.mult
162 rotation
163 (blender-to-jme axis))]
164 (doto
165 (HingeJoint.
166 control-a
167 control-b
168 pivot-a
169 pivot-b
170 hinge-axis
171 hinge-axis)
172 (.setLimit limit-1 limit-2))))
174 (defmethod joint-dispatch :cone
175 [constraints control-a control-b pivot-a pivot-b rotation]
176 (let [limit-xz (:limit-xz constraints)
177 limit-xy (:limit-xy constraints)
178 twist (:twist constraints)]
180 (println-repl "creating CONE joint")
181 (println-repl rotation)
182 (println-repl
183 "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0)))
184 (println-repl
185 "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0)))
186 (println-repl
187 "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1)))
188 (doto
189 (ConeJoint.
190 control-a
191 control-b
192 pivot-a
193 pivot-b
194 rotation
195 rotation)
196 (.setLimit (float limit-xz)
197 (float limit-xy)
198 (float twist)))))
200 (defn connect
201 "here are some examples:
202 {:type :point}
203 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)}
204 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints)
206 {:type :cone :limit-xz 0]
207 :limit-xy 0]
208 :twist 0]} (use XZY rotation mode in blender!)"
209 [#^Node obj-a #^Node obj-b #^Node joint]
210 (let [control-a (.getControl obj-a RigidBodyControl)
211 control-b (.getControl obj-b RigidBodyControl)
212 joint-center (.getWorldTranslation joint)
213 joint-rotation (.toRotationMatrix (.getWorldRotation joint))
214 pivot-a (world-to-local obj-a joint-center)
215 pivot-b (world-to-local obj-b joint-center)]
217 (if-let [constraints
218 (map-vals
219 eval
220 (read-string
221 (meta-data joint "joint")))]
222 ;; A side-effect of creating a joint registers
223 ;; it with both physics objects which in turn
224 ;; will register the joint with the physics system
225 ;; when the simulation is started.
226 (do
227 (println-repl "creating joint between"
228 (.getName obj-a) "and" (.getName obj-b))
229 (joint-dispatch constraints
230 control-a control-b
231 pivot-a pivot-b
232 joint-rotation))
233 (println-repl "could not find joint meta-data!"))))
235 (defn assemble-creature [#^Node pieces joints]
236 (dorun
237 (map
238 (fn [geom]
239 (let [physics-control
240 (RigidBodyControl.
241 (HullCollisionShape.
242 (.getMesh geom))
243 (if-let [mass (meta-data geom "mass")]
244 (do
245 (println-repl
246 "setting" (.getName geom) "mass to" (float mass))
247 (float mass))
248 (float 1)))]
250 (.addControl geom physics-control)))
251 (filter #(isa? (class %) Geometry )
252 (node-seq pieces))))
254 (dorun
255 (map
256 (fn [joint]
257 (let [[obj-a obj-b]
258 (joint-targets pieces joint)]
259 (connect obj-a obj-b joint)))
260 joints))
261 pieces)
263 (defn blender-creature [blender-path]
264 (let [model (load-blender-model blender-path)
265 joints
266 (if-let [joint-node (.getChild model "joints")]
267 (seq (.getChildren joint-node))
268 (do (println-repl "could not find joints node")
269 []))]
270 (assemble-creature model joints)))
272 (def hand "Models/creature1/one.blend")
274 (def worm "Models/creature1/try-again.blend")
276 (def touch "Models/creature1/touch.blend")
278 (defn worm-model [] (load-blender-model worm))
280 (defn x-ray [#^ColorRGBA color]
281 (doto (Material. (asset-manager)
282 "Common/MatDefs/Misc/Unshaded.j3md")
283 (.setColor "Color" color)
284 (-> (.getAdditionalRenderState)
285 (.setDepthTest false))))
287 (defn test-creature [thing]
288 (let [x-axis
289 (box 1 0.01 0.01 :physical? false :color ColorRGBA/Red)
290 y-axis
291 (box 0.01 1 0.01 :physical? false :color ColorRGBA/Green)
292 z-axis
293 (box 0.01 0.01 1 :physical? false :color ColorRGBA/Blue)]
294 (world
295 (nodify [(blender-creature thing)
296 (box 10 2 10 :position (Vector3f. 0 -9 0)
297 :color ColorRGBA/Gray :mass 0)
298 x-axis y-axis z-axis
299 ])
300 standard-debug-controls
301 (fn [world]
302 (light-up-everything world)
303 (enable-debug world)
304 ;;(com.aurellem.capture.Capture/captureVideo
305 ;; world (file-str "/home/r/proj/ai-videos/hand"))
306 (.setTimer world (NanoTimer.))
307 (set-gravity world (Vector3f. 0 0 0))
308 (speed-up world)
309 )
310 no-op
311 ;;(let [timer (atom 0)]
312 ;; (fn [_ _]
313 ;; (swap! timer inc)
314 ;; (if (= (rem @timer 60) 0)
315 ;; (println-repl (float (/ @timer 60))))))
316 )))
319 (defn colorful []
320 (.getChild (worm-model) "worm-21"))
322 (import jme3tools.converters.ImageToAwt)
324 (import ij.ImagePlus)
326 (defn triangle-indices
327 "Get the triangle vertex indices of a given triangle from a given
328 mesh."
329 [#^Mesh mesh triangle-index]
330 (let [indices (int-array 3)]
331 (.getTriangle mesh triangle-index indices)
332 (vec indices)))
334 (defn uv-coord
335 "Get the uv-coordinates of the vertex named by vertex-index"
336 [#^Mesh mesh vertex-index]
337 (let [UV-buffer
338 (.getData
339 (.getBuffer
340 mesh
341 VertexBuffer$Type/TexCoord))]
342 (Vector2f.
343 (.get UV-buffer (* vertex-index 2))
344 (.get UV-buffer (+ 1 (* vertex-index 2))))))
346 (defn tri-uv-coord
347 "Get the uv-cooridnates of the triangle's verticies."
348 [#^Mesh mesh #^Triangle triangle]
349 (map (partial uv-coord mesh)
350 (triangle-indices mesh (.getIndex triangle))))
352 (defn touch-receptor-image
353 "Return the touch-sensor distribution image in ImagePlus format."
354 [#^Geometry obj]
355 (let
356 [mat (.getMaterial obj)
357 texture
358 (.getTextureValue
359 (.getTextureParam
360 mat
361 MaterialHelper/TEXTURE_TYPE_DIFFUSE))
362 im (.getImage texture)]
363 (ImagePlus.
364 "UV-map"
365 (ImageToAwt/convert im false false 0))))
368 (import ij.process.ImageProcessor)
369 (import java.awt.image.BufferedImage)
371 (defprotocol Frame
372 (frame [this]))
374 (extend-type BufferedImage
375 Frame
376 (frame [image]
377 (merge
378 (apply
379 hash-map
380 (interleave
381 (doall (for [x (range (.getWidth image)) y (range (.getHeight image))]
382 (vector x y)))
383 (doall (for [x (range (.getWidth image)) y (range (.getHeight image))]
384 (let [data (.getRGB image x y)]
385 (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16)
386 :g (bit-shift-right (bit-and 0x00ff00 data) 8)
387 :b (bit-and 0x0000ff data)))))))
388 {:width (.getWidth image) :height (.getHeight image)})))
391 (extend-type ImagePlus
392 Frame
393 (frame [image+]
394 (frame (.getBufferedImage image+))))
397 (def white -1)
399 (defn filter-pixels
400 "List the coordinates of all pixels matching pred."
401 {:author "Dylan Holmes"}
402 [pred #^ImageProcessor ip]
403 (let
404 [width (.getWidth ip)
405 height (.getHeight ip)]
406 ((fn accumulate [x y matches]
407 (cond
408 (>= y height) matches
409 (>= x width) (recur 0 (inc y) matches)
410 (pred (.getPixel ip x y))
411 (recur (inc x) y (conj matches (Vector2f. x y)))
412 :else (recur (inc x) y matches)))
413 0 0 [])))
415 (defn white-coordinates
416 "List the coordinates of all the white pixels in an image."
417 [#^ImageProcessor ip]
418 (filter-pixels #(= % white) ip))
420 (defn same-side? [p1 p2 ref p]
421 (<=
422 0
423 (.dot
424 (.cross (.subtract p2 p1) (.subtract p p1))
425 (.cross (.subtract p2 p1) (.subtract ref p1)))))
428 (defn triangle->matrix4f
429 "Converts the triangle into a 4x4 matrix of vertices: The first
430 three columns contain the vertices of the triangle; the last
431 contains the unit normal of the triangle. The bottom row is filled
432 with 1s."
433 [#^Triangle t]
434 (let [mat (Matrix4f.)
435 [vert-1 vert-2 vert-3]
436 ((comp vec map) #(.get t %) (range 3))
437 unit-normal (do (.calculateNormal t)(.getNormal t))
438 vertices [vert-1 vert-2 vert-3 unit-normal]]
440 (dorun
441 (for [row (range 4) col (range 3)]
442 (do
443 (.set mat col row (.get (vertices row)col))
444 (.set mat 3 row 1))))
445 mat))
447 (defn triangle-transformation
448 "Returns the affine transformation that converts each vertex in the
449 first triangle into the corresponding vertex in the second
450 triangle."
451 [#^Triangle tri-1 #^Triangle tri-2]
452 (.mult
453 (triangle->matrix4f tri-2)
454 (.invert (triangle->matrix4f tri-1))))
456 (def death (Triangle.
457 (Vector3f. 1 1 1)
458 (Vector3f. 1 2 3)
459 (Vector3f. 5 6 7)))
461 (def death-2 (Triangle.
462 (Vector3f. 2 2 2)
463 (Vector3f. 1 1 1)
464 (Vector3f. 0 1 0)))
466 (defn vector2f->vector3f [v]
467 (Vector3f. (.getX v) (.getY v) 0))
470 (extend-type Triangle
471 Textual
472 (text [t]
473 (println "Triangle: " \newline (.get1 t) \newline
474 (.get2 t) \newline (.get3 t))))
477 (defn map-triangle [f #^Triangle tri]
478 (Triangle.
479 (f 0 (.get1 tri))
480 (f 1 (.get2 tri))
481 (f 2 (.get3 tri))))
483 (defn triangle-seq [#^Triangle tri]
484 [(.get1 tri) (.get2 tri) (.get3 tri)])
486 (defn vector3f-seq [#^Vector3f v]
487 [(.getX v) (.getY v) (.getZ v)])
489 (defn inside-triangle?
490 "Is the point inside the triangle? Now what do we do?
491 You might want to hold on there"
492 {:author "Dylan Holmes"}
493 [tri p]
494 (let [[vert-1 vert-2 vert-3] (triangle-seq tri)]
495 (and
496 (same-side? vert-1 vert-2 vert-3 p)
497 (same-side? vert-2 vert-3 vert-1 p)
498 (same-side? vert-3 vert-1 vert-2 p))))
500 (defn uv-triangle
501 "Convert the mesh triangle into the cooresponding triangle in
502 UV-space. Z-component of these triangles is always zero."
503 [#^Mesh mesh #^Triangle tri]
504 (apply #(Triangle. %1 %2 %3)
505 (map vector2f->vector3f
506 (tri-uv-coord mesh tri))))
508 (defn pixel-triangle
509 "Convert the mesh triange into the corresponding triangle in
510 UV-pixel-space. Z compenent will be zero."
511 [#^Mesh mesh #^Triangle tri width height]
512 (map-triangle (fn [_ v]
513 (Vector3f. (* width (.getX v))
514 (* height (.getY v))
515 0))
516 (uv-triangle mesh tri)))
518 (def rasterize pixel-triangle)
521 (defn triangle-bounds
522 "Dimensions of the bounding square of the triangle in the form
523 [x y width height].
524 Assumes that the triangle lies in the XY plane."
525 [#^Triangle tri]
526 (let [verts (map vector3f-seq (triangle-seq tri))
527 x (apply min (map first verts))
528 y (apply min (map second verts))]
530 [x y
531 (- (apply max (map first verts)) x)
532 (- (apply max (map second verts)) y)
533 ]))
536 (defn locate-tactile-sensors
537 "Search the geometry's tactile UV image for touch sensors, returning
538 their positions in geometry-relative coordinates."
539 [#^Geometry geo]
540 (let [mesh (.getMesh geo)
541 tris (triangles geo)
543 image (touch-receptor-image geo)
544 width (.getWidth image)
545 height (.getHeight image)
548 ;; for each triangle
549 sensor-coords
550 (fn [tri]
551 ;; translate triangle to uv-pixel-space
552 (let [uv-tri
553 (pixel-triangle mesh tri width height)
554 bounds (vec (triangle-bounds uv-tri))]
556 ;; get that part of the picture
558 (apply #(.setRoi image %1 %2 %3 %4) bounds)
559 (let [cutout (.crop (.getProcessor image))
560 ;; extract white pixels inside triangle
561 cutout-tri
562 (map-triangle
563 (fn [_ v]
564 (.subtract
565 v
566 (Vector3f. (bounds 0) (bounds 1) (float 0))))
567 uv-tri)
568 whites (filter (partial inside-triangle? cutout-tri)
569 (map vector2f->vector3f
570 (white-coordinates cutout)))
571 ;; translate pixel coordinates to world-space
572 transform (triangle-transformation cutout-tri tri)]
573 (map #(.mult transform %) whites))))]
577 (vec (map sensor-coords tris))))
579 (defn locate-tactile-sensors*
580 "Search the geometry's tactile UV image for touch sensors, returning
581 their positions in geometry-relative coordinates."
582 [#^Geometry geo]
583 (let [uv-image (touch-receptor-image geo)
584 width (.getWidth uv-image)
585 height (.getHeight uv-image)
587 mesh (.getMesh geo)
588 mesh-tris (triangles geo)
590 ;; for each triangle
591 sensor-coords
592 (fn [tri]
593 ;; translate triangle to uv-pixel-space
594 (let [uv-tri
595 (rasterize mesh tri width height)
596 bounds (vec (triangle-bounds uv-tri))]
598 ;; get that part of the picture
600 (apply (partial (memfn setRoi) uv-image) bounds)
601 (let [cutout (.crop (.getProcessor uv-image))
602 ;; extract white pixels inside triangle
603 cutout-tri
604 (map-triangle
605 (fn [_ v]
606 (.subtract
607 v
608 (Vector3f. (bounds 0) (bounds 1) (float 0))))
609 uv-tri)
610 whites (filter (partial inside-triangle? cutout-tri)
611 (map vector2f->vector3f
612 (white-coordinates cutout)))
613 ;; translate pixel coordinates to world-space
614 transform (triangle-transformation cutout-tri tri)]
615 (map #(.mult transform %) whites))))]
619 (for [mesh-tri mesh-tris]
621 (let [uv-tri (rasterize mesh mesh-tri width height)
622 bounding-box (vec (triangle-bounds uv-tri))]
623 (apply (partial (memfn setRoi) uv-image) bounding-box)
628 ))
629 (vec (map sensor-coords mesh-tris))))
633 (defn measure-touchies [#^Geometry geo]
634 (let [tactile-sensor-coords (locate-tactile-sensors geo)
635 tris (triangles geo)]
636 (fn [world]
637 (let [sensor-origins (vec
638 (map
639 #(map (partial local-to-world geo) %)
640 tactile-sensor-coords))
641 triangle-normals (vec
642 (map (partial get-ray-direction geo)
643 tris))
644 rays (flatten
645 (map
646 (fn [origins normals]
647 (map
648 #(Ray. %1 %2)
649 origins
650 normals))
651 sensor-origins
652 (map repeat triangle-normals)))
655 ]
656 rays))))
676 ;; for each triangle in the mesh,
677 ;; get the normal to the triangle,
678 ;; look at the UV touch map, restricted to that triangle,
679 ;; get the positions of those touch sensors in geometry-relative
680 ;; coordinates.
681 (defn tactile-coords [#^Geometry obj]
682 (let [mesh (.getMesh obj)
683 num-triangles (.getTriangleCount mesh)
684 num-verticies (.getVertexCount mesh)
685 uv-coord (partial uv-coord mesh)
686 triangle-indices (partial triangle-indices mesh)
687 receptors (touch-receptor-image obj)
688 tris (triangles obj)
689 ]
690 (map
691 (fn [[tri-1 tri-2 tri-3]]
692 (let [width (.getWidth receptors)
693 height (.getHeight receptors)
694 uv-1 (uv-coord tri-1)
695 uv-2 (uv-coord tri-2)
696 uv-3 (uv-coord tri-3)
697 x-coords (map #(.getX %) [uv-1 uv-2 uv-3])
698 y-coords (map #(.getY %) [uv-1 uv-2 uv-3])
699 max-x (Math/ceil (* width (apply max x-coords)))
700 min-x (Math/floor (* width (apply min x-coords)))
701 max-y (Math/ceil (* height (apply max y-coords)))
702 min-y (Math/floor (* height (apply min y-coords)))
704 image-1 (Vector2f. (* width (.getX uv-1))
705 (* height (.getY uv-1)))
706 image-2 (Vector2f. (* width (.getX uv-2))
707 (* height (.getY uv-2)))
708 image-3 (Vector2f. (* width (.getX uv-3))
709 (* height (.getY uv-3)))
710 left-corner
711 (Vector2f. min-x min-y)
712 ]
714 (.setRoi receptors min-x min-y (- max-x min-x) (- max-y min-y))
715 (let [processor (.crop (.getProcessor receptors))]
716 (map
717 #(.add left-corner %)
719 (filter
720 (partial
721 inside-triangle?
722 (.subtract image-1 left-corner)
723 (.subtract image-2 left-corner)
724 (.subtract image-3 left-corner))
725 (white-coordinates processor))))
726 )) (map triangle-indices (range num-triangles)))))
734 (defn all-names []
735 (concat
736 (re-split #"\n" (slurp (file-str
737 "/home/r/proj/names/dist.female.first")))
738 (re-split #"\n" (slurp (file-str
739 "/home/r/proj/names/dist.male.first")))
740 (re-split #"\n" (slurp (file-str
741 "/home/r/proj/names/dist.all.last")))))
751 (defrecord LulzLoader [])
752 (defprotocol Lulzable (load-lulz [this]))
753 (extend-type LulzLoader
754 Lulzable
755 (load-lulz [this] (println "the lulz have arrived!")))
758 (defn world-setup [joint]
759 (let [joint-position (Vector3f. 0 0 0)
760 joint-rotation
761 (.toRotationMatrix
762 (.mult
763 (doto (Quaternion.)
764 (.fromAngleAxis
765 (* 1 (/ Math/PI 4))
766 (Vector3f. -1 0 0)))
767 (doto (Quaternion.)
768 (.fromAngleAxis
769 (* 1 (/ Math/PI 2))
770 (Vector3f. 0 0 1)))))
771 top-position (.mult joint-rotation (Vector3f. 8 0 0))
773 origin (doto
774 (sphere 0.1 :physical? false :color ColorRGBA/Cyan
775 :position top-position))
776 top (doto
777 (sphere 0.1 :physical? false :color ColorRGBA/Yellow
778 :position top-position)
780 (.addControl
781 (RigidBodyControl.
782 (CapsuleCollisionShape. 0.5 1.5 1) (float 20))))
783 bottom (doto
784 (sphere 0.1 :physical? false :color ColorRGBA/DarkGray
785 :position (Vector3f. 0 0 0))
786 (.addControl
787 (RigidBodyControl.
788 (CapsuleCollisionShape. 0.5 1.5 1) (float 0))))
789 table (box 10 2 10 :position (Vector3f. 0 -20 0)
790 :color ColorRGBA/Gray :mass 0)
791 a (.getControl top RigidBodyControl)
792 b (.getControl bottom RigidBodyControl)]
794 (cond
795 (= joint :cone)
797 (doto (ConeJoint.
798 a b
799 (world-to-local top joint-position)
800 (world-to-local bottom joint-position)
801 joint-rotation
802 joint-rotation
803 )
806 (.setLimit (* (/ 10) Math/PI)
807 (* (/ 4) Math/PI)
808 0)))
809 [origin top bottom table]))
811 (defn test-joint [joint]
812 (let [[origin top bottom floor] (world-setup joint)
813 control (.getControl top RigidBodyControl)
814 move-up? (atom false)
815 move-down? (atom false)
816 move-left? (atom false)
817 move-right? (atom false)
818 roll-left? (atom false)
819 roll-right? (atom false)
820 timer (atom 0)]
822 (world
823 (nodify [top bottom floor origin])
824 (merge standard-debug-controls
825 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
826 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
827 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
828 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
829 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
830 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
832 (fn [world]
833 (light-up-everything world)
834 (enable-debug world)
835 (set-gravity world (Vector3f. 0 0 0))
836 )
838 (fn [world _]
839 (if (zero? (rem (swap! timer inc) 100))
840 (do
841 ;; (println-repl @timer)
842 (.attachChild (.getRootNode world)
843 (sphere 0.05 :color ColorRGBA/Yellow
844 :position (.getWorldTranslation top)
845 :physical? false))
846 (.attachChild (.getRootNode world)
847 (sphere 0.05 :color ColorRGBA/LightGray
848 :position (.getWorldTranslation bottom)
849 :physical? false))))
851 (if @move-up?
852 (.applyTorque control
853 (.mult (.getPhysicsRotation control)
854 (Vector3f. 0 0 10))))
855 (if @move-down?
856 (.applyTorque control
857 (.mult (.getPhysicsRotation control)
858 (Vector3f. 0 0 -10))))
859 (if @move-left?
860 (.applyTorque control
861 (.mult (.getPhysicsRotation control)
862 (Vector3f. 0 10 0))))
863 (if @move-right?
864 (.applyTorque control
865 (.mult (.getPhysicsRotation control)
866 (Vector3f. 0 -10 0))))
867 (if @roll-left?
868 (.applyTorque control
869 (.mult (.getPhysicsRotation control)
870 (Vector3f. -1 0 0))))
871 (if @roll-right?
872 (.applyTorque control
873 (.mult (.getPhysicsRotation control)
874 (Vector3f. 1 0 0))))))))
878 #+end_src
880 #+results: body-1
881 : #'cortex.silly/test-joint
884 * COMMENT purgatory
885 #+begin_src clojure
886 (defn bullet-trans []
887 (let [obj-a (sphere 0.5 :color ColorRGBA/Red
888 :position (Vector3f. -10 5 0))
889 obj-b (sphere 0.5 :color ColorRGBA/Blue
890 :position (Vector3f. -10 -5 0)
891 :mass 0)
892 control-a (.getControl obj-a RigidBodyControl)
893 control-b (.getControl obj-b RigidBodyControl)
894 swivel
895 (.toRotationMatrix
896 (doto (Quaternion.)
897 (.fromAngleAxis (/ Math/PI 2)
898 Vector3f/UNIT_X)))]
899 (doto
900 (ConeJoint.
901 control-a control-b
902 (Vector3f. 0 5 0)
903 (Vector3f. 0 -5 0)
904 swivel swivel)
905 (.setLimit (* 0.6 (/ Math/PI 4))
906 (/ Math/PI 4)
907 (* Math/PI 0.8)))
908 (world (nodify
909 [obj-a obj-b])
910 standard-debug-controls
911 enable-debug
912 no-op)))
915 (defn bullet-trans* []
916 (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red
917 :position (Vector3f. 5 0 0)
918 :mass 90)
919 obj-b (sphere 0.5 :color ColorRGBA/Blue
920 :position (Vector3f. -5 0 0)
921 :mass 0)
922 control-a (.getControl obj-a RigidBodyControl)
923 control-b (.getControl obj-b RigidBodyControl)
924 move-up? (atom nil)
925 move-down? (atom nil)
926 move-left? (atom nil)
927 move-right? (atom nil)
928 roll-left? (atom nil)
929 roll-right? (atom nil)
930 force 100
931 swivel
932 (.toRotationMatrix
933 (doto (Quaternion.)
934 (.fromAngleAxis (/ Math/PI 2)
935 Vector3f/UNIT_X)))
936 x-move
937 (doto (Matrix3f.)
938 (.fromStartEndVectors Vector3f/UNIT_X
939 (.normalize (Vector3f. 1 1 0))))
941 timer (atom 0)]
942 (doto
943 (ConeJoint.
944 control-a control-b
945 (Vector3f. -8 0 0)
946 (Vector3f. 2 0 0)
947 ;;swivel swivel
948 ;;Matrix3f/IDENTITY Matrix3f/IDENTITY
949 x-move Matrix3f/IDENTITY
950 )
951 (.setCollisionBetweenLinkedBodys false)
952 (.setLimit (* 1 (/ Math/PI 4)) ;; twist
953 (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane
954 (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane
955 (world (nodify
956 [obj-a obj-b])
957 (merge standard-debug-controls
958 {"key-r" (fn [_ pressed?] (reset! move-up? pressed?))
959 "key-t" (fn [_ pressed?] (reset! move-down? pressed?))
960 "key-f" (fn [_ pressed?] (reset! move-left? pressed?))
961 "key-g" (fn [_ pressed?] (reset! move-right? pressed?))
962 "key-v" (fn [_ pressed?] (reset! roll-left? pressed?))
963 "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))})
965 (fn [world]
966 (enable-debug world)
967 (set-gravity world Vector3f/ZERO)
968 )
970 (fn [world _]
972 (if @move-up?
973 (.applyForce control-a
974 (Vector3f. force 0 0)
975 (Vector3f. 0 0 0)))
976 (if @move-down?
977 (.applyForce control-a
978 (Vector3f. (- force) 0 0)
979 (Vector3f. 0 0 0)))
980 (if @move-left?
981 (.applyForce control-a
982 (Vector3f. 0 force 0)
983 (Vector3f. 0 0 0)))
984 (if @move-right?
985 (.applyForce control-a
986 (Vector3f. 0 (- force) 0)
987 (Vector3f. 0 0 0)))
989 (if @roll-left?
990 (.applyForce control-a
991 (Vector3f. 0 0 force)
992 (Vector3f. 0 0 0)))
993 (if @roll-right?
994 (.applyForce control-a
995 (Vector3f. 0 0 (- force))
996 (Vector3f. 0 0 0)))
998 (if (zero? (rem (swap! timer inc) 100))
999 (.attachChild
1000 (.getRootNode world)
1001 (sphere 0.05 :color ColorRGBA/Yellow
1002 :physical? false :position
1003 (.getWorldTranslation obj-a)))))
1005 ))
1009 #+end_src
1012 * COMMENT generate source
1013 #+begin_src clojure :tangle ../src/cortex/silly.clj
1014 <<body-1>>
1015 #+end_src
1021 (defn transform-trianglesdsd
1022 "Transform that converts each vertex in the first triangle
1023 into the corresponding vertex in the second triangle."
1024 [#^Triangle tri-1 #^Triangle tri-2]
1025 (let [in [(.get1 tri-1)
1026 (.get2 tri-1)
1027 (.get3 tri-1)]
1028 out [(.get1 tri-2)
1029 (.get2 tri-2)
1030 (.get3 tri-2)]]
1031 (let [translate (doto (Matrix4f.) (.setTranslation (.negate (in 0))))
1032 in* [(.mult translate (in 0))
1033 (.mult translate (in 1))
1034 (.mult translate (in 2))]
1035 final-translation
1036 (doto (Matrix4f.)
1037 (.setTranslation (out 1)))
1039 rotate-1
1040 (doto (Matrix3f.)
1041 (.fromStartEndVectors
1042 (.normalize
1043 (.subtract
1044 (in* 1) (in* 0)))
1045 (.normalize
1046 (.subtract
1047 (out 1) (out 0)))))
1048 in** [(.mult rotate-1 (in* 0))
1049 (.mult rotate-1 (in* 1))
1050 (.mult rotate-1 (in* 2))]
1051 scale-factor-1
1052 (.mult
1053 (.normalize
1054 (.subtract
1055 (out 1)
1056 (out 0)))
1057 (/ (.length
1058 (.subtract (out 1)
1059 (out 0)))
1060 (.length
1061 (.subtract (in** 1)
1062 (in** 0)))))
1063 scale-1 (doto (Matrix4f.) (.setScale scale-factor-1))
1064 in*** [(.mult scale-1 (in** 0))
1065 (.mult scale-1 (in** 1))
1066 (.mult scale-1 (in** 2))]
1074 (dorun (map println in))
1075 (println)
1076 (dorun (map println in*))
1077 (println)
1078 (dorun (map println in**))
1079 (println)
1080 (dorun (map println in***))
1081 (println)
1083 )))