rlm@0: #+title: The BODY!!! rlm@0: #+author: Robert McIntyre rlm@0: #+email: rlm@mit.edu rlm@4: #+description: Simulating a body (movement, touch, propioception) in jMonkeyEngine3. rlm@4: #+SETUPFILE: ../../aurellem/org/setup.org rlm@4: #+INCLUDE: ../../aurellem/org/level-0.org rlm@4: rlm@53: * COMMENT Body rlm@0: rlm@0: #+srcname: body-main rlm@0: #+begin_src clojure rlm@44: (ns cortex.body rlm@44: (use (cortex world util import))) rlm@44: rlm@0: (use 'clojure.contrib.def) rlm@0: (cortex.import/mega-import-jme3) rlm@0: (rlm.rlm-commands/help) rlm@0: rlm@44: ;;(.loadModel rlm@44: ;; (doto (asset-manager) rlm@44: ;; (.registerLoader BlenderModelLoader (into-array String ["blend"]))) rlm@44: ;; "Models/person/person.blend") rlm@44: rlm@44: (defn view-model [^String model] rlm@44: (view rlm@44: (.loadModel rlm@44: (doto (asset-manager) rlm@44: (.registerLoader BlenderModelLoader (into-array String ["blend"]))) rlm@44: model))) rlm@49: rlm@49: (defn load-blender-scene [^String model] rlm@49: (.loadModel rlm@49: (doto (asset-manager) rlm@49: (.registerLoader BlenderLoader (into-array String ["blend"]))) rlm@49: model)) rlm@49: rlm@49: (defn load-blender-model rlm@49: [^String model] rlm@49: (.loadModel rlm@49: (doto (asset-manager) rlm@49: (.registerLoader BlenderModelLoader (into-array String ["blend"]))) rlm@49: model)) rlm@49: rlm@49: (defn worm rlm@49: [] rlm@50: (.loadModel (asset-manager) "Models/anim2/Cube.mesh.xml")) rlm@49: rlm@50: (defn oto rlm@49: [] rlm@49: (.loadModel (asset-manager) "Models/Oto/Oto.mesh.xml")) rlm@49: rlm@50: (defn sinbad rlm@50: [] rlm@50: (.loadModel (asset-manager) "Models/Sinbad/Sinbad.mesh.xml")) rlm@50: rlm@50: (defn worm-blender rlm@50: [] rlm@50: (first (seq (.getChildren (load-blender-model rlm@56: "Models/anim2/simple-worm.blend"))))) rlm@50: rlm@52: (defn skel [node] rlm@52: (doto rlm@52: (.getSkeleton rlm@52: (.getControl node SkeletonControl)) rlm@52: ;; this is necessary to force the skeleton to have accurate world rlm@52: ;; transforms before it is rendered to the screen. rlm@52: (.resetAndUpdate))) rlm@52: rlm@50: (defprotocol Textual rlm@50: (text [something] rlm@50: "Display a detailed textual analysis of the given object.")) rlm@50: rlm@50: (extend-type com.jme3.scene.Node rlm@50: Textual rlm@50: (text [node] rlm@50: (println "Total Vertexes: " (.getVertexCount node)) rlm@50: (println "Total Triangles: " (.getTriangleCount node)) rlm@50: (println "Controls :") rlm@50: (dorun (map #(text (.getControl node %)) (range (.getNumControls node)))) rlm@50: (println "Has " (.getQuantity node) " Children:") rlm@50: (doall (map text (.getChildren node))))) rlm@50: rlm@50: (extend-type com.jme3.animation.AnimControl rlm@50: Textual rlm@50: (text [control] rlm@50: (let [animations (.getAnimationNames control)] rlm@52: (println "Animation Control with " (count animations) " animation(s):") rlm@50: (dorun (map println animations))))) rlm@50: rlm@50: (extend-type com.jme3.animation.SkeletonControl rlm@50: Textual rlm@50: (text [control] rlm@50: (println "Skeleton Control with the following skeleton:") rlm@50: (println (.getSkeleton control)))) rlm@50: rlm@52: (extend-type com.jme3.bullet.control.KinematicRagdollControl rlm@52: Textual rlm@52: (text [control] rlm@52: (println "Ragdoll Control"))) rlm@52: rlm@52: rlm@50: (extend-type com.jme3.scene.Geometry rlm@50: Textual rlm@50: (text [control] rlm@50: (println "...geo..."))) rlm@50: rlm@50: rlm@50: rlm@50: rlm@50: (defn body rlm@52: "given a node with a SkeletonControl, will produce a body sutiable rlm@52: for AI control with movement and proprioception." rlm@50: [node] rlm@50: (let [skeleton-control (.getControl node SkeletonControl) rlm@53: krc (KinematicRagdollControl.)] rlm@53: (comment rlm@50: (dorun rlm@50: (map #(.addBoneName krc %) rlm@53: ["mid2" "tail" "head" "mid1" "mid3" "mid4" "Dummy-Root" ""] rlm@53: ;;"mid2" "mid3" "tail" "head"] rlm@53: ))) rlm@50: (.addControl node krc) rlm@52: (.setRagdollMode krc) rlm@52: ) rlm@50: node rlm@50: ) rlm@50: rlm@52: (defn green-x-ray [] rlm@51: (doto (Material. (asset-manager) rlm@51: "Common/MatDefs/Misc/Unshaded.j3md") rlm@51: (.setColor "Color" ColorRGBA/Green) rlm@52: (-> (.getAdditionalRenderState) rlm@52: (.setDepthTest false)))) rlm@51: rlm@53: (defn show-skeleton [node] rlm@50: (let [sd rlm@51: rlm@50: (doto rlm@51: (SkeletonDebugger. "aurellem-skel-debug" rlm@51: (skel node)) rlm@51: (.setMaterial (green-x-ray)))] rlm@53: (.attachChild node sd) rlm@53: node)) rlm@50: rlm@51: rlm@50: rlm@50: (defn init-debug-skel-node rlm@50: [f debug-node skeleton] rlm@50: (let [bones rlm@50: (map #(.getBone skeleton %) rlm@50: (range (.getBoneCount skeleton)))] rlm@50: (dorun (map #(.setUserControl % true) bones)) rlm@50: (dorun (map (fn [b] rlm@50: (println (.getName b) rlm@50: " -- " (f b))) rlm@50: bones)) rlm@50: (dorun rlm@50: (map #(.attachChild rlm@50: debug-node rlm@51: (doto rlm@51: (sphere 0.1 rlm@51: :position (f %) rlm@51: :physical? false) rlm@51: (.setMaterial (green-x-ray)))) rlm@50: bones))) rlm@50: debug-node) rlm@50: rlm@52: (import jme3test.bullet.PhysicsTestHelper) rlm@50: rlm@53: rlm@53: (defn test-zzz [the-worm world value] rlm@53: (if (not value) rlm@53: (let [skeleton (skel the-worm)] rlm@53: (println-repl "enabling bones") rlm@53: (dorun rlm@53: (map rlm@53: #(.setUserControl (.getBone skeleton %) true) rlm@53: (range (.getBoneCount skeleton)))) rlm@53: rlm@53: rlm@56: (let [b (.getBone skeleton 2)] rlm@53: (println-repl "moving " (.getName b)) rlm@53: (println-repl (.getLocalPosition b)) rlm@53: (.setUserTransforms b rlm@54: Vector3f/UNIT_X rlm@53: Quaternion/IDENTITY rlm@54: ;;(doto (Quaternion.) rlm@54: ;; (.fromAngles (/ Math/PI 2) rlm@54: ;; 0 rlm@54: ;; 0 rlm@54: rlm@53: (Vector3f. 1 1 1)) rlm@53: ) rlm@53: rlm@53: (println-repl "hi! <3")))) rlm@53: rlm@53: rlm@50: (defn test-ragdoll [] rlm@50: rlm@50: (let [the-worm rlm@53: rlm@52: ;;(.loadModel (asset-manager) "Models/anim2/Cube.mesh.xml") rlm@53: (doto (show-skeleton (worm-blender)) rlm@53: (.setLocalTranslation (Vector3f. 0 10 0)) rlm@53: ;;(worm) rlm@52: ;;(oto) rlm@52: ;;(sinbad) rlm@50: ) rlm@50: ] rlm@50: rlm@50: rlm@50: (.start rlm@50: (world rlm@50: (doto (Node.) rlm@50: (.attachChild the-worm)) rlm@53: {"key-return" (fire-cannon-ball) rlm@53: "key-space" (partial test-zzz the-worm) rlm@53: } rlm@50: (fn [world] rlm@50: (light-up-everything world) rlm@52: (PhysicsTestHelper/createPhysicsTestWorld rlm@52: (.getRootNode world) rlm@52: (asset-manager) rlm@52: (.getPhysicsSpace rlm@52: (.getState (.getStateManager world) BulletAppState))) rlm@53: (set-gravity world Vector3f/ZERO) rlm@50: ;;(.setTimer world (NanoTimer.)) rlm@50: ;;(org.lwjgl.input.Mouse/setGrabbed false) rlm@50: ) rlm@50: no-op rlm@50: ) rlm@50: rlm@50: rlm@50: ))) rlm@50: rlm@55: (defn joint-control rlm@55: [joint] rlm@56: (let [physics-space (ref nil)] rlm@55: (reify PhysicsControl rlm@55: (setPhysicsSpace [this space] rlm@55: (dosync rlm@55: (ref-set physics-space space)) rlm@55: (.addJoint space joint)) rlm@55: (update [this tpf]) rlm@55: (setSpatial [this spatial]) rlm@55: (render [this rm vp]) rlm@55: (getPhysicsSpace [this] (deref physics-space)) rlm@56: (isEnabled [this] true) rlm@56: (setEnabled [this state])))) rlm@50: rlm@55: (defn add-joint rlm@55: "Add a joint to a particular object. When the object is added to the rlm@55: PhysicsSpace of a simulation, the joint will also be added" rlm@55: [object joint] rlm@55: (let [control (joint-control joint)] rlm@55: (.addControl object control)) rlm@55: object) rlm@50: rlm@55: (defn hinge-world rlm@55: [] rlm@55: (let [sphere1 (sphere) rlm@55: sphere2 (sphere 1 :position (Vector3f. 3 3 3)) rlm@55: joint (Point2PointJoint. rlm@55: (.getControl sphere1 RigidBodyControl) rlm@55: (.getControl sphere2 RigidBodyControl) rlm@55: Vector3f/ZERO (Vector3f. 3 3 3))] rlm@55: (add-joint sphere1 joint) rlm@55: (doto (Node. "hinge-world") rlm@55: (.attachChild sphere1) rlm@55: (.attachChild sphere2)))) rlm@55: rlm@56: (defn test-joint [] rlm@56: (view (hinge-world))) rlm@55: rlm@49: rlm@49: rlm@49: rlm@56: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; rlm@56: ;;; here is the ragdoll stuff rlm@56: rlm@56: (def worm-mesh (.getMesh (.getChild (worm-blender) 0))) rlm@56: (def mesh worm-mesh) rlm@56: rlm@56: (.getFloatBuffer mesh VertexBuffer$Type/Position) rlm@56: (.getFloatBuffer mesh VertexBuffer$Type/BoneWeight) rlm@56: (.getData (.getBuffer mesh VertexBuffer$Type/BoneIndex)) rlm@56: rlm@56: rlm@56: (defn position [index] rlm@56: (.get rlm@56: (.getFloatBuffer worm-mesh VertexBuffer$Type/Position) rlm@56: index)) rlm@56: rlm@56: (defn vec-pos [index] rlm@56: (let [offset (* index 3)] rlm@56: (Vector3f. (position offset) rlm@56: (position (inc offset)) rlm@56: (position (inc(inc offset)))))) rlm@56: rlm@56: (defn bones [index] rlm@56: (.get rlm@56: (.getData (.getBuffer mesh VertexBuffer$Type/BoneIndex)) rlm@56: index)) rlm@56: rlm@56: (defn bone-control-color [index] rlm@56: (get {[1 0 0 0] ColorRGBA/Red rlm@56: [1 2 0 0] ColorRGBA/Magenta rlm@56: [2 0 0 0] ColorRGBA/Blue} rlm@56: (vec (map (comp int bones) (range (* index 4) (+ (* index 4) 4)))) rlm@56: ColorRGBA/White)) rlm@56: rlm@56: (defn bone-weights [index] rlm@56: (.get rlm@56: (.getFloatBuffer mesh VertexBuffer$Type/BoneWeight) rlm@56: index)) rlm@56: rlm@56: (defn influence-color [index bone-num] rlm@56: (get rlm@56: {(float 0) ColorRGBA/Blue rlm@56: (float 0.5) ColorRGBA/Green rlm@56: (float 1) ColorRGBA/Red} rlm@56: (bone-weights (+ (* 4 index) bone-num)))) rlm@56: rlm@56: (defn test-info [] rlm@56: (let [points (Node.)] rlm@56: (dorun rlm@56: (map #(.attachChild points %) rlm@56: (map #(sphere 0.01 rlm@56: :position (vec-pos %) rlm@56: :color (influence-color % 0) rlm@56: :physical? false) rlm@56: (range 12)))) rlm@56: (view points))) rlm@56: rlm@56: rlm@56: rlm@56: rlm@56: rlm@56: rlm@56: rlm@56: rlm@56: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; rlm@56: rlm@56: rlm@56: rlm@56: rlm@56: rlm@56: rlm@56: rlm@56: rlm@0: #+end_src rlm@0: rlm@0: rlm@0: rlm@0: rlm@0: rlm@0: rlm@0: rlm@0: rlm@0: * COMMENT generate Source. rlm@44: #+begin_src clojure :tangle ../src/cortex/body.clj rlm@0: <> rlm@0: #+end_src rlm@0: