   (btRigidBody$btRigidBodyConstructionInfo.
     mass motion-state collision-shape local-inertia))
 
-(defmacro rigid-body-info!
-  "Calls a single method on a `rigid-body-info`."
-  [object k & options]
-  `(u/call! ^btRigidBody$btRigidBodyConstructionInfo ~object ~k ~@options))
+(defn soft-body*
+  [info]
+  (assoc (Body3D. (btSoftBody. info))
+         :info info))
+
+(defmacro soft-body
+  "Returns a body based on btSoftBody."
+  [info & options]
+  `(let [body# (soft-body* ~info)
+         ^btSoftBody object# (:object body#)]
+     (u/calls! object# ~@options)
+     body#))
+
+(defmacro soft-body!
+  "Calls a single method on a `soft-body`."
+  [object k & options]
+  `(let [^btSoftBody object# (:object (u/get-obj ~object :body))]
+     (u/call! object# ~k ~@options)))
+
+(defn soft-body-info
+  "Returns a btSoftBodyWorldInfo."
+  []
+  (btSoftBodyWorldInfo.))
 
 (defn ^:private body-x
   [entity]

           :config config
           :dispatcher dispatcher
           :broadphase broad
           :solver solver)))

(defn bullet-3d*
  [type]
  @init
  (case type
    :discrete-dynamics (discrete-dynamics)
    (u/throw-key-not-found type)))

(defmacro bullet-3d
  "Returns a world based on btCollisionWorld.

    (bullet-3d :discrete-dynamics)"
  [type & options]
  `(let [world# (bullet-3d* ~type)
         ^btCollisionWorld object# (:object world#)]
     (u/calls! object# ~@options)
     world#))

(defmacro bullet-3d!
  "Calls a single method on a `bullet-3d`."
  [screen k & options]
  `(let [^btCollisionWorld object# (:object (u/get-obj ~screen :world))]
     (u/call! object# ~k ~@options)))

; bodies

(defn basic-body*
  []
  (Body3D. (btCollisionObject.)))

(defmacro basic-body
  "Returns a body based on btCollisionObject."
  [& options]
  `(let [body# (basic-body*)
         ^btCollisionObject object# (:object body#)]
     (u/calls! object# ~@options)
     body#))

(defmacro basic-body!
  "Calls a single method on a `basic-body`."
  [object k & options]
  `(let [^btCollisionObject object# (:object (u/get-obj ~object :body))]
     (u/call! object# ~k ~@options)))

(defn rigid-body*
  [info]

  (cond
    (isa? (type (:object body)) btRigidBody)
    (bullet-3d! screen :add-rigid-body (:object body))
    (isa? (type (:object body)) btSoftBody)
    (bullet-3d! screen :add-soft-body (:object body)))
  body)

(defn ^:private get-bodies
