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-misc.lisp b/test/demo-misc.lisp index dac5e17..aecc8b6 100644 --- a/test/demo-misc.lisp +++ b/test/demo-misc.lisp @@ -168,7 +168,7 @@ in this and demos below, update the *EXAMPLE-MOL-FILENAME* for your setup.") (with-clear-scene (let* ((p-sys (make-particle-system (make-point-cloud (vector (p! 0 0.1 0))) (p! 0 .2 0) 10 -1 'particle - :update-angle (range-float (/ pi 8) (/ pi 16)) + :update-angle (range-float 20.0 10.0) :life-span (rand1 5 10)))) ; (setf (draw-live-points-only? p-sys) nil) (setf (name p-sys) 'p-system) @@ -187,7 +187,7 @@ in this and demos below, update the *EXAMPLE-MOL-FILENAME* for your setup.") (with-clear-scene (let* ((p-sys (make-particle-system (make-point-cloud (vector (p! 0 0.1 0))) (p! 0 .2 0) 10 -1 'particle - :update-angle (range-float (/ pi 8) (/ pi 16)) + :update-angle (range-float 20.0 10.0) :life-span (rand1 5 10))) (shape (make-point-instancer-group p-sys (make-octahedron .2)))) 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 ============================================================================ |# diff --git a/test/demo-sweep-mesh.lisp b/test/demo-sweep-mesh.lisp index ec462d8..77aa04a 100644 --- a/test/demo-sweep-mesh.lisp +++ b/test/demo-sweep-mesh.lisp @@ -83,7 +83,7 @@ with the particle system. (lambda (v) (p:scale v 0.2)) 'particle :life-span (round (rand2 5 10)) - :update-angle (range-float (/ pi 16) (/ pi 32)))) + :update-angle (range-float 20.0 10.0))) (sweep-mesh-group (make-sweep-mesh-group (make-circle 0.1 6) p-sys :taper 1.0 :twist 0.0))) (add-shape *scene* p-source) @@ -107,7 +107,7 @@ The mesh automatically grows with the particle system. (p-sys (make-particle-system-from-point (p! 0 3.0 0) 1 (p! -.5 0 -.5) (p! .5 0 .5) 'climbing-particle :support-polyh shape - :update-angle (range-float (/ pi 8) (/ pi 16)) + :update-angle (range-float 20.0 10.0) :life-span -1)) (sweep-mesh-group (make-sweep-mesh-group (make-circle 0.2 6) p-sys :taper 1.0 :twist 0.0))) diff --git a/test/demo-uv-mesh.lisp b/test/demo-uv-mesh.lisp index 8c0e40c..594e882 100644 --- a/test/demo-uv-mesh.lisp +++ b/test/demo-uv-mesh.lisp @@ -150,7 +150,7 @@ Create a group of UV-MESH shapes along a PARTICLE-SYSTEM. (with-clear-scene (let* ((p-sys (make-particle-system-from-point (p! 0 0 0) 10 (p! -.2 .2 -.2) (p! .2 .5 .2) 'particle - :update-angle (range-float (/ pi 8) (/ pi 16))))) + :update-angle (range-float 20.0 10.0)))) (setf (name p-sys) 'p-system) (add-shape *scene* p-sys) (add-motion *scene* p-sys)))