package.lisp should constantly be looked at since aside from the
documentation, its the only thing informing us of a given API and its expected
usage
v:trace is used a lot across Trial
(defmethod glfw:mouse-scrolled ((context context) x y) (v:trace :trial.input "Mouse wheel: ~a ~a" x y) (%handle context 'mouse-scroll :pos (mouse-pos context) :delta y))
trial/context.lisp is useful:
(let ((c (context +main+))) (values (valid-p c) (vsync c) (title c) (width c) (height c))) ;; => T ;; :OFF ;; "Trial" ;; 1651 ;; 1408
Note: The backend we use is glfw, so also take a look at trial/backends/glfw/context.lisp
trial/camera.lisp
Every camera is a:
located-entitylistenerEvery camera instance has a:
namelocationnear-planefar-planebsizeCameras of interest:
camera3d-cameratarget-camerapivot-camerafollowing-camerafps-camerafreeroam-cameraeditor-cameraMethods usually specialized for 3d cameras:
project-viewsetup-perspectivein-view-pfocal-pointNo matter the 3d camera setup, what am I always updating?
Update process:
xz location (simply a vector)
In keymap.lisp we only specify actions. Meaning, ACTION-SETs are not relevant to
the actual binding of EVENT<->KEY. The action sets are just a convenient way of
grouping together actions (events) so we can decide what actions are enabled at
any given time. Think of it like modality: action sets are 'layers' or 'modes'.
If your keymap isn't being updated no matter how many times you (load-keymap
:reset t), perhaps combined with a weird error when you try to press the
button/key in the game window:
unknown type specifier: KEYS
[Condition of type SIMPLE-ERROR]
Restarts:
0: [ABORT] Don't handle #<KEY-PRESS :V> in #<CONTROLLER :CONTROLLER {10010D7CA3}>.
You may be a victim of ✨being dumb✨ and missing a paren:
(trigger spectate (keys :one-of (:v)))
If you use (keys ...), use two paren forms: ((:v))
trial/container.lisptrial/helpers.lisp though not
clear on the overall scope of what's being done in this file.Shinmera nicely summed things up for me:
node → anything that can be part of the scene graph container → can hold other nodes entity → a node that has a global name
Given a thing
(define-shader-entity cube (vertex-entity transformed-entity listener) ((vertex-array :initform (// 'trial 'unit-cube))))
which we can enter, then we can also :name it, thereby becoming an entity
(enter (make-instance 'cube :name :bob) scene)
Regardless of whether it's an entity or not, its a node, and nodes go into the scene graph. We can query the node graph:
(node :bob T)
;; => #<CUBE :BOB {1000F5DD23}>
;; T
(do-scene-graph (n (scene +main+))
(format t "~%~A" n))
;; => #<PIPELINED-SCENE {1000D26C03}>
;; #<CUBE {10017C7173}>
;; #<CUBE :BOB {1000F5DD23}>
;; #<CONTROLLER :CONTROLLER {10017C7153}>
;;
;; NIL
Oddly enough, certain nodes can be found despite not being returned from
do-scene-graph. Something to figure out or ask about later
(node :camera (scene +main+))
;; => #<FPS-CAMERA :CAMERA {10014A1993}>
;; T
enter and leave are methods responsible for registering and deregistering
objects we add to a scene. For example, in Trial the base camera class is
defined as such:
(defclass scene (bag event-loop) ((camera :initarg :camera :initform NIL :accessor camera) (name-map :initform (make-hash-table :test 'equal) :accessor name-map)))
And has an enter and leave method:
(defmethod enter ((camera camera) (scene scene))
(register camera scene)
(unless (camera scene)
(setf (camera scene) camera)))
(defmethod leave ((camera camera) (scene scene))
(deregister camera scene)
(when (eq camera (camera scene))
(setf (camera scene) NIL)))
So, a question: when you (enter (make-instance '3d-camera) scene), how many
enter methods are happening for this one call?
Answer: 4
(compute-applicable-methods #'enter (list (make-instance '3d-camera)
(scene +main+)))