Mercurial > cortex
changeset 180:f1b078375484
refactored movement
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 04 Feb 2012 07:20:12 -0700 |
parents | 11bd5f0625ad |
children | 0f1c7921d967 |
files | org/movement.org org/test-creature.org |
diffstat | 2 files changed, 52 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/org/movement.org Sat Feb 04 07:09:40 2012 -0700 1.2 +++ b/org/movement.org Sat Feb 04 07:20:12 2012 -0700 1.3 @@ -6,56 +6,68 @@ 1.4 #+SETUPFILE: ../../aurellem/org/setup.org 1.5 #+INCLUDE: ../../aurellem/org/level-0.org 1.6 1.7 + 1.8 +Surprisingly enough, terristerial creatures only move by using torque 1.9 +applied about their joints. There's not a single straight line of 1.10 +force in the human body at all! (A straight line of force would 1.11 +correspond to some sort of jet or rocket propulseion.) 1.12 + 1.13 + 1.14 +Here's how motor-control/ proprioception will work: Each muscle is 1.15 +defined by a 1-D array of numbers (the "motor pool") each of which 1.16 +represent muscle fibers. A muscle also has a scalar :strength factor 1.17 +which determines how strong the muscle as a whole is. The effector 1.18 +function for a muscle takes a number < (count motor-pool) and that 1.19 +number is said to "activate" all the muscle fibers whose index is 1.20 +lower than the number. Each fiber will apply force in proportion to 1.21 +its value in the array. Lower values cause less force. The lower 1.22 +values can be put at the "beginning" of the 1-D array to simulate the 1.23 +layout of actual human muscles, which are capable of more percise 1.24 +movements when exerting less force. 1.25 + 1.26 #+name: movement 1.27 #+begin_src clojure 1.28 (ns cortex.movement 1.29 + "Give simulated creatures defined in special blender files the power 1.30 + to move around in a simulated environment." 1.31 + {:author "Robert McIntyre"} 1.32 (:use (cortex world util sense body)) 1.33 - (:import jme3tools.converters.ImageToAwt) 1.34 - (:import java.awt.image.BufferedImage)) 1.35 + (:use clojure.contrib.def) 1.36 + (:import java.awt.image.BufferedImage) 1.37 + (:import com.jme3.scene.Node) 1.38 + (:import com.jme3.math.Vector3f) 1.39 + (:import com.jme3.bullet.control.RigidBodyControl)) 1.40 1.41 -(cortex.import/mega-import-jme3) 1.42 - 1.43 -;; here's how motor-control/ proprioception will work: Each muscle is 1.44 -;; defined by a 1-D array of numbers (the "motor pool") each of which 1.45 -;; represent muscle fibers. A muscle also has a scalar :strength 1.46 -;; factor which determines how strong the muscle as a whole is. 1.47 -;; The effector function for a muscle takes a number < (count 1.48 -;; motor-pool) and that number is said to "activate" all the muscle 1.49 -;; fibers whose index is lower than the number. Each fiber will apply 1.50 -;; force in proportion to its value in the array. Lower values cause 1.51 -;; less force. The lower values can be put at the "beginning" of the 1.52 -;; 1-D array to simulate the layout of actual human muscles, which are 1.53 -;; capable of more percise movements when exerting less force. 1.54 - 1.55 -(defn muscle-fiber-values 1.56 - "get motor pool strengths" 1.57 - [#^BufferedImage image] 1.58 +(defn muscle-profile 1.59 + "Return a vector where each entry is the strength of the \"motor 1.60 + pool\" at that part in the muscle." 1.61 + [#^BufferedImage profile] 1.62 (vec 1.63 - (let [width (.getWidth image)] 1.64 + (let [width (.getWidth profile)] 1.65 (for [x (range width)] 1.66 (- 255 1.67 (bit-and 1.68 0x0000FF 1.69 - (.getRGB image x 0))))))) 1.70 + (.getRGB profile x 0))))))) 1.71 1.72 -(defn creature-muscles 1.73 - "Return the children of the creature's \"muscles\" node." 1.74 - [#^Node creature] 1.75 - (if-let [muscle-node (.getChild creature "muscles")] 1.76 - (seq (.getChildren muscle-node)) 1.77 - (do (println-repl "could not find muscles node") []))) 1.78 +(defvar 1.79 + ^{:arglists '([creature])} 1.80 + muscles 1.81 + (sense-nodes "muscles") 1.82 + "Return the children of the creature's \"muscles\" node.") 1.83 1.84 -(defn single-muscle [#^Node parts #^Node muscle] 1.85 +(defn movement-fn 1.86 + "Returns a function which when called with a integer value inside a 1.87 + running simulation, will cause movement in the creature according 1.88 + to the muscle's position and strength profile" 1.89 + [#^Node parts #^Node muscle] 1.90 (let [target (closest-node parts muscle) 1.91 axis 1.92 (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y) 1.93 strength (meta-data muscle "strength") 1.94 image-name (read-string (meta-data muscle "muscle")) 1.95 - image 1.96 - (ImageToAwt/convert 1.97 - (.getImage (.loadTexture (asset-manager) image-name)) 1.98 - false false 0) 1.99 - fibers (muscle-fiber-values image) 1.100 + image (load-image image-name) 1.101 + fibers (muscle-profile image) 1.102 fiber-integral (reductions + fibers) 1.103 force-index (vec 1.104 (map 1.105 @@ -67,14 +79,13 @@ 1.106 (let [pool-index (min n (count fibers))] 1.107 (.applyTorque control (.mult axis (force-index n))))))) 1.108 1.109 - 1.110 -(defn enable-muscles 1.111 - "Must be called on a creature after RigidBodyControls have been 1.112 - created." 1.113 +(defn movement! 1.114 + "Endow the creature with the power of movement. Returns a sequence 1.115 + of functions, each of which accept an integer value and will 1.116 + activate their corresponding muscle." 1.117 [#^Node creature] 1.118 - (let [muscles (creature-muscles creature)] 1.119 - (for [muscle muscles] 1.120 - (single-muscle creature muscle)))) 1.121 + (for [muscle (muscles creature)] 1.122 + (movement-fn creature muscle))) 1.123 1.124 1.125 #+end_src
2.1 --- a/org/test-creature.org Sat Feb 04 07:09:40 2012 -0700 2.2 +++ b/org/test-creature.org Sat Feb 04 07:20:12 2012 -0700 2.3 @@ -185,7 +185,7 @@ 2.4 prop (proprioception! creature) 2.5 prop-debug (proprioception-debug-window) 2.6 2.7 - muscle-fns (enable-muscles creature) 2.8 + muscle-fns (movement! creature) 2.9 ;; dream 2.10 fix-display (runonce 2.11 (fn [world] (add-camera! world (.getCamera world) no-op)))