
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]