diff org/body.org @ 203:0e5d5ee5a914

first draft of body.org complete
author Robert McIntyre <rlm@mit.edu>
date Wed, 08 Feb 2012 08:53:12 -0700
parents d5c597a7aed4
children 162b24a82712
line wrap: on
line diff
     1.1 --- a/org/body.org	Wed Feb 08 05:50:15 2012 -0700
     1.2 +++ b/org/body.org	Wed Feb 08 08:53:12 2012 -0700
     1.3 @@ -38,14 +38,22 @@
     1.4  
     1.5  The main reason that I use eve-style bodies is so that there will be
     1.6  correspondence between the AI's vision and the physical presence of
     1.7 -its body. 
     1.8 +its body. Each individual section is simulated by a separate rigid
     1.9 +body that corresponds exactly with its visual representation and does
    1.10 +not change. Sections are connected by invisible joints that are well
    1.11 +supported in jMonkyeEngine. Bullet, the physics backend for
    1.12 +jMonkeyEngine, can efficiently simulate hundreds of rigid bodies
    1.13 +connected by joints. Sections do not have to stay as one piece
    1.14 +forever; they can be dynamically replaced with multiple sections to
    1.15 +simulate splitting in two. This could be used to simulate retractable
    1.16 +claws or EVE's hands, which could coalece into one object in the
    1.17 +movie.
    1.18  
    1.19  * Solidifying the Body
    1.20  
    1.21  Here is a hand designed eve-style in blender.
    1.22  
    1.23 -
    1.24 -#+attr_html: width="500"
    1.25 +#+attr_html: width="755"
    1.26  [[../images/hand-screenshot0.png]]
    1.27  
    1.28  If we load it directly into jMonkeyEngine, we get this:
    1.29 @@ -92,10 +100,16 @@
    1.30  #+end_src
    1.31  
    1.32  #+begin_html
    1.33 -<video controls="controls" width="755">
    1.34 +<div class="figure">
    1.35 +<center>
    1.36 +<video controls="controls" width="640">
    1.37    <source src="../video/ghost-hand.ogg" type="video/ogg"
    1.38  	  preload="none" poster="../images/aurellem-1280x480.png" />
    1.39  </video>
    1.40 +</center>
    1.41 +<p>The hand model directly loaded from blender. It has no physical
    1.42 +  presense in the simulation. </p>
    1.43 +</div>
    1.44  #+end_html
    1.45  
    1.46  You will notice that the hand has no physical presence -- it's a
    1.47 @@ -106,7 +120,7 @@
    1.48  specify the mass of each object in blender and construct the physics
    1.49  shape based on the mesh in jMonkeyEngine.
    1.50  
    1.51 -#+name: joints-1
    1.52 +#+name: body-1
    1.53  #+begin_src clojure
    1.54  (defn physical!
    1.55    "Iterate through the nodes in creature and make them real physical
    1.56 @@ -134,6 +148,7 @@
    1.57  CollisionShapes for each geometry with the mass specified in that
    1.58  geometry's meta-data.
    1.59  
    1.60 +#+name: test-1
    1.61  #+begin_src clojure 
    1.62  (in-ns 'cortex.test.body)
    1.63  
    1.64 @@ -160,10 +175,16 @@
    1.65  #+end_src
    1.66  
    1.67  #+begin_html
    1.68 -<video controls="controls" width="755">
    1.69 +<div class="figure">
    1.70 +<center>
    1.71 +<video controls="controls" width="640">
    1.72    <source src="../video/crumbly-hand.ogg" type="video/ogg"
    1.73  	  preload="none" poster="../images/aurellem-1280x480.png" />
    1.74  </video>
    1.75 +</center>
    1.76 +<p>The hand now has a physical presence, but there is nothing to hold
    1.77 +it together.</p>
    1.78 +</div>
    1.79  #+end_html
    1.80  
    1.81  Now that's some progress.
    1.82 @@ -188,12 +209,44 @@
    1.83  has the name "joints". Their orientation and meta-data determine what
    1.84  joint is created.
    1.85  
    1.86 +#+attr_html: width="755"
    1.87 +#+caption: joints hack in blender. Each empty node here will be transformed into a joint in jMonkeyEngine
    1.88  [[../images/hand-screenshot1.png]]
    1.89  
    1.90 +The empty node in the upper right, highlighted in yellow, is the
    1.91 +parent node of all the emptys which represent joints. The following
    1.92 +functions must do three things to translate these into real joints:
    1.93  
    1.94 + - Find the children of the "joints" node.
    1.95 + - Determine the two spatials the joint it meant to connect.
    1.96 + - Create the joint based on the meta-data of the empty node.
    1.97  
    1.98 +** Finding the Joints 
    1.99 +#+name: joints-2 
   1.100 +#+begin_src clojure
   1.101 +(defvar 
   1.102 +  ^{:arglists '([creature])}
   1.103 +  joints
   1.104 +  (sense-nodes "joints")
   1.105 +  "Return the children of the creature's \"joints\" node.")
   1.106 +#+end_src
   1.107  
   1.108 -#+name: joints-2
   1.109 +The higher order function =(sense-nodes)= from cortex.sense makes our
   1.110 +first task very easy.
   1.111 +
   1.112 +** Joint Targets and Orientation
   1.113 +
   1.114 +This technique for finding a joint's targets is very similiar to
   1.115 +=(cortex.sense/closest-node)=.  A small cube, centered around the
   1.116 +empty-node, grows exponentially until it intersects two /physical/
   1.117 +objects. The objects are ordered according to the joint's rotation,
   1.118 +with the first one being the object that has more negative coordinates
   1.119 +in the joint's reference frame. Since the objects must be physical,
   1.120 +the empty-node itself escapes detection. Because the objects must be
   1.121 +physical, =(joint-targets)= must be called /after/ =(physical!)= is
   1.122 +called.
   1.123 +
   1.124 +#+name: joints-3
   1.125  #+begin_src clojure 
   1.126  (defn joint-targets
   1.127    "Return the two closest two objects to the joint object, ordered
   1.128 @@ -222,7 +275,16 @@
   1.129                      v))                  
   1.130             (take 2 targets))
   1.131            (recur (float (* radius 2))))))))
   1.132 +#+end_src
   1.133  
   1.134 +** Generating Joints
   1.135 +
   1.136 +This long chunk of code iterates through all the different ways of
   1.137 +specifying joints using blender meta-data and converts each one to the
   1.138 +appropriate jMonkyeEngine joint.
   1.139 +
   1.140 +#+name: joints-4
   1.141 +#+begin_src clojure
   1.142  (defmulti joint-dispatch
   1.143    "Translate blender pseudo-joints into real JME joints."
   1.144    (fn [constraints & _] 
   1.145 @@ -252,12 +314,7 @@
   1.146         pivot-b
   1.147         false)
   1.148      (.setLinearLowerLimit Vector3f/ZERO)
   1.149 -    (.setLinearUpperLimit Vector3f/ZERO)
   1.150 -    ;;(.setAngularLowerLimit (Vector3f. 1 1 1))
   1.151 -    ;;(.setAngularUpperLimit (Vector3f. 0 0 0))
   1.152 -
   1.153 -))
   1.154 -
   1.155 +    (.setLinearUpperLimit Vector3f/ZERO)))
   1.156  
   1.157  (defmethod joint-dispatch :hinge
   1.158    [constraints control-a control-b pivot-a pivot-b rotation]
   1.159 @@ -345,13 +402,12 @@
   1.160                          pivot-a pivot-b
   1.161                          joint-rotation))
   1.162        (println-repl "could not find joint meta-data!"))))
   1.163 +#+end_src
   1.164  
   1.165 -(defvar 
   1.166 -  ^{:arglists '([creature])}
   1.167 -  joints
   1.168 -  (sense-nodes "joints")
   1.169 -  "Return the children of the creature's \"joints\" node.")
   1.170 +Creating joints is now a matter applying =(connect)= to each joint
   1.171 +node.
   1.172  
   1.173 +#+begin_src clojure
   1.174  (defn joints!
   1.175    "Connect the solid parts of the creature with physical joints. The
   1.176     joints are taken from the \"joints\" node in the creature."
   1.177 @@ -362,7 +418,66 @@
   1.178        (let [[obj-a obj-b] (joint-targets creature joint)]
   1.179          (connect obj-a obj-b joint)))
   1.180      (joints creature))))
   1.181 +#+end_src
   1.182  
   1.183 +
   1.184 +** Round 3
   1.185 +
   1.186 +Now we can test the hand in all its glory.
   1.187 +
   1.188 +#+begin_src clojure 
   1.189 +(in-ns 'cortex.test.body)
   1.190 +
   1.191 +(def debug-control 
   1.192 +  {"key-h" (fn [world val]
   1.193 +             (if val (enable-debug world)))
   1.194 +
   1.195 +   "key-u" (fn [world _] (set-gravity world Vector3f/ZERO))
   1.196 +   })
   1.197 +  
   1.198 +(defn test-three []
   1.199 +  (world (nodify
   1.200 +          [(doto (hand)
   1.201 +           (physical!)
   1.202 +           (joints!) )
   1.203 +           (floor)])
   1.204 +         (merge standard-debug-controls debug-control
   1.205 +                normal-gravity)
   1.206 +         (comp
   1.207 +          #(Capture/captureVideo
   1.208 +            % (File. "/home/r/proj/cortex/render/body/3"))
   1.209 +          #(do (set-gravity % Vector3f/ZERO) %)
   1.210 +          setup)
   1.211 +         no-op))
   1.212 +#+end_src
   1.213 +
   1.214 +=(physical!)= makes the hand solid, then =(joints!)= connects each
   1.215 +piece together. 
   1.216 +
   1.217 +
   1.218 +#+begin_html
   1.219 +<div class="figure">
   1.220 +<center>
   1.221 +<video controls="controls" width="640">
   1.222 +  <source src="../video/full-hand.ogg" type="video/ogg"
   1.223 +	  preload="none" poster="../images/aurellem-1280x480.png" />
   1.224 +</video>
   1.225 +</center>
   1.226 +<p>Now the hand is physical and has joints.</p>
   1.227 +</div>
   1.228 +#+end_html
   1.229 +
   1.230 +The joints are visualized as green connections between each segment
   1.231 +for debug purposes. You can see that they correspond to the empty
   1.232 +nodes in the blender file.
   1.233 +
   1.234 +* Wrap-Up!
   1.235 +
   1.236 +It is convienent to combine =(physical!)= and =(joints!)= into one
   1.237 +function that completely creates the creature's physical body.
   1.238 +
   1.239 +#+name: joints-4
   1.240 +#+begin_src clojure
   1.241  (defn body!
   1.242    "Endow the creature with a physical body connected with joints.  The
   1.243     particulars of the joints and the masses of each pody part are
   1.244 @@ -374,6 +489,8 @@
   1.245  
   1.246  * Bookkeeping
   1.247  
   1.248 +Header; here for completeness.
   1.249 +
   1.250  #+name: body-0
   1.251  #+begin_src clojure
   1.252  (ns cortex.body
   1.253 @@ -397,6 +514,11 @@
   1.254  
   1.255  * Source 
   1.256  
   1.257 +Dylan -- I'll fill these in later
   1.258 +- cortex.body
   1.259 +- cortex.test.body
   1.260 +- blender files
   1.261 +
   1.262  * COMMENT Examples
   1.263  
   1.264  #+name: test-body