view org/movement.org @ 164:c33a8e5fe7bc

removed hearing-init-fns requirement, changed names
author Robert McIntyre <rlm@mit.edu>
date Sat, 04 Feb 2012 03:29:59 -0700
parents 2cbdd7034c6c
children f1b078375484
line wrap: on
line source
1 #+title: Movement!
2 #+author: Robert McIntyre
3 #+email: rlm@mit.edu
4 #+description: muscles for a simulated creature
5 #+keywords: simulation, jMonkeyEngine3, clojure
6 #+SETUPFILE: ../../aurellem/org/setup.org
7 #+INCLUDE: ../../aurellem/org/level-0.org
9 #+name: movement
10 #+begin_src clojure
11 (ns cortex.movement
12 (:use (cortex world util sense body))
13 (:import jme3tools.converters.ImageToAwt)
14 (:import java.awt.image.BufferedImage))
16 (cortex.import/mega-import-jme3)
18 ;; here's how motor-control/ proprioception will work: Each muscle is
19 ;; defined by a 1-D array of numbers (the "motor pool") each of which
20 ;; represent muscle fibers. A muscle also has a scalar :strength
21 ;; factor which determines how strong the muscle as a whole is.
22 ;; The effector function for a muscle takes a number < (count
23 ;; motor-pool) and that number is said to "activate" all the muscle
24 ;; fibers whose index is lower than the number. Each fiber will apply
25 ;; force in proportion to its value in the array. Lower values cause
26 ;; less force. The lower values can be put at the "beginning" of the
27 ;; 1-D array to simulate the layout of actual human muscles, which are
28 ;; capable of more percise movements when exerting less force.
30 (defn muscle-fiber-values
31 "get motor pool strengths"
32 [#^BufferedImage image]
33 (vec
34 (let [width (.getWidth image)]
35 (for [x (range width)]
36 (- 255
37 (bit-and
38 0x0000FF
39 (.getRGB image x 0)))))))
41 (defn creature-muscles
42 "Return the children of the creature's \"muscles\" node."
43 [#^Node creature]
44 (if-let [muscle-node (.getChild creature "muscles")]
45 (seq (.getChildren muscle-node))
46 (do (println-repl "could not find muscles node") [])))
48 (defn single-muscle [#^Node parts #^Node muscle]
49 (let [target (closest-node parts muscle)
50 axis
51 (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y)
52 strength (meta-data muscle "strength")
53 image-name (read-string (meta-data muscle "muscle"))
54 image
55 (ImageToAwt/convert
56 (.getImage (.loadTexture (asset-manager) image-name))
57 false false 0)
58 fibers (muscle-fiber-values image)
59 fiber-integral (reductions + fibers)
60 force-index (vec
61 (map
62 #(float (* strength (/ % (last
63 fiber-integral))))
64 fiber-integral))
65 control (.getControl target RigidBodyControl)]
66 (fn [n]
67 (let [pool-index (min n (count fibers))]
68 (.applyTorque control (.mult axis (force-index n)))))))
71 (defn enable-muscles
72 "Must be called on a creature after RigidBodyControls have been
73 created."
74 [#^Node creature]
75 (let [muscles (creature-muscles creature)]
76 (for [muscle muscles]
77 (single-muscle creature muscle))))
80 #+end_src
86 * COMMENT code generation
87 #+begin_src clojure :tangle ../src/cortex/movement.clj
88 <<movement>>
89 #+end_src