Mercurial > cortex
diff org/body.org @ 160:33278bf028e7
refactored joints
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 03 Feb 2012 06:47:05 -0700 |
parents | 84c67be00abe |
children | 0b9ae09eaec3 |
line wrap: on
line diff
1.1 --- a/org/body.org Fri Feb 03 06:41:16 2012 -0700 1.2 +++ b/org/body.org Fri Feb 03 06:47:05 2012 -0700 1.3 @@ -9,7 +9,7 @@ 1.4 #+name: proprioception 1.5 #+begin_src clojure 1.6 (ns cortex.body 1.7 - (:use (cortex world util)) 1.8 + (:use (cortex world util sense)) 1.9 (:import 1.10 com.jme3.math.Vector3f 1.11 com.jme3.math.Quaternion 1.12 @@ -20,6 +20,8 @@ 1.13 com.jme3.bounding.BoundingBox 1.14 com.jme3.scene.Node)) 1.15 1.16 +(cortex.import/mega-import-jme3) 1.17 + 1.18 (defn jme-to-blender 1.19 "Convert from JME coordinates to Blender coordinates" 1.20 [#^Vector3f in] 1.21 @@ -27,6 +29,14 @@ 1.22 (- (.getZ in)) 1.23 (.getY in))) 1.24 1.25 +(defn blender-to-jme 1.26 + "Convert from Blender coordinates to JME coordinates" 1.27 + [#^Vector3f in] 1.28 + (Vector3f. (.getX in) 1.29 + (.getZ in) 1.30 + (- (.getY in)))) 1.31 + 1.32 + 1.33 (defn joint-targets 1.34 "Return the two closest two objects to the joint object, ordered 1.35 from bottom to top according to the joint's rotation." 1.36 @@ -62,61 +72,160 @@ 1.37 (seq (.getChildren joint-node)) 1.38 (do (println-repl "could not find JOINTS node") []))) 1.39 1.40 -(defn tap [obj direction force] 1.41 - (let [control (.getControl obj RigidBodyControl)] 1.42 - (.applyTorque 1.43 - control 1.44 - (.mult (.getPhysicsRotation control) 1.45 - (.mult (.normalize direction) (float force)))))) 1.46 +(defmulti joint-dispatch 1.47 + "Translate blender pseudo-joints into real JME joints." 1.48 + (fn [constraints & _] 1.49 + (:type constraints))) 1.50 1.51 +(defmethod joint-dispatch :point 1.52 + [constraints control-a control-b pivot-a pivot-b rotation] 1.53 + (println-repl "creating POINT2POINT joint") 1.54 + ;; bullet's point2point joints are BROKEN, so we must use the 1.55 + ;; generic 6DOF joint instead of an actual Point2Point joint! 1.56 1.57 -(defn with-movement 1.58 - [object 1.59 - [up down left right roll-up roll-down :as keyboard] 1.60 - forces 1.61 - [root-node 1.62 - keymap 1.63 - intilization 1.64 - world-loop]] 1.65 - (let [add-keypress 1.66 - (fn [state keymap key] 1.67 - (merge keymap 1.68 - {key 1.69 - (fn [_ pressed?] 1.70 - (reset! state pressed?))})) 1.71 - move-up? (atom false) 1.72 - move-down? (atom false) 1.73 - move-left? (atom false) 1.74 - move-right? (atom false) 1.75 - roll-left? (atom false) 1.76 - roll-right? (atom false) 1.77 - 1.78 - directions [(Vector3f. 0 1 0)(Vector3f. 0 -1 0) 1.79 - (Vector3f. 0 0 1)(Vector3f. 0 0 -1) 1.80 - (Vector3f. -1 0 0)(Vector3f. 1 0 0)] 1.81 - atoms [move-left? move-right? move-up? move-down? 1.82 - roll-left? roll-right?] 1.83 + ;; should be able to do this: 1.84 + (comment 1.85 + (Point2PointJoint. 1.86 + control-a 1.87 + control-b 1.88 + pivot-a 1.89 + pivot-b)) 1.90 1.91 - keymap* (reduce merge 1.92 - (map #(add-keypress %1 keymap %2) 1.93 - atoms 1.94 - keyboard)) 1.95 - 1.96 - splice-loop (fn [] 1.97 - (dorun 1.98 - (map 1.99 - (fn [sym direction force] 1.100 - (if @sym 1.101 - (tap object direction force))) 1.102 - atoms directions forces))) 1.103 + ;; but instead we must do this: 1.104 + (println-repl "substuting 6DOF joint for POINT2POINT joint!") 1.105 + (doto 1.106 + (SixDofJoint. 1.107 + control-a 1.108 + control-b 1.109 + pivot-a 1.110 + pivot-b 1.111 + false) 1.112 + (.setLinearLowerLimit Vector3f/ZERO) 1.113 + (.setLinearUpperLimit Vector3f/ZERO) 1.114 + ;;(.setAngularLowerLimit (Vector3f. 1 1 1)) 1.115 + ;;(.setAngularUpperLimit (Vector3f. 0 0 0)) 1.116 1.117 - world-loop* (fn [world tpf] 1.118 - (world-loop world tpf) 1.119 - (splice-loop))] 1.120 - [root-node 1.121 - keymap* 1.122 - intilization 1.123 - world-loop*])) 1.124 +)) 1.125 + 1.126 + 1.127 +(defmethod joint-dispatch :hinge 1.128 + [constraints control-a control-b pivot-a pivot-b rotation] 1.129 + (println-repl "creating HINGE joint") 1.130 + (let [axis 1.131 + (if-let 1.132 + [axis (:axis constraints)] 1.133 + axis 1.134 + Vector3f/UNIT_X) 1.135 + [limit-1 limit-2] (:limit constraints) 1.136 + hinge-axis 1.137 + (.mult 1.138 + rotation 1.139 + (blender-to-jme axis))] 1.140 + (doto 1.141 + (HingeJoint. 1.142 + control-a 1.143 + control-b 1.144 + pivot-a 1.145 + pivot-b 1.146 + hinge-axis 1.147 + hinge-axis) 1.148 + (.setLimit limit-1 limit-2)))) 1.149 + 1.150 +(defmethod joint-dispatch :cone 1.151 + [constraints control-a control-b pivot-a pivot-b rotation] 1.152 + (let [limit-xz (:limit-xz constraints) 1.153 + limit-xy (:limit-xy constraints) 1.154 + twist (:twist constraints)] 1.155 + 1.156 + (println-repl "creating CONE joint") 1.157 + (println-repl rotation) 1.158 + (println-repl 1.159 + "UNIT_X --> " (.mult rotation (Vector3f. 1 0 0))) 1.160 + (println-repl 1.161 + "UNIT_Y --> " (.mult rotation (Vector3f. 0 1 0))) 1.162 + (println-repl 1.163 + "UNIT_Z --> " (.mult rotation (Vector3f. 0 0 1))) 1.164 + (doto 1.165 + (ConeJoint. 1.166 + control-a 1.167 + control-b 1.168 + pivot-a 1.169 + pivot-b 1.170 + rotation 1.171 + rotation) 1.172 + (.setLimit (float limit-xz) 1.173 + (float limit-xy) 1.174 + (float twist))))) 1.175 + 1.176 +(defn connect 1.177 + "here are some examples: 1.178 + {:type :point} 1.179 + {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)} 1.180 + (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints) 1.181 + 1.182 + {:type :cone :limit-xz 0] 1.183 + :limit-xy 0] 1.184 + :twist 0]} (use XZY rotation mode in blender!)" 1.185 + [#^Node obj-a #^Node obj-b #^Node joint] 1.186 + (let [control-a (.getControl obj-a RigidBodyControl) 1.187 + control-b (.getControl obj-b RigidBodyControl) 1.188 + joint-center (.getWorldTranslation joint) 1.189 + joint-rotation (.toRotationMatrix (.getWorldRotation joint)) 1.190 + pivot-a (world-to-local obj-a joint-center) 1.191 + pivot-b (world-to-local obj-b joint-center)] 1.192 + 1.193 + (if-let [constraints 1.194 + (map-vals 1.195 + eval 1.196 + (read-string 1.197 + (meta-data joint "joint")))] 1.198 + ;; A side-effect of creating a joint registers 1.199 + ;; it with both physics objects which in turn 1.200 + ;; will register the joint with the physics system 1.201 + ;; when the simulation is started. 1.202 + (do 1.203 + (println-repl "creating joint between" 1.204 + (.getName obj-a) "and" (.getName obj-b)) 1.205 + (joint-dispatch constraints 1.206 + control-a control-b 1.207 + pivot-a pivot-b 1.208 + joint-rotation)) 1.209 + (println-repl "could not find joint meta-data!")))) 1.210 + 1.211 + 1.212 + 1.213 + 1.214 +(defn assemble-creature [#^Node pieces joints] 1.215 + (dorun 1.216 + (map 1.217 + (fn [geom] 1.218 + (let [physics-control 1.219 + (RigidBodyControl. 1.220 + (HullCollisionShape. 1.221 + (.getMesh geom)) 1.222 + (if-let [mass (meta-data geom "mass")] 1.223 + (do 1.224 + (println-repl 1.225 + "setting" (.getName geom) "mass to" (float mass)) 1.226 + (float mass)) 1.227 + (float 1)))] 1.228 + 1.229 + (.addControl geom physics-control))) 1.230 + (filter #(isa? (class %) Geometry ) 1.231 + (node-seq pieces)))) 1.232 + (dorun 1.233 + (map 1.234 + (fn [joint] 1.235 + (let [[obj-a obj-b] (joint-targets pieces joint)] 1.236 + (connect obj-a obj-b joint))) 1.237 + joints)) 1.238 + pieces) 1.239 + 1.240 + 1.241 +;; TODO implement a function that adds joints in the style of the 1.242 +;; other sense functions 1.243 + 1.244 + 1.245 1.246 (import java.awt.image.BufferedImage) 1.247