     (u/throw-key-not-found type)))
 
 (defmacro bullet-3d
-  "Returns a subclass of btCollisionWorld.
+  "Returns a world based on btCollisionWorld.
 
     (bullet-3d :discrete-dynamics)"
   [type & options]
-  `(let [^btCollisionWorld object# (bullet-3d* ~type)]
-     (u/calls! object# ~@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# (u/get-obj ~screen :world)]
+  `(let [^btCollisionWorld object# (:object (u/get-obj ~screen :world))]
      (u/call! object# ~k ~@options)))
 
 ; bodies
 
 (defn basic-body*
   []
-  (btCollisionObject.))
+  (Body3D. (btCollisionObject.)))
 
 (defmacro basic-body
-  "Returns a btCollisionObject."
+  "Returns a body based on btCollisionObject."
   [& options]
-  `(u/calls! ^btCollisionObject (basic-body*) ~@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]
-  `(u/call! ^btCollisionObject (u/get-obj ~object :body) ~k ~@options))
+  `(let [^btCollisionObject object# (:object (u/get-obj ~object :body))]
+     (u/call! object# ~k ~@options)))
 
 (defn rigid-body*
   [info]
-  (btRigidBody. info))
+  (assoc (Body3D. (btRigidBody. info))
+         :info info))
 
 (defmacro rigid-body
-  "Returns a btRigidBody."
+  "Returns a body based on btRigidBody."
   [info & options]
-  `(u/calls! ^btRigidBody (rigid-body* ~info) ~@options))
+  `(let [body# (rigid-body* ~info)
+         ^btRigidBody object# (:object body#)]
+     (u/calls! object# ~@options)
+     body#))
 
 (defmacro rigid-body!
   "Calls a single method on a `rigid-body`."
   [object k & options]
-  `(u/call! ^btRigidBody (u/get-obj ~object :body) ~k ~@options))
+  `(let [^btRigidBody object# (:object (u/get-obj ~object :body))]
+     (u/call! object# ~k ~@options)))
 
 (defn rigid-body-info
   "Returns a btRigidBodyConstructionInfo."

                           (setWorldTransform [world-t]
                             (m/matrix-4! (. object transform) :set world-t)))))
          :else
          (.setWorldTransform body (. object transform))))))
  ; remove bodies that no longer exist
  (when entities
    (doseq [body (get-bodies screen)]
      (when-not (some #(= body (:body %)) entities)
        (cond
          (isa? (type body) btRigidBody)
          (bullet-3d! screen :remove-rigid-body body)


(def ^:private init (delay (Bullet/init)))

(defrecord World3D [object])
(defrecord Body3D [object])

; world

(defn ^:private discrete-dynamics
