Mercurial > cortex
changeset 77:1f84f425e05d
first draft of automatic constraints from blender
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 04 Jan 2012 08:36:42 -0700 |
parents | 5e75b616ca60 |
children | 77b506ac64f3 |
files | assets/Models/creature1/one.blend assets/Models/creature1/try-again.blend org/test-creature.org |
diffstat | 3 files changed, 448 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
1.1 Binary file assets/Models/creature1/one.blend has changed
2.1 Binary file assets/Models/creature1/try-again.blend has changed
3.1 --- a/org/test-creature.org Wed Dec 28 23:12:32 2011 -0700 3.2 +++ b/org/test-creature.org Wed Jan 04 08:36:42 2012 -0700 3.3 @@ -66,8 +66,6 @@ 3.4 (.findValue data key) 3.5 nil)) 3.6 3.7 -(defn hand2 [] 3.8 - (load-blender-model "Models/creature1/try-again.blend")) 3.9 3.10 (defn hand [] 3.11 (load-blender-model "Models/creature1/one.blend")) 3.12 @@ -100,55 +98,450 @@ 3.13 (map #(.getWorldTranslation %) 3.14 (filter #(re-matches #"joint\.\d\d\d" (.getName %)) 3.15 (node-seq (hand))))) 3.16 +(defn worm [] 3.17 + (load-blender-model "Models/creature1/try-again.blend")) 3.18 + 3.19 3.20 (defn worm-pieces [] 3.21 (filter 3.22 (comp #{"worm-2" "worm-1"} 3.23 #(apply str (drop-last (.getName %)))) 3.24 - (node-seq (hand2)))) 3.25 + (node-seq (worm)))) 3.26 3.27 (defn worm-joints [] 3.28 - [Vector3f/ZERO]) 3.29 + (filter #(re-matches #"joint\.\d\d\d" (.getName %)) 3.30 + (node-seq (worm)))) 3.31 3.32 +(defn bullet-trans [] 3.33 + (let [obj-a (sphere 0.5 :color ColorRGBA/Red 3.34 + :position (Vector3f. -10 5 0)) 3.35 + obj-b (sphere 0.5 :color ColorRGBA/Blue 3.36 + :position (Vector3f. -10 -5 0) 3.37 + :mass 0) 3.38 + control-a (.getControl obj-a RigidBodyControl) 3.39 + control-b (.getControl obj-b RigidBodyControl) 3.40 + swivel 3.41 + (.toRotationMatrix 3.42 + (doto (Quaternion.) 3.43 + (.fromAngleAxis (/ Math/PI 2) 3.44 + Vector3f/UNIT_X)))] 3.45 + (doto 3.46 + (ConeJoint. 3.47 + control-a control-b 3.48 + (Vector3f. 0 5 0) 3.49 + (Vector3f. 0 -5 0) 3.50 + swivel swivel) 3.51 + (.setLimit (* 0.6 (/ Math/PI 4)) 3.52 + (/ Math/PI 4) 3.53 + (* Math/PI 0.8))) 3.54 + (world (nodify 3.55 + [obj-a obj-b]) 3.56 + standard-debug-controls 3.57 + enable-debug 3.58 + no-op))) 3.59 3.60 3.61 -(defn find-joint 3.62 - [#^Node parts #^Vector3f joint-position] 3.63 +(defn bullet-trans* [] 3.64 + (let [obj-a (box 1.5 0.5 0.5 :color ColorRGBA/Red 3.65 + :position (Vector3f. 5 0 0) 3.66 + :mass 90) 3.67 + obj-b (sphere 0.5 :color ColorRGBA/Blue 3.68 + :position (Vector3f. -5 0 0) 3.69 + :mass 0) 3.70 + control-a (.getControl obj-a RigidBodyControl) 3.71 + control-b (.getControl obj-b RigidBodyControl) 3.72 + move-up? (atom nil) 3.73 + move-down? (atom nil) 3.74 + move-left? (atom nil) 3.75 + move-right? (atom nil) 3.76 + roll-left? (atom nil) 3.77 + roll-right? (atom nil) 3.78 + force 100 3.79 + swivel 3.80 + (.toRotationMatrix 3.81 + (doto (Quaternion.) 3.82 + (.fromAngleAxis (/ Math/PI 2) 3.83 + Vector3f/UNIT_X))) 3.84 + x-move 3.85 + (doto (Matrix3f.) 3.86 + (.fromStartEndVectors Vector3f/UNIT_X 3.87 + (.normalize (Vector3f. 1 1 0)))) 3.88 + 3.89 + timer (atom 0)] 3.90 + (doto 3.91 + (ConeJoint. 3.92 + control-a control-b 3.93 + (Vector3f. -8 0 0) 3.94 + (Vector3f. 2 0 0) 3.95 + ;;swivel swivel 3.96 + ;;Matrix3f/IDENTITY Matrix3f/IDENTITY 3.97 + x-move Matrix3f/IDENTITY 3.98 + ) 3.99 + (.setCollisionBetweenLinkedBodys false) 3.100 + (.setLimit (* 1 (/ Math/PI 4)) ;; twist 3.101 + (* 1 (/ Math/PI 4)) ;; swing span in X-Y plane 3.102 + (* 0 (/ Math/PI 4)))) ;; swing span in Y-Z plane 3.103 + (world (nodify 3.104 + [obj-a obj-b]) 3.105 + (merge standard-debug-controls 3.106 + {"key-r" (fn [_ pressed?] (reset! move-up? pressed?)) 3.107 + "key-t" (fn [_ pressed?] (reset! move-down? pressed?)) 3.108 + "key-f" (fn [_ pressed?] (reset! move-left? pressed?)) 3.109 + "key-g" (fn [_ pressed?] (reset! move-right? pressed?)) 3.110 + "key-v" (fn [_ pressed?] (reset! roll-left? pressed?)) 3.111 + "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))}) 3.112 + 3.113 + (fn [world] 3.114 + (enable-debug world) 3.115 + (set-gravity world Vector3f/ZERO) 3.116 + ) 3.117 + 3.118 + (fn [world _] 3.119 + 3.120 + (if @move-up? 3.121 + (.applyForce control-a 3.122 + (Vector3f. force 0 0) 3.123 + (Vector3f. 0 0 0))) 3.124 + (if @move-down? 3.125 + (.applyForce control-a 3.126 + (Vector3f. (- force) 0 0) 3.127 + (Vector3f. 0 0 0))) 3.128 + (if @move-left? 3.129 + (.applyForce control-a 3.130 + (Vector3f. 0 force 0) 3.131 + (Vector3f. 0 0 0))) 3.132 + (if @move-right? 3.133 + (.applyForce control-a 3.134 + (Vector3f. 0 (- force) 0) 3.135 + (Vector3f. 0 0 0))) 3.136 + 3.137 + (if @roll-left? 3.138 + (.applyForce control-a 3.139 + (Vector3f. 0 0 force) 3.140 + (Vector3f. 0 0 0))) 3.141 + (if @roll-right? 3.142 + (.applyForce control-a 3.143 + (Vector3f. 0 0 (- force)) 3.144 + (Vector3f. 0 0 0))) 3.145 + 3.146 + (if (zero? (rem (swap! timer inc) 100)) 3.147 + (.attachChild 3.148 + (.getRootNode world) 3.149 + (sphere 0.05 :color ColorRGBA/Yellow 3.150 + :physical? false :position 3.151 + (.getWorldTranslation obj-a))))) 3.152 + ) 3.153 + )) 3.154 + 3.155 + 3.156 + 3.157 + 3.158 + 3.159 + 3.160 + 3.161 + 3.162 + 3.163 + 3.164 + 3.165 +(defn world-setup [joint] 3.166 + (let [top (doto 3.167 + (sphere 0.1 :physical? false :color ColorRGBA/Yellow 3.168 + :position (Vector3f. 0 7 0)) 3.169 + (.addControl 3.170 + (RigidBodyControl. 3.171 + (CapsuleCollisionShape. 0.5 1.5 1) (float 15)))) 3.172 + bottom (doto 3.173 + (sphere 0.1 :physical? false :color ColorRGBA/DarkGray 3.174 + :position (Vector3f. 0 -1 0)) 3.175 + (.addControl 3.176 + (RigidBodyControl. 3.177 + (CapsuleCollisionShape. 0.5 1.5 1) (float 0)))) 3.178 + table (box 10 2 10 :position (Vector3f. 0 -6 0) 3.179 + :color ColorRGBA/Gray :mass 0) 3.180 + a (.getControl top RigidBodyControl) 3.181 + b (.getControl bottom RigidBodyControl)] 3.182 + (cond 3.183 + (= joint :point) 3.184 + (doto 3.185 + (Point2PointJoint. a b 3.186 + (Vector3f. 0 -2 0) 3.187 + (Vector3f. 0 2 0)) 3.188 + (.setCollisionBetweenLinkedBodys false)) 3.189 + (= joint :hinge) 3.190 + (doto 3.191 + (HingeJoint. 3.192 + a b 3.193 + (Vector3f. 0 -2 0) 3.194 + (Vector3f. 0 2 0) 3.195 + (Vector3f. 0 0 1) 3.196 + (Vector3f. 0 0 1) 3.197 + 3.198 + ) 3.199 + (.setCollisionBetweenLinkedBodys false) 3.200 + ;;(.setLimit (- Math/PI) Math/PI) 3.201 + ) 3.202 + (= joint :cone) 3.203 + ;; note to self -- jbullet does NOT implement cone joints 3.204 + ;; correctly. You must use plain ol' bullet for this to work. 3.205 + ;; It's faster anyway, so whatever. 3.206 + 3.207 + (doto (ConeJoint. 3.208 + a b 3.209 + (Vector3f. 0 -5 0) 3.210 + (Vector3f. 0 2 0) 3.211 + 3.212 + (doto (Matrix3f.) 3.213 + (.fromStartEndVectors Vector3f/UNIT_X 3.214 + Vector3f/UNIT_Y)) 3.215 + (doto (Matrix3f.) 3.216 + (.fromStartEndVectors Vector3f/UNIT_X 3.217 + Vector3f/UNIT_Y)) 3.218 + ) 3.219 + ;;(.setAngularOnly true) 3.220 + 3.221 + (.setCollisionBetweenLinkedBodys false) 3.222 + (.setLimit (* 1 (/ Math/PI 4)) 3.223 + (* 1 (/ Math/PI 4)) 3.224 + (* 0 (/ Math/PI 4))) 3.225 + 3.226 + ) 3.227 + (= joint :six) 3.228 + (doto 3.229 + (SixDofJoint. 3.230 + a b 3.231 + (Vector3f. 0 -2 0) 3.232 + (Vector3f. 0 2 0) 3.233 + ;;(doto (Matrix3f.) 3.234 + ;; (.fromStartEndVectors Vector3f/UNIT_X 3.235 + ;; Vector3f/UNIT_Y)) 3.236 + ;;(doto (Matrix3f.) 3.237 + ;; (.fromStartEndVectors Vector3f/UNIT_X 3.238 + ;; Vector3f/UNIT_Y)) 3.239 + true) 3.240 + (.setCollisionBetweenLinkedBodys false) 3.241 + (.setAngularLowerLimit (Vector3f. 0 3.242 + (- (/ Math/PI 2)) 3.243 + 0)) 3.244 + 3.245 + (.setAngularUpperLimit (Vector3f. 0 3.246 + (/ Math/PI 2) 3.247 + 0)) 3.248 + (.setLinearLowerLimit (Vector3f. 0 0 0)) 3.249 + (.setLinearUpperLimit (Vector3f. 0 0 0)) 3.250 + 3.251 + ) 3.252 + 3.253 + 3.254 + 3.255 + 3.256 + 3.257 + ) 3.258 + 3.259 + [top bottom table])) 3.260 + 3.261 +(defn speed-up [world] 3.262 + (.setMoveSpeed (.getFlyByCamera world) 3.263 + (float 100)) 3.264 + (.setRotationSpeed (.getFlyByCamera world) 3.265 + (float 20)) 3.266 + world) 3.267 + 3.268 + 3.269 +(defn test-joint [joint] 3.270 + (let [[top bottom floor] (world-setup joint) 3.271 + control (.getControl top RigidBodyControl) 3.272 + move-up? (atom false) 3.273 + move-down? (atom false) 3.274 + move-left? (atom false) 3.275 + move-right? (atom false) 3.276 + roll-left? (atom false) 3.277 + roll-right? (atom false) 3.278 + timer (atom 0)] 3.279 + 3.280 + (world 3.281 + (nodify [top bottom floor]) 3.282 + (merge standard-debug-controls 3.283 + {"key-r" (fn [_ pressed?] (reset! move-up? pressed?)) 3.284 + "key-t" (fn [_ pressed?] (reset! move-down? pressed?)) 3.285 + "key-f" (fn [_ pressed?] (reset! move-left? pressed?)) 3.286 + "key-g" (fn [_ pressed?] (reset! move-right? pressed?)) 3.287 + "key-v" (fn [_ pressed?] (reset! roll-left? pressed?)) 3.288 + "key-b" (fn [_ pressed?] (reset! roll-right? pressed?))}) 3.289 + 3.290 + (fn [world] 3.291 + (light-up-everything world) 3.292 + (enable-debug world) 3.293 + (set-gravity world (Vector3f. 0 0 0)) 3.294 + ) 3.295 + 3.296 + (fn [world _] 3.297 + (if (zero? (rem (swap! timer inc) 100)) 3.298 + (do 3.299 + ;; (println-repl @timer) 3.300 + (.attachChild (.getRootNode world) 3.301 + (sphere 0.05 :color ColorRGBA/Yellow 3.302 + :position (.getWorldTranslation top) 3.303 + :physical? false)))) 3.304 + (if @move-up? 3.305 + (.applyTorque control 3.306 + (.mult (.getPhysicsRotation control) 3.307 + (Vector3f. 0 0 10)))) 3.308 + (if @move-down? 3.309 + (.applyTorque control 3.310 + (.mult (.getPhysicsRotation control) 3.311 + (Vector3f. 0 0 -10)))) 3.312 + (if @move-left? 3.313 + (.applyTorque control 3.314 + (.mult (.getPhysicsRotation control) 3.315 + (Vector3f. 0 10 0)))) 3.316 + (if @move-right? 3.317 + (.applyTorque control 3.318 + (.mult (.getPhysicsRotation control) 3.319 + (Vector3f. 0 -10 0)))) 3.320 + (if @roll-left? 3.321 + (.applyTorque control 3.322 + (.mult (.getPhysicsRotation control) 3.323 + (Vector3f. -1 0 0)))) 3.324 + (if @roll-right? 3.325 + (.applyTorque control 3.326 + (.mult (.getPhysicsRotation control) 3.327 + (Vector3f. 1 0 0)))))))) 3.328 + 3.329 + 3.330 + 3.331 +(defn run [joint] (.start (test-joint joint))) 3.332 +(defn look [joint] (view (nodify (world-setup joint)))) 3.333 + 3.334 +(defn blender-to-jme 3.335 + "Convert from Blender coordinates to JME coordinates" 3.336 + [#^Vector3f in] 3.337 + (Vector3f. (.getX in) 3.338 + (.getZ in) 3.339 + (- (.getY in)))) 3.340 + 3.341 + 3.342 +(defn joint-targets 3.343 + "Return the two closest two objects to the joint object, ordered 3.344 + from bottom to top according to the joint's rotation." 3.345 + [#^Node parts #^Node joint] 3.346 + ;;(println (meta-data joint "joint")) 3.347 + (.getWorldRotation joint) 3.348 (loop [radius (float 0.01)] 3.349 (let [results (CollisionResults.)] 3.350 (.collideWith 3.351 parts 3.352 - (BoundingBox. joint-position radius radius radius) 3.353 + (BoundingBox. (.getWorldTranslation joint) 3.354 + radius radius radius) 3.355 results) 3.356 (let [targets 3.357 (distinct 3.358 (map #(.getGeometry %) results))] 3.359 (if (>= (count targets) 2) 3.360 - (take 2 targets) 3.361 + (sort-by 3.362 + #(.getY 3.363 + (.mult 3.364 + (.inverse (.getWorldRotation joint)) 3.365 + (.subtract (.getWorldTranslation %) 3.366 + (.getWorldTranslation joint)))) 3.367 + (take 2 targets)) 3.368 (recur (float (* radius 2)))))))) 3.369 3.370 +(defn connect 3.371 + "here are some examples: 3.372 + {:type :point} 3.373 + {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)} 3.374 + (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints) 3.375 3.376 + {:type :cone :limit-xz 0] 3.377 + :limit-yz 0] 3.378 + :twist 0]} 3.379 +" 3.380 + ([#^Node obj-a #^Node obj-b #^Node joint] 3.381 + (let [center-a (.getWorldTranslation obj-a) 3.382 + center-b (.getWorldTranslation obj-b) 3.383 + joint-center (.getWorldTranslation joint) 3.384 + pivot-a (.subtract joint-center center-a) 3.385 + pivot-b (.subtract joint-center center-b) 3.386 + control-a (.getControl obj-a RigidBodyControl) 3.387 + control-b (.getControl obj-b RigidBodyControl)] 3.388 + ;; A side-effect of creating a joint registers 3.389 + ;; it with both physics objects which in turn 3.390 + ;; will register the joint with the physics system 3.391 + ;; when the simulation is started. 3.392 + (if-let [constraints 3.393 + (map-vals 3.394 + eval 3.395 + (read-string 3.396 + (meta-data (first (worm-joints)) "joint")))] 3.397 3.398 -(defn connect-at-point 3.399 - [obj-a obj-b point] 3.400 - (let [center-a (.getWorldTranslation obj-a) 3.401 - center-b (.getWorldTranslation obj-b) 3.402 - pivot-a (.subtract point center-a) 3.403 - pivot-b (.subtract point center-b) 3.404 - ;; A side-effect of creating a joint registers 3.405 - ;; it with both physics objects which in turn 3.406 - ;; will register the joint with the physics system 3.407 - ;; when the simulation is started. 3.408 - joint (Point2PointJoint. 3.409 - (.getControl obj-a RigidBodyControl) 3.410 - (.getControl obj-b RigidBodyControl) 3.411 - pivot-a 3.412 - pivot-b)] 3.413 - obj-a)) 3.414 + (let [joint-type (:type constraints)] 3.415 + (cond (= :point joint-type) 3.416 + (do 3.417 + (println-repl "creating POINT joint") 3.418 + (Point2PointJoint. 3.419 + control-a 3.420 + control-b 3.421 + pivot-a 3.422 + pivot-b)) 3.423 + (= :hinge joint-type) 3.424 + (do 3.425 + (println-repl "creating HINGE joint") 3.426 + (let [axis (if-let 3.427 + [axis (:axis constraints)] 3.428 + axis 3.429 + Vector3f/UNIT_X) 3.430 + [limit-1 limit-2] (:limit constraints) 3.431 + hinge-axis 3.432 + (.mult 3.433 + (.getWorldRotation joint) 3.434 + (blender-to-jme axis))] 3.435 + (doto 3.436 + (HingeJoint. 3.437 + control-a 3.438 + control-b 3.439 + pivot-a 3.440 + pivot-b 3.441 + hinge-axis 3.442 + hinge-axis) 3.443 + (.setLimit limit-1 limit-2)))) 3.444 + (= :cone joint-type) 3.445 + (do 3.446 + (let [limit-xy (:limit-xz constraints) 3.447 + limit-yz (:limit-yz constraints) 3.448 + twist (:twist constraints)] 3.449 + 3.450 + (println-repl "creating CONE joint") 3.451 + (doto 3.452 + (ConeJoint. 3.453 + control-a 3.454 + control-b 3.455 + pivot-a 3.456 + pivot-b 3.457 + (doto (Matrix3f.) 3.458 + (.fromStartEndVectors 3.459 + Vector3f/UNIT_X 3.460 + (.normalize 3.461 + (.subtract (.getWorldTranslation joint) 3.462 + (.getWorldTranslation obj-a))))) 3.463 + (doto (Matrix3f.) 3.464 + (.fromStartEndVectors 3.465 + Vector3f/UNIT_X 3.466 + (.normalize 3.467 + (.subtract 3.468 + (.getWorldTranslation obj-b) 3.469 + (.getWorldTranslation joint)))))) 3.470 + (.setLimit (float limit-xy) 3.471 + (float limit-yz) 3.472 + (float twist))))) 3.473 + true 3.474 + (println-repl 3.475 + "joint-type " joint-type " not recognized"))) 3.476 + 3.477 + (println-repl "could not find joint meta-data!"))))) 3.478 + 3.479 3.480 3.481 -(defn physical-hand [#^Node pieces joints] 3.482 - ;; Make each piece a physical entity in the simulation. 3.483 +(defn physical-worm [#^Node pieces joints] 3.484 (dorun 3.485 (map 3.486 (fn [geom] 3.487 @@ -156,44 +549,48 @@ 3.488 (RigidBodyControl. 3.489 (HullCollisionShape. 3.490 (.getMesh geom)) 3.491 - ;; TODO: fix this. 3.492 - (float 1.0))] 3.493 + (if-let [mass (meta-data geom "mass")] 3.494 + (do 3.495 + (println-repl 3.496 + "setting mass to " (float mass)) 3.497 + (float mass)) 3.498 + (float 1)))] 3.499 + 3.500 (.addControl geom physics-control))) 3.501 (filter #(isa? (class %) Geometry ) 3.502 (node-seq pieces)))) 3.503 + 3.504 (dorun 3.505 (map 3.506 - (fn [joint-position] 3.507 - (let [[geom-a geom-b] (find-joint pieces joint-position)] 3.508 - (connect-at-point geom-a geom-b joint-position))) 3.509 - joints)) 3.510 - pieces) 3.511 + (fn [joint] 3.512 + (let [[obj-a obj-b] 3.513 + (joint-targets pieces joint)] 3.514 + (connect obj-a obj-b joint))) 3.515 + joints)) 3.516 + pieces) 3.517 3.518 +(defn the-worm [] 3.519 + (physical-worm (worm) (worm-joints))) 3.520 3.521 -(defn the-hand! [] (physical-hand (hand) (hand-joints))) 3.522 - 3.523 - 3.524 -(defn test-hand [] 3.525 +(defn test-worm [] 3.526 (world 3.527 - (nodify [(the-hand!) 3.528 - (box 10 1 10 :position (Vector3f. 0 -10 0) 3.529 - :color ColorRGBA/Gray 3.530 - :mass 0)]) 3.531 + (nodify [(the-worm) 3.532 + (box 10 2 10 :position (Vector3f. 0 -5 0) 3.533 + :color ColorRGBA/Gray :mass 0)]) 3.534 standard-debug-controls 3.535 - enable-debug 3.536 - (fn [_ _] 3.537 - (Thread/sleep 100)))) 3.538 - 3.539 - 3.540 - 3.541 - 3.542 - 3.543 - 3.544 + (comp light-up-everything enable-debug 3.545 + (fn [world] 3.546 + (.setTimer world (NanoTimer.)) 3.547 + (speed-up world) 3.548 + ;;(set-gravity world (Vector3f. 0 0 0)) 3.549 + world 3.550 + )) 3.551 + no-op)) 3.552 3.553 #+end_src 3.554 3.555 #+results: body-1 3.556 -: #'cortex.silly/test-hand 3.557 +: #'cortex.silly/test-try-again 3.558 3.559 3.560