From b1048e1d87f7f47b31b3dcb6c262eab4716c268a Mon Sep 17 00:00:00 2001 From: Kaveh Kardan <103860793+kaveh808@users.noreply.github.com> Date: Thu, 3 Aug 2023 11:11:27 -1000 Subject: [PATCH] Added time-varying-force-field --- src/kernel/noise.lisp | 6 ++++++ src/plugins/force-field.lisp | 20 ++++++++++++++++---- test/demo-parametric-curve.lisp | 13 +++++++++---- test/demo-particle.lisp | 32 +++++++++++++++++++++++++++++++- 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/kernel/noise.lisp b/src/kernel/noise.lisp index 7a6f060..c6002cb 100644 --- a/src/kernel/noise.lisp +++ b/src/kernel/noise.lisp @@ -91,6 +91,9 @@ (* y1 (+ (* x0 p012) (* x1 p112) (* x2 p212))) (* y2 (+ (* x0 p022) (* x1 p122) (* x2 p222)))))))) +(defun float-noise (v) + (noise (p! v 0 0))) + (defun turbulence (p n-octaves) (let ((sum 0.0) (scale 1.0)) @@ -108,6 +111,9 @@ (dz (- (noise (p! x y (+ z delta))) (noise (p! x y (- z delta)))))) (p! dx dy dz))) +(defun float-noise-gradient (v &optional (delta 0.01)) + (noise-gradient (p! v 0 0) delta)) + (defun color-noise (p &optional (delta 0.01)) (let ((pn (p:normalize (noise-gradient p delta)))) (c! (abs (p:x pn)) (abs (p:y pn)) (abs (p:z pn))))) diff --git a/src/plugins/force-field.lisp b/src/plugins/force-field.lisp index 53d0dc3..059b3d4 100644 --- a/src/plugins/force-field.lisp +++ b/src/plugins/force-field.lisp @@ -13,7 +13,7 @@ ;;;; constant-force-field ====================================================== (defclass constant-force-field (force-field) - ((force-vector :accessor force-vector :initarg :force-vector :initform (p! 0 -9.81 0)))) + ((force-vector :accessor force-vector :initarg :force-vector :initform (p! 0 0 0)))) (defmethod field-value ((field constant-force-field) point time) (declare (ignore point time)) @@ -33,13 +33,25 @@ (p! 0 0 0) (p:scale dir (/ (magnitude field) (* dist dist)))))) -;;;; noise-force-field ========================================================= +;;;; time-varying-force-field ================================================== -(defclass noise-force-field (force-field) +(defclass time-varying-force-field (constant-force-field) ((noise-frequency :accessor noise-frequency :initarg :noise-frequency :initform 1.0) (noise-amplitude :accessor noise-amplitude :initarg :noise-amplitude :initform 1.0))) -(defmethod field-value ((field noise-force-field) point time) +(defmethod field-value ((field time-varying-force-field) point time) + (declare (ignore point)) + (p+ (force-vector field) + (p:scale (float-noise-gradient (* time (noise-frequency field))) + (noise-amplitude field)))) + +;;;; 3d-noise-force-field ========================================================= + +(defclass 3d-noise-force-field (force-field) + ((noise-frequency :accessor noise-frequency :initarg :noise-frequency :initform 1.0) + (noise-amplitude :accessor noise-amplitude :initarg :noise-amplitude :initform 1.0))) + +(defmethod field-value ((field 3d-noise-force-field) point time) (declare (ignore time)) (p:scale (noise-gradient (p:scale point (noise-frequency field))) (noise-amplitude field))) diff --git a/test/demo-parametric-curve.lisp b/test/demo-parametric-curve.lisp index 6e5bbac..55452a7 100644 --- a/test/demo-parametric-curve.lisp +++ b/test/demo-parametric-curve.lisp @@ -155,8 +155,10 @@ Make sure you have opened the graphics window by doing: (make-spirograph-spring *scene* 2.5 0.7 0.6 t 0.0 2.0 2.0 1.0 0.5 :show-assembly? t :color (c! 0 0 1) :do-collisions? nil - :force-fields (list (make-instance 'constant-force-field - :force-vector (p! .1 0 0))))) + :force-fields (list (make-instance 'time-varying-force-field + :force-vector (p! 0 0 0) + :noise-frequency 10.0 + :noise-amplitude 8.0)))) ;;; hold down space key in 3D view to run animation ;;; run simulation @@ -168,8 +170,11 @@ Make sure you have opened the graphics window by doing: (make-spirograph-spring *scene* 2.5 0.7 0.6 t 0.0 2.0 2.0 1.0 0.5 :show-assembly? t :color (c! 0 0 1) :do-collisions? t - :force-fields (list (make-instance 'constant-force-field - :force-vector (p! .1 0 0))))) + :force-fields (list (make-instance 'time-varying-force-field + :force-vector (p! 0 0 0) + :noise-frequency 10.0 + :noise-amplitude 8.0)))) + ;;; hold down space key in 3D view to run animation ;;; run simulation diff --git a/test/demo-particle.lisp b/test/demo-particle.lisp index 6da336e..cf1ad66 100644 --- a/test/demo-particle.lisp +++ b/test/demo-particle.lisp @@ -194,7 +194,7 @@ force field. 'dynamic-particle :life-span -1 ;infinite life-span :do-collisions? nil - :force-fields (list (make-instance 'noise-force-field + :force-fields (list (make-instance '3d-noise-force-field :noise-frequency 0.2 :noise-amplitude 0.2))))) (add-shape *scene* shape) @@ -348,6 +348,36 @@ Create a row particle systems with varrying attributes. (update-scene *scene* 30) ;do update for batch testing +#| +(Demo 14 particle) dynamic particle system ===================================== + +Dynamic particles growing from a superquadric with a time-varying force field. +|# + +(format t " particle-system 14...~%") (finish-output) + +(with-clear-scene + (let ((p-source (freeze-transform (make-superquadric 16 8 2.0 1.0 1.0)))) + (setf (point-source-use-face-centers? p-source) t) ;comment out to use poly points + (let ((p-sys (make-particle-system-from-point-source + p-source + (lambda (v) (p:scale v 0.2)) + 'dynamic-particle + :life-span -1 ;infinite life-span + :do-collisions? nil + :force-fields (list (make-instance 'time-varying-force-field + :force-vector (p! 0 -0.0 0) + :noise-frequency 100 + :noise-amplitude 4.0))))) + (add-shape *scene* p-source) + (add-shape *scene* p-sys) + (add-motion *scene* p-sys)))) +;;; hold down space key in 3D view to run animation + +;;; for automated testing +(update-scene *scene* 30) + + #| END ============================================================================ |#