Mercurial > cortex
changeset 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 |
files | assets/Models/test-creature/hand.blend org/body.org |
diffstat | 2 files changed, 140 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
1.1 Binary file assets/Models/test-creature/hand.blend has changed
2.1 --- a/org/body.org Wed Feb 08 05:50:15 2012 -0700 2.2 +++ b/org/body.org Wed Feb 08 08:53:12 2012 -0700 2.3 @@ -38,14 +38,22 @@ 2.4 2.5 The main reason that I use eve-style bodies is so that there will be 2.6 correspondence between the AI's vision and the physical presence of 2.7 -its body. 2.8 +its body. Each individual section is simulated by a separate rigid 2.9 +body that corresponds exactly with its visual representation and does 2.10 +not change. Sections are connected by invisible joints that are well 2.11 +supported in jMonkyeEngine. Bullet, the physics backend for 2.12 +jMonkeyEngine, can efficiently simulate hundreds of rigid bodies 2.13 +connected by joints. Sections do not have to stay as one piece 2.14 +forever; they can be dynamically replaced with multiple sections to 2.15 +simulate splitting in two. This could be used to simulate retractable 2.16 +claws or EVE's hands, which could coalece into one object in the 2.17 +movie. 2.18 2.19 * Solidifying the Body 2.20 2.21 Here is a hand designed eve-style in blender. 2.22 2.23 - 2.24 -#+attr_html: width="500" 2.25 +#+attr_html: width="755" 2.26 [[../images/hand-screenshot0.png]] 2.27 2.28 If we load it directly into jMonkeyEngine, we get this: 2.29 @@ -92,10 +100,16 @@ 2.30 #+end_src 2.31 2.32 #+begin_html 2.33 -<video controls="controls" width="755"> 2.34 +<div class="figure"> 2.35 +<center> 2.36 +<video controls="controls" width="640"> 2.37 <source src="../video/ghost-hand.ogg" type="video/ogg" 2.38 preload="none" poster="../images/aurellem-1280x480.png" /> 2.39 </video> 2.40 +</center> 2.41 +<p>The hand model directly loaded from blender. It has no physical 2.42 + presense in the simulation. </p> 2.43 +</div> 2.44 #+end_html 2.45 2.46 You will notice that the hand has no physical presence -- it's a 2.47 @@ -106,7 +120,7 @@ 2.48 specify the mass of each object in blender and construct the physics 2.49 shape based on the mesh in jMonkeyEngine. 2.50 2.51 -#+name: joints-1 2.52 +#+name: body-1 2.53 #+begin_src clojure 2.54 (defn physical! 2.55 "Iterate through the nodes in creature and make them real physical 2.56 @@ -134,6 +148,7 @@ 2.57 CollisionShapes for each geometry with the mass specified in that 2.58 geometry's meta-data. 2.59 2.60 +#+name: test-1 2.61 #+begin_src clojure 2.62 (in-ns 'cortex.test.body) 2.63 2.64 @@ -160,10 +175,16 @@ 2.65 #+end_src 2.66 2.67 #+begin_html 2.68 -<video controls="controls" width="755"> 2.69 +<div class="figure"> 2.70 +<center> 2.71 +<video controls="controls" width="640"> 2.72 <source src="../video/crumbly-hand.ogg" type="video/ogg" 2.73 preload="none" poster="../images/aurellem-1280x480.png" /> 2.74 </video> 2.75 +</center> 2.76 +<p>The hand now has a physical presence, but there is nothing to hold 2.77 +it together.</p> 2.78 +</div> 2.79 #+end_html 2.80 2.81 Now that's some progress. 2.82 @@ -188,12 +209,44 @@ 2.83 has the name "joints". Their orientation and meta-data determine what 2.84 joint is created. 2.85 2.86 +#+attr_html: width="755" 2.87 +#+caption: joints hack in blender. Each empty node here will be transformed into a joint in jMonkeyEngine 2.88 [[../images/hand-screenshot1.png]] 2.89 2.90 +The empty node in the upper right, highlighted in yellow, is the 2.91 +parent node of all the emptys which represent joints. The following 2.92 +functions must do three things to translate these into real joints: 2.93 2.94 + - Find the children of the "joints" node. 2.95 + - Determine the two spatials the joint it meant to connect. 2.96 + - Create the joint based on the meta-data of the empty node. 2.97 2.98 +** Finding the Joints 2.99 +#+name: joints-2 2.100 +#+begin_src clojure 2.101 +(defvar 2.102 + ^{:arglists '([creature])} 2.103 + joints 2.104 + (sense-nodes "joints") 2.105 + "Return the children of the creature's \"joints\" node.") 2.106 +#+end_src 2.107 2.108 -#+name: joints-2 2.109 +The higher order function =(sense-nodes)= from cortex.sense makes our 2.110 +first task very easy. 2.111 + 2.112 +** Joint Targets and Orientation 2.113 + 2.114 +This technique for finding a joint's targets is very similiar to 2.115 +=(cortex.sense/closest-node)=. A small cube, centered around the 2.116 +empty-node, grows exponentially until it intersects two /physical/ 2.117 +objects. The objects are ordered according to the joint's rotation, 2.118 +with the first one being the object that has more negative coordinates 2.119 +in the joint's reference frame. Since the objects must be physical, 2.120 +the empty-node itself escapes detection. Because the objects must be 2.121 +physical, =(joint-targets)= must be called /after/ =(physical!)= is 2.122 +called. 2.123 + 2.124 +#+name: joints-3 2.125 #+begin_src clojure 2.126 (defn joint-targets 2.127 "Return the two closest two objects to the joint object, ordered 2.128 @@ -222,7 +275,16 @@ 2.129 v)) 2.130 (take 2 targets)) 2.131 (recur (float (* radius 2)))))))) 2.132 +#+end_src 2.133 2.134 +** Generating Joints 2.135 + 2.136 +This long chunk of code iterates through all the different ways of 2.137 +specifying joints using blender meta-data and converts each one to the 2.138 +appropriate jMonkyeEngine joint. 2.139 + 2.140 +#+name: joints-4 2.141 +#+begin_src clojure 2.142 (defmulti joint-dispatch 2.143 "Translate blender pseudo-joints into real JME joints." 2.144 (fn [constraints & _] 2.145 @@ -252,12 +314,7 @@ 2.146 pivot-b 2.147 false) 2.148 (.setLinearLowerLimit Vector3f/ZERO) 2.149 - (.setLinearUpperLimit Vector3f/ZERO) 2.150 - ;;(.setAngularLowerLimit (Vector3f. 1 1 1)) 2.151 - ;;(.setAngularUpperLimit (Vector3f. 0 0 0)) 2.152 - 2.153 -)) 2.154 - 2.155 + (.setLinearUpperLimit Vector3f/ZERO))) 2.156 2.157 (defmethod joint-dispatch :hinge 2.158 [constraints control-a control-b pivot-a pivot-b rotation] 2.159 @@ -345,13 +402,12 @@ 2.160 pivot-a pivot-b 2.161 joint-rotation)) 2.162 (println-repl "could not find joint meta-data!")))) 2.163 +#+end_src 2.164 2.165 -(defvar 2.166 - ^{:arglists '([creature])} 2.167 - joints 2.168 - (sense-nodes "joints") 2.169 - "Return the children of the creature's \"joints\" node.") 2.170 +Creating joints is now a matter applying =(connect)= to each joint 2.171 +node. 2.172 2.173 +#+begin_src clojure 2.174 (defn joints! 2.175 "Connect the solid parts of the creature with physical joints. The 2.176 joints are taken from the \"joints\" node in the creature." 2.177 @@ -362,7 +418,66 @@ 2.178 (let [[obj-a obj-b] (joint-targets creature joint)] 2.179 (connect obj-a obj-b joint))) 2.180 (joints creature)))) 2.181 +#+end_src 2.182 2.183 + 2.184 +** Round 3 2.185 + 2.186 +Now we can test the hand in all its glory. 2.187 + 2.188 +#+begin_src clojure 2.189 +(in-ns 'cortex.test.body) 2.190 + 2.191 +(def debug-control 2.192 + {"key-h" (fn [world val] 2.193 + (if val (enable-debug world))) 2.194 + 2.195 + "key-u" (fn [world _] (set-gravity world Vector3f/ZERO)) 2.196 + }) 2.197 + 2.198 +(defn test-three [] 2.199 + (world (nodify 2.200 + [(doto (hand) 2.201 + (physical!) 2.202 + (joints!) ) 2.203 + (floor)]) 2.204 + (merge standard-debug-controls debug-control 2.205 + normal-gravity) 2.206 + (comp 2.207 + #(Capture/captureVideo 2.208 + % (File. "/home/r/proj/cortex/render/body/3")) 2.209 + #(do (set-gravity % Vector3f/ZERO) %) 2.210 + setup) 2.211 + no-op)) 2.212 +#+end_src 2.213 + 2.214 +=(physical!)= makes the hand solid, then =(joints!)= connects each 2.215 +piece together. 2.216 + 2.217 + 2.218 +#+begin_html 2.219 +<div class="figure"> 2.220 +<center> 2.221 +<video controls="controls" width="640"> 2.222 + <source src="../video/full-hand.ogg" type="video/ogg" 2.223 + preload="none" poster="../images/aurellem-1280x480.png" /> 2.224 +</video> 2.225 +</center> 2.226 +<p>Now the hand is physical and has joints.</p> 2.227 +</div> 2.228 +#+end_html 2.229 + 2.230 +The joints are visualized as green connections between each segment 2.231 +for debug purposes. You can see that they correspond to the empty 2.232 +nodes in the blender file. 2.233 + 2.234 +* Wrap-Up! 2.235 + 2.236 +It is convienent to combine =(physical!)= and =(joints!)= into one 2.237 +function that completely creates the creature's physical body. 2.238 + 2.239 +#+name: joints-4 2.240 +#+begin_src clojure 2.241 (defn body! 2.242 "Endow the creature with a physical body connected with joints. The 2.243 particulars of the joints and the masses of each pody part are 2.244 @@ -374,6 +489,8 @@ 2.245 2.246 * Bookkeeping 2.247 2.248 +Header; here for completeness. 2.249 + 2.250 #+name: body-0 2.251 #+begin_src clojure 2.252 (ns cortex.body 2.253 @@ -397,6 +514,11 @@ 2.254 2.255 * Source 2.256 2.257 +Dylan -- I'll fill these in later 2.258 +- cortex.body 2.259 +- cortex.test.body 2.260 +- blender files 2.261 + 2.262 * COMMENT Examples 2.263 2.264 #+name: test-body