Mercurial > cortex
diff org/movement.org @ 158:811127d79d24
refactored muscles
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 03 Feb 2012 06:33:37 -0700 |
parents | |
children | 2cbdd7034c6c |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/org/movement.org Fri Feb 03 06:33:37 2012 -0700 1.3 @@ -0,0 +1,98 @@ 1.4 +#+title: Movement! 1.5 +#+author: Robert McIntyre 1.6 +#+email: rlm@mit.edu 1.7 +#+description: muscles for a simulated creature 1.8 +#+keywords: simulation, jMonkeyEngine3, clojure 1.9 +#+SETUPFILE: ../../aurellem/org/setup.org 1.10 +#+INCLUDE: ../../aurellem/org/level-0.org 1.11 + 1.12 +#+name: movement 1.13 +#+begin_src clojure 1.14 +(ns cortex.movement 1.15 + (:use (cortex world util sense body)) 1.16 + (:import jme3tools.converters.ImageToAwt) 1.17 + (:import java.awt.image.BufferedImage)) 1.18 + 1.19 +(cortex.import/mega-import-jme3) 1.20 + 1.21 + 1.22 + 1.23 + 1.24 +;; here's how motor-control/ proprioception will work: Each muscle is 1.25 +;; defined by a 1-D array of numbers (the "motor pool") each of which 1.26 +;; represent muscle fibers. A muscle also has a scalar :strength 1.27 +;; factor which determines how strong the muscle as a whole is. 1.28 +;; The effector function for a muscle takes a number < (count 1.29 +;; motor-pool) and that number is said to "activate" all the muscle 1.30 +;; fibers whose index is lower than the number. Each fiber will apply 1.31 +;; force in proportion to its value in the array. Lower values cause 1.32 +;; less force. The lower values can be put at the "beginning" of the 1.33 +;; 1-D array to simulate the layout of actual human muscles, which are 1.34 +;; capable of more percise movements when exerting less force. 1.35 + 1.36 +;; I don't know how to encode proprioception, so for now, just return 1.37 +;; a function for each joint that returns a triplet of floats which 1.38 +;; represent relative roll, pitch, and yaw. Write display code for 1.39 +;; this though. 1.40 + 1.41 +(defn muscle-fiber-values 1.42 + "get motor pool strengths" 1.43 + [#^BufferedImage image] 1.44 + (vec 1.45 + (let [width (.getWidth image)] 1.46 + (for [x (range width)] 1.47 + (- 255 1.48 + (bit-and 1.49 + 0x0000FF 1.50 + (.getRGB image x 0))))))) 1.51 + 1.52 + 1.53 +(defn creature-muscles 1.54 + "Return the children of the creature's \"muscles\" node." 1.55 + [#^Node creature] 1.56 + (if-let [muscle-node (.getChild creature "muscles")] 1.57 + (seq (.getChildren muscle-node)) 1.58 + (do (println-repl "could not find muscles node") []))) 1.59 + 1.60 +(defn single-muscle [#^Node parts #^Node muscle] 1.61 + (let [target (closest-node parts muscle) 1.62 + axis 1.63 + (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y) 1.64 + strength (meta-data muscle "strength") 1.65 + image-name (read-string (meta-data muscle "muscle")) 1.66 + image 1.67 + (ImageToAwt/convert 1.68 + (.getImage (.loadTexture (asset-manager) image-name)) 1.69 + false false 0) 1.70 + fibers (muscle-fiber-values image) 1.71 + fiber-integral (reductions + fibers) 1.72 + force-index (vec 1.73 + (map 1.74 + #(float (* strength (/ % (last 1.75 + fiber-integral)))) 1.76 + fiber-integral)) 1.77 + control (.getControl target RigidBodyControl)] 1.78 + (fn [n] 1.79 + (let [pool-index (min n (count fibers))] 1.80 + (.applyTorque control (.mult axis (force-index n))))))) 1.81 + 1.82 + 1.83 +(defn enable-muscles 1.84 + "Must be called on a creature after RigidBodyControls have been 1.85 + created." 1.86 + [#^Node creature] 1.87 + (let [muscles (creature-muscles creature)] 1.88 + (for [muscle muscles] 1.89 + (single-muscle creature muscle)))) 1.90 + 1.91 + 1.92 +#+end_src 1.93 + 1.94 + 1.95 + 1.96 + 1.97 + 1.98 +* COMMENT code generation 1.99 +#+begin_src clojure :tangle ../src/cortex/movement.clj 1.100 +<<movement>> 1.101 +#+end_src