changeset 112:128fa71ee188

working on retina design
author Robert McIntyre <rlm@mit.edu>
date Thu, 19 Jan 2012 11:29:46 -0700
parents 61d9c0e8d188
children a980462ebe76
files assets/Models/creature1/retina-uv.png assets/Models/creature1/retina.png assets/Models/creature1/retina.xcf assets/Models/creature1/try-again.blend org/eyes.org org/test-creature.org
diffstat 6 files changed, 102 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
     1.1 Binary file assets/Models/creature1/retina-uv.png has changed
     2.1 Binary file assets/Models/creature1/retina.png has changed
     3.1 Binary file assets/Models/creature1/retina.xcf has changed
     4.1 Binary file assets/Models/creature1/try-again.blend has changed
     5.1 --- a/org/eyes.org	Thu Jan 19 08:09:15 2012 -0700
     5.2 +++ b/org/eyes.org	Thu Jan 19 11:29:46 2012 -0700
     5.3 @@ -20,7 +20,7 @@
     5.4    {:author "Robert McIntyre"}
     5.5    (:use cortex.world)
     5.6    (:import com.jme3.post.SceneProcessor)
     5.7 -  (:import (com.jme3.util Screenshots BufferUtils))
     5.8 +  (:import (com.jme3.util BufferUtils))
     5.9    (:import java.nio.ByteBuffer)
    5.10    (:import java.awt.image.BufferedImage)
    5.11    (:import com.jme3.renderer.ViewPort)
    5.12 @@ -31,11 +31,10 @@
    5.13    continuation function. The SceneProcessor will take care of
    5.14    converting the rendered frame to a BufferedImage and passing that
    5.15    BufferedImage to the continuation.  The continuation should be a
    5.16 -  function that takes a BufferedImage."
    5.17 +  function that takes a ByteBuffer which represents the image."
    5.18    [continuation]
    5.19    (let [byte-buffer (atom nil)
    5.20 -	renderer (atom nil)
    5.21 -	image (atom nil)]
    5.22 +	renderer (atom nil)]
    5.23    (proxy [SceneProcessor] []
    5.24      (initialize
    5.25       [renderManager viewPort]
    5.26 @@ -45,10 +44,7 @@
    5.27         (reset! renderer (.getRenderer renderManager))
    5.28         (reset! byte-buffer
    5.29  	     (BufferUtils/createByteBuffer
    5.30 -	      (* width height 4)))
    5.31 -       (reset! image (BufferedImage.
    5.32 -                      width height
    5.33 -                      BufferedImage/TYPE_4BYTE_ABGR))))
    5.34 +	      (* width height 4)))))
    5.35      (isInitialized [] (not (nil? @byte-buffer)))
    5.36      (reshape [_ _ _])
    5.37      (preFrame [_])
    5.38 @@ -56,11 +52,17 @@
    5.39      (postFrame
    5.40       [#^FrameBuffer fb]
    5.41       (.clear @byte-buffer)
    5.42 -     (.readFrameBuffer @renderer fb @byte-buffer)
    5.43 -     (Screenshots/convertScreenShot @byte-buffer @image)
    5.44 -     (continuation @image))
    5.45 +     ;;(.readFrameBuffer @renderer fb @byte-buffer)
    5.46 +     (continuation @byte-buffer))
    5.47      (cleanup []))))
    5.48      
    5.49 +(defn buffer->image! [width height]
    5.50 +  (let [image (BufferedImage. width height
    5.51 +                              BufferedImage/TYPE_4BYTE_ABGR)]
    5.52 +    (fn [byte-buffer]
    5.53 +      (Screenshots/convertScreenShot byte-buffer image)
    5.54 +      image)))
    5.55 +
    5.56  (defn add-eye
    5.57    "Add an eye to the world, calling continuation on every frame
    5.58    produced." 
    5.59 @@ -71,11 +73,14 @@
    5.60  	viewport (.createMainView render-manager "eye-view" camera)]
    5.61      (doto viewport
    5.62        (.setClearFlags true true true)
    5.63 -      (.setBackgroundColor ColorRGBA/Gray)
    5.64 +      (.setBackgroundColor ColorRGBA/Black)
    5.65        (.addProcessor (scene-processor continuation))
    5.66        (.attachScene (.getRootNode world)))))
    5.67  #+end_src
    5.68  
    5.69 +#+results: eyes
    5.70 +: #'cortex.vision/add-eye
    5.71 +
    5.72  Note the use of continuation passing style for connecting the eye to a
    5.73  function to process the output. You can create any number of eyes, and
    5.74  each of them will see the world from their own =Camera=. Once every
    5.75 @@ -96,7 +101,8 @@
    5.76    (:import javax.swing.JFrame)
    5.77    (:import com.jme3.math.ColorRGBA)
    5.78    (:import com.jme3.scene.Node)
    5.79 -  (:import com.jme3.math.Vector3f))
    5.80 +  (:import com.jme3.math.Vector3f)
    5.81 +  (:import (com.jme3.util Screenshots)))
    5.82  
    5.83  (defn view-image
    5.84    "Initailizes a JPanel on which you may draw a BufferedImage.
    5.85 @@ -137,26 +143,37 @@
    5.86    []
    5.87    (let [candy
    5.88          (box 1 1 1 :physical? false :color ColorRGBA/Blue)]
    5.89 -    (world (doto (Node.)
    5.90 -             (.attachChild candy))
    5.91 -           {}
    5.92 -           (fn [world]
    5.93 -             (let [cam (.clone (.getCamera world))
    5.94 -                   width (.getWidth cam)
    5.95 -                   height (.getHeight cam)]
    5.96 -               (add-eye world cam (view-image))
    5.97 -               (add-eye world
    5.98 -                        (doto (.clone cam)
    5.99 -                          (.setLocation (Vector3f. -10 0 0))
   5.100 -                          (.lookAt Vector3f/ZERO Vector3f/UNIT_Y))
   5.101 -                        (view-image))
   5.102 -                ;; This is here to restore the main view
   5.103 -               ;; after the other views have completed processing
   5.104 -               (add-eye world (.getCamera world) no-op)))
   5.105 -           (fn [world tpf]
   5.106 -             (.rotate candy (* tpf 0.2) 0 0)))))
   5.107 +    (world
   5.108 +     (doto (Node.)
   5.109 +       (.attachChild candy))
   5.110 +     {}
   5.111 +     (fn [world]
   5.112 +       (let [cam (.clone (.getCamera world))
   5.113 +             width (.getWidth cam)
   5.114 +             height (.getHeight cam)]
   5.115 +         (add-eye world cam 
   5.116 +                  no-op
   5.117 +                  ;;(comp (view-image) (buffer->image! width height))
   5.118 +                  )
   5.119 +         (add-eye world
   5.120 +                  (doto (.clone cam)
   5.121 +                    (.setLocation (Vector3f. -10 0 0))
   5.122 +                    (.lookAt Vector3f/ZERO Vector3f/UNIT_Y))
   5.123 +                  no-op
   5.124 +                  ;;(comp (view-image) (buffer->image! width height))
   5.125 +                  )
   5.126 +         
   5.127 +         
   5.128 +         ;; This is here to restore the main view
   5.129 +         ;; after the other views have completed processing
   5.130 +         (add-eye world (.getCamera world) no-op)))
   5.131 +     (fn [world tpf]
   5.132 +       (.rotate candy (* tpf 0.2) 0 0)))))
   5.133  #+end_src
   5.134  
   5.135 +#+results: test-vision
   5.136 +: #'cortex.test.vision/test-two-eyes
   5.137 +
   5.138  The example code will create two videos of the same rotating object
   5.139  from different angles. It can be used both for stereoscopic vision
   5.140  simulation or for simulating multiple creatures, each with their own
     6.1 --- a/org/test-creature.org	Thu Jan 19 08:09:15 2012 -0700
     6.2 +++ b/org/test-creature.org	Thu Jan 19 11:29:46 2012 -0700
     6.3 @@ -455,11 +455,14 @@
     6.4  
     6.5  (defn white-coordinates
     6.6    "Coordinates of all the white pixels in a subset of the image."
     6.7 -  [#^BufferedImage image bounds]
     6.8 -  (filter-pixels #(= % white) image bounds))
     6.9 +  ([#^BufferedImage image bounds]
    6.10 +     (filter-pixels #(= % white) image bounds))
    6.11 +  ([#^BufferedImage image]
    6.12 +     (filter-pixels #(= % white) image)))
    6.13  
    6.14  (defn triangle
    6.15 -  "Get the triangle specified by triangle-index from the mesh"
    6.16 +  "Get the triangle specified by triangle-index from the mesh within
    6.17 +  bounds."
    6.18    [#^Mesh mesh triangle-index]
    6.19    (let [scratch (Triangle.)]
    6.20      (.getTriangle mesh triangle-index scratch)
    6.21 @@ -687,8 +690,56 @@
    6.22         eye-map))))
    6.23  
    6.24  
    6.25 +(defn enable-vision
    6.26  
    6.27 +  ;; need to create a camera based on uv image,
    6.28 +  ;; update this camera every frame based on the position of this
    6.29 +  ;; geometry. (maybe can get cam to follow the object)
    6.30  
    6.31 +  ;; use a stack for the continuation to grab the image.
    6.32 +  
    6.33 +
    6.34 +  [#^Geometry eye]
    6.35 +  
    6.36 +
    6.37 +  ;; Here's how vision will work.
    6.38 +
    6.39 +  ;; Make the continuation in scene-processor take FrameBuffer,
    6.40 +  ;; byte-buffer, BufferedImage already sized to the correct
    6.41 +  ;; dimensions. the continuation will decide wether to "mix" them
    6.42 +  ;; into the BufferedImage, lazily ignore them, or mix them halfway
    6.43 +  ;; and call c/graphics card routines.
    6.44 +  
    6.45 +  ;; (vision creature) will take an optional :skip argument which will
    6.46 +  ;; inform the continuations in scene processor to skip the given
    6.47 +  ;; number of cycles; 0 means that no cycles will be skipped.
    6.48 +
    6.49 +  ;; (vision creature) will return [init-functions sensor-functions].
    6.50 +  ;; The init-functions are each single-arg functions that take the
    6.51 +  ;; world and register the cameras and must each be called before the
    6.52 +  ;; corresponding sensor-functions.  Each init-function returns the
    6.53 +  ;; viewport for that eye which can be manipulated, saved, etc. Each
    6.54 +  ;; sensor-function is a thunk and will return data in the same
    6.55 +  ;; format as the tactile-sensor functions; the structure is
    6.56 +  ;; [topology, sensor-data]. Internally, these sensor-functions
    6.57 +  ;; maintain a reference to sensor-data which is periodically updated
    6.58 +  ;; by the continuation function established by its init-function.
    6.59 +  ;; They can be queried every cycle, but their information may not
    6.60 +  ;; necessairly be different every cycle.
    6.61 +
    6.62 +  ;; Each eye in the creature in blender will work the same way as
    6.63 +  ;; joints -- a one dimensional object with no geometry whose local
    6.64 +  ;; coordinate system determines the orientation of the resulting
    6.65 +  ;; eye. All eyes will have a parent named "eyes" just as all joints
    6.66 +  ;; have a parent named "joints". The resulting camera will be a
    6.67 +  ;; ChaseCamera or a CameraNode bound to the geo that is closest to
    6.68 +  ;; the eye marker. The eye marker will contain the metadata for the
    6.69 +  ;; eye, and will be moved by it's bound geometry. The dimensions of
    6.70 +  ;; the eye's camera are equal to the dimensions of the eye's "UV"
    6.71 +  ;; map. 
    6.72 +  
    6.73 +
    6.74 +)
    6.75  
    6.76  (defn debug-window
    6.77    "creates function that offers a debug view of sensor data"