rlm@73: #+title: First attempt at a creature! rlm@73: #+author: Robert McIntyre rlm@73: #+email: rlm@mit.edu rlm@73: #+description: rlm@73: #+keywords: simulation, jMonkeyEngine3, clojure rlm@73: #+SETUPFILE: ../../aurellem/org/setup.org rlm@73: #+INCLUDE: ../../aurellem/org/level-0.org rlm@73: rlm@73: * Intro rlm@73: So far, I've made the following senses -- rlm@73: - Vision rlm@73: - Hearing rlm@73: - Touch rlm@73: - Proprioception rlm@73: rlm@73: And one effector: rlm@73: - Movement rlm@73: rlm@73: However, the code so far has only enabled these senses, but has not rlm@73: actually implemented them. For example, there is still a lot of work rlm@73: to be done for vision. I need to be able to create an /eyeball/ in rlm@73: simulation that can be moved around and see the world from different rlm@73: angles. I also need to determine weather to use log-polar or cartesian rlm@73: for the visual input, and I need to determine how/wether to rlm@73: disceritise the visual input. rlm@73: rlm@73: I also want to be able to visualize both the sensors and the rlm@73: effectors in pretty pictures. This semi-retarted creature will by my rlm@73: first attempt at bringing everything together. rlm@73: rlm@73: * The creature's body rlm@73: rlm@73: Still going to do an eve-like body in blender, but due to problems rlm@73: importing the joints, etc into jMonkeyEngine3, I',m going to do all rlm@73: the connecting here in clojure code, using the names of the individual rlm@73: components and trial and error. Later, I'll maybe make some sort of rlm@73: creature-building modifications to blender that support whatever rlm@73: discreitized senses I'm going to make. rlm@73: rlm@73: #+name: body-1 rlm@73: #+begin_src clojure rlm@73: (ns cortex.silly rlm@73: "let's play!" rlm@73: {:author "Robert McIntyre"}) rlm@73: rlm@73: ;; TODO remove this! rlm@73: (require 'cortex.import) rlm@73: (cortex.import/mega-import-jme3) rlm@73: (use '(cortex world util body hearing touch vision)) rlm@73: rlm@73: (use '[clojure.contrib [seq :only [find-first]]]) rlm@73: rlm@73: rlm@73: (rlm.rlm-commands/help) rlm@73: rlm@73: (defn load-blender-model rlm@73: "Load a .blend file using an asset folder relative path." rlm@73: [^String model] rlm@73: (.loadModel rlm@73: (doto (asset-manager) rlm@73: (.registerLoader BlenderModelLoader (into-array String ["blend"]))) rlm@73: model)) rlm@73: rlm@74: (defn meta-data [blender-node key] rlm@74: (if-let [data (.getUserData blender-node "properties")] rlm@74: (.findValue data key) rlm@74: nil)) rlm@73: rlm@74: (defn hand2 [] rlm@74: (load-blender-model "Models/creature1/try-again.blend")) rlm@74: rlm@74: (defn hand [] rlm@74: (load-blender-model "Models/creature1/one.blend")) rlm@74: rlm@74: rlm@73: rlm@74: (def hand-names rlm@74: #{ rlm@74: "middle-1" rlm@74: "middle-2" rlm@74: "middle-3" rlm@74: "palm" rlm@74: "pinky-1" rlm@74: "pinky-2" rlm@74: "pinky-3" rlm@74: "pointer-1" rlm@74: "pointer-2" rlm@74: "pointer-3" rlm@74: "ring-1" rlm@74: "ring-2" rlm@74: "ring-3" rlm@74: "thumb-1" rlm@74: "thumb-2"}) rlm@74: rlm@74: (defn hand-pieces [] rlm@74: (filter rlm@74: (comp hand-names #(apply str (drop-last (.getName %)))) (node-seq (hand)))) rlm@74: rlm@74: (defn hand-joints [] rlm@74: (map #(.getWorldTranslation %) rlm@74: (filter #(re-matches #"joint\.\d\d\d" (.getName %)) rlm@74: (node-seq (hand))))) rlm@74: rlm@74: (defn worm-pieces [] rlm@74: (filter rlm@74: (comp #{"worm-2" "worm-1"} rlm@74: #(apply str (drop-last (.getName %)))) rlm@74: (node-seq (hand2)))) rlm@74: rlm@74: (defn worm-joints [] rlm@74: [Vector3f/ZERO]) rlm@74: rlm@74: rlm@74: rlm@74: (defn find-joint rlm@74: [#^Node parts #^Vector3f joint-position] rlm@74: (loop [radius (float 0.01)] rlm@74: (let [results (CollisionResults.)] rlm@74: (.collideWith rlm@74: parts rlm@74: (BoundingBox. joint-position radius radius radius) rlm@74: results) rlm@74: (let [targets rlm@74: (distinct rlm@74: (map #(.getGeometry %) results))] rlm@74: (if (>= (count targets) 2) rlm@74: (take 2 targets) rlm@74: (recur (float (* radius 2)))))))) rlm@74: rlm@74: rlm@74: rlm@74: (defn connect-at-point rlm@74: [obj-a obj-b point] rlm@74: (let [center-a (.getWorldTranslation obj-a) rlm@74: center-b (.getWorldTranslation obj-b) rlm@74: pivot-a (.subtract point center-a) rlm@74: pivot-b (.subtract point center-b) rlm@74: ;; A side-effect of creating a joint registers rlm@74: ;; it with both physics objects which in turn rlm@74: ;; will register the joint with the physics system rlm@74: ;; when the simulation is started. rlm@74: joint (Point2PointJoint. rlm@74: (.getControl obj-a RigidBodyControl) rlm@74: (.getControl obj-b RigidBodyControl) rlm@74: pivot-a rlm@74: pivot-b)] rlm@74: obj-a)) rlm@74: rlm@74: rlm@74: (defn physical-hand [#^Node pieces joints] rlm@74: ;; Make each piece a physical entity in the simulation. rlm@74: (dorun rlm@74: (map rlm@74: (fn [geom] rlm@74: (let [physics-control rlm@74: (RigidBodyControl. rlm@74: (HullCollisionShape. rlm@74: (.getMesh geom)) rlm@74: ;; TODO: fix this. rlm@74: (float 1.0))] rlm@74: (.addControl geom physics-control))) rlm@74: (filter #(isa? (class %) Geometry ) rlm@74: (node-seq pieces)))) rlm@74: (dorun rlm@74: (map rlm@74: (fn [joint-position] rlm@74: (let [[geom-a geom-b] (find-joint pieces joint-position)] rlm@74: (connect-at-point geom-a geom-b joint-position))) rlm@74: joints)) rlm@74: pieces) rlm@74: rlm@74: rlm@74: (defn the-hand! [] (physical-hand (hand) (hand-joints))) rlm@74: rlm@74: rlm@74: (defn test-hand [] rlm@74: (world rlm@74: (nodify [(the-hand!) rlm@74: (box 10 0.1 10 :position (Vector3f. 0 -10 0) rlm@74: :color ColorRGBA/Gray rlm@74: :mass 0)]) rlm@74: standard-debug-controls rlm@74: enable-debug rlm@74: no-op)) rlm@74: rlm@74: rlm@74: rlm@74: rlm@74: rlm@73: rlm@73: rlm@73: #+end_src rlm@73: rlm@73: rlm@73: rlm@73: * COMMENT generate source rlm@73: #+begin_src clojure :tangle ../src/cortex/silly.clj rlm@73: <> rlm@73: #+end_src rlm@73: