(in-package #:trial) (defclass workbench (main) () (:default-initargs :clear-color (vec 0.25 0.3 0.35 0))) (define-pool workbench) (define-asset (workbench grid) mesh (make-line-grid 10 100 100)) (define-shader-entity grid (vertex-entity) ((vertex-array :initform (// 'workbench 'grid)))) (define-shader-entity rope (lines listener) ((points :reader points) (previous :reader previous) (distance :initarg :distance :reader distance) (anchor :initarg :anchor :initform (vec 0 0 0) :accessor anchor)) (:default-initargs :distance 5)) (defmethod initialize-instance :after ((rope rope) &key distance (count 50)) (let ((points (make-array count)) (previous (make-array count))) (loop for i from 0 below count for x from 0 by distance do (setf (aref points i) (vec x 0 0)) (setf (aref previous i) (vcopy (aref points i)))) (setf (slot-value rope 'points) points) (setf (slot-value rope 'previous) previous))) (defmethod handle ((ev mouse-move) (rope rope)) (vsetf (anchor rope) (vx (pos ev)) (vy (pos ev))) (nv- (anchor rope) (vec 400 300 0))) (defmethod handle ((ev tick) (rope rope)) (let ((points (points rope)) (previous (previous rope)) (dist (distance rope)) (anchor (anchor rope))) (loop for i from 0 below (length points) for pos = (aref points i) for prev = (aref previous i) do (vsetf prev (vx pos) (vy pos)) (nv+ pos (v- pos prev) (v* (dt ev) (vec 0 -98.1 0)))) ;; Substeps (dotimes (s 50) (vsetf (aref points 0) (vx anchor) (vy anchor) (vz anchor)) (when (retained :left) (let ((base (aref points 20))) (loop for i from 1 to 5 do (vsetf (aref points (+ 20 i)) (+ (vx base) (* dist i)) (+ (vy base)) (vz base))))) (loop for i from 1 below (length points) for n1 = (aref points (1- i)) for n2 = (aref points i) for cdist = (vlength (v- n1 n2)) for diff = (abs (- cdist dist)) for dir = (cond ((< dist cdist) (nvunit (v- n1 n2))) ((< cdist dist) (nvunit (v- n2 n1))) (T (vec 0 0 0))) for move = (v* dir diff 0.5) do (nv- n1 move) (nv+ n2 move))) ;; Update (let ((mesh (make-instance 'vertex-mesh :vertex-type 'line-vertex))) (with-vertex-filling (mesh) (loop for i from 1 below (length points) for a = (aref points (1- i)) for b = (aref points i) do (vertex :location a :normal (v- a b) :color (vec 0 0 0 1)) (vertex :location b :normal (v- a b) :color (vec 0 0 0 1)) (vertex :location a :normal (v- b a) :color (vec 0 0 0 1)) (vertex :location b :normal (v- a b) :color (vec 0 0 0 1)) (vertex :location b :normal (v- b a) :color (vec 0 0 0 1)) (vertex :location a :normal (v- b a) :color (vec 0 0 0 1)))) (replace-vertex-data (vertex-array rope) mesh :update T)))) (progn (defmethod setup-scene ((workbench workbench) scene) (enter (make-instance 'grid) scene) (enter (make-instance 'rope) scene) (enter (make-instance 'editor-camera) scene) (enter (make-instance 'render-pass) scene)) (maybe-reload-scene))