rlm@0: #+title: SKIN! rlm@0: #+author: Robert McIntyre rlm@0: #+email: rlm@mit.edu rlm@0: #+description: Simulating touch in JMonkeyEngine rlm@4: #+SETUPFILE: ../../aurellem/org/setup.org rlm@4: #+INCLUDE: ../../aurellem/org/level-0.org rlm@0: rlm@0: rlm@0: rlm@0: rlm@0: * skin! rlm@0: rlm@0: #+srcname: skin-main rlm@0: #+begin_src clojure rlm@0: (ns body.skin) rlm@0: (use 'cortex.world) rlm@0: (use 'cortex.import) rlm@0: (use 'clojure.contrib.def) rlm@0: (cortex.import/mega-import-jme3) rlm@0: (rlm.rlm-commands/help) rlm@0: rlm@0: (import java.util.logging.Level) rlm@0: (import java.util.logging.Logger) rlm@0: rlm@0: rlm@0: rlm@0: ;; looks like we can use GhostControls for implementing touch. rlm@0: ;; for example: rlm@0: (def rc (GhostControl. (BoxCollisionShape. (Vector3f. 2 2 2)))) rlm@0: (def shifted-sphere rlm@0: (doto (CompoundCollisionShape.) rlm@0: (.addChildShape (SphereCollisionShape. 3) (Vector3f. 1 0 0)))) rlm@0: rlm@0: (def gc (GhostControl. shifted-sphere)) rlm@0: (def b (box 1 1 1 :mass 1)) rlm@0: (.addControl b rc) rlm@0: (.addControl b gc) rlm@0: rlm@0: rlm@0: (defn looksies! [] rlm@0: (view b)) rlm@0: rlm@0: ;; overlapping objects can be gotten via =.getOverlappingCount= and rlm@0: ;; =.getOverlappingObjects= rlm@0: rlm@0: ;; looks like I might be able to place a small "touch-sphere" whther rlm@0: ;; on every triangle in the object's mesh, or at the verticies, using rlm@0: ;; .getTriangleCount() on the mesh gotten by .getMesh() rlm@0: rlm@0: ;; this way, I can create a mesh and just divide up it's faces using rlm@0: ;; blender, and this will create the touch sensor distribution. rlm@0: rlm@0: rlm@0: (defn make-touch-sphere [#^Geometry geom] rlm@0: (let [tri (Triangle.) rlm@0: mesh (.getMesh geom) rlm@0: controls! (transient [])] rlm@0: (dorun rlm@0: (for [n (range (.getTriangleCount mesh))] rlm@0: (do rlm@0: (.getTriangle mesh n tri) rlm@0: (.calculateCenter tri) rlm@0: (let [control rlm@0: (doto rlm@0: (GhostControl. rlm@0: (doto (CompoundCollisionShape.) rlm@0: (.addChildShape rlm@0: (SphereCollisionShape. (float 0.1)) rlm@0: (.mult (.getCenter tri) (float 1))) rlm@0: (.setMargin -0.1))) rlm@0: (.setApplyPhysicsLocal true))] rlm@0: rlm@0: (.addControl geom control) rlm@0: (conj! controls! control))))) rlm@0: (persistent! controls!))) rlm@0: rlm@0: rlm@0: (defn make-touch [#^Geometry geom] rlm@0: (let [tri (Triangle.) rlm@0: mesh (.getMesh geom) rlm@0: controls! (transient [])] rlm@0: (dorun rlm@0: (for [n (range (.getTriangleCount mesh))] rlm@0: (do rlm@0: (.getTriangle mesh n tri) rlm@0: (.calculateCenter tri) rlm@0: (.calculateNormal tri) rlm@0: (println-repl tri) rlm@0: (println-repl (.get1 tri)) rlm@0: (println-repl (.get2 tri)) rlm@0: (println-repl (.get3 tri)) rlm@0: (println-repl (.getCenter tri)) rlm@0: (println-repl (.getNormal tri)) rlm@0: (let [control rlm@0: (doto rlm@0: (GhostControl. rlm@0: rlm@0: (doto (CompoundCollisionShape.) rlm@0: (.addChildShape rlm@0: (SimplexCollisionShape. Vector3f/ZERO) rlm@0: (.mult (.getCenter tri) (float 1))) rlm@0: (.setMargin 0) rlm@0: )) rlm@0: (.setApplyPhysicsLocal true))] rlm@0: rlm@0: (.addControl geom control) rlm@0: (conj! controls! control))))) rlm@0: (persistent! controls!))) rlm@0: rlm@0: (defn make-fucked-touch [#^Geometry geom] rlm@0: (let [tri (Triangle.) rlm@0: mesh (.getMesh geom) rlm@0: controls! (transient [])] rlm@0: (dorun rlm@0: (for [n (range (.getTriangleCount mesh))] rlm@0: (do rlm@0: (.getTriangle mesh n tri) rlm@0: (.calculateCenter tri) rlm@0: (.calculateNormal tri) rlm@0: (println-repl tri) rlm@0: (println-repl (.get1 tri)) rlm@0: (println-repl (.get2 tri)) rlm@0: (println-repl (.get3 tri)) rlm@0: (println-repl (.getCenter tri)) rlm@0: (println-repl (.getNormal tri)) rlm@0: (let [control1 rlm@0: (doto rlm@0: (GhostControl. rlm@0: (doto (CompoundCollisionShape.) rlm@0: (.addChildShape rlm@0: (SimplexCollisionShape. Vector3f/ZERO) rlm@0: (.get1 tri)))) rlm@0: (.setApplyPhysicsLocal true))] rlm@0: rlm@0: (.addControl geom control1) rlm@0: (conj! controls! control1) rlm@0: ) rlm@0: rlm@0: ;; (let [control1 rlm@0: ;; (doto rlm@0: ;; (GhostControl. rlm@0: ;; (doto (CompoundCollisionShape.) rlm@0: ;; (.addChildShape rlm@0: ;; (SimplexCollisionShape. Vector3f/ZERO) rlm@0: ;; (.get2 tri)))) rlm@0: ;; (.setApplyPhysicsLocal true))] rlm@0: rlm@0: ;; (.addControl geom control1) rlm@0: ;; (conj! controls! control1) rlm@0: ;; ) rlm@0: rlm@0: ;; (let [control1 rlm@0: ;; (doto rlm@0: ;; (GhostControl. rlm@0: ;; (doto (CompoundCollisionShape.) rlm@0: ;; (.addChildShape rlm@0: ;; (SimplexCollisionShape. Vector3f/ZERO) rlm@0: ;; (.get3 tri)))) rlm@0: ;; (.setApplyPhysicsLocal true))] rlm@0: rlm@0: ;; (.addControl geom control1) rlm@0: ;; (conj! controls! control1) rlm@0: rlm@0: ))) rlm@0: (persistent! controls!))) rlm@0: rlm@0: rlm@0: rlm@0: (use 'hello.brick-wall) rlm@0: rlm@0: (defn touch-reception [controls] rlm@0: (let [control rlm@0: (first rlm@0: (filter rlm@0: #(< 2 (.getOverlappingCount %)) controls))] rlm@0: (if (not (nil? control)) rlm@0: (println rlm@0: (seq rlm@0: (.getOverlappingObjects control)))))) rlm@0: rlm@0: (defn touch-print [controls] rlm@0: (println rlm@0: (map #(count (.getNonGhostOverlappingObjects %)) controls))) rlm@0: rlm@0: (defn set-debug-color [#^ColorRGBA color #^GhostControl gc] rlm@0: (.setColor (.getMaterial (.getChild (.getDebugShape gc) 0)) "Color" color)) rlm@0: rlm@0: (defn html-color [html-str] rlm@0: ((fn [[r g b]] (ColorRGBA. r g b (float 1))) rlm@0: (map #(float (/ (Integer/parseInt % 16) 255)) rlm@0: (map (partial apply str) (partition 2 html-str))))) rlm@0: rlm@0: rlm@0: (defn color-touch [controls] rlm@0: (no-exceptions rlm@0: (dorun rlm@0: (map rlm@0: (fn [control] rlm@0: (case (count (.getNonGhostOverlappingObjects control)) rlm@0: 0 (set-debug-color ColorRGBA/Gray control) rlm@0: 1 (set-debug-color ColorRGBA/Blue control) rlm@0: 2 (set-debug-color ColorRGBA/Green control) rlm@0: 3 (set-debug-color ColorRGBA/Yellow control) rlm@0: 4 (set-debug-color ColorRGBA/Orange control) rlm@0: 5 (set-debug-color ColorRGBA/Red control) rlm@0: 6 (set-debug-color ColorRGBA/Magenta control) rlm@0: 7 (set-debug-color ColorRGBA/Pink control) rlm@0: 8 (set-debug-color ColorRGBA/White control))) rlm@0: controls)))) rlm@0: rlm@0: (defn enable-debug [world] rlm@0: (.enableDebug rlm@0: (.getPhysicsSpace rlm@0: (.getState rlm@0: (.getStateManager world) rlm@0: BulletAppState)) rlm@0: (asset-manager))) rlm@0: rlm@0: (def with-debug rlm@0: '(1 1 1 1 0 1 2 0 2 0 1 1 1 1 0 2 0 2 2 1 0 0 0 1 0 0 0 0 1 0)) rlm@0: (def no-debug rlm@0: '(1 1 1 1 0 1 2 0 2 0 1 1 1 1 0 2 0 2 2 1 0 0 0 1 0 0 0 0 1 0)) rlm@0: rlm@0: rlm@0: rlm@0: (defn transparent-sphere [] rlm@0: (doto rlm@0: (make-shape rlm@0: (merge base-shape rlm@0: {:position (Vector3f. 0 2 0) rlm@0: :name "the blob." rlm@0: :material "Common/MatDefs/Misc/Unshaded.j3md" rlm@0: :texture "Textures/purpleWisp.png" rlm@0: :physical? true rlm@0: :mass 70 rlm@0: :color ColorRGBA/Blue rlm@0: :shape (Sphere. 10 10 1)})) rlm@0: (-> (.getMaterial) rlm@0: (.getAdditionalRenderState) rlm@0: (.setBlendMode RenderState$BlendMode/Alpha)) rlm@0: (.setQueueBucket RenderQueue$Bucket/Transparent))) rlm@0: rlm@0: (defn transparent-box [] rlm@0: (doto rlm@0: (make-shape rlm@0: (merge base-shape rlm@0: {:position (Vector3f. 0 2 0) rlm@0: :name "the blob." rlm@0: :material "Common/MatDefs/Misc/Unshaded.j3md" rlm@0: :texture "Textures/purpleWisp.png" rlm@0: :physical? true rlm@0: :mass 70 rlm@0: :color ColorRGBA/Blue rlm@0: :shape (Box. 1 1 1)})) rlm@0: (-> (.getMaterial) rlm@0: (.getAdditionalRenderState) rlm@0: (.setBlendMode RenderState$BlendMode/Alpha)) rlm@0: (.setQueueBucket RenderQueue$Bucket/Transparent))) rlm@0: rlm@0: rlm@0: rlm@0: (defn no-logging [] rlm@0: (.setLevel (Logger/getLogger "com.jme3") Level/OFF)) rlm@0: rlm@0: (defn set-accuracy [world new-accuracy] rlm@0: (let [physics-manager (.getState (.getStateManager world) BulletAppState)] rlm@0: (.setAccuracy (.getPhysicsSpace physics-manager) (float new-accuracy)))) rlm@0: rlm@0: (defn test-skin [] rlm@0: (let [b rlm@0: ;;(transparent-box) rlm@0: (transparent-sphere) rlm@0: rlm@0: controls rlm@0: ;;(make-touch-sphere b) rlm@0: (make-touch b) rlm@0: ] rlm@0: rlm@0: (world rlm@0: (doto (Node.) (.attachChild b) rlm@0: (.attachChild rlm@0: (doto rlm@0: (box 5 0.2 5 :mass 0 :position (Vector3f. 0 -2 0) rlm@0: :material "Common/MatDefs/Misc/Unshaded.j3md" rlm@0: :texture "Textures/redWisp.png") rlm@0: (-> (.getMaterial) rlm@0: (.getAdditionalRenderState) rlm@0: (.setBlendMode RenderState$BlendMode/Alpha)) rlm@0: (.setQueueBucket RenderQueue$Bucket/Transparent)))) rlm@0: rlm@0: {"key-return" (fire-cannon-ball) rlm@0: "key-space" (fn [game value] rlm@0: (touch-print controls))} rlm@0: (fn [world] rlm@1: (Capture/SimpleCaptureVideo rlm@1: world rlm@3: (file-str "/home/r/proj/cortex/tmp/blob.avi")) rlm@0: (no-logging) rlm@0: (enable-debug world) rlm@0: (set-accuracy world (/ 1 60)) rlm@0: ) rlm@0: rlm@0: (fn [& _] rlm@0: (touch-print controls) rlm@0: (color-touch controls) rlm@0: )))) rlm@0: rlm@0: #+end_src rlm@0: rlm@3: #+results: skin-main rlm@3: : #'body.skin/test-skin rlm@3: rlm@0: rlm@0: rlm@0: rlm@0: rlm@0: rlm@0: * COMMENT code generation rlm@0: #+begin_src clojure :tangle ../src/body/skin.clj rlm@0: <> rlm@0: #+end_src rlm@0: rlm@0: rlm@0: rlm@0: