view org/movement.org @ 181:0f1c7921d967

removed blender.org; got rid of magic constant in sense-utils.
author Robert McIntyre <rlm@mit.edu>
date Sat, 04 Feb 2012 07:31:08 -0700
parents f1b078375484
children 66fbab414d45
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
10 Surprisingly enough, terristerial creatures only move by using torque
11 applied about their joints. There's not a single straight line of
12 force in the human body at all! (A straight line of force would
13 correspond to some sort of jet or rocket propulseion.)
16 Here's how motor-control/ proprioception will work: Each muscle is
17 defined by a 1-D array of numbers (the "motor pool") each of which
18 represent muscle fibers. A muscle also has a scalar :strength factor
19 which determines how strong the muscle as a whole is. The effector
20 function for a muscle takes a number < (count motor-pool) and that
21 number is said to "activate" all the muscle fibers whose index is
22 lower than the number. Each fiber will apply force in proportion to
23 its value in the array. Lower values cause less force. The lower
24 values can be put at the "beginning" of the 1-D array to simulate the
25 layout of actual human muscles, which are capable of more percise
26 movements when exerting less force.
28 #+name: movement
29 #+begin_src clojure
30 (ns cortex.movement
31 "Give simulated creatures defined in special blender files the power
32 to move around in a simulated environment."
33 {:author "Robert McIntyre"}
34 (:use (cortex world util sense body))
35 (:use clojure.contrib.def)
36 (:import java.awt.image.BufferedImage)
37 (:import com.jme3.scene.Node)
38 (:import com.jme3.math.Vector3f)
39 (:import com.jme3.bullet.control.RigidBodyControl))
41 (defn muscle-profile
42 "Return a vector where each entry is the strength of the \"motor
43 pool\" at that part in the muscle."
44 [#^BufferedImage profile]
45 (vec
46 (let [width (.getWidth profile)]
47 (for [x (range width)]
48 (- 255
49 (bit-and
50 0x0000FF
51 (.getRGB profile x 0)))))))
53 (defvar
54 ^{:arglists '([creature])}
55 muscles
56 (sense-nodes "muscles")
57 "Return the children of the creature's \"muscles\" node.")
59 (defn movement-fn
60 "Returns a function which when called with a integer value inside a
61 running simulation, will cause movement in the creature according
62 to the muscle's position and strength profile"
63 [#^Node parts #^Node muscle]
64 (let [target (closest-node parts muscle)
65 axis
66 (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y)
67 strength (meta-data muscle "strength")
68 image-name (read-string (meta-data muscle "muscle"))
69 image (load-image image-name)
70 fibers (muscle-profile image)
71 fiber-integral (reductions + fibers)
72 force-index (vec
73 (map
74 #(float (* strength (/ % (last
75 fiber-integral))))
76 fiber-integral))
77 control (.getControl target RigidBodyControl)]
78 (fn [n]
79 (let [pool-index (min n (count fibers))]
80 (.applyTorque control (.mult axis (force-index n)))))))
82 (defn movement!
83 "Endow the creature with the power of movement. Returns a sequence
84 of functions, each of which accept an integer value and will
85 activate their corresponding muscle."
86 [#^Node creature]
87 (for [muscle (muscles creature)]
88 (movement-fn creature muscle)))
90 #+end_src
96 * COMMENT code generation
97 #+begin_src clojure :tangle ../src/cortex/movement.clj
98 <<movement>>
99 #+end_src