Mercurial > cortex
comparison 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 |
comparison
equal
deleted
inserted
replaced
157:84c67be00abe | 158:811127d79d24 |
---|---|
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 | |
8 | |
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)) | |
15 | |
16 (cortex.import/mega-import-jme3) | |
17 | |
18 | |
19 | |
20 | |
21 ;; here's how motor-control/ proprioception will work: Each muscle is | |
22 ;; defined by a 1-D array of numbers (the "motor pool") each of which | |
23 ;; represent muscle fibers. A muscle also has a scalar :strength | |
24 ;; factor which determines how strong the muscle as a whole is. | |
25 ;; The effector function for a muscle takes a number < (count | |
26 ;; motor-pool) and that number is said to "activate" all the muscle | |
27 ;; fibers whose index is lower than the number. Each fiber will apply | |
28 ;; force in proportion to its value in the array. Lower values cause | |
29 ;; less force. The lower values can be put at the "beginning" of the | |
30 ;; 1-D array to simulate the layout of actual human muscles, which are | |
31 ;; capable of more percise movements when exerting less force. | |
32 | |
33 ;; I don't know how to encode proprioception, so for now, just return | |
34 ;; a function for each joint that returns a triplet of floats which | |
35 ;; represent relative roll, pitch, and yaw. Write display code for | |
36 ;; this though. | |
37 | |
38 (defn muscle-fiber-values | |
39 "get motor pool strengths" | |
40 [#^BufferedImage image] | |
41 (vec | |
42 (let [width (.getWidth image)] | |
43 (for [x (range width)] | |
44 (- 255 | |
45 (bit-and | |
46 0x0000FF | |
47 (.getRGB image x 0))))))) | |
48 | |
49 | |
50 (defn creature-muscles | |
51 "Return the children of the creature's \"muscles\" node." | |
52 [#^Node creature] | |
53 (if-let [muscle-node (.getChild creature "muscles")] | |
54 (seq (.getChildren muscle-node)) | |
55 (do (println-repl "could not find muscles node") []))) | |
56 | |
57 (defn single-muscle [#^Node parts #^Node muscle] | |
58 (let [target (closest-node parts muscle) | |
59 axis | |
60 (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y) | |
61 strength (meta-data muscle "strength") | |
62 image-name (read-string (meta-data muscle "muscle")) | |
63 image | |
64 (ImageToAwt/convert | |
65 (.getImage (.loadTexture (asset-manager) image-name)) | |
66 false false 0) | |
67 fibers (muscle-fiber-values image) | |
68 fiber-integral (reductions + fibers) | |
69 force-index (vec | |
70 (map | |
71 #(float (* strength (/ % (last | |
72 fiber-integral)))) | |
73 fiber-integral)) | |
74 control (.getControl target RigidBodyControl)] | |
75 (fn [n] | |
76 (let [pool-index (min n (count fibers))] | |
77 (.applyTorque control (.mult axis (force-index n))))))) | |
78 | |
79 | |
80 (defn enable-muscles | |
81 "Must be called on a creature after RigidBodyControls have been | |
82 created." | |
83 [#^Node creature] | |
84 (let [muscles (creature-muscles creature)] | |
85 (for [muscle muscles] | |
86 (single-muscle creature muscle)))) | |
87 | |
88 | |
89 #+end_src | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 * COMMENT code generation | |
96 #+begin_src clojure :tangle ../src/cortex/movement.clj | |
97 <<movement>> | |
98 #+end_src |