Add g3d-physics

This commit is contained in:
oakes
2014-04-16 13:10:47 -04:00
parent b523b237db
commit 3298382982
9 changed files with 441 additions and 92 deletions

View File

@@ -23,9 +23,10 @@
"BlendingAttribute" {"attribute :blending" :constructors "BlendingAttribute" {"attribute :blending" :constructors
"attribute-type :blending" :static-fields "attribute-type :blending" :static-fields
"attribute! :blending" :static-methods} "attribute! :blending" :static-methods}
"Body" {"create-body!" :methods "Body" {"body!" :methods}
"body!" :methods}
"BodyDef" {"body-def" :fields} "BodyDef" {"body-def" :fields}
"BoundingBox" {"bounding-box" :methods
"bounding-box!" :methods}
"Bresenham2" {"bresenham-2" :methods "Bresenham2" {"bresenham-2" :methods
"bresenham-2!" :methods} "bresenham-2!" :methods}
"BSpline" {"b-spline" :methods "BSpline" {"b-spline" :methods
@@ -183,6 +184,8 @@
"PulleyJointDef" {"joint-def :pulley" :fields} "PulleyJointDef" {"joint-def :pulley" :fields}
"Quaternion" {"quaternion" :methods "Quaternion" {"quaternion" :methods
"quaternion!" :methods} "quaternion!" :methods}
"Ray" {"ray" :methods
"ray!" :methods}
"Rectangle" {"rectangle" :methods "Rectangle" {"rectangle" :methods
"rectangle!" :methods} "rectangle!" :methods}
"RectangleMapObject" {"map-object :rectangle" :methods} "RectangleMapObject" {"map-object :rectangle" :methods}
@@ -192,6 +195,8 @@
"ScrollPane" {"scroll-pane" :methods "ScrollPane" {"scroll-pane" :methods
"scroll-pane!" :methods} "scroll-pane!" :methods}
"ScrollPane.ScrollPaneStyle" {"style :scroll-pane" :constructors} "ScrollPane.ScrollPaneStyle" {"style :scroll-pane" :constructors}
"Segment" {"segment" :methods
"segment!" :methods}
"SelectBox" {"select-box" :methods "SelectBox" {"select-box" :methods
"select-box!" :methods} "select-box!" :methods}
"SelectBox.SelectBoxStyle" {"style :select-box" :constructors} "SelectBox.SelectBoxStyle" {"style :select-box" :constructors}
@@ -208,6 +213,8 @@
"sound!" :methods} "sound!" :methods}
"SoundLoader" {"loader :sound" :constructors "SoundLoader" {"loader :sound" :constructors
"loader! :sound" :methods} "loader! :sound" :methods}
"Sphere" {"sphere" :methods
"sphere!" :methods}
"SplitPane.SplitPaneStyle" {"style :split-pane" :constructors} "SplitPane.SplitPaneStyle" {"style :split-pane" :constructors}
"SpriteDrawable" {"drawable :sprite" :constructors} "SpriteDrawable" {"drawable :sprite" :constructors}
"Stack" {"stack" :methods "Stack" {"stack" :methods

View File

@@ -4,6 +4,7 @@
:license {:name "Public Domain" :license {:name "Public Domain"
:url "http://unlicense.org/UNLICENSE"} :url "http://unlicense.org/UNLICENSE"}
:dependencies [[com.badlogicgames.gdx/gdx "1.0-SNAPSHOT"] :dependencies [[com.badlogicgames.gdx/gdx "1.0-SNAPSHOT"]
[com.badlogicgames.gdx/gdx-bullet "1.0-SNAPSHOT"]
[org.clojure/clojure "1.5.1"]] [org.clojure/clojure "1.5.1"]]
:repositories [["sonatype" :repositories [["sonatype"
"https://oss.sonatype.org/content/repositories/snapshots/"]]) "https://oss.sonatype.org/content/repositories/snapshots/"]])

View File

