Mercurial > cortex
changeset 183:446b115bddc2
renamed sense-util.org to sense.org.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 04 Feb 2012 07:49:46 -0700 |
parents | f2552d61e8df |
children | bdca0daa3778 |
files | org/sense-util.org sense.org |
diffstat | 2 files changed, 223 insertions(+), 227 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/org/sense-util.org Sat Feb 04 07:44:48 2012 -0700 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,227 +0,0 @@ 1.4 -#+title: General sense/effector utilities 1.5 -#+author: Robert McIntyre 1.6 -#+email: rlm@mit.edu 1.7 -#+description: sensory utilities 1.8 -#+keywords: simulation, jMonkeyEngine3, clojure, simulated senses 1.9 -#+SETUPFILE: ../../aurellem/org/setup.org 1.10 -#+INCLUDE: ../../aurellem/org/level-0.org 1.11 - 1.12 -#+name: sense-util 1.13 -#+begin_src clojure 1.14 -(ns cortex.sense 1.15 - "Here are functions usefull in the construction of two or more 1.16 - senses/effectors." 1.17 - {:author "Robert McInytre"} 1.18 - (:use (cortex world util)) 1.19 - (:import ij.process.ImageProcessor) 1.20 - (:import jme3tools.converters.ImageToAwt) 1.21 - (:import java.awt.image.BufferedImage) 1.22 - (:import com.jme3.collision.CollisionResults) 1.23 - (:import com.jme3.bounding.BoundingBox) 1.24 - (:import (com.jme3.scene Node Spatial)) 1.25 - (:import com.jme3.scene.control.AbstractControl) 1.26 - (:import (com.jme3.math Quaternion Vector3f))) 1.27 - 1.28 -(defn meta-data 1.29 - "Get the meta-data for a node created with blender." 1.30 - [blender-node key] 1.31 - (if-let [data (.getUserData blender-node "properties")] 1.32 - (.findValue data key) 1.33 - nil)) 1.34 - 1.35 -(defn closest-node 1.36 - "Return the node in creature which is closest to the given node." 1.37 - [#^Node creature #^Node eye] 1.38 - (loop [radius (float 0.01)] 1.39 - (let [results (CollisionResults.)] 1.40 - (.collideWith 1.41 - creature 1.42 - (BoundingBox. (.getWorldTranslation eye) 1.43 - radius radius radius) 1.44 - results) 1.45 - (if-let [target (first results)] 1.46 - (.getGeometry target) 1.47 - (recur (float (* 2 radius))))))) 1.48 - 1.49 -(defn bind-sense 1.50 - "Bind the sense to the Spatial such that it will maintain its 1.51 - current position relative to the Spatial no matter how the spatial 1.52 - moves. 'sense can be either a Camera or Listener object." 1.53 - [#^Spatial obj sense] 1.54 - (let [sense-offset (.subtract (.getLocation sense) 1.55 - (.getWorldTranslation obj)) 1.56 - initial-sense-rotation (Quaternion. (.getRotation sense)) 1.57 - base-anti-rotation (.inverse (.getWorldRotation obj))] 1.58 - (.addControl 1.59 - obj 1.60 - (proxy [AbstractControl] [] 1.61 - (controlUpdate [tpf] 1.62 - (let [total-rotation 1.63 - (.mult base-anti-rotation (.getWorldRotation obj))] 1.64 - (.setLocation 1.65 - sense 1.66 - (.add 1.67 - (.mult total-rotation sense-offset) 1.68 - (.getWorldTranslation obj))) 1.69 - (.setRotation 1.70 - sense 1.71 - (.mult total-rotation initial-sense-rotation)))) 1.72 - (controlRender [_ _]))))) 1.73 - 1.74 -(def white 0xFFFFFF) 1.75 - 1.76 -(defn white? [rgb] 1.77 - (= (bit-and white rgb) white)) 1.78 - 1.79 -(defn filter-pixels 1.80 - "List the coordinates of all pixels matching pred, within the bounds 1.81 - provided. 1.82 - bounds -> [x0 y0 width height]" 1.83 - {:author "Dylan Holmes"} 1.84 - ([pred #^BufferedImage image] 1.85 - (filter-pixels pred image [0 0 (.getWidth image) (.getHeight image)])) 1.86 - ([pred #^BufferedImage image [x0 y0 width height]] 1.87 - ((fn accumulate [x y matches] 1.88 - (cond 1.89 - (>= y (+ height y0)) matches 1.90 - (>= x (+ width x0)) (recur 0 (inc y) matches) 1.91 - (pred (.getRGB image x y)) 1.92 - (recur (inc x) y (conj matches [x y])) 1.93 - :else (recur (inc x) y matches))) 1.94 - x0 y0 []))) 1.95 - 1.96 -(defn white-coordinates 1.97 - "Coordinates of all the white pixels in a subset of the image." 1.98 - ([#^BufferedImage image bounds] 1.99 - (filter-pixels white? image bounds)) 1.100 - ([#^BufferedImage image] 1.101 - (filter-pixels white? image))) 1.102 - 1.103 -(defn points->image 1.104 - "Take a sparse collection of points and visuliaze it as a 1.105 - BufferedImage." 1.106 - [points] 1.107 - (if (empty? points) 1.108 - (BufferedImage. 1 1 BufferedImage/TYPE_BYTE_BINARY) 1.109 - (let [xs (vec (map first points)) 1.110 - ys (vec (map second points)) 1.111 - x0 (apply min xs) 1.112 - y0 (apply min ys) 1.113 - width (- (apply max xs) x0) 1.114 - height (- (apply max ys) y0) 1.115 - image (BufferedImage. (inc width) (inc height) 1.116 - BufferedImage/TYPE_INT_RGB)] 1.117 - (dorun 1.118 - (for [x (range (.getWidth image)) 1.119 - y (range (.getHeight image))] 1.120 - (.setRGB image x y 0xFF0000))) 1.121 - (dorun 1.122 - (for [index (range (count points))] 1.123 - (.setRGB image (- (xs index) x0) (- (ys index) y0) -1))) 1.124 - image))) 1.125 - 1.126 -(defn average [coll] 1.127 - (/ (reduce + coll) (count coll))) 1.128 - 1.129 -(defn collapse-1d 1.130 - "One dimensional analogue of collapse." 1.131 - [center line] 1.132 - (let [length (count line) 1.133 - num-above (count (filter (partial < center) line)) 1.134 - num-below (- length num-above)] 1.135 - (range (- center num-below) 1.136 - (+ center num-above)))) 1.137 - 1.138 -(defn collapse 1.139 - "Take a set of pairs of integers and collapse them into a 1.140 - contigous bitmap with no \"holes\"." 1.141 - [points] 1.142 - (if (empty? points) [] 1.143 - (let 1.144 - [num-points (count points) 1.145 - center (vector 1.146 - (int (average (map first points))) 1.147 - (int (average (map first points)))) 1.148 - flattened 1.149 - (reduce 1.150 - concat 1.151 - (map 1.152 - (fn [column] 1.153 - (map vector 1.154 - (map first column) 1.155 - (collapse-1d (second center) 1.156 - (map second column)))) 1.157 - (partition-by first (sort-by first points)))) 1.158 - squeezed 1.159 - (reduce 1.160 - concat 1.161 - (map 1.162 - (fn [row] 1.163 - (map vector 1.164 - (collapse-1d (first center) 1.165 - (map first row)) 1.166 - (map second row))) 1.167 - (partition-by second (sort-by second flattened)))) 1.168 - relocated 1.169 - (let [min-x (apply min (map first squeezed)) 1.170 - min-y (apply min (map second squeezed))] 1.171 - (map (fn [[x y]] 1.172 - [(- x min-x) 1.173 - (- y min-y)]) 1.174 - squeezed))] 1.175 - relocated))) 1.176 - 1.177 -(defn world-to-local 1.178 - "Convert the world coordinates into coordinates relative to the 1.179 - object (i.e. local coordinates), taking into account the rotation 1.180 - of object." 1.181 - [#^Spatial object world-coordinate] 1.182 - (.worldToLocal object world-coordinate nil)) 1.183 - 1.184 -(defn local-to-world 1.185 - "Convert the local coordinates into world relative coordinates" 1.186 - [#^Spatial object local-coordinate] 1.187 - (.localToWorld object local-coordinate nil)) 1.188 - 1.189 -(defn sense-nodes 1.190 - "For each sense there is a special blender node whose children are 1.191 - considered markers for an instance of a that sense. This function 1.192 - generates functions to find those children, given the name of the 1.193 - special parent node." 1.194 - [parent-name] 1.195 - (fn [#^Node creature] 1.196 - (if-let [sense-node (.getChild creature parent-name)] 1.197 - (seq (.getChildren sense-node)) 1.198 - (do (println-repl "could not find" parent-name "node") [])))) 1.199 - 1.200 -(defn load-image 1.201 - "Load an image as a BufferedImage using the asset-manager system." 1.202 - [asset-relative-path] 1.203 - (ImageToAwt/convert 1.204 - (.getImage (.loadTexture (asset-manager) asset-relative-path)) 1.205 - false false 0)) 1.206 - 1.207 -(defn jme-to-blender 1.208 - "Convert from JME coordinates to Blender coordinates" 1.209 - [#^Vector3f in] 1.210 - (Vector3f. (.getX in) 1.211 - (- (.getZ in)) 1.212 - (.getY in))) 1.213 - 1.214 -(defn blender-to-jme 1.215 - "Convert from Blender coordinates to JME coordinates" 1.216 - [#^Vector3f in] 1.217 - (Vector3f. (.getX in) 1.218 - (.getZ in) 1.219 - (- (.getY in)))) 1.220 -#+end_src 1.221 - 1.222 -#+results: sense-util 1.223 -: #'cortex.sense/meta-data 1.224 - 1.225 - 1.226 - 1.227 -* COMMENT generate source 1.228 -#+begin_src clojure :tangle ../src/cortex/sense.clj 1.229 -<<sense-util>> 1.230 -#+end_src
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/sense.org Sat Feb 04 07:49:46 2012 -0700 2.3 @@ -0,0 +1,223 @@ 2.4 +#+title: General sense/effector utilities 2.5 +#+author: Robert McIntyre 2.6 +#+email: rlm@mit.edu 2.7 +#+description: sensory utilities 2.8 +#+keywords: simulation, jMonkeyEngine3, clojure, simulated senses 2.9 +#+SETUPFILE: ../../aurellem/org/setup.org 2.10 +#+INCLUDE: ../../aurellem/org/level-0.org 2.11 + 2.12 +#+name: sense 2.13 +#+begin_src clojure 2.14 +(ns cortex.sense 2.15 + "Here are functions useful in the construction of two or more 2.16 + sensors/effectors." 2.17 + {:author "Robert McInytre"} 2.18 + (:use (cortex world util)) 2.19 + (:import ij.process.ImageProcessor) 2.20 + (:import jme3tools.converters.ImageToAwt) 2.21 + (:import java.awt.image.BufferedImage) 2.22 + (:import com.jme3.collision.CollisionResults) 2.23 + (:import com.jme3.bounding.BoundingBox) 2.24 + (:import (com.jme3.scene Node Spatial)) 2.25 + (:import com.jme3.scene.control.AbstractControl) 2.26 + (:import (com.jme3.math Quaternion Vector3f))) 2.27 + 2.28 +(defn meta-data 2.29 + "Get the meta-data for a node created with blender." 2.30 + [blender-node key] 2.31 + (if-let [data (.getUserData blender-node "properties")] 2.32 + (.findValue data key) 2.33 + nil)) 2.34 + 2.35 +(defn closest-node 2.36 + "Return the node in creature which is closest to the given node." 2.37 + [#^Node creature #^Node eye] 2.38 + (loop [radius (float 0.01)] 2.39 + (let [results (CollisionResults.)] 2.40 + (.collideWith 2.41 + creature 2.42 + (BoundingBox. (.getWorldTranslation eye) 2.43 + radius radius radius) 2.44 + results) 2.45 + (if-let [target (first results)] 2.46 + (.getGeometry target) 2.47 + (recur (float (* 2 radius))))))) 2.48 + 2.49 +(defn bind-sense 2.50 + "Bind the sense to the Spatial such that it will maintain its 2.51 + current position relative to the Spatial no matter how the spatial 2.52 + moves. 'sense can be either a Camera or Listener object." 2.53 + [#^Spatial obj sense] 2.54 + (let [sense-offset (.subtract (.getLocation sense) 2.55 + (.getWorldTranslation obj)) 2.56 + initial-sense-rotation (Quaternion. (.getRotation sense)) 2.57 + base-anti-rotation (.inverse (.getWorldRotation obj))] 2.58 + (.addControl 2.59 + obj 2.60 + (proxy [AbstractControl] [] 2.61 + (controlUpdate [tpf] 2.62 + (let [total-rotation 2.63 + (.mult base-anti-rotation (.getWorldRotation obj))] 2.64 + (.setLocation 2.65 + sense 2.66 + (.add 2.67 + (.mult total-rotation sense-offset) 2.68 + (.getWorldTranslation obj))) 2.69 + (.setRotation 2.70 + sense 2.71 + (.mult total-rotation initial-sense-rotation)))) 2.72 + (controlRender [_ _]))))) 2.73 + 2.74 +(def white 0xFFFFFF) 2.75 + 2.76 +(defn white? [rgb] 2.77 + (= (bit-and white rgb) white)) 2.78 + 2.79 +(defn filter-pixels 2.80 + "List the coordinates of all pixels matching pred, within the bounds 2.81 + provided. 2.82 + bounds -> [x0 y0 width height]" 2.83 + {:author "Dylan Holmes"} 2.84 + ([pred #^BufferedImage image] 2.85 + (filter-pixels pred image [0 0 (.getWidth image) (.getHeight image)])) 2.86 + ([pred #^BufferedImage image [x0 y0 width height]] 2.87 + ((fn accumulate [x y matches] 2.88 + (cond 2.89 + (>= y (+ height y0)) matches 2.90 + (>= x (+ width x0)) (recur 0 (inc y) matches) 2.91 + (pred (.getRGB image x y)) 2.92 + (recur (inc x) y (conj matches [x y])) 2.93 + :else (recur (inc x) y matches))) 2.94 + x0 y0 []))) 2.95 + 2.96 +(defn white-coordinates 2.97 + "Coordinates of all the white pixels in a subset of the image." 2.98 + ([#^BufferedImage image bounds] 2.99 + (filter-pixels white? image bounds)) 2.100 + ([#^BufferedImage image] 2.101 + (filter-pixels white? image))) 2.102 + 2.103 +(defn points->image 2.104 + "Take a sparse collection of points and visuliaze it as a 2.105 + BufferedImage." 2.106 + [points] 2.107 + (if (empty? points) 2.108 + (BufferedImage. 1 1 BufferedImage/TYPE_BYTE_BINARY) 2.109 + (let [xs (vec (map first points)) 2.110 + ys (vec (map second points)) 2.111 + x0 (apply min xs) 2.112 + y0 (apply min ys) 2.113 + width (- (apply max xs) x0) 2.114 + height (- (apply max ys) y0) 2.115 + image (BufferedImage. (inc width) (inc height) 2.116 + BufferedImage/TYPE_INT_RGB)] 2.117 + (dorun 2.118 + (for [x (range (.getWidth image)) 2.119 + y (range (.getHeight image))] 2.120 + (.setRGB image x y 0xFF0000))) 2.121 + (dorun 2.122 + (for [index (range (count points))] 2.123 + (.setRGB image (- (xs index) x0) (- (ys index) y0) -1))) 2.124 + image))) 2.125 + 2.126 +(defn average [coll] 2.127 + (/ (reduce + coll) (count coll))) 2.128 + 2.129 +(defn collapse-1d 2.130 + "One dimensional analogue of collapse." 2.131 + [center line] 2.132 + (let [length (count line) 2.133 + num-above (count (filter (partial < center) line)) 2.134 + num-below (- length num-above)] 2.135 + (range (- center num-below) 2.136 + (+ center num-above)))) 2.137 + 2.138 +(defn collapse 2.139 + "Take a set of pairs of integers and collapse them into a 2.140 + contigous bitmap with no \"holes\"." 2.141 + [points] 2.142 + (if (empty? points) [] 2.143 + (let 2.144 + [num-points (count points) 2.145 + center (vector 2.146 + (int (average (map first points))) 2.147 + (int (average (map first points)))) 2.148 + flattened 2.149 + (reduce 2.150 + concat 2.151 + (map 2.152 + (fn [column] 2.153 + (map vector 2.154 + (map first column) 2.155 + (collapse-1d (second center) 2.156 + (map second column)))) 2.157 + (partition-by first (sort-by first points)))) 2.158 + squeezed 2.159 + (reduce 2.160 + concat 2.161 + (map 2.162 + (fn [row] 2.163 + (map vector 2.164 + (collapse-1d (first center) 2.165 + (map first row)) 2.166 + (map second row))) 2.167 + (partition-by second (sort-by second flattened)))) 2.168 + relocated 2.169 + (let [min-x (apply min (map first squeezed)) 2.170 + min-y (apply min (map second squeezed))] 2.171 + (map (fn [[x y]] 2.172 + [(- x min-x) 2.173 + (- y min-y)]) 2.174 + squeezed))] 2.175 + relocated))) 2.176 + 2.177 +(defn world-to-local 2.178 + "Convert the world coordinates into coordinates relative to the 2.179 + object (i.e. local coordinates), taking into account the rotation 2.180 + of object." 2.181 + [#^Spatial object world-coordinate] 2.182 + (.worldToLocal object world-coordinate nil)) 2.183 + 2.184 +(defn local-to-world 2.185 + "Convert the local coordinates into world relative coordinates" 2.186 + [#^Spatial object local-coordinate] 2.187 + (.localToWorld object local-coordinate nil)) 2.188 + 2.189 +(defn sense-nodes 2.190 + "For each sense there is a special blender node whose children are 2.191 + considered markers for an instance of a that sense. This function 2.192 + generates functions to find those children, given the name of the 2.193 + special parent node." 2.194 + [parent-name] 2.195 + (fn [#^Node creature] 2.196 + (if-let [sense-node (.getChild creature parent-name)] 2.197 + (seq (.getChildren sense-node)) 2.198 + (do (println-repl "could not find" parent-name "node") [])))) 2.199 + 2.200 +(defn load-image 2.201 + "Load an image as a BufferedImage using the asset-manager system." 2.202 + [asset-relative-path] 2.203 + (ImageToAwt/convert 2.204 + (.getImage (.loadTexture (asset-manager) asset-relative-path)) 2.205 + false false 0)) 2.206 + 2.207 +(defn jme-to-blender 2.208 + "Convert from JME coordinates to Blender coordinates" 2.209 + [#^Vector3f in] 2.210 + (Vector3f. (.getX in) 2.211 + (- (.getZ in)) 2.212 + (.getY in))) 2.213 + 2.214 +(defn blender-to-jme 2.215 + "Convert from Blender coordinates to JME coordinates" 2.216 + [#^Vector3f in] 2.217 + (Vector3f. (.getX in) 2.218 + (.getZ in) 2.219 + (- (.getY in)))) 2.220 +#+end_src 2.221 + 2.222 + 2.223 +* COMMENT generate source 2.224 +#+begin_src clojure :tangle ../src/cortex/sense.clj 2.225 +<<sense>> 2.226 +#+end_src