Update of /project/cells/cvsroot/cells-ode
In directory clnet:/tmp/cvs-serv32070
Added Files:
bodies.lisp cells-ode.asd collision.lisp core.lisp geoms.lisp
joints.lisp mass.lisp objects.lisp ode-compat.lisp
package.lisp primitives.lisp simulate.lisp test-c-ode.lisp
types.lisp utility.lisp world.lisp
Log Message:
initial ci
--- /project/cells/cvsroot/cells-ode/bodies.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/bodies.lisp 2008/02/08 18:09:31 1.1
(in-package :c-ode)
;;;
;;; body
;;;
(def-ode-model body ()
((position :type vector)
(linear-vel :type vector)
(angular-vel :type vector)
(quaternion :type quaternion)
(force :type vector)
(torque :type vector)
(mass :type mass :result-arg t)
(auto-disable-flag :type bool)
(auto-disable-linear-threshold)
(auto-disable-angular-threshold)
(auto-disable-steps :type int)
(auto-disable-time)
(finite-rotation-mode :type bool) ; 0 = infinitesimal, 1 = finite
(finite-rotation-axis :type vector :result-arg t)
(gravity-mode :type bool :initform (c-in t)))
(:default-initargs
:ode-id (call-ode body-create ((*world* object)))))
(defmethod initialize-instance :after ((self body) &rest initargs))
(defmethod ode-destroy ((self body))
(call-ode body-destroy ((self object)))
(call-next-method))
(defmethod echo-slots append ((self body))
'(position linear-vel angular-vel quaternion))
;;;
;;; Forces
;;;
;;; add force or torque
(def-ode-method add-force ((self body) (force vector)))
(def-ode-method add-torque ((self body) (force vector)))
(def-ode-method add-rel-force ((self body) (force vector)))
(def-ode-method add-rel-torque ((self body) (force vector)))
;;; add force at a point
(def-ode-method add-force-at-pos ((self body) (force vector) (pos vector)))
(def-ode-method add-force-at-rel-pos ((self body) (force vector) (pos vector)))
(def-ode-method add-rel-force-at-pos ((self body) (force vector) (pos vector)))
(def-ode-method add-rel-force-at-rel-pos ((self body) (force vector) (pos vector)))
;;;
;;; coordinate transforms
;;;
;;; get absolute velocity or position for a point
(def-ode-method get-rel-point-pos ((self body) (point vector) (result vector)))
(def-ode-method get-rel-point-vel ((self body) (point vector) (result vector)))
(def-ode-method get-point-vel ((self body) (point vector) (result vector)))
;;; get relative position for a point
(def-ode-method get-pos-rel-point ((self body) (point vector) (result vector)))
;;; rotate a vector to/from relative coordinates
(def-ode-method vector-to-world ((self body) (point vector) (result vector)))
(def-ode-method vector-from-world ((self body) (point vector) (result vector)))
;;;
;;; auto disabling
;;;
(def-ode-method enable ((self body)))
(def-ode-method disable ((self body)))
(def-ode-method is-enabled ((self body)) bool)
(def-ode-method set-auto-disable-defaults ((self body)))
;;;
;;; Joint handling
;;;
(def-ode-method get-num-joints ((self body)) number)
(def-ode-method get-joint ((self body) (index int)) object)
--- /project/cells/cvsroot/cells-ode/cells-ode.asd 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/cells-ode.asd 2008/02/08 18:09:31 1.1
(asdf:defsystem :cells-ode
:name "cells-ode"
:depends-on (:cells :cl-ode :utils-kt :cffi)
:serial t
:components
((:file "package")
(:file "ode-compat")
(:file "types" :depends-on ("package"))
(:file "core" :depends-on ("types" "ode-compat"))
(:file "objects" :depends-on ("core"))
(:file "mass" :depends-on ("core"))
(:file "world" :depends-on ("objects"))
(:file "bodies" :depends-on ("objects"))
(:file "geoms" :depends-on ("objects"))
(:file "joints" :depends-on ("objects"))
(:file "utility" :depends-on ("objects"))
(:file "primitives" :depends-on ("geoms" "bodies" "mass"))
(:file "collision" :depends-on ("objects"))
(:file "simulate" :depends-on ("collision" "objects" "world"))
(:file "test-c-ode" :depends-on ("simulate"))
))--- /project/cells/cvsroot/cells-ode/collision.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/collision.lisp 2008/02/08 18:09:31 1.1
;;; -----------------------------------------------------------------------------------------------
;;; collision detection
;;; -----------------------------------------------------------------------------------------------
(in-package :c-ode)
;;;
;;; Spaces
;;;
(def-ode-model space ()
((cleanup :type bool :initform (c-in t)) ; automatic cleanup
(num-geoms :type int :read-only t))
)
(defmethod ode-destroy ((self space))
(call-ode space-destroy ((self object)))
(call-next-method))
(defmethod echo-slots append ((self space))
'(num-geoms))
;;; simple space
(def-ode-model simple-space (space)
()
(:default-initargs
:ode-id (call-ode simple-space-create (((null-pointer))))))
;;; hash space
(def-ode-model hash-space (space)
()
(:default-initargs
:ode-id (call-ode hash-space-create (((null-pointer))))))
(def-ode-method set-levels ((self hash-space) (minlevel int) (maxlevel int)))
;;; TODO (def-ode-method get-levels) ;; needs multiple return values
;;; quad tree space
(def-ode-model quad-tree-space (space)
()
(:default-initargs
:ode-id (error "Use mk-quad-tree-space to create a quad-tree-space")))
(defun mk-quad-tree-space (center extents depth)
(make-instance 'quad-tree-space :ode-id (call-ode quad-tree-space-create (((null-pointer)) (center vector) (extents vector) (depth int)))))
;;;
;;; geom/space bookkeeping
;;;
(def-ode-method (add-geom :ode-name add) ((self space) (geom object)))
(def-ode-method (remove-geom :ode-name remove) ((self space) (geom object)))
(def-ode-method (query-geom :ode-name query) ((self space) (geom object)) bool)
(def-ode-method get-geom ((self space) (num int)) object)
(defmethod geoms ((self space))
(bwhen (num (num-geoms self))
(loop for i from 0 below num collecting (get-geom self i))))
;;;
;;; collision detection
;;;
(defconstant +max-collision-contacts+ 256)
(defvar *collision-joint-group* nil "ODE joint group")
(def-ode-method (space-collide :ode-name collide) ((self space) data near-collision-callback))
(def-ode-fun space-collide2 ((geom-1 object) (geom-2 object) data near-collision-callback))
(def-ode-fun collide ((geom-1 object) (geom-2 object) (max-contacts int) contact (skip int)) int
(format t "~&in collide~%")
(let ((res (call-ode-fun)))
(format t "~&called collide -- result ~a~%" res)
res))
#+nil (collide (,geom-1
,geom-2
,max-contacts
(foreign-slot-value (mem-aref ,contacts 'ode:contact 0) 'ode:contact 'ode:geom)
(foreign-type-size 'ode:contact)))
(defmacro do-contacts ((contact geom-1 geom-2 &key (max-contacts +max-collision-contacts+)) &body body)
(with-uniqs (contacts num-contacts)
`(with-foreign-object (,contacts 'ode:contact ,max-contacts)
(let ((,num-contacts (call-ode collide ((,geom-1 object)
(,geom-2 object)
(,max-contacts int)
((foreign-slot-value (mem-aref ,contacts 'ode:contact 0) 'ode:contact 'ode:geom))
((foreign-type-size 'ode:contact))) int)
))
(dotimes (i ,num-contacts)
(let ((,contact (mem-aref ,contacts 'ode:contact i)))
(flet ((mk-collision () (attach (mk-contact-joint *collision-joint-group* ,contact) (body ,geom-1) (body ,geom-2))))
,@body)))))))
(eval-now!
(defun ode-sym (sym)
(intern (string sym) :ode))
(defun make-with (type slots-and-types)
(multiple-value-bind (slots types) (parse-typed-args slots-and-types)
`(defmacro ,(intern-string 'with type) (,type (&optional ,@(mapcar #'(lambda (slot) `(,slot ',(gensym (string slot)))) slots)) &body body)
(list 'with-foreign-slots (list ',(mapcar #'ode-sym slots) ,type ',(ode-sym type))
(append (list 'let (list ,@(mapcar #'(lambda (slot type) `(list ,slot ',(make-from-ode type nil (list (ode-sym slot))))) slots types)))
body))))))
(defmacro def-with-ode (type (&rest slots-and-types))
(make-with type slots-and-types))
(def-with-ode contact (surface geom (f-dir-1 vector)))
(def-with-ode contact-geom ((pos vector) (normal vector) (g-1 object) (g-2 object) (depth number) (side-1 int) (side-2 int)))
(defmacro with-surface-parameters ((ode-surface geom-1 geom-2) select &body body)
(let ((params '(mu slip-1 slip-2 soft-erp bounce bounce-vel soft-cfm)))
(let ((ode-params (mapcar #'(lambda (sym) (intern (string sym) :ode)) params)))
(with-uniqs mode
`(with-foreign-slots (,(append ode-params '(ode:mode)) ,ode-surface ode:surface-parameters)
(let ,(append (list (list mode 0)) params)
(macrolet ((select-max (&rest params) `(progn ,@(mapcar #'(lambda (param) `(setf ,param (max (,param ,',geom-1) (,param ,',geom-2)))) ',params))))
,select)
,@(loop for sym in params for ode-sym in ode-params
collecting `(when ,sym
(setf ,ode-sym ,@(make-convert sym 'number))
(setf ,mode (logior ,mode
,(intern (format nil "+CONTACT-~a+" (case sym
(bounce-vel 'bounce)
(mu 'approx-1)
(t sym)))
:ode)))))
(setf ,(intern "MODE" :ode) ,mode)
,@body))))))
;;;
;;; collision detection callback
;;;
(defcallback near-collision-callback :void ((data :pointer) (geom-id-1 ode:geom-id) (geom-id-2 ode:geom-id))
(let ((geom-1 (lookup geom-id-1))
(geom-2 (lookup geom-id-2)))
(if (or (is-space geom-1) (is-space geom-2))
(space-collide geom-1 geom-2 data (callback near-collision-callback))
(progn
(format t "~&Colliding geoms ~a <--> ~a~%" (md-name geom-1) (md-name geom-2))
(do-contacts (contact geom-1 geom-2)
(with-contact contact (surface contact-geom friction-dir-1)
(with-contact-geom contact-geom (pos normal)
(with-surface-parameters (surface geom-1 geom-2)
(progn (select-max mu bounce bounce-vel))
(mk-collision)))))))))
;;;
;;; high level collision detection routine
(defmacro with-collision ((space) &body body)
`(let ((*collision-joint-group* (mk-joint-group (* +max-collision-contacts+ 1000))))
(space-collide ,space (null-pointer) (callback near-collision-callback))
,@body
(ode-destroy *collision-joint-group*)))
--- /project/cells/cvsroot/cells-ode/core.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/core.lisp 2008/02/08 18:09:31 1.1
(in-package :cells-ode)
;;;
;;; General purpose utilities
;;;
(eval-when (:compile-toplevel :load-toplevel :execute)
(defmacro eval-now! (&body body)
`(eval-when (:compile-toplevel :load-toplevel :execute)
,@body)))
(eval-now!
(defun mk-list (var)
(if (listp var) var (list var)))
(defmacro nconcf (place add)
`(setf ,place (nconc (mk-list ,place) (mk-list ,add))))
(defmacro with-uniqs (syms &body body)
`(let ,(mapcar #'(lambda (sym) `(,sym (gensym ,(concatenate 'string (string sym) "-")))) (mk-list syms))
,@body))
(defmacro csetf (place value)
(with-uniqs newval
`(let ((,newval ,value))
(unless (eql ,newval ,place)
(setf ,place ,newval)))))
(defmacro dohash ((obj hash-table) &body body)
`(loop for ,obj being the hash-values of ,hash-table do ,@body))
(defun denil (lst)
(loop for x in lst if x collect x))
(defun concat (&rest parts)
(format nil "~:@(~{~@[~a~#[~:;-~]~]~}~)" (denil parts)))
(defun intern-string (&rest strings)
(intern (apply #'concat strings))))
;;; ODE function names
(eval-now!
(defun setter (name slot)
(intern-string name 'set slot))
(defun getter (name slot)
(intern-string name 'get slot)))
;;; deactivating an observer
;; later
;;;
;;; ODE model, method, function, call
;;;
(defvar *dbg* nil)
(defmacro with-dbg (&body body)
`(let ((*dbg* t))
,@body))
(eval-now!
(defun make-call (fn ret-type args-and-types &optional (self 'self))
(multiple-value-bind (args types) (parse-typed-args args-and-types)
(let (par-list result-arg-type)
(labels ((call-with (args types)
(let ((arg (car args))
(type (car types)))
(cond
((not args)
(let ((fn-call `(,(intern (string fn) :ode) ,@par-list)))
(if result-arg-type
`(progn ,fn-call result)
fn-call)))
((eq arg 'result)
(setf result-arg-type type)
(nconcf par-list arg)
(call-with (rest args) (rest types)))
(t
(nconcf par-list (make-convert arg type))
(make-with-ode arg type (list (call-with (rest args) (rest types))) self))))))
(let ((fn-call (call-with args types)))
(let ((fn-call-ret (bif (return-type (or ret-type result-arg-type))
(make-from-ode return-type (when result-arg-type 'result) (list fn-call))
fn-call)))
(with-uniqs result
`(if *dbg*
(progn
(format t ,(format nil "~&~%Calling ~a (~~@{~~a~~#[~~:; ~~]~~}) ... " fn) ,@(remove 'result args))
(let ((,result ,fn-call-ret))
(format t "==> ~a~%" ,result)
,result))
,fn-call-ret))))))))
(defun canonic-args-list (args-and-types)
(mapcar #'mk-list args-and-types))
(defun parse-typed-args (args-and-types)
(loop for (arg type) in (canonic-args-list args-and-types)
collect arg into args
collect type into types
finally (return (values args types))))
[110 lines skipped]
--- /project/cells/cvsroot/cells-ode/geoms.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/geoms.lisp 2008/02/08 18:09:31 1.1
[275 lines skipped]
--- /project/cells/cvsroot/cells-ode/joints.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/joints.lisp 2008/02/08 18:09:31 1.1
[472 lines skipped]
--- /project/cells/cvsroot/cells-ode/mass.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/mass.lisp 2008/02/08 18:09:31 1.1
[612 lines skipped]
--- /project/cells/cvsroot/cells-ode/objects.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/objects.lisp 2008/02/08 18:09:31 1.1
[732 lines skipped]
--- /project/cells/cvsroot/cells-ode/ode-compat.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/ode-compat.lisp 2008/02/08 18:09:31 1.1
[777 lines skipped]
--- /project/cells/cvsroot/cells-ode/package.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/package.lisp 2008/02/08 18:09:31 1.1
[787 lines skipped]
--- /project/cells/cvsroot/cells-ode/primitives.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/primitives.lisp 2008/02/08 18:09:31 1.1
[810 lines skipped]
--- /project/cells/cvsroot/cells-ode/simulate.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/simulate.lisp 2008/02/08 18:09:31 1.1
[862 lines skipped]
--- /project/cells/cvsroot/cells-ode/test-c-ode.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/test-c-ode.lisp 2008/02/08 18:09:31 1.1
[928 lines skipped]
--- /project/cells/cvsroot/cells-ode/types.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/types.lisp 2008/02/08 18:09:31 1.1
[1092 lines skipped]
--- /project/cells/cvsroot/cells-ode/utility.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/utility.lisp 2008/02/08 18:09:31 1.1
[1109 lines skipped]
--- /project/cells/cvsroot/cells-ode/world.lisp 2008/02/08 18:09:31 NONE
+++ /project/cells/cvsroot/cells-ode/world.lisp 2008/02/08 18:09:31 1.1
[1169 lines skipped]