@@ -8,7 +8,8 @@
[com.badlogic.gdx.assets AssetManager] [com.badlogic.gdx.assets AssetManager]
[com.badlogic.gdx.assets.loaders AsynchronousAssetLoader] [com.badlogic.gdx.assets.loaders AsynchronousAssetLoader]
[com.badlogic.gdx.graphics Camera Color GL20 OrthographicCamera [com.badlogic.gdx.graphics Camera Color GL20 OrthographicCamera
PerspectiveCamera Pixmap Pixmap$Format PixmapIO Texture VertexAttributes$Usage] PerspectiveCamera Pixmap Pixmap$Format PixmapIO Texture
VertexAttributes$Usage]
[com.badlogic.gdx.graphics.g2d SpriteBatch] [com.badlogic.gdx.graphics.g2d SpriteBatch]
[com.badlogic.gdx.graphics.g3d ModelBatch] [com.badlogic.gdx.graphics.g3d ModelBatch]
[com.badlogic.gdx.graphics.glutils ShapeRenderer] [com.badlogic.gdx.graphics.glutils ShapeRenderer]
@@ -24,7 +25,6 @@
IsometricStaggeredTiledMapRenderer IsometricStaggeredTiledMapRenderer
IsometricTiledMapRenderer IsometricTiledMapRenderer
OrthogonalTiledMapRenderer] OrthogonalTiledMapRenderer]
[com.badlogic.gdx.physics.box2d ContactListener Joint World]
[com.badlogic.gdx.scenes.scene2d Actor Stage] [com.badlogic.gdx.scenes.scene2d Actor Stage]
[com.badlogic.gdx.scenes.scene2d.utils ActorGestureListener Align [com.badlogic.gdx.scenes.scene2d.utils ActorGestureListener Align
ChangeListener ClickListener DragListener FocusListener] ChangeListener ClickListener DragListener FocusListener]
@@ -35,6 +35,7 @@
(load "core_cameras") (load "core_cameras")
(load "core_graphics") (load "core_graphics")
(load "core_listeners") (load "core_listeners")
(load "core_physics")
(load "core_utils") (load "core_utils")
(defn ^:private reset-changed! (defn ^:private reset-changed!
@@ -74,9 +75,11 @@
:update-fn! #(apply swap! screen %1 %2) :update-fn! #(apply swap! screen %1 %2)
:execute-fn! execute-fn! :execute-fn! execute-fn!
:on-timer on-timer :on-timer on-timer
:ui-listeners (ui-listeners options execute-fn!) :ui-listeners (ui-listeners options execute-fn!))
:g2dp-listener (contact-listener options execute-fn!)) (execute-fn! on-show)
(execute-fn! on-show)) (swap! screen assoc
:physics-listeners
(physics-listeners @screen options execute-fn!)))
:render (fn [d] :render (fn [d]
(swap! screen #(assoc % :total-time (+ (:total-time %) d))) (swap! screen #(assoc % :total-time (+ (:total-time %) d)))
(execute-fn! on-render :delta-time d)) (execute-fn! on-render :delta-time d))

View File

@@ -160,20 +160,11 @@
(drag-listener options execute-fn!) (drag-listener options execute-fn!)
(focus-listener options execute-fn!)]) (focus-listener options execute-fn!)])
; g2d-physics (defmulti physics-listeners
(fn [screen options execute-fn!] (-> screen :world class))
:default nil)
(defn ^:private contact-listener (defmethod physics-listeners nil [_ _ _])
[{:keys [on-begin-contact on-end-contact on-post-solve on-pre-solve]}
execute-fn!]
(reify ContactListener
(beginContact [this c]
(execute-fn! on-begin-contact :contact c))
(endContact [this c]
(execute-fn! on-end-contact :contact c))
(postSolve [this c i]
(execute-fn! on-post-solve :contact c :impulse i))
(preSolve [this c m]
(execute-fn! on-pre-solve :contact c :old-manifold m))))
; update functions ; update functions
@@ -195,32 +186,18 @@
(remove-input! renderer) (remove-input! renderer)
(add-input! renderer))) (add-input! renderer)))
(defn ^:private update-box-2d! (defmulti update-physics!
([{:keys [^World world g2dp-listener]}] (fn [screen & [entities]] (-> screen :world class))
(.setContactListener world g2dp-listener)) :default nil)
([{:keys [^World world]} entities]
(when-not (.isLocked world) (defmethod update-physics! nil [_ & _])
(let [arr (u/gdx-array [])]
; remove bodies that no longer exist
(.getBodies world arr)
(doseq [body arr]
(when-not (some #(= body (:body %)) entities)
(.destroyBody world body)))
; remove joints whose bodies no longer exist
(.getJoints world arr)
(doseq [^Joint joint arr]
(when (and (not (some #(= (.getBodyA joint) (:body %)) entities))
(not (some #(= (.getBodyB joint) (:body %)) entities)))
(.destroyJoint world joint)))))))
(defn ^:private update-screen! (defn ^:private update-screen!
([{:keys [renderer world] :as screen}] ([{:keys [renderer world] :as screen}]
(when (isa? (type renderer) Stage) (when (isa? (type renderer) Stage)
(update-stage! screen)) (update-stage! screen))
(when (isa? (type world) World) (update-physics! screen))
(update-box-2d! screen)))
([{:keys [renderer world] :as screen} entities] ([{:keys [renderer world] :as screen} entities]
(when (isa? (type renderer) Stage) (when (isa? (type renderer) Stage)
(update-stage! screen entities)) (update-stage! screen entities))
(when (isa? (type world) World) (update-physics! screen entities)))
(update-box-2d! screen entities))))

View File

@@ -0,0 +1,30 @@
(in-ns 'play-clj.core)
(defmulti step!
"Runs the physics simulations for a single frame and optionally returns the
`entities` with their positions updated."
(fn [screen & [entities]] (-> screen (u/get-obj :world) class)))
(defmulti add-body!
"Adds the `body` to the `screen` for physics simulations and returns it."
(fn [screen body] (-> screen (u/get-obj :world) class)))
(defmulti body-position!
"Changes the position of the body in `entity`."
(fn [entity a1 a2 a3] (-> entity (u/get-obj :body) class)))
(defmulti body-x!
"Changes the `x` of the body in `entity`."
(fn [entity x] (-> entity (u/get-obj :body) class)))
(defmulti body-y!
"Changes the `y` of the body in `entity`."
(fn [entity y] (-> entity (u/get-obj :body) class)))
(defmulti body-z!
"Changes the `z` of the body in `entity`."
(fn [entity z] (-> entity (u/get-obj :body) class)))
(defmulti body-angle!
"Changes the `angle` of the body in `entity`."
(fn [entity angle] (-> entity (u/get-obj :body) class)))

View File

@@ -54,9 +54,14 @@
(.draw object ^SpriteBatch batch 1))) (.draw object ^SpriteBatch batch 1)))
(defrecord ModelEntity [object] Entity (defrecord ModelEntity [object] Entity
(draw-entity! [{:keys [^ModelInstance object]} (draw-entity! [{:keys [^ModelInstance object x y z]}
{:keys [^ModelBatch renderer ^Environment attributes]} {:keys [^ModelBatch renderer ^Environment attributes]}
_] _]
(let [^Matrix4 m (. object transform)
x (float (or x 0))
y (float (or y 0))
z (float (or z 0))]
(.setTranslation m x y z))
(.render renderer object attributes))) (.render renderer object attributes)))
(defrecord ShapeEntity [object] Entity (defrecord ShapeEntity [object] Entity

View File

@@ -1,9 +1,10 @@
(ns play-clj.g2d-physics (ns play-clj.g2d-physics
(:require [play-clj.math :as m] (:require [play-clj.core :as c]
[play-clj.math :as m]
[play-clj.utils :as u]) [play-clj.utils :as u])
(:import [com.badlogic.gdx.physics.box2d Body BodyDef ChainShape CircleShape (:import [com.badlogic.gdx.physics.box2d Body BodyDef ChainShape CircleShape
Contact EdgeShape Fixture FixtureDef JointDef PolygonShape Transform Contact ContactListener EdgeShape Fixture FixtureDef Joint JointDef
World])) PolygonShape Transform World]))
; world ; world
@@ -51,51 +52,37 @@
`(let [^Body object# (u/get-obj ~entity :body)] `(let [^Body object# (u/get-obj ~entity :body)]
(u/call! object# ~k ~@options))) (u/call! object# ~k ~@options)))
(defn create-body!* (defn ^:private body-x
[screen b-def]
(box-2d! screen :create-body b-def))
(defmacro create-body!
"Returns a [Body](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/physics/box2d/Body.html)."
[screen b-def & options]
`(let [^Body object# (create-body!* ~screen ~b-def)]
(u/calls! object# ~@options)))
(defn body-x
"Returns the x position of the body in `entity`."
[entity] [entity]
(. (body! entity :get-position) x)) (. (body! entity :get-position) x))
(defn body-y (defn ^:private body-y
"Returns the y position of the body in `entity`."
[entity] [entity]
(. (body! entity :get-position) y)) (. (body! entity :get-position) y))
(defn body-angle (defn ^:private body-angle
"Returns the angle of the body in `entity`."
[entity] [entity]
(.getRotation ^Transform (body! entity :get-transform))) (.getRotation ^Transform (body! entity :get-transform)))
(defn body-transform! (defmethod c/body-position!
"Changes the `x`, `y`, and `angle` of the body in `entity`." Body
[entity x y angle] [entity x y angle]
(body! entity :set-transform x y angle) (body! entity :set-transform x y angle))
entity)
(defn body-x! (defmethod c/body-x!
"Changes the `x` of the body in `entity`." Body
[entity x] [entity x]
(body-transform! entity x (body-y entity) (body-angle entity))) (c/body-position! entity x (body-y entity) (body-angle entity)))
(defn body-y! (defmethod c/body-y!
"Changes the `y` of the body in `entity`." Body
[entity y] [entity y]
(body-transform! entity (body-x entity) y (body-angle entity))) (c/body-position! entity (body-x entity) y (body-angle entity)))
(defn body-angle! (defmethod c/body-angle!
"Changes the `angle` of the body in `entity`." Body
[entity angle] [entity angle]
(body-transform! entity (body-x entity) (body-y entity) angle)) (c/body-position! entity (body-x entity) (body-y entity) angle))
; joints ; joints
@@ -228,22 +215,56 @@
(assert contact) (assert contact)
(-> contact .getFixtureB .getBody))) (-> contact .getFixtureB .getBody)))
(defn step! (defmethod c/add-body!
"Runs the physics simulations for a single frame and optionally returns the World
`entities` with their positions updated." [screen b-def]
([{:keys [world time-step velocity-iterations position-iterations] (box-2d! screen :create-body b-def))
(defmethod c/physics-listeners
World
[screen
{:keys [on-begin-contact on-end-contact on-post-solve on-pre-solve]}
execute-fn!]
{:contact (reify ContactListener
(beginContact [this c]
(execute-fn! on-begin-contact :contact c))
(endContact [this c]
(execute-fn! on-end-contact :contact c))
(postSolve [this c i]
(execute-fn! on-post-solve :contact c :impulse i))
(preSolve [this c m]
(execute-fn! on-pre-solve :contact c :old-manifold m)))})
(defmethod c/update-physics!
World
[{:keys [^World world physics-listeners]} & [entities]]
(.setContactListener world (:contact physics-listeners))
(when (and entities (not (.isLocked world)))
(let [arr (u/gdx-array [])]
; remove bodies that no longer exist
(.getBodies world arr)
(doseq [body arr]
(when-not (some #(= body (:body %)) entities)
(.destroyBody world body)))
; remove joints whose bodies no longer exist
(.getJoints world arr)
(doseq [^Joint joint arr]
(when (and (not (some #(= (.getBodyA joint) (:body %)) entities))
(not (some #(= (.getBodyB joint) (:body %)) entities)))
(.destroyJoint world joint))))))
(defmethod c/step!
World
[{:keys [^World world time-step velocity-iterations position-iterations]
:or {time-step (/ 1 60) velocity-iterations 10 position-iterations 10} :or {time-step (/ 1 60) velocity-iterations 10 position-iterations 10}
:as screen}] :as screen}
(assert world) & [entities]]
(cond (.step world time-step velocity-iterations position-iterations)
(isa? (type world) World) (when entities
(.step ^World world time-step velocity-iterations position-iterations))) (map (fn [e]
([screen entities] (if (u/get-obj e :body)
(step! screen) (assoc e
(map (fn [entity] :x (body-x e)
(if-let [body (:body entity)] :y (body-y e))
(assoc entity e))
:x (body-x body)
:y (body-y body))
entity))
entities))) entities)))

View File

@@ -0,0 +1,234 @@
(ns play-clj.g3d-physics
(:require [play-clj.core :as c]
[play-clj.math :as m]
[play-clj.utils :as u])
(:import [com.badlogic.gdx.math Matrix4]
[com.badlogic.gdx.physics.bullet Bullet]
[com.badlogic.gdx.physics.bullet.collision btBoxShape
btCollisionDispatcher btCylinderShape btCollisionObject
btCollisionWorld btDefaultCollisionConfiguration btDbvtBroadphase
btSphereShape]
[com.badlogic.gdx.physics.bullet.dynamics btDiscreteDynamicsWorld
btRigidBody btRigidBody$btRigidBodyConstructionInfo
btSequentialImpulseConstraintSolver]
[com.badlogic.gdx.physics.bullet.linearmath btMotionState]))
(def ^:private init (delay (Bullet/init)))
; world
(defn ^:private discrete-dynamics
[]
(let [config (btDefaultCollisionConfiguration.)
dispatcher (btCollisionDispatcher. config)
broad (btDbvtBroadphase.)
solver (btSequentialImpulseConstraintSolver.)]
(btDiscreteDynamicsWorld. dispatcher broad solver config)))
(defn bullet-3d*
[type]
@init
(case type
:discrete-dynamics (discrete-dynamics)
(u/throw-key-not-found type)))
(defmacro bullet-3d
"Returns a subclass of btCollisionWorld.
(bullet-3d :discrete-dynamics)"
[type & options]
`(let [^btCollisionWorld object# (bullet-3d* ~type)]
(u/calls! object# ~@options)))
(defmacro bullet-3d!
"Calls a single method on a `bullet-3d`."
[screen k & options]
`(let [^btCollisionWorld object# (u/get-obj ~screen :world)]
(u/call! object# ~k ~@options)))
; bodies
(defn basic-body*
[]
(btCollisionObject.))
(defmacro basic-body
"Returns a btCollisionObject."
[& options]
`(u/calls! ^btCollisionObject (basic-body*) ~@options))
(defmacro basic-body!
"Calls a single method on a `basic-body`."
[object k & options]
`(u/call! ^btCollisionObject (u/get-obj ~object :body) ~k ~@options))
(defn rigid-body*
[info]
(btRigidBody. info))
(defmacro rigid-body
"Returns a btRigidBody."
[info & options]
`(u/calls! ^btRigidBody (rigid-body* ~info) ~@options))
(defmacro rigid-body!
"Calls a single method on a `rigid-body`."
[object k & options]
`(u/call! ^btRigidBody (u/get-obj ~object :body) ~k ~@options))
(defn rigid-body-info
"Returns a btRigidBodyConstructionInfo."
[mass motion-state collision-shape local-inertia]
(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 ^:private body-x
[entity]
(let [^btCollisionObject object (u/get-obj entity :body)]
(-> object .getWorldTransform (. val) (aget Matrix4/M03))))
(defn ^:private body-y
[entity]
(let [^btCollisionObject object (u/get-obj entity :body)]
(-> object .getWorldTransform (. val) (aget Matrix4/M13))))
(defn ^:private body-z
[entity]
(let [^btCollisionObject object (u/get-obj entity :body)]
(-> object .getWorldTransform (. val) (aget Matrix4/M23))))
(defmethod c/body-position!
btCollisionObject
[entity x y z]
(let [^btCollisionObject object (u/get-obj entity :body)]
(.setWorldTransform object
(doto (m/matrix-4*)
(m/matrix-4! :set-translation x y z)))))
(defmethod c/body-x!
btCollisionObject
[entity x]
(c/body-position! entity x (body-y entity) (body-z entity)))
(defmethod c/body-y!
btCollisionObject
[entity y]
(c/body-position! entity (body-x entity) y (body-z entity)))
(defmethod c/body-z!
btCollisionObject
[entity z]
(c/body-position! entity (body-x entity) (body-y entity) z))
; shapes
(defn box-shape*
[box-half-extents]
(btBoxShape. box-half-extents))
(defmacro box-shape
"Returns a btSphereShape."
[box-half-extents & options]
`(u/calls! ^btBoxShape (box-shape* ~box-half-extents) ~@options))
(defmacro box-shape!
"Calls a single method on a `box-shape`."
[object k & options]
`(u/call! ^btBoxShape ~object ~k ~@options))
(defn cylinder-shape*
[half-extents]
(btCylinderShape. half-extents))
(defmacro cylinder-shape
"Returns a btCylinderShape."
[half-extents & options]
`(u/calls! ^btCylinderShape (cylinder-shape* ~half-extents) ~@options))
(defmacro cylinder-shape!
"Calls a single method on a `cylinder-shape`."
[object k & options]
`(u/call! ^btCylinderShape ~object ~k ~@options))
(defn sphere-shape*
[radius]
(btSphereShape. radius))
(defmacro sphere-shape
"Returns a btSphereShape."
[radius & options]
`(u/calls! ^btSphereShape (sphere-shape* ~radius) ~@options))
(defmacro sphere-shape!
"Calls a single method on a `sphere-shape`."
[object k & options]
`(u/call! ^btSphereShape ~object ~k ~@options))
; misc
(defmethod c/add-body!
btCollisionWorld
[screen body]
(cond
(isa? (type body) btRigidBody)
(bullet-3d! screen :add-rigid-body body)
:else
(bullet-3d! screen :add-collision-object body))
body)
(defn ^:private get-bodies
[screen]
(let [arr (bullet-3d! screen :get-collision-object-array)]
(for [i (range (.size arr))]
(.at arr i))))
(defmethod c/update-physics!
btCollisionWorld
[screen & [entities]]
; initialize bodies
(doseq [e entities]
(let [object (u/get-obj e :object)
body (u/get-obj e :body)]
(when (and object body)
(cond
(isa? (type body) btRigidBody)
(when-not (rigid-body! body :get-motion-state)
(rigid-body! body
:set-motion-state
(proxy [btMotionState] []
(getWorldTransform [world-t])
(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)
:else
(bullet-3d! screen :remove-collision-object body))))))
(defmethod c/step!
btCollisionWorld
[{:keys [^btCollisionWorld world delta-time max-sub-steps time-step]
:or {max-sub-steps 5 time-step (/ 1 60)}
:as screen}
& [entities]]
(.stepSimulation world delta-time max-sub-steps time-step)
(when entities
(map (fn [e]
(if (u/get-obj e :body)
(assoc e
:x (body-x e)
:y (body-y e)
:z (body-z e))
e))
entities)))

View File

@@ -4,7 +4,8 @@
Circle ConvexHull DelaunayTriangulator EarClippingTriangulator Circle ConvexHull DelaunayTriangulator EarClippingTriangulator
Ellipse FloatCounter Frustum GridPoint2 GridPoint3 Matrix3 Matrix4 Ellipse FloatCounter Frustum GridPoint2 GridPoint3 Matrix3 Matrix4
Plane Polygon Polyline Quaternion Rectangle Vector2 Vector3 Plane Polygon Polyline Quaternion Rectangle Vector2 Vector3
WindowedMean])) WindowedMean]
[com.badlogic.gdx.math.collision BoundingBox Ray Segment Sphere]))
; static methods/fields ; static methods/fields
@@ -436,3 +437,73 @@
"Calls a single method on a `windowed-mean`." "Calls a single method on a `windowed-mean`."
[object k & options] [object k & options]
`(u/call! ^WindowedMean ~object ~k ~@options)) `(u/call! ^WindowedMean ~object ~k ~@options))
; bounding-box
(defn bounding-box*
([]
(BoundingBox.))
([box]
(BoundingBox. box))
([min max]
(BoundingBox. min max)))
(defmacro bounding-box
"Returns a [BoundingBox](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/math/collision/BoundingBox.html)."
[min max & options]
`(u/calls! ^BoundingBox (bounding-box* ~min ~max) ~@options))
(defmacro bounding-box!
"Calls a single method on a `bounding-box`."
[object k & options]
`(u/call! ^BoundingBox ~object ~k ~@options))
; ray
(defn ray*
[origin direction]
(Ray. origin direction))
(defmacro ray
"Returns a [Ray](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/math/collision/Ray.html)."
[origin direction & options]
`(u/calls! ^Ray (ray* ~origin ~direction) ~@options))
(defmacro ray!
"Calls a single method on a `ray`."
[object k & options]
`(u/call! ^Ray ~object ~k ~@options))
; segment
(defn segment*
([a-x a-y a-z b-x b-y b-z]
(Segment. a-x a-y a-z b-x b-y b-z))
([a b]
(Segment. a b)))
(defmacro segment
"Returns a [Segment](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/math/collision/Segment.html)."
[a b & options]
`(u/calls! ^Segment (segment* ~a ~b) ~@options))
(defmacro segment!
"Calls a single method on a `segment`."
[object k & options]
`(u/call! ^Segment ~object ~k ~@options))
; sphere
(defn sphere*
[center radius]
(Sphere. center radius))
(defmacro sphere
"Returns a [Sphere](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/math/collision/Sphere.html)."
[center radius & options]
`(u/calls! ^Sphere (sphere* ~center ~radius) ~@options))
(defmacro sphere!
"Calls a single method on a `sphere`."
[object k & options]
`(u/call! ^Sphere ~object ~k ~@options))