# HG changeset patch # User Robert McIntyre # Date 1328276017 25200 # Node ID 811127d79d24b9637d2311fedf9c41e5f05d7be6 # Parent 84c67be00abe4d37a51a9b5156c7d132d83d7b6f refactored muscles diff -r 84c67be00abe -r 811127d79d24 org/movement.org --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org/movement.org Fri Feb 03 06:33:37 2012 -0700 @@ -0,0 +1,98 @@ +#+title: Movement! +#+author: Robert McIntyre +#+email: rlm@mit.edu +#+description: muscles for a simulated creature +#+keywords: simulation, jMonkeyEngine3, clojure +#+SETUPFILE: ../../aurellem/org/setup.org +#+INCLUDE: ../../aurellem/org/level-0.org + +#+name: movement +#+begin_src clojure +(ns cortex.movement + (:use (cortex world util sense body)) + (:import jme3tools.converters.ImageToAwt) + (:import java.awt.image.BufferedImage)) + +(cortex.import/mega-import-jme3) + + + + +;; here's how motor-control/ proprioception will work: Each muscle is +;; defined by a 1-D array of numbers (the "motor pool") each of which +;; represent muscle fibers. A muscle also has a scalar :strength +;; factor which determines how strong the muscle as a whole is. +;; The effector function for a muscle takes a number < (count +;; motor-pool) and that number is said to "activate" all the muscle +;; fibers whose index is lower than the number. Each fiber will apply +;; force in proportion to its value in the array. Lower values cause +;; less force. The lower values can be put at the "beginning" of the +;; 1-D array to simulate the layout of actual human muscles, which are +;; capable of more percise movements when exerting less force. + +;; I don't know how to encode proprioception, so for now, just return +;; a function for each joint that returns a triplet of floats which +;; represent relative roll, pitch, and yaw. Write display code for +;; this though. + +(defn muscle-fiber-values + "get motor pool strengths" + [#^BufferedImage image] + (vec + (let [width (.getWidth image)] + (for [x (range width)] + (- 255 + (bit-and + 0x0000FF + (.getRGB image x 0))))))) + + +(defn creature-muscles + "Return the children of the creature's \"muscles\" node." + [#^Node creature] + (if-let [muscle-node (.getChild creature "muscles")] + (seq (.getChildren muscle-node)) + (do (println-repl "could not find muscles node") []))) + +(defn single-muscle [#^Node parts #^Node muscle] + (let [target (closest-node parts muscle) + axis + (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y) + strength (meta-data muscle "strength") + image-name (read-string (meta-data muscle "muscle")) + image + (ImageToAwt/convert + (.getImage (.loadTexture (asset-manager) image-name)) + false false 0) + fibers (muscle-fiber-values image) + fiber-integral (reductions + fibers) + force-index (vec + (map + #(float (* strength (/ % (last + fiber-integral)))) + fiber-integral)) + control (.getControl target RigidBodyControl)] + (fn [n] + (let [pool-index (min n (count fibers))] + (.applyTorque control (.mult axis (force-index n))))))) + + +(defn enable-muscles + "Must be called on a creature after RigidBodyControls have been + created." + [#^Node creature] + (let [muscles (creature-muscles creature)] + (for [muscle muscles] + (single-muscle creature muscle)))) + + +#+end_src + + + + + +* COMMENT code generation +#+begin_src clojure :tangle ../src/cortex/movement.clj +<> +#+end_src diff -r 84c67be00abe -r 811127d79d24 org/test-creature.org --- a/org/test-creature.org Fri Feb 03 06:21:39 2012 -0700 +++ b/org/test-creature.org Fri Feb 03 06:33:37 2012 -0700 @@ -38,7 +38,7 @@ the connecting here in clojure code, using the names of the individual components and trial and error. Later, I'll maybe make some sort of creature-building modifications to blender that support whatever -discreitized senses I'm going to make. +discritized senses I'm going to make. #+name: body-1 #+begin_src clojure @@ -49,7 +49,8 @@ ;; TODO remove this! (require 'cortex.import) (cortex.import/mega-import-jme3) -(use '(cortex world util body hearing touch vision sense proprioception)) +(use '(cortex world util body hearing touch vision sense +proprioception movement)) (rlm.rlm-commands/help) (import java.awt.image.BufferedImage) @@ -421,72 +422,6 @@ -;; here's how motor-control/ proprioception will work: Each muscle is -;; defined by a 1-D array of numbers (the "motor pool") each of which -;; represent muscle fibers. A muscle also has a scalar :strength -;; factor which determines how strong the muscle as a whole is. -;; The effector function for a muscle takes a number < (count -;; motor-pool) and that number is said to "activate" all the muscle -;; fibers whose index is lower than the number. Each fiber will apply -;; force in proportion to its value in the array. Lower values cause -;; less force. The lower values can be put at the "beginning" of the -;; 1-D array to simulate the layout of actual human muscles, which are -;; capable of more percise movements when exerting less force. - -;; I don't know how to encode proprioception, so for now, just return -;; a function for each joint that returns a triplet of floats which -;; represent relative roll, pitch, and yaw. Write display code for -;; this though. - -(defn muscle-fiber-values - "get motor pool strengths" - [#^BufferedImage image] - (vec - (let [width (.getWidth image)] - (for [x (range width)] - (- 255 - (bit-and - 0x0000FF - (.getRGB image x 0))))))) - - -(defn creature-muscles - "Return the children of the creature's \"muscles\" node." - [#^Node creature] - (if-let [muscle-node (.getChild creature "muscles")] - (seq (.getChildren muscle-node)) - (do (println-repl "could not find muscles node") []))) - -(defn single-muscle [#^Node parts #^Node muscle] - (let [target (closest-node parts muscle) - axis - (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y) - strength (meta-data muscle "strength") - image-name (read-string (meta-data muscle "muscle")) - image - (ImageToAwt/convert - (.getImage (.loadTexture (asset-manager) image-name)) - false false 0) - fibers (muscle-fiber-values image) - fiber-integral (reductions + fibers) - force-index (vec - (map - #(float (* strength (/ % (last - fiber-integral)))) - fiber-integral)) - control (.getControl target RigidBodyControl)] - (fn [n] - (let [pool-index (min n (count fibers))] - (.applyTorque control (.mult axis (force-index n))))))) - - -(defn enable-muscles - "Must be called on a creature after RigidBodyControls have been - created." - [#^Node creature] - (let [muscles (creature-muscles creature)] - (for [muscle muscles] - (single-muscle creature muscle)))) (defn test-creature [thing] (let [x-axis